X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/01101e2da6f4493ce8cfcf4d9509163b9c264d58..d968078adbfb147e913b9a33fc54242a36f117ce:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index ef18195d59..25e1dea928 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -79,6 +79,7 @@ #endif #include "wx/msw/private.h" +#include "wx/msw/dcclient.h" #if wxUSE_TOOLTIPS #include "wx/tooltip.h" @@ -121,6 +122,31 @@ #endif #endif +#if wxUSE_UXTHEME + #include "wx/msw/uxtheme.h" + #define EP_EDITTEXT 1 + #define ETS_NORMAL 1 + #define ETS_HOT 2 + #define ETS_SELECTED 3 + #define ETS_DISABLED 4 + #define ETS_FOCUSED 5 + #define ETS_READONLY 6 + #define ETS_ASSIST 7 +#endif + +// define the constants used by AnimateWindow() if our SDK doesn't have them +#ifndef AW_CENTER + #define AW_HOR_POSITIVE 0x00000001 + #define AW_HOR_NEGATIVE 0x00000002 + #define AW_VER_POSITIVE 0x00000004 + #define AW_VER_NEGATIVE 0x00000008 + #define AW_CENTER 0x00000010 + #define AW_HIDE 0x00010000 + #define AW_ACTIVATE 0x00020000 + #define AW_SLIDE 0x00040000 + #define AW_BLEND 0x00080000 +#endif + #if defined(TME_LEAVE) && defined(WM_MOUSELEAVE) && wxUSE_DYNLIB_CLASS #define HAVE_TRACKMOUSEEVENT #endif // everything needed for TrackMouseEvent() @@ -143,13 +169,19 @@ #define wxUSE_MOUSEEVENT_HACK 1 #endif +// not all compilers/platforms have X button related declarations (notably +// Windows CE doesn't, and probably some old SDKs don't neither) +#ifdef WM_XBUTTONDOWN + #define wxHAS_XBUTTON +#endif + // --------------------------------------------------------------------------- // global variables // --------------------------------------------------------------------------- #if wxUSE_MENUS_NATIVE -wxMenu *wxCurrentPopupMenu = NULL; -#endif // wxUSE_MENUS_NATIVE +extern wxMenu *wxCurrentPopupMenu; +#endif #ifdef __WXWINCE__ extern wxChar *wxCanvasClassName; @@ -492,8 +524,6 @@ void wxWindowMSW::Init() m_mouseInWindow = false; m_lastKeydownProcessed = false; - m_frozenness = 0; - m_hWnd = 0; m_hDWP = 0; @@ -683,6 +713,108 @@ bool wxWindowMSW::Show(bool show) return true; } +bool +wxWindowMSW::MSWShowWithEffect(bool show, + wxShowEffect effect, + unsigned timeout, + wxDirection dir) +{ + typedef BOOL (WINAPI *AnimateWindow_t)(HWND, DWORD, DWORD); + + static AnimateWindow_t s_pfnAnimateWindow = NULL; + static bool s_initDone = false; + if ( !s_initDone ) + { + wxDynamicLibrary dllUser32(_T("user32.dll"), wxDL_VERBATIM | wxDL_QUIET); + wxDL_INIT_FUNC(s_pfn, AnimateWindow, dllUser32); + + s_initDone = true; + + // notice that it's ok to unload user32.dll here as it won't be really + // unloaded, being still in use because we link to it statically too + } + + if ( !s_pfnAnimateWindow ) + return Show(show); + + // 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; + break; + + case wxSHOW_EFFECT_SLIDE: + needsDir = true; + dwFlags |= AW_SLIDE; + break; + + case wxSHOW_EFFECT_BLEND: + dwFlags |= AW_BLEND; + break; + + case wxSHOW_EFFECT_EXPAND: + dwFlags |= AW_CENTER; + break; + + + case wxSHOW_EFFECT_MAX: + wxFAIL_MSG( _T("invalid window show effect") ); + return false; + + default: + wxFAIL_MSG( _T("unknown window show effect") ); + 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")); + + return false; + } + + return true; +} + // Raise the window to the top of the Z order void wxWindowMSW::Raise() { @@ -1076,7 +1208,7 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd) // we're officially created now, send the event wxWindowCreateEvent event((wxWindow *)this); - (void)GetEventHandler()->ProcessEvent(event); + (void)HandleWindowEvent(event); } void wxWindowMSW::UnsubclassWin() @@ -1268,6 +1400,43 @@ void wxWindowMSW::MSWUpdateStyle(long flagsOld, long exflagsOld) } } +wxBorder wxWindowMSW::GetDefaultBorderForControl() const +{ + return wxBORDER_THEME; +} + +wxBorder wxWindowMSW::GetDefaultBorder() const +{ + return wxWindowBase::GetDefaultBorder(); +} + +// Translate wxBORDER_THEME (and other border styles if necessary) to the value +// that makes most sense for this Windows environment +wxBorder wxWindowMSW::TranslateBorder(wxBorder border) const +{ +#if defined(__POCKETPC__) || defined(__SMARTPHONE__) + if (border == wxBORDER_THEME || border == wxBORDER_SUNKEN || border == wxBORDER_SIMPLE) + return wxBORDER_SIMPLE; + else + return wxBORDER_NONE; +#else +#if wxUSE_UXTHEME + if (border == wxBORDER_THEME) + { + if (CanApplyThemeBorder()) + { + wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive(); + if (theme) + return wxBORDER_THEME; + } + return wxBORDER_SUNKEN; + } +#endif + return border; +#endif +} + + WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const { // translate common wxWidgets styles to Windows ones @@ -1297,7 +1466,10 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const if ( flags & wxHSCROLL ) style |= WS_HSCROLL; - const wxBorder border = GetBorder(flags); + const wxBorder border = TranslateBorder(GetBorder(flags)); + + // After translation, border is now optimized for the specific version of Windows + // and theme engine presence. // WS_BORDER is only required for wxBORDER_SIMPLE if ( border == wxBORDER_SIMPLE ) @@ -1322,6 +1494,7 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const case wxBORDER_NONE: case wxBORDER_SIMPLE: + case wxBORDER_THEME: break; case wxBORDER_STATIC: @@ -1337,9 +1510,9 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const style &= ~WS_BORDER; break; - case wxBORDER_DOUBLE: - *exstyle |= WS_EX_DLGMODALFRAME; - break; +// case wxBORDER_DOUBLE: +// *exstyle |= WS_EX_DLGMODALFRAME; +// break; } // wxUniv doesn't use Windows dialog navigation functions at all @@ -1397,7 +1570,7 @@ void wxWindowMSW::OnInternalIdle() } #endif // !HAVE_TRACKMOUSEEVENT - if (wxUpdateUIEvent::CanUpdate(this)) + if (wxUpdateUIEvent::CanUpdate(this) && IsShown()) UpdateWindowUI(wxUPDATE_UI_FROMIDLE); } @@ -1429,29 +1602,21 @@ static inline void SendSetRedraw(HWND hwnd, bool on) #endif } -void wxWindowMSW::Freeze() +void wxWindowMSW::DoFreeze() { - if ( !m_frozenness++ ) - { - if ( IsShown() ) - SendSetRedraw(GetHwnd(), false); - } + if ( IsShown() ) + SendSetRedraw(GetHwnd(), false); } -void wxWindowMSW::Thaw() +void wxWindowMSW::DoThaw() { - wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") ); - - if ( --m_frozenness == 0 ) + if ( IsShown() ) { - if ( IsShown() ) - { - SendSetRedraw(GetHwnd(), true); + SendSetRedraw(GetHwnd(), true); - // we need to refresh everything or otherwise the invalidated area - // is not going to be repainted - Refresh(); - } + // we need to refresh everything or otherwise the invalidated area + // is not going to be repainted + Refresh(); } } @@ -1963,19 +2128,19 @@ int wxWindowMSW::GetCharWidth() const void wxWindowMSW::GetTextExtent(const wxString& string, int *x, int *y, int *descent, int *externalLeading, - const wxFont *theFont) const + const wxFont *fontToUse) const { - wxASSERT_MSG( !theFont || theFont->Ok(), + wxASSERT_MSG( !fontToUse || fontToUse->Ok(), _T("invalid font in GetTextExtent()") ); - wxFont fontToUse; - if (theFont) - fontToUse = *theFont; + HFONT hfontToUse; + if ( fontToUse ) + hfontToUse = GetHfontOf(*fontToUse); else - fontToUse = GetFont(); + hfontToUse = GetHfontOf(GetFont()); WindowHDC hdc(GetHwnd()); - SelectInHDC selectFont(hdc, GetHfontOf(fontToUse)); + SelectInHDC selectFont(hdc, hfontToUse); SIZE sizeRect; TEXTMETRIC tm; @@ -2042,7 +2207,6 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y) point.x = x; point.y = y; ::ClientToScreen(hWnd, &point); - wxCurrentPopupMenu = menu; #if defined(__WXWINCE__) static const UINT flags = 0; #else // !__WXWINCE__ @@ -2071,8 +2235,6 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y) // for example) and so we do need to process the event immediately wxYieldForCommandsOnly(); - wxCurrentPopupMenu = NULL; - menu->SetInvokingWindow(NULL); return true; @@ -2174,13 +2336,6 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) case VK_RETURN: { - if ( (lDlgCode & DLGC_WANTMESSAGE) && !bCtrlDown ) - { - // control wants to process Enter itself, don't - // call IsDialogMessage() which would consume it - return false; - } - #if wxUSE_BUTTON // currently active button should get enter press even // if there is a default button elsewhere so check if @@ -2202,9 +2357,49 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) } else // not a button itself, do we have default button? { - wxTopLevelWindow * - tlw = wxDynamicCast(wxGetTopLevelParent(this), - wxTopLevelWindow); + // check if this window or any of its ancestors + // wants the message for itself (we always reserve + // Ctrl-Enter for dialog navigation though) + wxWindow *win = this; + if ( !bCtrlDown ) + { + // this will contain the dialog code of this + // window and all of its parent windows in turn + LONG lDlgCode2 = lDlgCode; + + while ( win ) + { + if ( lDlgCode2 & DLGC_WANTMESSAGE ) + { + // as it wants to process Enter itself, + // don't call IsDialogMessage() which + // would consume it + return false; + } + + // don't propagate keyboard messages beyond + // the first top level window parent + if ( win->IsTopLevel() ) + break; + + win = win->GetParent(); + + lDlgCode2 = ::SendMessage + ( + GetHwndOf(win), + WM_GETDLGCODE, + 0, + 0 + ); + } + } + else // bCtrlDown + { + win = wxGetTopLevelParent(win); + } + + wxTopLevelWindow * const + tlw = wxDynamicCast(win, wxTopLevelWindow); if ( tlw ) { btn = wxDynamicCast(tlw->GetDefaultItem(), @@ -2224,7 +2419,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) // map Enter presses into button presses on PDAs wxJoystickEvent event(wxEVT_JOY_BUTTON_DOWN); event.SetEventObject(this); - if ( GetEventHandler()->ProcessEvent(event) ) + if ( HandleWindowEvent(event) ) return true; #endif // __WXWINCE__ } @@ -2242,7 +2437,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) event.SetFromTab(bFromTab); event.SetEventObject(this); - if ( GetEventHandler()->ProcessEvent(event) ) + if ( HandleWindowEvent(event) ) { // as we don't call IsDialogMessage(), which would take of // this by default, we need to manually send this message @@ -2536,7 +2731,19 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l } } break; +#if 0 + case WM_ENTERSIZEMOVE: + { + processed = HandleEnterSizeMove(); + } + break; + case WM_EXITSIZEMOVE: + { + processed = HandleExitSizeMove(); + } + break; +#endif case WM_SIZING: { LPRECT pRect = (LPRECT)lParam; @@ -2652,9 +2859,11 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_MBUTTONDBLCLK: +#ifdef wxHAS_XBUTTON case WM_XBUTTONDOWN: case WM_XBUTTONUP: case WM_XBUTTONDBLCLK: +#endif // wxHAS_XBUTTON { #ifdef __WXMICROWIN__ // MicroWindows seems to ignore the fact that a window is @@ -2721,7 +2930,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt); evtCtx.SetEventObject(this); - if (GetEventHandler()->ProcessEvent(evtCtx)) + if (HandleWindowEvent(evtCtx)) { processed = true; return true; @@ -3109,14 +3318,14 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l ); helpEvent.SetEventObject(this); - GetEventHandler()->ProcessEvent(helpEvent); + HandleWindowEvent(helpEvent); #ifndef __WXWINCE__ } else if ( info->iContextType == HELPINFO_MENUITEM ) { wxHelpEvent helpEvent(wxEVT_HELP, info->iCtrlId); helpEvent.SetEventObject(this); - GetEventHandler()->ProcessEvent(helpEvent); + HandleWindowEvent(helpEvent); } else // unknown help event? @@ -3149,7 +3358,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l win = this; evtCtx.SetEventObject(win); - processed = win->GetEventHandler()->ProcessEvent(evtCtx); + processed = win->HandleWindowEvent(evtCtx); } break; #endif @@ -3180,6 +3389,98 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l break; #endif // __WXWINCE__ +#if wxUSE_UXTHEME + // If we want the default themed border then we need to draw it ourselves + case WM_NCCALCSIZE: + { + wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive(); + const wxBorder border = TranslateBorder(GetBorder()); + if (theme && border == wxBORDER_THEME) + { + // first ask the widget to calculate the border size + rc.result = MSWDefWindowProc(message, wParam, lParam); + processed = true; + + // now alter the client size making room for drawing a themed border + NCCALCSIZE_PARAMS *csparam = NULL; + RECT rect; + if (wParam) + { + csparam = (NCCALCSIZE_PARAMS*)lParam; + rect = csparam->rgrc[0]; + } + else + { + rect = *((RECT*)lParam); + } + wxUxThemeHandle hTheme((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) + { + InflateRect(&rcClient, -1, -1); + if (wParam) + csparam->rgrc[0] = rcClient; + else + *((RECT*)lParam) = rcClient; + rc.result = WVR_REDRAW; + } + } + } + break; + + case WM_NCPAINT: + { + wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive(); + const wxBorder border = TranslateBorder(GetBorder()); + if (theme && border == wxBORDER_THEME) + { + // first ask the widget to paint its non-client area, such as scrollbars, etc. + rc.result = MSWDefWindowProc(message, wParam, lParam); + processed = true; + + wxUxThemeHandle hTheme((wxWindow *)this, L"EDIT"); + wxWindowDC dc((wxWindow *)this); + wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); + + // Clip the DC so that you only draw on the non-client area + RECT rcBorder; + wxCopyRectToRECT(GetSize(), rcBorder); + + RECT rcClient; + theme->GetThemeBackgroundContentRect( + hTheme, GetHdcOf(*impl), EP_EDITTEXT, ETS_NORMAL, &rcBorder, &rcClient); + InflateRect(&rcClient, -1, -1); + + ::ExcludeClipRect(GetHdcOf(*impl), rcClient.left, rcClient.top, + rcClient.right, rcClient.bottom); + + // Make sure the background is in a proper state + if (theme->IsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL)) + { + theme->DrawThemeParentBackground(GetHwnd(), GetHdcOf(*impl), &rcBorder); + } + + // Draw the border + int nState; + if ( !IsEnabled() ) + nState = ETS_DISABLED; + // should we check this? + //else if ( ::GetWindowLong(GetHwnd(), GWL_STYLE) & ES_READONLY) + // nState = ETS_READONLY; + else + nState = ETS_NORMAL; + theme->DrawThemeBackground(hTheme, GetHdcOf(*impl), EP_EDITTEXT, nState, &rcBorder, NULL); + } + } + break; + +#endif // wxUSE_UXTHEME + default: // try a custom message handler const MSWMessageHandlers::const_iterator @@ -3652,7 +3953,7 @@ bool wxWindowMSW::HandleActivate(int state, m_windowId); event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } bool wxWindowMSW::HandleSetFocus(WXHWND hwnd) @@ -3667,7 +3968,7 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd) // notify the parent keeping track of focus for the kbd navigation // purposes that we got it wxChildFocusEvent eventFocus((wxWindow *)this); - (void)GetEventHandler()->ProcessEvent(eventFocus); + (void)HandleWindowEvent(eventFocus); #if wxUSE_CARET // Deal with caret @@ -3677,22 +3978,13 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd) } #endif // wxUSE_CARET -#if wxUSE_TEXTCTRL - // If it's a wxTextCtrl don't send the event as it will be done - // after the control gets to process it from EN_FOCUS handler - if ( wxDynamicCastThis(wxTextCtrl) ) - { - return false; - } -#endif // wxUSE_TEXTCTRL - wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId); event.SetEventObject(this); // wxFindWinFromHandle() may return NULL, it is ok event.SetWindow(wxFindWinFromHandle(hwnd)); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } bool wxWindowMSW::HandleKillFocus(WXHWND hwnd) @@ -3705,16 +3997,6 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd) } #endif // wxUSE_CARET -#if wxUSE_TEXTCTRL - // If it's a wxTextCtrl don't send the event as it will be done - // after the control gets to process it. - wxTextCtrl *ctrl = wxDynamicCastThis(wxTextCtrl); - if ( ctrl ) - { - return false; - } -#endif - // Don't send the event when in the process of being deleted. This can // only cause problems if the event handler tries to access the object. if ( m_isBeingDeleted ) @@ -3728,7 +4010,7 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd) // wxFindWinFromHandle() may return NULL, it is ok event.SetWindow(wxFindWinFromHandle(hwnd)); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } // --------------------------------------------------------------------------- @@ -3754,7 +4036,7 @@ bool wxWindowMSW::HandleShow(bool show, int WXUNUSED(status)) wxShowEvent event(GetId(), show); event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus)) @@ -3762,7 +4044,7 @@ bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus)) wxInitDialogEvent event(GetId()); event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam) @@ -3802,7 +4084,7 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam) event.m_pos.x = dropPoint.x; event.m_pos.y = dropPoint.y; - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); #endif } @@ -3845,7 +4127,7 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd), ScreenToClient(&x, &y); wxSetCursorEvent event(x, y); - bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event); + bool processedEvtSetCursor = HandleWindowEvent(event); if ( processedEvtSetCursor && event.HasCursor() ) { hcursor = GetHcursorOf(event.GetCursor()); @@ -3941,7 +4223,7 @@ bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam), // TODO: notify about PBTF_APMRESUMEFROMFAILURE in case of resume events? wxPowerEvent event(evtType); - if ( !GetEventHandler()->ProcessEvent(event) ) + if ( !HandleWindowEvent(event) ) return false; *vetoed = event.IsVetoed(); @@ -4091,7 +4373,7 @@ bool wxWindowMSW::HandleSysColorChange() wxSysColourChangedEvent event; event.SetEventObject(this); - (void)GetEventHandler()->ProcessEvent(event); + (void)HandleWindowEvent(event); // always let the system carry on the default processing to allow the // native controls to react to the colours update @@ -4103,7 +4385,7 @@ bool wxWindowMSW::HandleDisplayChange() wxDisplayChangedEvent event; event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } #ifndef __WXMICROWIN__ @@ -4167,7 +4449,7 @@ bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange) event.SetEventObject(this); event.SetChangedWindow(wxFindWinFromHandle(hWndPalChange)); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture) @@ -4179,7 +4461,7 @@ bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture) wxWindow *win = wxFindWinFromHandle(hWndGainedCapture); wxMouseCaptureChangedEvent event(GetId(), win); event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } bool wxWindowMSW::HandleSettingChange(WXWPARAM wParam, WXLPARAM lParam) @@ -4234,7 +4516,7 @@ bool wxWindowMSW::HandleQueryNewPalette() wxQueryNewPaletteEvent event(GetId()); event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event) && event.GetPaletteRealized(); + return HandleWindowEvent(event) && event.GetPaletteRealized(); } // Responds to colour changes: passes event on to children. @@ -4350,14 +4632,18 @@ bool wxWindowMSW::HandlePaint() wxPaintEvent event(m_windowId); event.SetEventObject(this); - bool processed = GetEventHandler()->ProcessEvent(event); + bool processed = HandleWindowEvent(event); // note that we must generate NC event after the normal one as otherwise // BeginPaint() will happily overwrite our decorations with the background // colour wxNcPaintEvent eventNc(m_windowId); eventNc.SetEventObject(this); - GetEventHandler()->ProcessEvent(eventNc); + HandleWindowEvent(eventNc); + + // don't keep an HRGN we don't need any longer (GetUpdateRegion() can only + // be called from inside the event handlers called above) + m_updateRegion.Clear(); return processed; } @@ -4368,7 +4654,7 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event) #ifdef __WXUNIVERSAL__ event.Skip(); #else - HDC hDC = (HDC) wxPaintDC::FindDCInCache((wxWindow*) event.GetEventObject()); + HDC hDC = (HDC) wxPaintDCImpl::FindDCInCache((wxWindow*) event.GetEventObject()); if (hDC != 0) { MSWDefWindowProc(WM_PAINT, (WPARAM) hDC, 0); @@ -4379,16 +4665,17 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event) bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc) { wxDCTemp dc(hdc, GetClientSize()); + wxDCTempImpl *impl = (wxDCTempImpl*) dc.GetImpl(); - dc.SetHDC(hdc); - dc.SetWindow((wxWindow *)this); + impl->SetHDC(hdc); + impl->SetWindow((wxWindow *)this); wxEraseEvent event(m_windowId, &dc); event.SetEventObject(this); - bool rc = GetEventHandler()->ProcessEvent(event); + bool rc = HandleWindowEvent(event); // must be called manually as ~wxDC doesn't do anything for wxDCTemp - dc.SelectOldObjects(hdc); + impl->SelectOldObjects(hdc); return rc; } @@ -4412,9 +4699,12 @@ void wxWindowMSW::OnEraseBackground(wxEraseEvent& event) return; } + wxDC *dc = event.GetDC(); + if (!dc) return; + wxMSWDCImpl *impl = (wxMSWDCImpl*) dc->GetImpl(); // do default background painting - if ( !DoEraseBackground(GetHdcOf(*event.GetDC())) ) + if ( !DoEraseBackground(GetHdcOf(*impl)) ) { // let the system paint the background event.Skip(); @@ -4524,7 +4814,7 @@ bool wxWindowMSW::HandleMinimize() wxIconizeEvent event(m_windowId); event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } bool wxWindowMSW::HandleMaximize() @@ -4532,7 +4822,7 @@ bool wxWindowMSW::HandleMaximize() wxMaximizeEvent event(m_windowId); event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } bool wxWindowMSW::HandleMove(int x, int y) @@ -4541,7 +4831,7 @@ bool wxWindowMSW::HandleMove(int x, int y) wxMoveEvent event(point, m_windowId); event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } bool wxWindowMSW::HandleMoving(wxRect& rect) @@ -4549,12 +4839,30 @@ bool wxWindowMSW::HandleMoving(wxRect& rect) wxMoveEvent event(rect, m_windowId); event.SetEventObject(this); - bool rc = GetEventHandler()->ProcessEvent(event); + bool rc = HandleWindowEvent(event); if (rc) rect = event.GetRect(); return rc; } +bool wxWindowMSW::HandleEnterSizeMove() +{ + wxMoveEvent event(wxPoint(0,0), m_windowId); + event.SetEventType(wxEVT_MOVE_START); + event.SetEventObject(this); + + return HandleWindowEvent(event); +} + +bool wxWindowMSW::HandleExitSizeMove() +{ + wxMoveEvent event(wxPoint(0,0), m_windowId); + event.SetEventType(wxEVT_MOVE_END); + event.SetEventObject(this); + + return HandleWindowEvent(event); +} + bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam) { #if USE_DEFERRED_SIZING @@ -4614,7 +4922,7 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam) wxSizeEvent event(GetSize(), m_windowId); event.SetEventObject(this); - processed = GetEventHandler()->ProcessEvent(event); + processed = HandleWindowEvent(event); } #if USE_DEFERRED_SIZING @@ -4654,7 +4962,7 @@ bool wxWindowMSW::HandleSizing(wxRect& rect) wxSizeEvent event(rect, m_windowId); event.SetEventObject(this); - bool rc = GetEventHandler()->ProcessEvent(event); + bool rc = HandleWindowEvent(event); if (rc) rect = event.GetRect(); return rc; @@ -4706,8 +5014,11 @@ bool wxWindowMSW::HandleGetMinMaxInfo(void *WXUNUSED_IN_WINCE(mmInfo)) // command messages // --------------------------------------------------------------------------- -bool wxWindowMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) +bool wxWindowMSW::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND control) { + // sign extend to int from short before comparing with the other int ids + int id = (signed short)id_; + #if wxUSE_MENUS_NATIVE if ( !cmd && wxCurrentPopupMenu ) { @@ -4730,8 +5041,7 @@ bool wxWindowMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) // try the id if ( !win ) { - // must cast to a signed type before comparing with other ids! - win = FindItem((signed short)id); + win = FindItem(id); } if ( win ) @@ -4753,7 +5063,7 @@ bool wxWindowMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) event.SetId(id); event.SetInt(id); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } else { @@ -4797,9 +5107,11 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event, event.m_leftDown = (flags & MK_LBUTTON) != 0; event.m_middleDown = (flags & MK_MBUTTON) != 0; event.m_rightDown = (flags & MK_RBUTTON) != 0; +#ifdef wxHAS_XBUTTON event.m_aux1Down = (flags & MK_XBUTTON1) != 0; event.m_aux2Down = (flags & MK_XBUTTON2) != 0; - event.m_altDown = ::GetKeyState(VK_MENU) < 0; +#endif // wxHAS_XBUTTON + event.m_altDown = ::wxIsAltDown(); #ifndef __WXWINCE__ event.SetTimestamp(::GetMessageTime()); @@ -4907,6 +5219,7 @@ bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags) wxEVT_AUX2_DCLICK }; +#ifdef wxHAS_XBUTTON // the same messages are used for both auxillary mouse buttons so we need // to adjust the index manually switch ( msg ) @@ -4917,11 +5230,12 @@ bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags) if ( flags & MK_XBUTTON2 ) msg += wxEVT_AUX2_DOWN - wxEVT_AUX1_DOWN; } +#endif // wxHAS_XBUTTON wxMouseEvent event(eventsMouse[msg - WM_MOUSEMOVE]); InitMouseEvent(event, x, y, flags); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags) @@ -4978,7 +5292,7 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags) wxMouseEvent event(wxEVT_ENTER_WINDOW); InitMouseEvent(event, x, y, flags); - (void)GetEventHandler()->ProcessEvent(event); + (void)HandleWindowEvent(event); } } #ifdef HAVE_TRACKMOUSEEVENT @@ -5047,7 +5361,7 @@ bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam) } event.m_linesPerAction = s_linesPerRotation; - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); #else // !wxUSE_MOUSEWHEEL wxUnusedVar(wParam); @@ -5094,7 +5408,7 @@ void wxWindowMSW::GenerateMouseLeave() wxMouseEvent event(wxEVT_LEAVE_WINDOW); InitMouseEvent(event, pt.x, pt.y, state); - (void)GetEventHandler()->ProcessEvent(event); + (void)HandleWindowEvent(event); } // --------------------------------------------------------------------------- @@ -5181,7 +5495,7 @@ bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam, bool isASCII) event.m_altDown = false; } - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam, WXLPARAM lParam) @@ -5195,7 +5509,7 @@ bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam, WXLPARAM lParam) } wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam)); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam) @@ -5209,7 +5523,7 @@ bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam) } wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam)); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } #if wxUSE_MENUS @@ -5247,7 +5561,7 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel), // menu creation code wxMenuItem *item = (wxMenuItem*)mii.dwItemData; - const wxChar *p = wxStrchr(item->GetText().wx_str(), _T('&')); + const wxChar *p = wxStrchr(item->GetItemLabel().wx_str(), _T('&')); while ( p++ ) { if ( *p == _T('&') ) @@ -5292,7 +5606,7 @@ bool wxWindowMSW::HandleClipboardEvent( WXUINT nMsg ) evt.SetEventObject(this); - return GetEventHandler()->ProcessEvent(evt); + return HandleWindowEvent(evt); } #endif // wxUSE_MENUS @@ -5378,7 +5692,7 @@ bool wxWindowMSW::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags) event.SetPosition(wxPoint(x, y)); event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); #else wxUnusedVar(msg); wxUnusedVar(x); @@ -5465,7 +5779,7 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam, return false; } - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } // ---------------------------------------------------------------------------- @@ -5764,10 +6078,18 @@ WXWORD wxCharCodeWXToMSW(int wxk, bool *isVirtual) break; default: - if ( isVirtual ) - *isVirtual = false; - vk = (WXWORD)wxk; - break; + // check to see if its one of the OEM key codes. + BYTE vks = LOBYTE(VkKeyScan(wxk)); + if ( vks != 0xff ) + { + vk = vks; + } + else + { + if ( isVirtual ) + *isVirtual = false; + vk = (WXWORD)wxk; + } } return vk; @@ -5833,12 +6155,14 @@ wxMouseState wxGetMouseState() ms.SetLeftDown(wxIsKeyDown(VK_LBUTTON)); ms.SetMiddleDown(wxIsKeyDown(VK_MBUTTON)); ms.SetRightDown(wxIsKeyDown(VK_RBUTTON)); +#ifdef wxHAS_XBUTTON ms.SetAux1Down(wxIsKeyDown(VK_XBUTTON1)); ms.SetAux2Down(wxIsKeyDown(VK_XBUTTON2)); +#endif // wxHAS_XBUTTON - ms.SetControlDown(wxIsKeyDown(VK_CONTROL)); - ms.SetShiftDown(wxIsKeyDown(VK_SHIFT)); - ms.SetAltDown(wxIsKeyDown(VK_MENU)); + ms.SetControlDown(wxIsCtrlDown ()); + ms.SetShiftDown (wxIsShiftDown()); + ms.SetAltDown (wxIsAltDown ()); // ms.SetMetaDown(); return ms; @@ -6602,7 +6926,7 @@ bool wxWindowMSW::HandleHotKey(WXWPARAM wParam, WXLPARAM lParam) event.m_altDown = (win_modifiers & MOD_ALT) != 0; event.m_metaDown = (win_modifiers & MOD_WIN) != 0; - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } #endif // wxUSE_ACCEL