]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
Commit FM's GTK+ native assert dialog code.
[wxWidgets.git] / src / msw / window.cpp
index f5e330a252054e110e4a2158745926ea68004188..313a182e1cdfec0a98965e723c78ae07c331a4de 100644 (file)
@@ -93,6 +93,7 @@
 
 #include "wx/notebook.h"
 #include "wx/listctrl.h"
+#include "wx/dynlib.h"
 
 #include <string.h>
 
 #endif
 #endif
 
-#if defined(TME_LEAVE) && defined(WM_MOUSELEAVE)
+#if defined(TME_LEAVE) && defined(WM_MOUSELEAVE) && wxUSE_DYNLIB_CLASS
     #define HAVE_TRACKMOUSEEVENT
 #endif // everything needed for TrackMouseEvent()
 
@@ -1539,9 +1540,13 @@ void wxWindowMSW::Update()
 // drag and drop
 // ---------------------------------------------------------------------------
 
+#if wxUSE_DRAG_AND_DROP || !defined(__WXWINCE__)
+
+#if wxUSE_STATBOX
+
 // we need to lower the sibling static boxes so controls contained within can be
 // a drop target
-static inline void AdjustStaticBoxZOrder(wxWindow *parent)
+static void AdjustStaticBoxZOrder(wxWindow *parent)
 {
     // no sibling static boxes if we have no parent (ie TLW)
     if ( !parent )
@@ -1560,6 +1565,16 @@ static inline void AdjustStaticBoxZOrder(wxWindow *parent)
     }
 }
 
+#else // !wxUSE_STATBOX
+
+static inline void AdjustStaticBoxZOrder(wxWindow * WXUNUSED(parent))
+{
+}
+
+#endif // wxUSE_STATBOX/!wxUSE_STATBOX
+
+#endif // drag and drop is used
+
 #if wxUSE_DRAG_AND_DROP
 void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
 {
@@ -1703,7 +1718,7 @@ void wxWindowMSW::DoGetPosition(int *x, int *y) const
         {
             if ( wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft )
             {
-                // In RTL mode, we want the logical left x-coordinate, 
+                // In RTL mode, we want the logical left x-coordinate,
                 // which would be the physical right x-coordinate.
                 point.x = rect.right;
             }
@@ -2140,10 +2155,13 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
             switch ( msg->wParam )
             {
                 case VK_TAB:
-                    if ( lDlgCode & DLGC_WANTTAB ) {
+                    if ( (lDlgCode & DLGC_WANTTAB) && !bCtrlDown )
+                    {
+                        // let the control have the TAB
                         bProcess = false;
                     }
-                    else {
+                    else // use it for navigation
+                    {
                         // Ctrl-Tab cycles thru notebook pages
                         bWindowChange = bCtrlDown;
                         bForward = !bShiftDown;
@@ -2173,9 +2191,9 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                     // we treat PageUp/Dn as arrows because chances are that
                     // a control which needs arrows also needs them for
                     // navigation (e.g. wxTextCtrl, wxListCtrl, ...)
-                    if ( (lDlgCode & DLGC_WANTARROWS) || !bCtrlDown )
+                    if ( (lDlgCode & DLGC_WANTARROWS) && !bCtrlDown )
                         bProcess = false;
-                    else
+                    else // OTOH Ctrl-PageUp/Dn works as [Shift-]Ctrl-Tab
                         bWindowChange = true;
                     break;
 
@@ -2630,7 +2648,8 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
 
 #ifdef HAVE_TRACKMOUSEEVENT
         case WM_MOUSELEAVE:
-            // filter out excess WM_MOUSELEAVE events sent after PopupMenu() (on XP at least)
+            // filter out excess WM_MOUSELEAVE events sent after PopupMenu()
+            // (on XP at least)
             if ( m_mouseInWindow )
             {
                 GenerateMouseLeave();
@@ -3950,6 +3969,19 @@ bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam),
 #endif
 }
 
+bool wxWindowMSW::IsDoubleBuffered() const
+{
+    for ( const wxWindowMSW *wnd = this;
+          wnd && !wnd->IsTopLevel(); wnd =
+          wnd->GetParent() )
+    {
+        if ( ::GetWindowLong(GetHwndOf(wnd), GWL_EXSTYLE) & WS_EX_COMPOSITED )
+            return true;
+    }
+
+    return false;
+}
+
 // ---------------------------------------------------------------------------
 // owner drawn stuff
 // ---------------------------------------------------------------------------
@@ -4468,11 +4500,37 @@ WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC, WXHWND hWndToPaint)
     return 0;
 }
 
-bool wxWindowMSW::HandlePrintClient(WXHDC WXUNUSED(hDC))
+bool wxWindowMSW::HandlePrintClient(WXHDC hDC)
 {
-    // TODO: handle wxBG_STYLE_CUSTOM and/or wxBG_STYLE_COLOUR here so when
-    // DrawParentThemeBackground() from uxtheme.dll is called we don't get
-    // the default background e.g. the border when custom drawing buttons
+    // we receive this message when DrawThemeParentBackground() is
+    // called from def window proc of several controls under XP and we
+    // must draw properly themed background here
+    //
+    // note that naively I'd expect filling the client rect with the
+    // brush returned by MSWGetBgBrush() work -- but for some reason it
+    // doesn't and we have to call parents MSWPrintChild() which is
+    // supposed to call DrawThemeBackground() with appropriate params
+    //
+    // also note that in this case lParam == PRF_CLIENT but we're
+    // clearly expected to paint the background and nothing else!
+
+    if ( IsTopLevel() || InheritsBackgroundColour() )
+        return false;
+
+    // sometimes we don't want the parent to handle it at all, instead
+    // return whatever value this window wants
+    if ( !MSWShouldPropagatePrintChild() )
+        return MSWPrintChild(hDC, (wxWindow *)this);
+
+    for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
+    {
+        if ( win->MSWPrintChild(hDC, (wxWindow *)this) )
+            return true;
+
+        if ( win->IsTopLevel() || win->InheritsBackgroundColour() )
+            break;
+    }
+
     return false;
 }
 
@@ -4879,14 +4937,41 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
             m_mouseInWindow = true;
 
 #ifdef HAVE_TRACKMOUSEEVENT
-            WinStruct<TRACKMOUSEEVENT> trackinfo;
+            typedef BOOL (WINAPI *_TrackMouseEvent_t)(LPTRACKMOUSEEVENT);
+#ifdef __WXWINCE__
+            static const _TrackMouseEvent_t
+                s_pfn_TrackMouseEvent = _TrackMouseEvent;
+#else // !__WXWINCE__
+            static _TrackMouseEvent_t s_pfn_TrackMouseEvent;
+            static bool s_initDone = false;
+            if ( !s_initDone )
+            {
+                wxLogNull noLog;
 
-            trackinfo.dwFlags = TME_LEAVE;
-            trackinfo.hwndTrack = GetHwnd();
+                wxDynamicLibrary dllComCtl32(_T("comctl32.dll"), wxDL_VERBATIM);
+                if ( dllComCtl32.IsLoaded() )
+                {
+                    s_pfn_TrackMouseEvent = (_TrackMouseEvent_t)
+                        dllComCtl32.GetSymbol(_T("_TrackMouseEvent"));
+                }
+
+                s_initDone = true;
 
-            // Use the commctrl.h _TrackMouseEvent(), which will call the real
-            // TrackMouseEvent() if available or emulate it
-            _TrackMouseEvent(&trackinfo);
+                // notice that it's ok to unload comctl32.dll here as it won't
+                // be really unloaded, being still in use because we link to it
+                // statically too
+            }
+
+            if ( s_pfn_TrackMouseEvent )
+#endif // __WXWINCE__/!__WXWINCE__
+            {
+                WinStruct<TRACKMOUSEEVENT> trackinfo;
+
+                trackinfo.dwFlags = TME_LEAVE;
+                trackinfo.hwndTrack = GetHwnd();
+
+                (*s_pfn_TrackMouseEvent)(&trackinfo);
+            }
 #endif // HAVE_TRACKMOUSEEVENT
 
             wxMouseEvent event(wxEVT_ENTER_WINDOW);
@@ -4896,7 +4981,7 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
         }
     }
 #ifdef HAVE_TRACKMOUSEEVENT
-    else
+    else // mouse not in window
     {
         // Check if we need to send a LEAVE event
         // Windows doesn't send WM_MOUSELEAVE if the mouse has been captured so