X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2f68482ef84a4ef3b1302ea67e2b23d6fe0cedee..c944775f72435d2c0493113e05445898ab8baf1b:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 67992184f1..d8be1a890b 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -121,6 +121,18 @@ #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 + #if defined(TME_LEAVE) && defined(WM_MOUSELEAVE) && wxUSE_DYNLIB_CLASS #define HAVE_TRACKMOUSEEVENT #endif // everything needed for TrackMouseEvent() @@ -1274,6 +1286,42 @@ 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; + } + } +#endif + return border; +#endif +} + + WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const { // translate common wxWidgets styles to Windows ones @@ -1303,7 +1351,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 ) @@ -1328,6 +1379,7 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const case wxBORDER_NONE: case wxBORDER_SIMPLE: + case wxBORDER_THEME: break; case wxBORDER_STATIC: @@ -1343,9 +1395,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 @@ -1403,7 +1455,7 @@ void wxWindowMSW::OnInternalIdle() } #endif // !HAVE_TRACKMOUSEEVENT - if (wxUpdateUIEvent::CanUpdate(this)) + if (wxUpdateUIEvent::CanUpdate(this) && IsShown()) UpdateWindowUI(wxUPDATE_UI_FROMIDLE); } @@ -2180,13 +2232,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 @@ -2208,9 +2253,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(), @@ -2542,7 +2627,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; @@ -3188,6 +3285,96 @@ 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); + + if (theme->GetThemeBackgroundContentRect( + hTheme, GetHdcOf(dc), 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); + + // Clip the DC so that you only draw on the non-client area + RECT rcBorder; + wxCopyRectToRECT(GetSize(), rcBorder); + + RECT rcClient; + theme->GetThemeBackgroundContentRect( + hTheme, GetHdcOf(dc), EP_EDITTEXT, ETS_NORMAL, &rcBorder, &rcClient); + InflateRect(&rcClient, -1, -1); + + ::ExcludeClipRect(GetHdcOf(dc), 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(dc), &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(dc), EP_EDITTEXT, nState, &rcBorder, NULL); + } + } + break; + +#endif // wxUSE_UXTHEME + default: // try a custom message handler const MSWMessageHandlers::const_iterator @@ -4367,6 +4554,10 @@ bool wxWindowMSW::HandlePaint() eventNc.SetEventObject(this); GetEventHandler()->ProcessEvent(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; } @@ -4563,6 +4754,24 @@ bool wxWindowMSW::HandleMoving(wxRect& rect) return rc; } +bool wxWindowMSW::HandleEnterSizeMove() +{ + wxMoveEvent event(wxPoint(0,0), m_windowId); + event.SetEventType(wxEVT_MOVE_START); + event.SetEventObject(this); + + return GetEventHandler()->ProcessEvent(event); +} + +bool wxWindowMSW::HandleExitSizeMove() +{ + wxMoveEvent event(wxPoint(0,0), m_windowId); + event.SetEventType(wxEVT_MOVE_END); + event.SetEventObject(this); + + return GetEventHandler()->ProcessEvent(event); +} + bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam) { #if USE_DEFERRED_SIZING @@ -4714,8 +4923,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 ) { @@ -4738,8 +4950,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 ) @@ -4809,7 +5020,7 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event, event.m_aux1Down = (flags & MK_XBUTTON1) != 0; event.m_aux2Down = (flags & MK_XBUTTON2) != 0; #endif // wxHAS_XBUTTON - event.m_altDown = ::GetKeyState(VK_MENU) < 0; + event.m_altDown = ::wxIsAltDown(); #ifndef __WXWINCE__ event.SetTimestamp(::GetMessageTime()); @@ -5259,7 +5470,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('&') ) @@ -5850,9 +6061,9 @@ wxMouseState wxGetMouseState() 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;