]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
WinCE fixes (in case a WinCE-friendly backend gets written one day)
[wxWidgets.git] / src / msw / window.cpp
index 88f22022508dcc7873fecdd107218cde70195c00..2e1ff1f6a48134c67fadd447f45f66741bdfcfc2 100644 (file)
@@ -848,15 +848,10 @@ inline int GetScrollPosition(HWND hWnd, int wOrient)
     WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.cbSize = sizeof(SCROLLINFO);
     scrollInfo.fMask = SIF_POS;
-    if ( !::GetScrollInfo(hWnd,
-                          wOrient,
-                          &scrollInfo) )
-    {
-        // Not necessarily an error, if there are no scrollbars yet.
-        // wxLogLastError(_T("GetScrollInfo"));
-    }
+    ::GetScrollInfo(hWnd, wOrient, &scrollInfo );
+
     return scrollInfo.nPos;
-//    return ::GetScrollPos(hWnd, wOrient);
+
 #endif
 }
 
@@ -943,11 +938,13 @@ void wxWindowMSW::SetScrollbar(int orient,
     HWND hWnd = GetHwnd();
     if ( hWnd )
     {
+        // We have to set the variables here to make them valid in events
+        // triggered by ::SetScrollInfo()
+        *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize;
+        
         ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
                         &info, refresh);
     }
-
-    *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize;
 }
 
 void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
@@ -1516,14 +1513,24 @@ void wxWindowMSW::DoGetSize(int *x, int *y) const
 // Get size *available for subwindows* i.e. excluding menu bar etc.
 void wxWindowMSW::DoGetClientSize(int *x, int *y) const
 {
-    // this is only for top level windows whose resizing is never deferred, so
-    // we can safely use the current size here
-    RECT rect = wxGetClientRect(GetHwnd());
+    if ( IsTopLevel() || m_pendingSize == wxDefaultSize )
+    {
+        // top level windows resizing is never deferred, so we can safely use
+        // the current size here
+        RECT rect = wxGetClientRect(GetHwnd());
 
-    if ( x )
-        *x = rect.right;
-    if ( y )
-        *y = rect.bottom;
+        if ( x )
+            *x = rect.right;
+        if ( y )
+            *y = rect.bottom;
+    }
+    else // non top level
+    {
+        // size is the same as client size for non top level windows, so
+        // forward to GetSize() to take into account deferred sizing (which
+        // wxGetClientRect() doesn't)
+        DoGetSize(x, y);
+    }
 }
 
 void wxWindowMSW::DoGetPosition(int *x, int *y) const
@@ -1618,7 +1625,7 @@ wxWindowMSW::DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height)
     if ( hdwp )
     {
         hdwp = ::DeferWindowPos(hdwp, (HWND)hwnd, NULL, x, y, width, height,
-                                SWP_NOZORDER);
+                                SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
         if ( !hdwp )
         {
             wxLogLastError(_T("DeferWindowPos"));
@@ -1742,9 +1749,10 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
 {
     // setting the client size is less obvious than it could have been
     // because in the result of changing the total size the window scrollbar
-    // may [dis]appear and/or its menubar may [un]wrap and so the client size
-    // will not be correct as the difference between the total and client size
-    // changes - so we keep changing it until we get it right
+    // may [dis]appear and/or its menubar may [un]wrap (and AdjustWindowRect()
+    // doesn't take neither into account) and so the client size will not be
+    // correct as the difference between the total and client size changes --
+    // so we keep changing it until we get it right
     //
     // normally this loop shouldn't take more than 3 iterations (usually 1 but
     // if scrollbars [dis]appear as the result of the first call, then 2 and it
@@ -1785,7 +1793,9 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
         }
 
         // don't call DoMoveWindow() because we want to move window immediately
-        // and not defer it here
+        // and not defer it here as otherwise the value returned by
+        // GetClient/WindowRect() wouldn't change as the window wouldn't be
+        // really resized
         if ( !::MoveWindow(GetHwnd(),
                            rectWin.left,
                            rectWin.top,
@@ -2399,28 +2409,6 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             break;
 #endif // !__WXWINCE__
 
-#if !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
-        case WM_WINDOWPOSCHANGED:
-            {
-                WINDOWPOS *lpPos = (WINDOWPOS *)lParam;
-
-                if ( !(lpPos->flags & SWP_NOSIZE) )
-                {
-                    RECT rc;
-                    ::GetClientRect(GetHwnd(), &rc);
-
-                    AutoHRGN hrgnClient(::CreateRectRgnIndirect(&rc));
-                    AutoHRGN hrgnNew(::CreateRectRgn(lpPos->x,  lpPos->y,
-                                                     lpPos->cx, lpPos->cy));
-
-                    // we need to invalidate any new exposed areas here
-                    // to force them to repaint
-                    if ( ::CombineRgn(hrgnNew, hrgnNew, hrgnClient, RGN_DIFF) != NULLREGION )
-                        ::InvalidateRgn(GetHwnd(), hrgnNew, TRUE);
-                }
-            }
-            break;
-#endif
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
             // This implicitly sends a wxEVT_ACTIVATE_APP event
@@ -3202,8 +3190,6 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
 // WM_NOTIFY
 // ---------------------------------------------------------------------------
 
-#ifdef __WIN95__
-
 bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
 #ifndef __WXMICROWIN__
@@ -3347,8 +3333,6 @@ bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl),
     return false;
 }
 
-#endif // __WIN95__
-
 // ---------------------------------------------------------------------------
 // end session messages
 // ---------------------------------------------------------------------------
@@ -4924,12 +4908,20 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
     MENUITEMINFO mii;
     wxZeroMemory(mii);
     mii.cbSize = sizeof(MENUITEMINFO);
+
+    // we could use MIIM_FTYPE here as we only need to know if the item is
+    // ownerdrawn or not and not dwTypeData which MIIM_TYPE also returns, but
+    // MIIM_FTYPE is not supported under Win95
     mii.fMask = MIIM_TYPE | MIIM_DATA;
 
     // find if we have this letter in any owner drawn item
     const int count = ::GetMenuItemCount(hmenu);
     for ( int i = 0; i < count; i++ )
     {
+        // previous loop iteration could modify it, reset it back before
+        // calling GetMenuItemInfo() to prevent it from overflowing dwTypeData
+        mii.cch = 0;
+
         if ( ::GetMenuItemInfo(hmenu, i, TRUE, &mii) )
         {
             if ( mii.fType == MFT_OWNERDRAW )
@@ -4967,8 +4959,7 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
         }
         else // failed to get the menu text?
         {
-            // it's not fatal, so don't show error, but still log
-            // it
+            // it's not fatal, so don't show error, but still log it
             wxLogLastError(_T("GetMenuItemInfo"));
         }
     }
@@ -5179,6 +5170,13 @@ void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont& the_font)
     //   the_font.ReleaseResource();
 }
 
+// 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)
+{
+    return lParam & (1 << 24) ? keyExtended : keyNormal;
+}
+
 // Returns 0 if was a normal ASCII value, not a special key. This indicates that
 // the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
 int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam)
@@ -5197,19 +5195,9 @@ int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam)
         case VK_CAPITAL:    id = WXK_CAPITAL; break;
         case VK_SPACE:      id = WXK_SPACE; break;
         case VK_ESCAPE:     id = WXK_ESCAPE; break;
-        case VK_PRIOR:      id = WXK_PRIOR; break;
-        case VK_NEXT :      id = WXK_NEXT; break;
-        case VK_END:        id = WXK_END; break;
-        case VK_HOME :      id = WXK_HOME; break;
-        case VK_LEFT :      id = WXK_LEFT; break;
-        case VK_UP:         id = WXK_UP; break;
-        case VK_RIGHT:      id = WXK_RIGHT; break;
-        case VK_DOWN :      id = WXK_DOWN; break;
         case VK_SELECT:     id = WXK_SELECT; break;
         case VK_PRINT:      id = WXK_PRINT; break;
         case VK_EXECUTE:    id = WXK_EXECUTE; break;
-        case VK_INSERT:     id = WXK_INSERT; break;
-        case VK_DELETE:     id = WXK_DELETE; break;
         case VK_HELP :      id = WXK_HELP; break;
         case VK_NUMPAD0:    id = WXK_NUMPAD0; break;
         case VK_NUMPAD1:    id = WXK_NUMPAD1; break;
@@ -5273,11 +5261,40 @@ int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam)
         case VK_APPS:       id = WXK_WINDOWS_MENU; break;
 #endif // VK_APPS defined
 
+        // handle extended keys
+        case VK_PRIOR:
+            id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_PRIOR, WXK_PRIOR);
+            break;
+        case VK_NEXT:
+            id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_NEXT, WXK_NEXT);
+            break;
+        case VK_END:
+            id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_END, WXK_END);
+            break;
+        case VK_HOME:
+            id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_HOME, WXK_HOME);
+            break;
+        case VK_LEFT:
+            id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_LEFT, WXK_LEFT);
+            break;
+        case VK_UP:
+            id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_UP, WXK_UP);
+            break;
+        case VK_RIGHT:
+            id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_RIGHT, WXK_RIGHT);
+            break;
+        case VK_DOWN:
+            id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_DOWN, WXK_DOWN);
+            break;
+        case VK_INSERT:
+            id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_INSERT, WXK_INSERT);
+            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:
-            // the same key is sent for both the "return" key on the main
-            // keyboard and the numeric keypad but we want to distinguish
-            // between them: we do this using the "extended" bit (24) of lParam
-            id = lParam & (1 << 24) ? WXK_NUMPAD_ENTER : WXK_RETURN;
+            id = ChooseNormalOrExtended(lParam, WXK_RETURN, WXK_NUMPAD_ENTER);
             break;
 
         default:
@@ -5399,6 +5416,28 @@ bool wxGetKeyState(wxKeyCode key)
 #endif
 }
 
+
+wxMouseState wxGetMouseState()
+{
+    wxMouseState ms;
+    POINT pt;
+    GetCursorPos( &pt );
+
+    ms.SetX(pt.x);
+    ms.SetY(pt.y);
+    ms.SetLeftDown( (GetAsyncKeyState(VK_LBUTTON) & (1<<15)) != 0 );
+    ms.SetMiddleDown( (GetAsyncKeyState(VK_MBUTTON) & (1<<15)) != 0 );
+    ms.SetRightDown( (GetAsyncKeyState(VK_RBUTTON) & (1<<15)) != 0 );
+
+    ms.SetControlDown( (GetAsyncKeyState(VK_CONTROL) & (1<<15)) != 0 );
+    ms.SetShiftDown( (GetAsyncKeyState(VK_SHIFT) & (1<<15)) != 0 );
+    ms.SetAltDown( (GetAsyncKeyState(VK_MENU) & (1<<15)) != 0 );
+//    ms.SetMetaDown();
+
+    return ms;
+}
+
+
 wxWindow *wxGetActiveWindow()
 {
     HWND hWnd = GetActiveWindow();