OSDN Git Service

Add facility for control of child window placement.
authorKeith Marshall <keithmarshall@users.sourceforge.net>
Mon, 19 Aug 2013 14:56:08 +0000 (15:56 +0100)
committerKeith Marshall <keithmarshall@users.sourceforge.net>
Mon, 19 Aug 2013 14:56:08 +0000 (15:56 +0100)
ChangeLog
Makefile.in
configure.ac
dlgproc.cpp
wtkalign.c [new file with mode: 0644]
wtkalign.h [new file with mode: 0644]

index 09b8254..a99d7d3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 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.
index 5589ce8..2c44c8d 100644 (file)
@@ -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
 
index 809884a..cae230b 100644 (file)
@@ -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 <keithmarshall@users.sourceforge.net>
-# 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.
index 483e38c..11ed73d 100644 (file)
@@ -12,7 +12,7 @@
  * 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.
  *
  * ---------------------------------------------------------------------------
  *
@@ -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 (file)
index 0000000..e6b8541
--- /dev/null
@@ -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 <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 */
diff --git a/wtkalign.h b/wtkalign.h
new file mode 100644 (file)
index 0000000..270ff68
--- /dev/null
@@ -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 <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 */