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)
};
// 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()
// hide the window
virtual void Dismiss();
-
+ // can the window be dismissed now?
+ //
+ // VZ: where is this used??
virtual bool CanDismiss()
{ return TRUE; }
}
if ( !processed )
- rc = wxWindow::MSWWindowProc(message, wParam, lParam);
+ rc = wxFrameBase::MSWWindowProc(message, wParam, lParam);
return rc;
}
#include "wx/msw/private.h" // for WS_CHILD and WS_POPUP
+wxWindowList wxPopupWindow::ms_shownPopups;
+
// ============================================================================
// implementation
// ============================================================================
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;
+}
+
#include "wx/msw/private.h"
+#include "wx/popupwin.h"
+
#ifndef ICON_BIG
#define ICON_BIG 1
#endif
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);
+}
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