]> git.saurik.com Git - wxWidgets.git/commitdiff
prevent the parent window from losing activation when a popup is shown
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 25 May 2002 13:02:58 +0000 (13:02 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 25 May 2002 13:02:58 +0000 (13:02 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15662 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/popupwin.h
include/wx/msw/toplevel.h
include/wx/popupwin.h
src/msw/frame.cpp
src/msw/popupwin.cpp
src/msw/toplevel.cpp
src/msw/window.cpp

index 3ec588a47680b7044c8991adb7e3d98de8e8b1d7..9147f5bac1c64c836b36a062fae15e3154d5a169 100644 (file)
@@ -30,11 +30,26 @@ public:
 
     bool Create(wxWindow *parent, int flags = wxBORDER_NONE);
 
+    // implementation only from now on
+    // -------------------------------
+
+    // override Show() to prevent wxPopupWindow from being activated
+    virtual bool Show(bool show = TRUE);
+
+    // find a shown popup window with the given window as parent, return NULL
+    // if none
+    static wxPopupWindow *FindPopupFor(wxWindow *win);
+
 protected:
+    // popups handle the position like wxTopLevelWindow, not wxWindow
     virtual void DoGetPosition(int *x, int *y) const;
 
+    // return the style to be used for the popup windows
     virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle) const;
 
+    // the list of all currently shown popup windows used by FindPopupFor()
+    static wxWindowList ms_shownPopups;
+
     DECLARE_DYNAMIC_CLASS(wxPopupWindow)
 };
 
index 85bf00c07286e73bdf65aa09012b2d9f10c7ead7..5db5199e477787ec0c6db3ca6355abed393a1c86 100644 (file)
@@ -89,10 +89,17 @@ protected:
     // common part of Iconize(), Maximize() and Restore()
     void DoShowWindow(int nShowCmd);
 
+    // prevent the window from being deactivated sometimes (see comments in the
+    // code)
+    long HandleNcActivate(bool activate);
+
     // translate wxWindows flags to Windows ones
     virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle) const;
 
-    // is the frame currently iconized?
+    // we handle WM_NCACTIVATE specially here
+    virtual long MSWWindowProc(WXUINT msg, WXWPARAM wParam, WXLPARAM lParam);
+
+    // is the window currently iconized?
     bool m_iconized;
 
     // should the frame be maximized when it will be shown? set by Maximize()
index 63c4d65eead6c65a56eec2b5d26406ddfb93d469..b4558ee4d468106c8301be95fe3ff0b228316cd3 100644 (file)
@@ -86,8 +86,10 @@ public:
 
     // hide the window
     virtual void Dismiss();
-    
 
+    // can the window be dismissed now?
+    //
+    // VZ: where is this used??
     virtual bool CanDismiss()
         { return TRUE; }
 
index 99f1e9c7634efe9265d5e26f87ff1b0ef236e5dc..98c8c7eacdcd5523ef33754120cad4d4fa68711e 100644 (file)
@@ -841,7 +841,7 @@ long wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
     }
 
     if ( !processed )
-        rc = wxWindow::MSWWindowProc(message, wParam, lParam);
+        rc = wxFrameBase::MSWWindowProc(message, wParam, lParam);
 
     return rc;
 }
index ab655565667aebeec8979f59cff35299ef92429b..87d82460ca5e9f2ed366318ef5301ef8f4fe4993 100644 (file)
@@ -35,6 +35,8 @@
 
 #include "wx/msw/private.h"     // for WS_CHILD and WS_POPUP
 
+wxWindowList wxPopupWindow::ms_shownPopups;
+
 // ============================================================================
 // implementation
 // ============================================================================
@@ -76,3 +78,43 @@ WXDWORD wxPopupWindow::MSWGetStyle(long flags, WXDWORD *exstyle) const
     return style;
 }
 
+bool wxPopupWindow::Show(bool show)
+{
+    // skip wxWindow::Show() which calls wxBringWindowToTop(): this results in
+    // activating the popup window and stealing the atcivation from our parent
+    // which means that the parent frame becomes deactivated when opening a
+    // combobox, for example -- definitely not what we want
+    if ( !wxWindowBase::Show(show) )
+        return FALSE;
+
+    if ( show )
+    {
+        ms_shownPopups.Append(this);
+    }
+    else // remove from the shown list
+    {
+        ms_shownPopups.DeleteObject(this);
+    }
+
+    ::ShowWindow(GetHwnd(), show ? SW_SHOWNOACTIVATE : SW_HIDE);
+
+    return TRUE;
+}
+
+/* static */
+wxPopupWindow *wxPopupWindow::FindPopupFor(wxWindow *winParent)
+{
+    // find a popup with the given parent in the linked list of all shown
+    // popups
+    for ( wxWindowList::Node *node = ms_shownPopups.GetFirst();
+          node;
+          node = node->GetNext() )
+    {
+        wxWindow *win = node->GetData();
+        if ( win->GetParent() == winParent )
+            return (wxPopupWindow *)win;
+    }
+
+    return NULL;
+}
+
index 8283ec20d63680fad47c24cc543ed5a1ac2c2982..83c019347d4182b5ebd82376f576622e082bcb02 100644 (file)
@@ -39,6 +39,8 @@
 
 #include "wx/msw/private.h"
 
+#include "wx/popupwin.h"
+
 #ifndef ICON_BIG
     #define ICON_BIG 1
 #endif
@@ -653,3 +655,41 @@ bool wxTopLevelWindowMSW::EnableCloseButton(bool enable)
     return TRUE;
 }
 
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowMSW message processing
+// ----------------------------------------------------------------------------
+
+long wxTopLevelWindowMSW::HandleNcActivate(bool activate)
+{
+#if wxUSE_POPUPWIN
+    /*
+       Normally, when another top level (whether it is overlapped or popup)
+       window is shown, it is activated and the parent window (i.e. we) loses
+       the activation. This, however, looks very ugly when the child window is
+       a [custom] combobox which we implement using a popup window as surely
+       opening a combobox shouldn't result in deactivating the parent window.
+
+       So we don't redraw the title bar in this case, even if we still return
+       TRUE to let the change of activation to take place as otherwise the
+       controls inside the popup window wouldn't work properly.
+     */
+    if ( !activate && wxPopupWindow::FindPopupFor(this) )
+    {
+        return TRUE;
+    }
+#endif // wxUSE_POPUPWIN
+
+    return FALSE;
+}
+
+long
+wxTopLevelWindowMSW::MSWWindowProc(WXUINT msg, WXWPARAM wParam, WXLPARAM lParam)
+{
+    if ( msg == WM_NCACTIVATE && HandleNcActivate(wParam != 0) )
+    {
+        // we processed WM_NCACTIVATE ourselves
+        return TRUE;
+    }
+
+    return wxTopLevelWindowBase::MSWWindowProc(msg, wParam, lParam);
+}
index 19ee42d586a770872ebfd105e39da206c921d1a3..ebd05bfd52bd386c847d68b3d697b0c41a336cd0 100644 (file)
@@ -2918,31 +2918,19 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
     wxWindow *parent = GetParent();
     bool isChild = (style & WS_CHILD) != 0;
     HWND hParent;
-    if ( GetWindowStyleFlag() & wxPOPUP_WINDOW )
+    if ( (isChild || HasFlag(wxPOPUP_WINDOW) || HasFlag(wxFRAME_TOOL_WINDOW)) )
     {
-        // popup windows should have desktop as parent because they shouldn't
-        // be limited to the parents client area as child windows usually are
-        hParent = ::GetDesktopWindow();
+        // this is either a normal child window, a popup window or a top level
+        // window with wxFRAME_TOOL_WINDOW style (see below)
+        hParent = parent ? GetHwndOf(parent) : NULL;
     }
-    else // !popup
+    else
     {
-        if ( (isChild || HasFlag(wxFRAME_TOOL_WINDOW)) && parent )
-        {
-            // this is either a normal child window or a top level window with
-            // wxFRAME_TOOL_WINDOW style (see below)
-            hParent = GetHwndOf(parent);
-        }
-        else
-        {
-            // this is either a window for which no parent was specified (not
-            // much we can do then) or a frame without wxFRAME_TOOL_WINDOW
-            // style: we should use NULL parent HWND for it or it would be
-            // always on top of its parent which is not what we usually want
-            // (in fact, we only want it for frames with the special
-            // wxFRAME_TOOL_WINDOW as above)
-            hParent = NULL;
-        }
-
+        // this is a frame without wxFRAME_TOOL_WINDOW style: we should use
+        // NULL parent HWND for it or it would be always on top of its parent
+        // which is not what we usually want (in fact, we only want it for
+        // frames with the special wxFRAME_TOOL_WINDOW as above)
+        hParent = NULL;
     }
 
     // controlId is menu handle for the top level windows, so set it to 0