X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4eb77d8bce9c29fe465f2fad3a8e5f3b1c6b6e62..af27647706cb7ca50cf04814ff867532919a252c:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 25e1dea928..5ddf3d7a8c 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -212,6 +212,13 @@ WX_DECLARE_HASH_MAP(int, wxWindow::MSWMessageHandler, static MSWMessageHandlers gs_messageHandlers; +// hash containing all our windows, it uses HWND keys and wxWindow* values +WX_DECLARE_HASH_MAP(HWND, wxWindow *, + wxPointerHash, wxPointerEqual, + WindowHandles); + +static WindowHandles gs_windowHandles; + // --------------------------------------------------------------------------- // private functions // --------------------------------------------------------------------------- @@ -227,7 +234,6 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, void wxRemoveHandleAssociation(wxWindowMSW *win); extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win); -wxWindow *wxFindWinFromHandle(WXHWND hWnd); // get the text metrics for the current font static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win); @@ -275,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(); @@ -710,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; @@ -737,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_SLIDE: - needsDir = true; - dwFlags |= AW_SLIDE; + 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_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: @@ -773,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")); @@ -848,7 +861,7 @@ void wxWindowMSW::DoReleaseMouse() /* static */ wxWindow *wxWindowBase::GetCapture() { HWND hwnd = ::GetCapture(); - return hwnd ? wxFindWinFromHandle((WXHWND)hwnd) : (wxWindow *)NULL; + return hwnd ? wxFindWinFromHandle(hwnd) : NULL; } bool wxWindowMSW::SetFont(const wxFont& font) @@ -862,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") ); @@ -1124,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 ) @@ -1147,7 +1164,7 @@ void wxWindowMSW::SetLayoutDirection(wxLayoutDirection dir) if ( styleNew != styleOld ) { - ::SetWindowLong(hwnd, GWL_EXSTYLE, styleNew); + wxSetWindowExStyle(this, styleNew); } #endif } @@ -1157,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 } @@ -1187,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); @@ -1245,7 +1262,7 @@ void wxWindowMSW::AssociateHandle(WXWidget handle) WXHWND wxhwnd = (WXHWND)handle; - SetHWND(wxhwnd); + // this also calls SetHWND(wxhwnd) SubclassWin(wxhwnd); } @@ -1371,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; @@ -1570,7 +1587,7 @@ void wxWindowMSW::OnInternalIdle() } #endif // !HAVE_TRACKMOUSEEVENT - if (wxUpdateUIEvent::CanUpdate(this) && IsShown()) + if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen()) UpdateWindowUI(wxUPDATE_UI_FROMIDLE); } @@ -1586,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()); } @@ -1604,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) @@ -2350,7 +2369,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) if ( (style & BS_OWNERDRAW) == BS_OWNERDRAW ) { // emulate the button click - btn = wxFindWinFromHandle((WXHWND)msg->hwnd); + btn = wxFindWinFromHandle(msg->hwnd); } bProcess = false; @@ -2528,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; @@ -2641,11 +2659,11 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM w // trace all messages - useful for the debugging #ifdef __WXDEBUG__ wxLogTrace(wxTraceMessages, - wxT("Processing %s(hWnd=%08lx, wParam=%8lx, lParam=%8lx)"), - wxGetMessageName(message), (long)hWnd, (long)wParam, lParam); + wxT("Processing %s(hWnd=%p, wParam=%08lx, lParam=%08lx)"), + wxGetMessageName(message), hWnd, (long)wParam, lParam); #endif // __WXDEBUG__ - wxWindowMSW *wnd = wxFindWinFromHandle((WXHWND) hWnd); + wxWindowMSW *wnd = wxFindWinFromHandle(hWnd); // when we get the first message for the HWND we just created, we associate // it with wxWindow stored in gs_winBeingCreated @@ -2781,11 +2799,11 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l break; case WM_SETFOCUS: - processed = HandleSetFocus((WXHWND)(HWND)wParam); + processed = HandleSetFocus((WXHWND)wParam); break; case WM_KILLFOCUS: - processed = HandleKillFocus((WXHWND)(HWND)wParam); + processed = HandleKillFocus((WXHWND)wParam); break; case WM_PRINTCLIENT: @@ -3007,23 +3025,15 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l // for these messages we must return true if process the message #ifdef WM_DRAWITEM case WM_DRAWITEM: - case WM_MEASUREITEM: - { - int idCtrl = (UINT)wParam; - if ( message == WM_DRAWITEM ) - { - processed = MSWOnDrawItem(idCtrl, - (WXDRAWITEMSTRUCT *)lParam); - } - else - { - processed = MSWOnMeasureItem(idCtrl, - (WXMEASUREITEMSTRUCT *)lParam); - } + processed = MSWOnDrawItem(wParam, (WXDRAWITEMSTRUCT *)lParam); + if ( processed ) + rc.result = TRUE; + break; - if ( processed ) - rc.result = TRUE; - } + case WM_MEASUREITEM: + processed = MSWOnMeasureItem(wParam, (WXMEASUREITEMSTRUCT *)lParam); + if ( processed ) + rc.result = TRUE; break; #endif // defined(WM_DRAWITEM) @@ -3164,6 +3174,12 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l break; #endif // wxUSE_HOTKEY + case WM_CUT: + case WM_COPY: + case WM_PASTE: + processed = HandleClipboardEvent(message); + break; + case WM_HSCROLL: case WM_VSCROLL: { @@ -3209,11 +3225,11 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l #endif case WM_PALETTECHANGED: - processed = HandlePaletteChanged((WXHWND) (HWND) wParam); + processed = HandlePaletteChanged((WXHWND)wParam); break; case WM_CAPTURECHANGED: - processed = HandleCaptureChanged((WXHWND) (HWND) lParam); + processed = HandleCaptureChanged((WXHWND)lParam); break; case WM_SETTINGCHANGE: @@ -3225,7 +3241,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l break; case WM_ERASEBKGND: - processed = HandleEraseBkgnd((WXHDC)(HDC)wParam); + processed = HandleEraseBkgnd((WXHDC)wParam); if ( processed ) { // we processed the message, i.e. erased the background @@ -3240,7 +3256,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l #endif case WM_INITDIALOG: - processed = HandleInitDialog((WXHWND)(HWND)wParam); + processed = HandleInitDialog((WXHWND)wParam); if ( processed ) { @@ -3264,7 +3280,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l #endif case WM_SETCURSOR: - processed = HandleSetCursor((WXHWND)(HWND)wParam, + processed = HandleSetCursor((WXHWND)wParam, LOWORD(lParam), // hit test HIWORD(lParam)); // mouse msg @@ -3349,9 +3365,10 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l // we could have got an event from our child, reflect it back // to it if this is the case wxWindowMSW *win = NULL; - if ( (WXHWND)wParam != m_hWnd ) + WXHWND hWnd = (WXHWND)wParam; + if ( hWnd != m_hWnd ) { - win = FindItemByHWND((WXHWND)wParam); + win = FindItemByHWND(hWnd); } if ( !win ) @@ -3403,30 +3420,33 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l // now alter the client size making room for drawing a themed border NCCALCSIZE_PARAMS *csparam = NULL; - RECT rect; - if (wParam) + RECT *rect; + if ( wParam ) { - csparam = (NCCALCSIZE_PARAMS*)lParam; - rect = csparam->rgrc[0]; + csparam = (NCCALCSIZE_PARAMS *)lParam; + rect = &csparam->rgrc[0]; } else { - rect = *((RECT*)lParam); + 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(); - if (theme->GetThemeBackgroundContentRect( - hTheme, GetHdcOf(*impl), EP_EDITTEXT, ETS_NORMAL, - &rect, &rcClient) == S_OK) + if ( theme->GetThemeBackgroundContentRect + ( + hTheme, + GetHdcOf(*impl), + EP_EDITTEXT, + ETS_NORMAL, + rect, + &rcClient) == S_OK ) { InflateRect(&rcClient, -1, -1); - if (wParam) - csparam->rgrc[0] = rcClient; - else - *((RECT*)lParam) = rcClient; + *rect = rcClient; rc.result = WVR_REDRAW; } } @@ -3443,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(); @@ -3507,38 +3527,40 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l // wxWindow <-> HWND map // ---------------------------------------------------------------------------- -wxWinHashTable *wxWinHandleHash = NULL; - -wxWindow *wxFindWinFromHandle(WXHWND hWnd) +wxWindow *wxFindWinFromHandle(HWND hwnd) { - return (wxWindow*)wxWinHandleHash->Get((long)hWnd); + WindowHandles::const_iterator i = gs_windowHandles.find(hwnd); + return i == gs_windowHandles.end() ? NULL : i->second; } -void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win) +void wxAssociateWinWithHandle(HWND hwnd, wxWindowMSW *win) { - // adding NULL hWnd is (first) surely a result of an error and + // adding NULL hwnd is (first) surely a result of an error and // (secondly) breaks menu command processing - wxCHECK_RET( hWnd != (HWND)NULL, - wxT("attempt to add a NULL hWnd to window list ignored") ); + wxCHECK_RET( hwnd != (HWND)NULL, + wxT("attempt to add a NULL hwnd to window list ignored") ); - wxWindow *oldWin = wxFindWinFromHandle((WXHWND) hWnd); #ifdef __WXDEBUG__ - if ( oldWin && (oldWin != win) ) + WindowHandles::const_iterator i = gs_windowHandles.find(hwnd); + if ( i != gs_windowHandles.end() ) { - wxLogDebug(wxT("HWND %X already associated with another window (%s)"), - (int) hWnd, win->GetClassInfo()->GetClassName()); + if ( i->second != win ) + { + wxLogDebug(wxT("HWND %p already associated with another window (%s)"), + hwnd, win->GetClassInfo()->GetClassName()); + } + //else: this actually happens currently because we associate the window + // with its HWND during creation (if we create it) and also when + // SubclassWin() is called later, this is ok } - else #endif // __WXDEBUG__ - if (!oldWin) - { - wxWinHandleHash->Put((long)hWnd, (wxWindow *)win); - } + + gs_windowHandles[hwnd] = (wxWindow *)win; } void wxRemoveHandleAssociation(wxWindowMSW *win) { - wxWinHandleHash->Delete((long)win->GetHWND()); + gs_windowHandles.erase(GetHwndOf(win)); } // ---------------------------------------------------------------------------- @@ -3652,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); @@ -3680,7 +3708,7 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass, style, x, y, w, h, (HWND)MSWGetParent(), - (HMENU)controlId, + (HMENU)wxUIntToPtr(controlId), wxGetInstance(), NULL // no extra data ); @@ -3710,7 +3738,7 @@ bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) #ifndef __WXMICROWIN__ LPNMHDR hdr = (LPNMHDR)lParam; HWND hWnd = hdr->hwndFrom; - wxWindow *win = wxFindWinFromHandle((WXHWND)hWnd); + wxWindow *win = wxFindWinFromHandle(hWnd); // if the control is one of our windows, let it handle the message itself if ( win ) @@ -3891,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 @@ -4193,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; @@ -4212,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; } @@ -4234,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 // --------------------------------------------------------------------------- @@ -5055,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); @@ -5177,7 +5217,7 @@ static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) ::IsWindowVisible(hwndUnderMouse) && ::IsWindowEnabled(hwndUnderMouse) ) { - wxWindow *winUnderMouse = wxFindWinFromHandle((WXHWND)hwndUnderMouse); + wxWindow *winUnderMouse = wxFindWinFromHandle(hwndUnderMouse); if ( winUnderMouse ) { // translate the mouse coords to the other window coords @@ -5597,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 @@ -6078,6 +6119,9 @@ WXWORD wxCharCodeWXToMSW(int wxk, bool *isVirtual) break; default: + // no VkKeyScan() under CE unfortunately, we need to test how does + // it handle OEM keys +#ifndef __WXWINCE__ // check to see if its one of the OEM key codes. BYTE vks = LOBYTE(VkKeyScan(wxk)); if ( vks != 0xff ) @@ -6085,6 +6129,7 @@ WXWORD wxCharCodeWXToMSW(int wxk, bool *isVirtual) vk = vks; } else +#endif // !__WXWINCE__ { if ( isVirtual ) *isVirtual = false; @@ -6095,22 +6140,23 @@ WXWORD wxCharCodeWXToMSW(int wxk, bool *isVirtual) return vk; } -#ifndef SM_SWAPBUTTON - #define SM_SWAPBUTTON 23 -#endif - // small helper for wxGetKeyState() and wxGetMouseState() static inline bool wxIsKeyDown(WXWORD vk) { - switch (vk) + // SM_SWAPBUTTON is not available under CE, so don't swap buttons there +#ifdef SM_SWAPBUTTON + if ( vk == VK_LBUTTON || vk == VK_RBUTTON ) { - case VK_LBUTTON: - if (GetSystemMetrics(SM_SWAPBUTTON)) vk = VK_RBUTTON; - break; - case VK_RBUTTON: - if (GetSystemMetrics(SM_SWAPBUTTON)) vk = VK_LBUTTON; - break; + if ( ::GetSystemMetrics(SM_SWAPBUTTON) ) + { + if ( vk == VK_LBUTTON ) + vk = VK_RBUTTON; + else // vk == VK_RBUTTON + vk = VK_LBUTTON; + } } +#endif // SM_SWAPBUTTON + // the low order bit indicates whether the key was pressed since the last // call and the high order one indicates whether it is down right now and // we only want that one @@ -6174,7 +6220,7 @@ wxWindow *wxGetActiveWindow() HWND hWnd = GetActiveWindow(); if ( hWnd != 0 ) { - return wxFindWinFromHandle((WXHWND) hWnd); + return wxFindWinFromHandle(hWnd); } return NULL; } @@ -6189,7 +6235,7 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd) wxWindow *win = (wxWindow *)NULL; if ( hwnd ) { - win = wxFindWinFromHandle((WXHWND)hwnd); + win = wxFindWinFromHandle(hwnd); if ( !win ) { #if wxUSE_RADIOBOX @@ -6233,7 +6279,7 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd) #endif hwnd = ::GetParent(hwnd); - win = wxFindWinFromHandle((WXHWND)hwnd); + win = wxFindWinFromHandle(hwnd); } return win;