]> git.saurik.com Git - wxWidgets.git/commitdiff
fixed problems with hanging inside IsDialogMessage or DefDlgProc by forcing all paren...
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 13 Jun 2002 23:59:11 +0000 (23:59 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 13 Jun 2002 23:59:11 +0000 (23:59 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15832 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/msw/dialog.cpp
src/msw/toplevel.cpp
src/msw/window.cpp

index f37849b3ee09e7ce847b57e59a05506a1225d894..170d28ddab88a288b74562c92ed9f538a9acd56e 100644 (file)
@@ -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;
index 3a25093115d0036f6149120023f8aa03ebab7cd4..97580ec69e7c7591f418d68ff6daa86f3b71eba2 100644 (file)
@@ -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
 // ----------------------------------------------------------------------------
index af673944c34a34caa6e343b785637b6bd612b54c..5dc59b9efb0e6007429af68fdbe7f16c1f8be831 100644 (file)
@@ -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);