]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
wxTinderbox build fix (!PCH support).
[wxWidgets.git] / src / msw / window.cpp
index cac2a3f2dbaef139e8b8053282bdbb04e48ef979..919f3c3c8a0681aeb907f5b35454c077f592eae9 100644 (file)
 
 #if defined(__WXWINCE__)
     #include "wx/msw/wince/missing.h"
 
 #if defined(__WXWINCE__)
     #include "wx/msw/wince/missing.h"
+#ifdef __POCKETPC__
+    #include <windows.h>
+    #include <shellapi.h>
+    #include <ole2.h>
+    #include <aygshell.h>
+#endif
 #endif
 
 #if defined(TME_LEAVE) && defined(WM_MOUSELEAVE)
 #endif
 
 #if defined(TME_LEAVE) && defined(WM_MOUSELEAVE)
@@ -487,6 +493,10 @@ void wxWindowMSW::Init()
 
     m_pendingPosition = wxDefaultPosition;
     m_pendingSize = wxDefaultSize;
 
     m_pendingPosition = wxDefaultPosition;
     m_pendingSize = wxDefaultSize;
+
+#ifdef __POCKETPC__
+    m_contextMenuEnabled = false;
+#endif
 }
 
 // Destructor
 }
 
 // Destructor
@@ -788,22 +798,10 @@ bool wxWindowMSW::SetCursor(const wxCursor& cursor)
         return false;
     }
 
         return false;
     }
 
-    if ( m_cursor.Ok() )
+    // don't "overwrite" busy cursor
+    if ( m_cursor.Ok() && !wxIsBusy() )
     {
     {
-        HWND hWnd = GetHwnd();
-
-        // Change the cursor NOW if we're within the correct window
-        POINT point;
-#ifdef __WXWINCE__
-        ::GetCursorPosWinCE(&point);
-#else
-        ::GetCursorPos(&point);
-#endif
-
-        RECT rect = wxGetWindowRect(hWnd);
-
-        if ( ::PtInRect(&rect, point) && !wxIsBusy() )
-            ::SetCursor(GetHcursorOf(m_cursor));
+        ::SetCursor(GetHcursorOf(m_cursor));
     }
 
     return true;
     }
 
     return true;
@@ -1113,6 +1111,10 @@ bool wxCheckWindowWndProc(WXHWND hWnd,
     wxString str(wxGetWindowClass(hWnd));
     if (str == wxCanvasClassName ||
         str == wxCanvasClassNameNR ||
     wxString str(wxGetWindowClass(hWnd));
     if (str == wxCanvasClassName ||
         str == wxCanvasClassNameNR ||
+#if wxUSE_GLCANVAS
+        str == _T("wxGLCanvasClass") ||
+        str == _T("wxGLCanvasClassNR") ||
+#endif // wxUSE_GLCANVAS
         str == wxMDIFrameClassName ||
         str == wxMDIFrameClassNameNoRedraw ||
         str == wxMDIChildFrameClassName ||
         str == wxMDIFrameClassName ||
         str == wxMDIFrameClassNameNoRedraw ||
         str == wxMDIChildFrameClassName ||
@@ -1141,6 +1143,9 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
     if ( !GetHwnd() )
         return;
 
     if ( !GetHwnd() )
         return;
 
+    // we may need to call SetWindowPos() when we change some styles
+    bool callSWP = false;
+
     WXDWORD exstyle, exstyleOld;
     long style = MSWGetStyle(flags, &exstyle),
          styleOld = MSWGetStyle(flagsOld, &exstyleOld);
     WXDWORD exstyle, exstyleOld;
     long style = MSWGetStyle(flags, &exstyle),
          styleOld = MSWGetStyle(flagsOld, &exstyleOld);
@@ -1156,17 +1161,40 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
         styleReal |= style;
 
         ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal);
         styleReal |= style;
 
         ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal);
+
+        // If any of the style changes changed any of the frame styles:
+        // MSDN: SetWindowLong:
+        //       Certain window data is cached, so changes you make using 
+        //       SetWindowLong will not take effect until you call the 
+        //       SetWindowPos function. Specifically, if you change any of 
+        //       the frame styles, you must call SetWindowPos with the 
+        //       SWP_FRAMECHANGED flag for the cache to be updated properly.
+
+        callSWP = ((styleOld ^ style ) & (WS_BORDER |
+                                      WS_THICKFRAME |
+                                      WS_CAPTION |
+                                      WS_DLGFRAME |
+                                      WS_MAXIMIZEBOX |
+                                      WS_MINIMIZEBOX |
+                                      WS_SYSMENU) ) != 0;
     }
 
     // and the extended style
     }
 
     // and the extended style
+    long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
+
     if ( exstyle != exstyleOld )
     {
     if ( exstyle != exstyleOld )
     {
-        long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
         exstyleReal &= ~exstyleOld;
         exstyleReal |= exstyle;
 
         ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal);
 
         exstyleReal &= ~exstyleOld;
         exstyleReal |= exstyle;
 
         ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal);
 
+        // ex style changes don't take effect without calling SetWindowPos
+        callSWP = true;
+    }
+
+    if ( callSWP )
+    {
         // we must call SetWindowPos() to flush the cached extended style and
         // also to make the change to wxSTAY_ON_TOP style take effect: just
         // setting the style simply doesn't work
         // we must call SetWindowPos() to flush the cached extended style and
         // also to make the change to wxSTAY_ON_TOP style take effect: just
         // setting the style simply doesn't work
@@ -1174,7 +1202,7 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
                              exstyleReal & WS_EX_TOPMOST ? HWND_TOPMOST
                                                          : HWND_NOTOPMOST,
                              0, 0, 0, 0,
                              exstyleReal & WS_EX_TOPMOST ? HWND_TOPMOST
                                                          : HWND_NOTOPMOST,
                              0, 0, 0, 0,
-                             SWP_NOMOVE | SWP_NOSIZE) )
+                             SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED) )
         {
             wxLogLastError(_T("SetWindowPos"));
         }
         {
             wxLogLastError(_T("SetWindowPos"));
         }
@@ -1355,7 +1383,7 @@ void wxWindowMSW::Thaw()
 {
     wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") );
 
 {
     wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") );
 
-    if ( !--m_frozenness )
+    if ( --m_frozenness == 0 )
     {
         if ( IsShown() )
         {
     {
         if ( IsShown() )
         {
@@ -1420,6 +1448,26 @@ void wxWindowMSW::Update()
 // drag and drop
 // ---------------------------------------------------------------------------
 
 // drag and drop
 // ---------------------------------------------------------------------------
 
+// we need to lower the sibling static boxes so controls contained within can be
+// a drop target
+static inline void AdjustStaticBoxZOrder(wxWindow *parent)
+{
+    // no sibling static boxes if we have no parent (ie TLW)
+    if ( !parent )
+        return;
+
+    for ( wxWindowList::compatibility_iterator node = parent->GetChildren().GetFirst();
+          node;
+          node = node->GetNext() )
+    {
+        wxStaticBox *statbox = wxDynamicCast(node->GetData(), wxStaticBox);
+        if ( statbox )
+        {
+            ::SetWindowPos(GetHwndOf(statbox), HWND_BOTTOM, 0, 0, 0, 0,
+                           SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+        }
+    }
+}
 
 #if wxUSE_DRAG_AND_DROP
 void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
 
 #if wxUSE_DRAG_AND_DROP
 void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
@@ -1431,7 +1479,10 @@ void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
 
     m_dropTarget = pDropTarget;
     if ( m_dropTarget != 0 )
 
     m_dropTarget = pDropTarget;
     if ( m_dropTarget != 0 )
+    {
+        AdjustStaticBoxZOrder(GetParent());
         m_dropTarget->Register(m_hWnd);
         m_dropTarget->Register(m_hWnd);
+    }
 }
 #endif // wxUSE_DRAG_AND_DROP
 
 }
 #endif // wxUSE_DRAG_AND_DROP
 
@@ -1442,7 +1493,10 @@ void wxWindowMSW::DragAcceptFiles(bool WXUNUSED_IN_WINCE(accept))
 #ifndef __WXWINCE__
     HWND hWnd = GetHwnd();
     if ( hWnd )
 #ifndef __WXWINCE__
     HWND hWnd = GetHwnd();
     if ( hWnd )
+    {
+        AdjustStaticBoxZOrder(GetParent());
         ::DragAcceptFiles(hWnd, (BOOL)accept);
         ::DragAcceptFiles(hWnd, (BOOL)accept);
+    }
 #endif
 }
 
 #endif
 }
 
@@ -1917,7 +1971,7 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
 #if defined(__WXWINCE__)
     UINT flags = 0;
 #else
 #if defined(__WXWINCE__)
     UINT flags = 0;
 #else
-    UINT flags = TPM_RIGHTBUTTON;
+    UINT flags = TPM_RIGHTBUTTON | TPM_RECURSE;
 #endif
     ::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL);
 
 #endif
     ::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL);
 
@@ -2552,6 +2606,36 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     wxCHECK_MSG( win, 0,
                                  _T("FindWindowForMouseEvent() returned NULL") );
                 }
                     wxCHECK_MSG( win, 0,
                                  _T("FindWindowForMouseEvent() returned NULL") );
                 }
+#ifdef __POCKETPC__
+                if (IsContextMenuEnabled() && message == WM_LBUTTONDOWN)
+                {
+                    SHRGINFO shrgi = {0};
+                    
+                    shrgi.cbSize = sizeof(SHRGINFO);
+                    shrgi.hwndClient = (HWND) GetHWND();
+                    shrgi.ptDown.x = x;
+                    shrgi.ptDown.y = y;
+                    
+                    shrgi.dwFlags = SHRG_RETURNCMD;
+                    // shrgi.dwFlags = SHRG_NOTIFYPARENT;
+                    
+                    if (GN_CONTEXTMENU == ::SHRecognizeGesture(&shrgi))
+                    {
+                        wxPoint pt(x, y);
+                        pt = ClientToScreen(pt);
+                        
+                        wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt);
+                        
+                        evtCtx.SetEventObject(this);
+                        if (GetEventHandler()->ProcessEvent(evtCtx))
+                        {
+                            processed = true;
+                            return true;
+                        }
+                    }
+                }
+#endif
+
 #else // !__WXWINCE__
                 wxWindowMSW *win = this;
 #endif // __WXWINCE__/!__WXWINCE__
 #else // !__WXWINCE__
                 wxWindowMSW *win = this;
 #endif // __WXWINCE__/!__WXWINCE__
@@ -2819,6 +2903,10 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             processed = HandleCaptureChanged((WXHWND) (HWND) lParam);
             break;
 
             processed = HandleCaptureChanged((WXHWND) (HWND) lParam);
             break;
 
+        case WM_SETTINGCHANGE:
+            processed = HandleSettingChange(wParam, lParam);
+            break;
+
         case WM_QUERYNEWPALETTE:
             processed = HandleQueryNewPalette();
             break;
         case WM_QUERYNEWPALETTE:
             processed = HandleQueryNewPalette();
             break;
@@ -3903,6 +3991,30 @@ bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture)
     return GetEventHandler()->ProcessEvent(event);
 }
 
     return GetEventHandler()->ProcessEvent(event);
 }
 
+bool wxWindowMSW::HandleSettingChange(WXWPARAM wParam, WXLPARAM lParam)
+{
+    // despite MSDN saying "(This message cannot be sent directly to a window.)"
+    // we need to send this to child windows (it is only sent to top-level
+    // windows) so {list,tree}ctrls can adjust their font size if necessary
+    // this is exactly how explorer does it to enable the font size changes
+
+    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+    while ( node )
+    {
+        // top-level windows already get this message from the system
+        wxWindow *win = node->GetData();
+        if ( !win->IsTopLevel() )
+        {
+            ::SendMessage(GetHwndOf(win), WM_SETTINGCHANGE, wParam, lParam);
+        }
+
+        node = node->GetNext();
+    }
+
+    // let the system handle it
+    return false;
+}
+
 bool wxWindowMSW::HandleQueryNewPalette()
 {
 
 bool wxWindowMSW::HandleQueryNewPalette()
 {
 
@@ -4079,14 +4191,11 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 
     dc.SetHDC(hdc);
     dc.SetWindow((wxWindow *)this);
 
     dc.SetHDC(hdc);
     dc.SetWindow((wxWindow *)this);
-    dc.BeginDrawing();
 
     wxEraseEvent event(m_windowId, &dc);
     event.SetEventObject(this);
     bool rc = GetEventHandler()->ProcessEvent(event);
 
 
     wxEraseEvent event(m_windowId, &dc);
     event.SetEventObject(this);
     bool rc = GetEventHandler()->ProcessEvent(event);
 
-    dc.EndDrawing();
-
     // must be called manually as ~wxDC doesn't do anything for wxDCTemp
     dc.SelectOldObjects(hdc);
 
     // must be called manually as ~wxDC doesn't do anything for wxDCTemp
     dc.SelectOldObjects(hdc);
 
@@ -5175,9 +5284,14 @@ void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont& the_font)
 
 // use the "extended" bit (24) of lParam to distinguish extended keys
 // from normal keys as the same key is sent
 
 // use the "extended" bit (24) of lParam to distinguish extended keys
 // from normal keys as the same key is sent
-static inline int ChooseNormalOrExtended(int lParam, int keyNormal, int keyExtended)
+static inline
+int ChooseNormalOrExtended(int lParam, int keyNormal, int keyExtended)
 {
 {
-    return lParam & (1 << 24) ? keyExtended : keyNormal;
+    // except that if lParam is 0, it means we don't have real lParam from
+    // WM_KEYDOWN but are just translating just a VK constant (e.g. done from
+    // msw/treectrl.cpp when processing TVN_KEYDOWN) -- then assume this is a
+    // non-numpad (hence extended) key as this is a more common case
+    return !lParam || (lParam & (1 << 24)) ? keyExtended : keyNormal;
 }
 
 // Returns 0 if was a normal ASCII value, not a special key. This indicates that
 }
 
 // Returns 0 if was a normal ASCII value, not a special key. This indicates that
@@ -5295,9 +5409,10 @@ int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam)
         case VK_DELETE:
             id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_DELETE, WXK_DELETE);
             break;
         case VK_DELETE:
             id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_DELETE, WXK_DELETE);
             break;
-        // this order is correct as the numpad enter is the extended key
         case VK_RETURN:
         case VK_RETURN:
-            id = ChooseNormalOrExtended(lParam, WXK_RETURN, WXK_NUMPAD_ENTER);
+            // don't use ChooseNormalOrExtended() here as the keys are reversed
+            // here: numpad enter is the extended one
+            id = lParam && (lParam & (1 << 24)) ? WXK_NUMPAD_ENTER : WXK_RETURN;
             break;
 
         default:
             break;
 
         default: