X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0d7f75df793b32c7ff6e28c83792ab3f8eafe46e..848c37c35b42e3e18e98a578f794172b8f2c46d0:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index e7129e32d5..422745e451 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -28,7 +28,6 @@ #include "wx/msw/wrapwin.h" #include "wx/window.h" #include "wx/accel.h" - #include "wx/setup.h" #include "wx/menu.h" #include "wx/dc.h" #include "wx/dcclient.h" @@ -121,7 +120,11 @@ // resizing complicated window hierarchies, but this can in theory result in // different behaviour than the old code so we keep the possibility to use it // by setting this to 0 (in the future this should be removed completely) +#ifdef __WXWINCE__ +#define USE_DEFERRED_SIZING 0 +#else #define USE_DEFERRED_SIZING 1 +#endif // set this to 1 to filter out duplicate mouse events, e.g. mouse move events // when mouse position didnd't change @@ -938,11 +941,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) @@ -1088,20 +1093,19 @@ void wxWindowMSW::DissociateHandle() bool wxCheckWindowWndProc(WXHWND hWnd, - WXFARPROC WXUNUSED_IN_WINCE(wndProc)) + WXFARPROC WXUNUSED(wndProc)) { - // Unicows note: the code below works, but only because WNDCLASS contains - // original window handler rather that the unicows fake one. This may not - // be on purpose, though; if it stops working with future versions of - // unicows.dll, we can override unicows hooks by setting - // Unicows_{Set,Get}WindowLong and Unicows_RegisterClass to our own - // versions that keep track of fake<->real wnd proc mapping. +// TODO: This list of window class names should be factored out so they can be +// managed in one place and then accessed from here and other places, such as +// wxApp::RegisterWindowClasses() and wxApp::UnregisterWindowClasses() - // On WinCE (at least), the wndproc comparison doesn't work, - // so have to use something like this. #ifdef __WXWINCE__ extern wxChar *wxCanvasClassName; extern wxChar *wxCanvasClassNameNR; +#else + extern const wxChar *wxCanvasClassName; + extern const wxChar *wxCanvasClassNameNR; +#endif extern const wxChar *wxMDIFrameClassName; extern const wxChar *wxMDIFrameClassNameNoRedraw; extern const wxChar *wxMDIChildFrameClassName; @@ -1109,25 +1113,18 @@ bool wxCheckWindowWndProc(WXHWND hWnd, 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 == wxMDIChildFrameClassNameNoRedraw || str == _T("wxTLWHiddenParent")) return true; // Effectively means don't subclass - - return false; -#else - WNDCLASS cls; - if ( !::GetClassInfo(wxGetInstance(), wxGetWindowClass(hWnd), &cls) ) - { - wxLogLastError(_T("GetClassInfo")); - + else return false; - } - - return wndProc == (WXFARPROC)cls.lpfnWndProc; -#endif } // ---------------------------------------------------------------------------- @@ -1511,9 +1508,10 @@ 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 { +#if USE_DEFERRED_SIZING if ( IsTopLevel() || m_pendingSize == wxDefaultSize ) - { - // top level windows resizing is never deferred, so we can safely use +#endif + { // top level windows resizing is never deferred, so we can safely use // the current size here RECT rect = wxGetClientRect(GetHwnd()); @@ -1522,13 +1520,24 @@ void wxWindowMSW::DoGetClientSize(int *x, int *y) const if ( y ) *y = rect.bottom; } - else // non top level +#if USE_DEFERRED_SIZING + else // non top level and using deferred sizing { - // 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); + // we need to calculate the *pending* client size here + RECT rect; + rect.left = m_pendingPosition.x; + rect.top = m_pendingPosition.y; + rect.right = rect.left + m_pendingSize.x; + rect.bottom = rect.top + m_pendingSize.y; + + ::SendMessage(GetHwnd(), WM_NCCALCSIZE, FALSE, (LPARAM)&rect); + + if ( x ) + *x = rect.right - rect.left; + if ( y ) + *y = rect.bottom - rect.top; } +#endif } void wxWindowMSW::DoGetPosition(int *x, int *y) const @@ -1747,9 +1756,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 @@ -1790,7 +1800,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, @@ -4071,14 +4083,11 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc) dc.SetHDC(hdc); dc.SetWindow((wxWindow *)this); - dc.BeginDrawing(); 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); @@ -5165,6 +5174,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) @@ -5183,19 +5199,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; @@ -5259,11 +5265,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: