]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
use wxModalEvtLoop, made more code exception safe
[wxWidgets.git] / src / msw / window.cpp
index b0fa0492c15e7193076692275557c121b7258494..c1ff69c32ee74dd6494dae3125718fb7c2ef728f 100644 (file)
 // global variables
 // ---------------------------------------------------------------------------
 
-// the last Windows message we got (FIXME-MT)
-extern MSG s_currentMsg;
-
 #if wxUSE_MENUS_NATIVE
 wxMenu *wxCurrentPopupMenu = NULL;
 #endif // wxUSE_MENUS_NATIVE
@@ -221,6 +218,38 @@ static inline void wxBringWindowToTop(HWND hwnd)
     }
 }
 
+// ensure that all our parent windows have WS_EX_CONTROLPARENT style
+static void EnsureParentHasControlParentStyle(wxWindow *parent)
+{
+    /*
+       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 currently
+       focused one 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 the initial (focused) window: as we do have this style,
+       GetNextDlgTabItem() will leave this window and continue in its parent,
+       but if the parent doesn't have it, it wouldn't recurse inside it later
+       on and so wouldn't have a chance of getting back to this window neither.
+     */
+#ifndef __WXWINCE__
+    while ( 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);
+        }
+
+        parent = parent->GetParent();
+    }
+#endif // !__WXWINCE__
+}
+
 // ---------------------------------------------------------------------------
 // event tables
 // ---------------------------------------------------------------------------
@@ -488,9 +517,6 @@ wxWindowMSW::~wxWindowMSW()
     //     find their parent frame (see above).
     DestroyChildren();
 
-    if ( m_parent )
-        m_parent->RemoveChild(this);
-
     if ( m_hWnd )
     {
         // VZ: test temp removed to understand what really happens here
@@ -1290,6 +1316,13 @@ bool wxWindowMSW::Reparent(wxWindowBase *parent)
 
     ::SetParent(hWndChild, hWndParent);
 
+#ifndef __WXWINCE__
+    if ( ::GetWindowLong(hWndChild, GWL_EXSTYLE) & WS_EX_CONTROLPARENT )
+    {
+        EnsureParentHasControlParentStyle(GetParent());
+    }
+#endif // !__WXWINCE__
+
     return TRUE;
 }
 
@@ -1714,15 +1747,21 @@ static void wxYieldForCommandsOnly()
     // peek all WM_COMMANDs (it will always return WM_QUIT too but we don't
     // want to process it here)
     MSG msg;
-    while ( ::PeekMessage(&msg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE)
-                && msg.message != WM_QUIT )
+    while ( ::PeekMessage(&msg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE) )
     {
-        wxTheApp->DoMessage((WXMSG *)&msg);
-    }
+        if ( msg.message == WM_QUIT )
+        {
+            // if we retrieved a WM_QUIT, insert back into the message queue.
+            ::PostQuitMessage(0);
+            break;
+        }
 
-    // If we retrieved a WM_QUIT, insert back into the message queue.
-    if (msg.message == WM_QUIT)
-        ::PostQuitMessage(0);
+        // luckily (as we don't have access to wxEventLoopImpl method from here
+        // anyhow...) we don't need to pre process WM_COMMANDs so dispatch it
+        // immediately
+        ::TranslateMessage(&msg);
+        ::DispatchMessage(&msg);
+    }
 }
 
 bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
@@ -2321,6 +2360,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
                 break;
             }
 
+#ifndef __WXWINCE__
         case WM_PRINT:
             {
                 // Don't call the wx handlers in this case
@@ -2334,6 +2374,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
                 processed = HandlePaint();
             }
             break;
+#endif
 
         case WM_CLOSE:
 #ifdef __WXUNIVERSAL__
@@ -3229,32 +3270,13 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
 
 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
+    // VZ: why is this commented out for WinCE? If it doesn't support
+    //     WS_EX_CONTROLPARENT at all it should be somehow handled globally,
+    //     not with multiple #ifdef's!
 #ifndef __WXWINCE__
     if ( ((CREATESTRUCT *)cs)->dwExStyle & WS_EX_CONTROLPARENT )
-    {
-        // there is no need to do anything for the top level windows
-        const wxWindow *parent = GetParent();
-        while ( 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);
-            }
-
-            parent = parent->GetParent();
-        }
-    }
-#endif
+        EnsureParentHasControlParentStyle(GetParent());
+#endif // !__WXWINCE__
 
     // TODO: should generate this event from WM_NCCREATE
     wxWindowCreateEvent event((wxWindow *)this);
@@ -4201,7 +4223,7 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
     // so simply test for negative value.
     event.m_altDown = ::GetKeyState(VK_MENU) < 0;
 
-    event.SetTimestamp(s_currentMsg.time);
+    event.SetTimestamp(::GetMessageTime());
     event.m_eventObject = this;
     event.SetId(GetId());
 
@@ -4399,7 +4421,7 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType,
     event.m_keyCode = id;
     event.m_rawCode = (wxUint32) wParam;
     event.m_rawFlags = (wxUint32) lParam;
-    event.SetTimestamp(s_currentMsg.time);
+    event.SetTimestamp(::GetMessageTime());
 
     // translate the position to client coords
     POINT pt;
@@ -5073,7 +5095,7 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
             event.m_keyCode = id;
             event.m_shiftDown = wxIsShiftDown();
             event.m_controlDown = wxIsCtrlDown();
-            event.SetTimestamp(s_currentMsg.time);
+            event.SetTimestamp(::GetMessageTime());
 
             wxWindow *win = wxGetActiveWindow();
             wxEvtHandler *handler;