X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dca0f651782d5c2659203c97b3243f613966998d..697c314b162ff4758db0047e548d5401994d2c70:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 3efc43f1e9..5ddf3d7a8c 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -281,12 +281,11 @@ static void EnsureParentHasControlParentStyle(wxWindow *parent) */ while ( parent && !parent->IsTopLevel() ) { - LONG exStyle = ::GetWindowLong(GetHwndOf(parent), GWL_EXSTYLE); + LONG exStyle = wxGetWindowExStyle(parent); if ( !(exStyle & WS_EX_CONTROLPARENT) ) { // force the parent to have this style - ::SetWindowLong(GetHwndOf(parent), GWL_EXSTYLE, - exStyle | WS_EX_CONTROLPARENT); + wxSetWindowExStyle(parent, exStyle | WS_EX_CONTROLPARENT); } parent = parent->GetParent(); @@ -716,15 +715,27 @@ bool wxWindowMSW::Show(bool show) ::ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE); } + if ( IsFrozen() ) + { + // DoFreeze/DoThaw don't do anything if the window is not shown, so + // we have to call them from here now + if ( show ) + DoFreeze(); + else + DoThaw(); + } + return true; } bool wxWindowMSW::MSWShowWithEffect(bool show, wxShowEffect effect, - unsigned timeout, - wxDirection dir) + unsigned timeout) { + if ( !wxWindowBase::Show(show) ) + return false; + typedef BOOL (WINAPI *AnimateWindow_t)(HWND, DWORD, DWORD); static AnimateWindow_t s_pfnAnimateWindow = NULL; @@ -743,22 +754,50 @@ wxWindowMSW::MSWShowWithEffect(bool show, if ( !s_pfnAnimateWindow ) return Show(show); + // Show() has a side effect of sending a WM_SIZE to the window, which helps + // ensuring that it's laid out correctly, but AnimateWindow() doesn't do + // this so send the event ourselves + SendSizeEvent(); + // prepare to use AnimateWindow() if ( !timeout ) timeout = 200; // this is the default animation timeout, per MSDN DWORD dwFlags = show ? 0 : AW_HIDE; - bool needsDir = false; + switch ( effect ) { - case wxSHOW_EFFECT_ROLL: - needsDir = true; + case wxSHOW_EFFECT_ROLL_TO_LEFT: + dwFlags |= AW_HOR_NEGATIVE; + break; + + case wxSHOW_EFFECT_ROLL_TO_RIGHT: + dwFlags |= AW_HOR_POSITIVE; + break; + + case wxSHOW_EFFECT_ROLL_TO_TOP: + dwFlags |= AW_VER_NEGATIVE; + break; + + case wxSHOW_EFFECT_ROLL_TO_BOTTOM: + dwFlags |= AW_VER_POSITIVE; + break; + + case wxSHOW_EFFECT_SLIDE_TO_LEFT: + dwFlags |= AW_SLIDE | AW_HOR_NEGATIVE; break; - case wxSHOW_EFFECT_SLIDE: - needsDir = true; - dwFlags |= AW_SLIDE; + case wxSHOW_EFFECT_SLIDE_TO_RIGHT: + dwFlags |= AW_SLIDE | AW_HOR_POSITIVE; + break; + + case wxSHOW_EFFECT_SLIDE_TO_TOP: + dwFlags |= AW_SLIDE | AW_VER_NEGATIVE; + break; + + case wxSHOW_EFFECT_SLIDE_TO_BOTTOM: + dwFlags |= AW_SLIDE | AW_VER_POSITIVE; break; case wxSHOW_EFFECT_BLEND: @@ -779,38 +818,6 @@ wxWindowMSW::MSWShowWithEffect(bool show, return false; } - if ( needsDir ) - { - switch ( dir ) - { - case wxTOP: - dwFlags |= AW_VER_NEGATIVE; - break; - - case wxBOTTOM: - dwFlags |= AW_VER_POSITIVE; - break; - - case wxLEFT: - dwFlags |= AW_HOR_NEGATIVE; - break; - - case wxRIGHT: - dwFlags |= AW_HOR_POSITIVE; - break; - - default: - wxFAIL_MSG( _T("unknown window effect direction") ); - return false; - } - } - else // animation effect which doesn't need the direction - { - wxASSERT_MSG( dir == wxBOTTOM, - _T("non-default direction used unnecessarily") ); - } - - if ( !(*s_pfnAnimateWindow)(GetHwnd(), timeout, dwFlags) ) { wxLogLastError(_T("AnimateWindow")); @@ -868,7 +875,11 @@ bool wxWindowMSW::SetFont(const wxFont& font) HWND hWnd = GetHwnd(); if ( hWnd != 0 ) { - WXHANDLE hFont = m_font.GetResourceHandle(); + // note the use of GetFont() instead of m_font: our own font could have + // just been reset and in this case we need to change the font used by + // the native window to the default for this class, i.e. exactly what + // GetFont() returns + WXHANDLE hFont = GetFont().GetResourceHandle(); wxASSERT_MSG( hFont, wxT("should have valid font") ); @@ -1130,10 +1141,10 @@ void wxWindowMSW::SetLayoutDirection(wxLayoutDirection dir) #ifdef __WXWINCE__ wxUnusedVar(dir); #else - const HWND hwnd = GetHwnd(); - wxCHECK_RET( hwnd, _T("layout direction must be set after window creation") ); + wxCHECK_RET( GetHwnd(), + _T("layout direction must be set after window creation") ); - LONG styleOld = ::GetWindowLong(hwnd, GWL_EXSTYLE); + LONG styleOld = wxGetWindowExStyle(this); LONG styleNew = styleOld; switch ( dir ) @@ -1153,7 +1164,7 @@ void wxWindowMSW::SetLayoutDirection(wxLayoutDirection dir) if ( styleNew != styleOld ) { - ::SetWindowLong(hwnd, GWL_EXSTYLE, styleNew); + wxSetWindowExStyle(this, styleNew); } #endif } @@ -1163,12 +1174,10 @@ wxLayoutDirection wxWindowMSW::GetLayoutDirection() const #ifdef __WXWINCE__ return wxLayout_Default; #else - const HWND hwnd = GetHwnd(); - wxCHECK_MSG( hwnd, wxLayout_Default, _T("invalid window") ); + wxCHECK_MSG( GetHwnd(), wxLayout_Default, _T("invalid window") ); - return ::GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL - ? wxLayout_RightToLeft - : wxLayout_LeftToRight; + return wxHasWindowExStyle(this, WS_EX_LAYOUTRTL) ? wxLayout_RightToLeft + : wxLayout_LeftToRight; #endif } @@ -1193,6 +1202,8 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd) HWND hwnd = (HWND)hWnd; wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in SubclassWin") ); + SetHWND(hWnd); + wxAssociateWinWithHandle(hwnd, this); m_oldWndProc = (WXFARPROC)wxGetWindowProc((HWND)hWnd); @@ -1251,7 +1262,7 @@ void wxWindowMSW::AssociateHandle(WXWidget handle) WXHWND wxhwnd = (WXHWND)handle; - SetHWND(wxhwnd); + // this also calls SetHWND(wxhwnd) SubclassWin(wxhwnd); } @@ -1377,14 +1388,14 @@ void wxWindowMSW::MSWUpdateStyle(long flagsOld, long exflagsOld) } // and the extended style - long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE); + long exstyleReal = wxGetWindowExStyle(this); if ( exstyle != exstyleOld ) { exstyleReal &= ~exstyleOld; exstyleReal |= exstyle; - ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal); + wxSetWindowExStyle(this, exstyleReal); // ex style changes don't take effect without calling SetWindowPos callSWP = true; @@ -1592,7 +1603,7 @@ bool wxWindowMSW::Reparent(wxWindowBase *parent) ::SetParent(hWndChild, hWndParent); #ifndef __WXWINCE__ - if ( ::GetWindowLong(hWndChild, GWL_EXSTYLE) & WS_EX_CONTROLPARENT ) + if ( wxHasWindowExStyle(this, WS_EX_CONTROLPARENT) ) { EnsureParentHasControlParentStyle(GetParent()); } @@ -1610,20 +1621,22 @@ static inline void SendSetRedraw(HWND hwnd, bool on) void wxWindowMSW::DoFreeze() { - if ( IsShown() ) - SendSetRedraw(GetHwnd(), false); + if ( !IsShown() ) + return; // no point in freezing hidden window + + SendSetRedraw(GetHwnd(), false); } void wxWindowMSW::DoThaw() { - if ( IsShown() ) - { - SendSetRedraw(GetHwnd(), true); + if ( !IsShown() ) + return; // hidden windows aren't frozen by DoFreeze - // we need to refresh everything or otherwise the invalidated area - // is not going to be repainted - Refresh(); - } + SendSetRedraw(GetHwnd(), true); + + // we need to refresh everything or otherwise the invalidated area + // is not going to be repainted + Refresh(); } void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect) @@ -2534,8 +2547,7 @@ bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* msg) { wxWindow * const win = node->GetData(); if ( win->CanAcceptFocus() && - !(::GetWindowLong(GetHwndOf(win), GWL_EXSTYLE) & - WS_EX_CONTROLPARENT) ) + !wxHasWindowExStyle(win, WS_EX_CONTROLPARENT) ) { // it shouldn't hang... canSafelyCallIsDlgMsg = true; @@ -3419,7 +3431,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l rect = (RECT *)lParam; } - wxUxThemeHandle hTheme((wxWindow *)this, L"EDIT"); + wxUxThemeHandle hTheme((const wxWindow *)this, L"EDIT"); RECT rcClient = { 0, 0, 0, 0 }; wxClientDC dc((wxWindow *)this); wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); @@ -3451,7 +3463,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l rc.result = MSWDefWindowProc(message, wParam, lParam); processed = true; - wxUxThemeHandle hTheme((wxWindow *)this, L"EDIT"); + wxUxThemeHandle hTheme((const wxWindow *)this, L"EDIT"); wxWindowDC dc((wxWindow *)this); wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); @@ -3543,7 +3555,7 @@ void wxAssociateWinWithHandle(HWND hwnd, wxWindowMSW *win) } #endif // __WXDEBUG__ - gs_windowHandles[hwnd] = win; + gs_windowHandles[hwnd] = (wxWindow *)win; } void wxRemoveHandleAssociation(wxWindowMSW *win) @@ -3662,6 +3674,12 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass, WXDWORD style, WXDWORD extendedStyle) { + // check a common bug in the user code: if the window is created with a + // non-default ctor and Create() is called too, we'd create 2 HWND for a + // single wxWindow object and this results in all sorts of trouble, + // especially for wxTLWs + wxCHECK_MSG( !m_hWnd, true, "window can't be recreated" ); + // choose the position/size for the new window int x, y, w, h; (void)MSWGetCreateWindowCoords(pos, size, x, y, w, h); @@ -3901,7 +3919,7 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff) wxCloseEvent event(wxEVT_END_SESSION, wxID_ANY); event.SetEventObject(wxTheApp); event.SetCanVeto(false); - event.SetLoggingOff( (logOff == (long)ENDSESSION_LOGOFF) ); + event.SetLoggingOff((logOff & ENDSESSION_LOGOFF) != 0); return wxTheApp->ProcessEvent(event); #else @@ -4203,9 +4221,6 @@ bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam), break; case PBT_APMRESUMESUSPEND: -#ifdef PBT_APMRESUMEAUTOMATIC - case PBT_APMRESUMEAUTOMATIC: -#endif evtType = wxEVT_POWER_RESUME; break; @@ -4222,6 +4237,9 @@ bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam), case PBT_APMPOWERSTATUSCHANGE: case PBT_APMOEMEVENT: case PBT_APMRESUMECRITICAL: +#ifdef PBT_APMRESUMEAUTOMATIC + case PBT_APMRESUMEAUTOMATIC: +#endif evtType = wxEVT_NULL; break; } @@ -4244,17 +4262,33 @@ bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam), bool wxWindowMSW::IsDoubleBuffered() const { - for ( const wxWindowMSW *wnd = this; - wnd && !wnd->IsTopLevel(); wnd = - wnd->GetParent() ) + for ( const wxWindowMSW *win = this; win; win = win->GetParent() ) { - if ( ::GetWindowLong(GetHwndOf(wnd), GWL_EXSTYLE) & WS_EX_COMPOSITED ) + if ( wxHasWindowExStyle(win, WS_EX_COMPOSITED) ) return true; + + if ( win->IsTopLevel() ) + break; } return false; } +void wxWindowMSW::SetDoubleBuffered(bool on) +{ + // Get the current extended style bits + long exstyle = wxGetWindowExStyle(this); + + // Twiddle the bit as needed + if ( on ) + exstyle |= WS_EX_COMPOSITED; + else + exstyle &= ~WS_EX_COMPOSITED; + + // put it back + wxSetWindowExStyle(this, exstyle); +} + // --------------------------------------------------------------------------- // owner drawn stuff // --------------------------------------------------------------------------- @@ -5065,12 +5099,8 @@ bool wxWindowMSW::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND control) // coming from a control to wxEVT_COMMAND_MENU_SELECTED if ( !control ) { - // If no child window, it may be an accelerator, e.g. for a popup menu - // command - - wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED); + wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, id); event.SetEventObject(this); - event.SetId(id); event.SetInt(id); return HandleWindowEvent(event); @@ -5607,18 +5637,19 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel), return wxNOT_FOUND; } -bool wxWindowMSW::HandleClipboardEvent( WXUINT nMsg ) +#endif // wxUSE_MENUS + +bool wxWindowMSW::HandleClipboardEvent(WXUINT nMsg) { - const wxEventType type = ( nMsg == WM_CUT ) ? wxEVT_COMMAND_TEXT_CUT : - ( nMsg == WM_COPY ) ? wxEVT_COMMAND_TEXT_COPY : - /*( nMsg == WM_PASTE ) ? */ wxEVT_COMMAND_TEXT_PASTE; + const wxEventType type = nMsg == WM_CUT ? wxEVT_COMMAND_TEXT_CUT + : nMsg == WM_COPY ? wxEVT_COMMAND_TEXT_COPY + : /* nMsg == WM_PASTE */ wxEVT_COMMAND_TEXT_PASTE; wxClipboardTextEvent evt(type, GetId()); evt.SetEventObject(this); return HandleWindowEvent(evt); } -#endif // wxUSE_MENUS // --------------------------------------------------------------------------- // joystick