2013-08-19 Keith Marshall <keithmarshall@users.sourceforge.net>
+ Add facility for control of child window placement.
+
+ * wtkalign.h: New file; it declares the API for...
+ (AlignWindow): ...this new extern "C" function; declare it.
+ * wtkalign.c: New file; implement it.
+
+ * dlgproc.cpp (GenericDialogue::Dismiss) [WM_INITDIALOG]: Use it.
+
+ * configure.ac (AC_INIT): Bump version number to 0.1.1
+ (AC_PROG_CC): Add test for C compiler.
+
+ * Makefile.in (LIBWTK_OBJECTS): Add wtkalign.$OBJEXT
+ (CC, CFLAGS): Define for compilation of C code, according to...
+ (%.$OBJEXT: %.c): ...this new build rule; define it.
+ (SRCDIST_FILES): Add wtkalign.c and wtkalign.h
+ (install-headers): Add wtkalign.h
+
+2013-08-19 Keith Marshall <keithmarshall@users.sourceforge.net>
+
Convert to one-shot C++ compilation with dependency tracking.
* Makefile.in (DEPFLAGS): Redefine; incorporate CPPFLAGS.
includedir = @includedir@
libdir = @libdir@
-# Compiler identification; note that this is a C++ only project.
+# Compiler identification.
#
+CC = @CC@
CXX = @CXX@
CPPFLAGS = @CPPFLAGS@
CXXFLAGS = @CXXFLAGS@
+CFLAGS = @CFLAGS@
OBJEXT = @OBJEXT@
# Archive librarian identification.
LIBWTK_OBJECTS = wtkbase.$(OBJEXT) wtkmain.$(OBJEXT) wndproc.$(OBJEXT) \
dlgproc.$(OBJEXT) wtkchild.$(OBJEXT) wtkexcept.$(OBJEXT) errtext.$(OBJEXT) \
sashctrl.$(OBJEXT) hsashctl.$(OBJEXT) vsashctl.$(OBJEXT) strres.$(OBJEXT) \
- wtkraise.$(OBJEXT)
+ wtkraise.$(OBJEXT) wtkalign.$(OBJEXT)
libwtklite.a: $(LIBWTK_OBJECTS)
$(AR) $(ARFLAGS) $@ $^
# Other object modules may be implicitly compiled.
#
+%.$(OBJEXT): %.c
+ $(CC) -c $(DEPFLAGS) $(CFLAGS) -o $@ $<
+
%.$(OBJEXT): %.cpp
$(CXX) -c $(DEPFLAGS) $(CXXFLAGS) -o $@ $<
install-dirs:
$(MKDIR_P) ${includedir} ${libdir}
-install-headers: wtklite.h wtkdefs.h wtkexcept.h
+install-headers: wtklite.h wtkdefs.h wtkalign.h wtkexcept.h
$(INSTALL_DATA) $^ ${includedir}
install-libs: libwtklite.a
#
TARNAME = $(PACKAGE)-$(VERSION)-mingw32
SRCDIST_FILES = ChangeLog configure configure.ac Makefile.in install-sh \
- wtklite.h wtkdefs.h wtkexcept.h wtkbase.cpp wtkmain.cpp wtkchild.cpp \
+ wtklite.h wtkdefs.h wtkalign.h wtkexcept.h wtkbase.cpp wtkmain.cpp wtkchild.cpp \
wndproc.cpp dlgproc.cpp sashctrl.cpp wtkexcept.cpp errtext.cpp strres.cpp \
- wtkraise.cpp
+ wtkraise.cpp wtkalign.c
dist: srcdist devdist
# configure.ac
#
- AC_INIT([wtklite],[0.1.0],[http://mingw.org/Reporting_Bugs])
+ AC_INIT([wtklite],[0.1.1],[http://mingw.org/Reporting_Bugs])
#
# Implementation of a minimal C++ class framework for use with the
# Microsoft Windows Application Programming Interface.
# $Id$
#
# Written by Keith Marshall <keithmarshall@users.sourceforge.net>
-# Copyright (C) 2012, MinGW.org Project.
+# Copyright (C) 2012, 2013, MinGW.org Project.
#
# ---------------------------------------------------------------------------
#
#
AC_PREFIX_DEFAULT([/mingw])
-# Identify compiler.
+# Identify compilers.
#
+ AC_PROG_CC
AC_PROG_CXX
# Identify other tools.
* which is available to all window classes derived from GenericDialogue.
*
* Written by Keith Marshall <keithmarshall@users.sourceforge.net>
- * Copyright (C) 2012, MinGW.org Project.
+ * Copyright (C) 2012, 2013, MinGW.org Project.
*
* ---------------------------------------------------------------------------
*
#define WIN32_LEAN_AND_MEAN
#include "wtklite.h"
+#include "wtkalign.h"
namespace WTK
{
/* We need to handle only two message types:
*/
case WM_INITDIALOG:
- /*
- * We make this a no-op, while marking it as handled.
+ /* Other than positioning this dialogue box centrally,
+ * relative to its parent window, we make this a no-op,
+ * while marking it as handled.
*/
+ AlignWindow( window, WTK_ALIGN_CENTRED );
return TRUE;
case WM_COMMAND:
--- /dev/null
+/*
+ * wtkalign.c
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * Implementation of a minimal C++ class framework for use with the
+ * Microsoft Windows Application Programming Interface.
+ *
+ * $Id$
+ *
+ * This file provides the implementation of AlignWindow(), a helper
+ * function for controlling the placement of child windows relative
+ * to their parent, or to the screen bounds.
+ *
+ * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
+ * Copyright (C) 2013, MinGW.org Project.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice, this permission notice, and the following
+ * disclaimer shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ */
+#define WIN32_LEAN_AND_MEAN
+
+#include <windows.h>
+#include "wtkalign.h"
+
+void AlignWindow( HWND child, unsigned int alignment )
+{
+ /* Helper to be invoked while handling a WM_CREATE or WM_INITDIALOG
+ * message; it adjusts the position at which the window or dialogue
+ * box is created, such that it is displayed either neatly centred,
+ * or flush with specified boundaries, on the screen, or within its
+ * parent window.
+ */
+ HWND parent = ((alignment & WTK_ALIGN_ONSCREEN) == 0)
+ /*
+ * Unless alignment relative to the screen is specified, we must
+ * identify the parent window from which the alignment bounds are
+ * to be deduced.
+ */
+ ? GetParent( child )
+ : NULL;
+
+ if( parent == NULL )
+ /* When no parent has yet been identified, we are either explicitly
+ * attempting to align within the desktop bounds, or the window we
+ * are attempting to align has no valid parent; in either case, we
+ * use the desktop window as the effective parent.
+ */
+ parent = GetDesktopWindow();
+
+ if( parent != NULL )
+ {
+ /* We now have a valid effective parent, so we may continue...
+ */
+ RECT screen, window;
+ unsigned int mode;
+
+ /* First, we obtain the physical co-ordinates of the four corners
+ * for both the dialogue box in its default position, and for the
+ * parent window, all mapped as screen co-ordinates.
+ */
+ GetWindowRect( child, &window );
+ GetWindowRect( parent, &screen );
+
+ /* Adjust the left-right position, setting the left ordinate for the
+ * "screen" co-ordinate group to the physical left ordinate for final
+ * placement of the dialogue on-screen...
+ */
+ switch( mode = alignment & WTK_ALIGN_HCENTRE )
+ {
+ case WTK_ALIGN_RIGHT:
+ case WTK_ALIGN_HCENTRE:
+ /* In the case of right or centred alignment, we initially push
+ * the left ordinate of the "window" co-ordinate group as far to
+ * the right as possible, while still keeping the window within
+ * the designated screen bounds...
+ */
+ window.left += screen.right - screen.left - window.right;
+ if( mode == WTK_ALIGN_HCENTRE )
+ /* ...then, in the centred case, we move it back to the left,
+ * by half of the distance between the leftmost "screen" bound
+ * and the right-adjusted "window" ordinate.
+ */
+ screen.left += (window.left > 0) ? window.left >> 1 : 0;
+
+ case WTK_ALIGN_LEFT:
+ /* In the case of left alignment we have nothing to do -- the
+ * left bound of the "screen" co-ordinate group is already set
+ * to the position where we want to place the left side of the
+ * aligned window.
+ */
+ break;
+
+ default:
+ /* In the case where no left-right alignment is specified, we
+ * can simply make the left "screen" ordinate coincide with the
+ * default position of the window.
+ */
+ screen.left = window.left;
+ }
+
+ /* Adjust the top-bottom position, setting the top ordinate for the
+ * "screen" co-ordinate group to the physical top ordinate for final
+ * placement of the dialogue on-screen...
+ */
+ switch( mode = alignment & WTK_ALIGN_VCENTRE )
+ {
+ case WTK_ALIGN_BOTTOM:
+ case WTK_ALIGN_VCENTRE:
+ /* In the case of bottom or centred alignment, we initially push
+ * the top ordinate of the "window" co-ordinate group downwards as
+ * far as is possible, while still keeping the window within the
+ * designated screen bounds...
+ */
+ window.top += screen.bottom - screen.top - window.bottom;
+ if( mode == WTK_ALIGN_VCENTRE )
+ /* ...then, in the centred case, we adjust it upwards again,
+ * by half of the distance between the topmost "screen" bound
+ * and the downwards adjusted top "window" ordinate.
+ */
+ screen.top += (window.top > 0) ? window.top >> 1 : 0;
+
+ case WTK_ALIGN_TOP:
+ /* In the case of top alignment we have nothing to do -- the
+ * top bound of the "screen" co-ordinate group is already set
+ * to the position where we want to place the top edge of the
+ * aligned window.
+ */
+ break;
+
+ default:
+ /* In the case where no top-bottom alignment is specified, we
+ * can simply make the top "screen" ordinate coincide with the
+ * default position of the window.
+ */
+ screen.top = window.top;
+ }
+
+ /* Finally, we reposition the dialogue box to the top left screen
+ * co-ordinate we've just computed, preserving its original size.
+ */
+ SetWindowPos( child, HWND_TOP, screen.left, screen.top, 0, 0, SWP_NOSIZE );
+ }
+}
+
+/* $RCSfile$: end of file */
--- /dev/null
+#ifndef WTKALIGN_H
+/*
+ * wtkalign.h
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * Implementation of an AlignWindow() function, to complement the
+ * Microsoft Windows Application Programming Interface.
+ *
+ * $Id$
+ *
+ * This header file is to be included by all users of AlignWindow().
+ *
+ * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
+ * Copyright (C) 2013, MinGW.org Project.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice, this permission notice, and the following
+ * disclaimer shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ */
+#define WTKALIGN_H 1
+
+/* AlignWindow() is written in C, but for C++ clients we subsume
+ * it into the WTK namespace.
+ */
+#include "wtkdefs.h"
+
+BEGIN_NAMESPACE( WTK )
+
+/* Specify reference bounds for child window alignment.
+ * By default, child windows are aligned within the frame of their parent.
+ * Adding this bit-flag, (by bit-wise OR), to the alignment parameter which
+ * is passed to the WTK::AlignWindow function, will override this default,
+ * so alignment becomes relative to the screen bounds.
+ */
+#define WTK_ALIGN_ONSCREEN 0x0100
+
+/* Define the individual component flags, for specification of window
+ * placement relative to each of the four alignment boundaries.
+ */
+#define WTK_ALIGN_LEFT 0x0001
+#define WTK_ALIGN_RIGHT 0x0002
+#define WTK_ALIGN_HCENTRE 0x0003
+#define WTK_ALIGN_TOP 0x0010
+#define WTK_ALIGN_BOTTOM 0x0020
+#define WTK_ALIGN_VCENTRE 0x0030
+
+/* Combine these, to define the nine logical placement classes.
+ */
+#define WTK_ALIGN_TOPLEFT ( WTK_ALIGN_TOP | WTK_ALIGN_LEFT )
+#define WTK_ALIGN_TOPRIGHT ( WTK_ALIGN_TOP | WTK_ALIGN_RIGHT )
+#define WTK_ALIGN_CENTRETOP ( WTK_ALIGN_TOP | WTK_ALIGN_HCENTRE )
+#define WTK_ALIGN_CENTRELEFT ( WTK_ALIGN_LEFT | WTK_ALIGN_VCENTRE )
+#define WTK_ALIGN_CENTRERIGHT ( WTK_ALIGN_RIGHT | WTK_ALIGN_VCENTRE )
+#define WTK_ALIGN_CENTRED ( WTK_ALIGN_HCENTRE | WTK_ALIGN_VCENTRE )
+#define WTK_ALIGN_CENTREBOTTOM ( WTK_ALIGN_BOTTOM | WTK_ALIGN_HCENTRE )
+#define WTK_ALIGN_BOTTOMRIGHT ( WTK_ALIGN_BOTTOM | WTK_ALIGN_RIGHT )
+#define WTK_ALIGN_BOTTOMLEFT ( WTK_ALIGN_BOTTOM | WTK_ALIGN_LEFT )
+
+/* Provide a set of aliases to suit American users, (and any others
+ * who can't spell "centre").
+ */
+#define WTK_ALIGN_CENTERED WTK_ALIGN_CENTRED
+#define WTK_ALIGN_CENTERTOP WTK_ALIGN_CENTRETOP
+#define WTK_ALIGN_CENTERLEFT WTK_ALIGN_CENTRELEFT
+#define WTK_ALIGN_CENTERBOTTOM WTK_ALIGN_CENTREBOTTOM
+#define WTK_ALIGN_CENTERRIGHT WTK_ALIGN_CENTRERIGHT
+
+/* Declare the prototype for the alignmemnt function.
+ */
+EXTERN_C void AlignWindow( HWND child, unsigned int alignment );
+
+END_NAMESPACE( WTK )
+
+#endif /* WTKALIGN_H: $RCSfile$: end of file */