From: Keith Marshall Date: Mon, 19 Aug 2013 14:56:08 +0000 (+0100) Subject: Add facility for control of child window placement. X-Git-Tag: r0.1.2~3 X-Git-Url: http://git.osdn.net/view?p=mingw%2Fwtklite.git;a=commitdiff_plain;h=8a62513a814901c984042683c701ce2f2f715d7b Add facility for control of child window placement. --- diff --git a/ChangeLog b/ChangeLog index 09b8254..a99d7d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,24 @@ 2013-08-19 Keith Marshall + 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 + Convert to one-shot C++ compilation with dependency tracking. * Makefile.in (DEPFLAGS): Redefine; incorporate CPPFLAGS. diff --git a/Makefile.in b/Makefile.in index 5589ce8..2c44c8d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -44,11 +44,13 @@ exec_prefix = @exec_prefix@ 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. @@ -64,7 +66,7 @@ all: libwtklite.a 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) $@ $^ @@ -88,6 +90,9 @@ vsashctl.$(OBJEXT): sashctrl.cpp sashctrl.o # Other object modules may be implicitly compiled. # +%.$(OBJEXT): %.c + $(CC) -c $(DEPFLAGS) $(CFLAGS) -o $@ $< + %.$(OBJEXT): %.cpp $(CXX) -c $(DEPFLAGS) $(CXXFLAGS) -o $@ $< @@ -103,7 +108,7 @@ install: install-dirs install-headers install-libs 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 @@ -113,9 +118,9 @@ 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 diff --git a/configure.ac b/configure.ac index 809884a..cae230b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # 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. @@ -8,7 +8,7 @@ # $Id$ # # Written by Keith Marshall -# Copyright (C) 2012, MinGW.org Project. +# Copyright (C) 2012, 2013, MinGW.org Project. # # --------------------------------------------------------------------------- # @@ -35,8 +35,9 @@ # AC_PREFIX_DEFAULT([/mingw]) -# Identify compiler. +# Identify compilers. # + AC_PROG_CC AC_PROG_CXX # Identify other tools. diff --git a/dlgproc.cpp b/dlgproc.cpp index 483e38c..11ed73d 100644 --- a/dlgproc.cpp +++ b/dlgproc.cpp @@ -12,7 +12,7 @@ * which is available to all window classes derived from GenericDialogue. * * Written by Keith Marshall - * Copyright (C) 2012, MinGW.org Project. + * Copyright (C) 2012, 2013, MinGW.org Project. * * --------------------------------------------------------------------------- * @@ -41,6 +41,7 @@ #define WIN32_LEAN_AND_MEAN #include "wtklite.h" +#include "wtkalign.h" namespace WTK { @@ -55,9 +56,11 @@ 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: diff --git a/wtkalign.c b/wtkalign.c new file mode 100644 index 0000000..e6b8541 --- /dev/null +++ b/wtkalign.c @@ -0,0 +1,167 @@ +/* + * 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 + * 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 +#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 */ diff --git a/wtkalign.h b/wtkalign.h new file mode 100644 index 0000000..270ff68 --- /dev/null +++ b/wtkalign.h @@ -0,0 +1,95 @@ +#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 + * 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 */