From: Vadim Zeitlin Date: Thu, 13 Jun 2002 23:59:11 +0000 (+0000) Subject: fixed problems with hanging inside IsDialogMessage or DefDlgProc by forcing all paren... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/61179e28bd7f9e29af93582326919b91549db357 fixed problems with hanging inside IsDialogMessage or DefDlgProc by forcing all parents of windows with WS_EX_CONTROLPARENT to have this style themselves as well git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15832 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp index f37849b3ee..170d28ddab 100644 --- a/src/msw/dialog.cpp +++ b/src/msw/dialog.cpp @@ -398,6 +398,40 @@ void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event)) // dialog window proc // --------------------------------------------------------------------------- +// the DialogProc for all wxWindows dialogs +LONG APIENTRY _EXPORT +wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch ( message ) + { +#if 0 + case WM_ACTIVATE: + case WM_SHOWWINDOW: + // DefDlgProc() has a bug which makes it enter an infinite loop + // when a dialog containing a notebook whose children have + // WS_EX_CONTROLPARENT (automatically set for the windows with + // wxTAB_TRAVERSAL style as it's needed to get it right) is + // deactivated or hidden -- simply remove this code to see this + // happen in the notebook sample + // + // The only way I found to prevent this from happening is to never + // let it process these messages at all. + if ( !wParam ) + return TRUE; +#endif + + case WM_INITDIALOG: + // for this message, returning TRUE tells system to set focus to + // the first control in the dialog box, but as we set the focus + // ourselves, we return FALSE from here as well, so fall through + + default: + // for all the other ones, FALSE means that we didn't process the + // message + return FALSE; + } +} + long wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) { long rc = 0; diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index 3a25093115..97580ec69e 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -60,6 +60,10 @@ static inline bool IsZoomed(HWND WXUNUSED(hwnd)) { return FALSE; } #endif // __WXMICROWIN__ +// this is defined in dialog.cpp +LONG APIENTRY _EXPORT +wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + // ---------------------------------------------------------------------------- // globals // ---------------------------------------------------------------------------- @@ -81,28 +85,6 @@ BEGIN_EVENT_TABLE(wxTopLevelWindowMSW, wxTopLevelWindowBase) EVT_ACTIVATE(wxTopLevelWindowMSW::OnActivate) END_EVENT_TABLE() -// ---------------------------------------------------------------------------- -// wxDialog helpers -// ---------------------------------------------------------------------------- - -// Dialog window proc -LONG APIENTRY _EXPORT -wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch ( message ) - { - case WM_INITDIALOG: - // for this message, returning TRUE tells system to set focus to - // the first control in the dialog box, but as we set the focus - // ourselves, we return FALSE from here as well, so fall through - - default: - // for all the other ones, FALSE means that we didn't process the - // message - return FALSE; - } -} - // ---------------------------------------------------------------------------- // wxTopLevelWindowMSW creation // ---------------------------------------------------------------------------- diff --git a/src/msw/window.cpp b/src/msw/window.cpp index af673944c3..5dc59b9efb 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -3110,8 +3110,31 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff) // window creation/destruction // --------------------------------------------------------------------------- -bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT WXUNUSED(cs), bool *mayCreate) -{ +bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate) +{ + // if we have WS_EX_CONTROLPARENT flag we absolutely *must* set it for our + // parent as well as otherwise several Win32 functions using + // GetNextDlgTabItem() to iterate over all controls such as + // IsDialogMessage() or DefDlgProc() would enter an infinite loop: indeed, + // all of them iterate over all the controls starting from the focus and + // stop iterating when they get back to the focus but unless all parents + // have WS_EX_CONTROLPARENT bit set, they would never get back to focus + if ( ((CREATESTRUCT *)cs)->dwExStyle & WS_EX_CONTROLPARENT ) + { + // there is no need to do anything for the top level windows + const wxWindow *parent = GetParent(); + if ( parent && !parent->IsTopLevel() ) + { + LONG exStyle = ::GetWindowLong(GetHwndOf(parent), GWL_EXSTYLE); + if ( !(exStyle & WS_EX_CONTROLPARENT) ) + { + // force the parent to have this style + ::SetWindowLong(GetHwndOf(parent), GWL_EXSTYLE, + exStyle | WS_EX_CONTROLPARENT); + } + } + } + // TODO: should generate this event from WM_NCCREATE wxWindowCreateEvent event((wxWindow *)this); (void)GetEventHandler()->ProcessEvent(event);