X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/66e2ba91b27a5867ef46cc16049c2a7c61c811f1..8e181eae04877c1369a3ad01160f889ddc48971b:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 850a15f17d..3189e52624 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -701,6 +701,110 @@ 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 ) + { + wxLogNull noLog; + + wxDynamicLibrary dllUser32(_T("user32.dll"), wxDL_VERBATIM); + 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() { @@ -1288,29 +1392,39 @@ void wxWindowMSW::MSWUpdateStyle(long flagsOld, long exflagsOld) wxBorder wxWindowMSW::GetDefaultBorderForControl() const { - // we want to automatically give controls a sunken style (confusingly, - // it may not really mean sunken at all as we map it to WS_EX_CLIENTEDGE - // which is not sunken at all under Windows XP -- rather, just the default) + 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__) - return wxBORDER_SIMPLE; + if (border == wxBORDER_THEME || border == wxBORDER_SUNKEN || border == wxBORDER_SIMPLE) + return wxBORDER_SIMPLE; + else + return wxBORDER_NONE; #else #if wxUSE_UXTHEME - if (CanApplyThemeBorder()) + if (border == wxBORDER_THEME) { - wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive(); - if (theme) - return wxBORDER_THEME; + if (CanApplyThemeBorder()) + { + wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive(); + if (theme) + return wxBORDER_THEME; + } } #endif - return wxBORDER_SUNKEN; + return border; #endif } -wxBorder wxWindowMSW::GetDefaultBorder() const -{ - return GetDefaultBorderForControl(); -} WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const { @@ -1341,7 +1455,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 ) @@ -1359,11 +1476,14 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const switch ( border ) { - case wxBORDER_DEFAULT: // also wxBORDER_THEME - break; + default: + case wxBORDER_DEFAULT: + wxFAIL_MSG( _T("unknown border style") ); + // fall through case wxBORDER_NONE: case wxBORDER_SIMPLE: + case wxBORDER_THEME: break; case wxBORDER_STATIC: @@ -1379,13 +1499,9 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const style &= ~WS_BORDER; break; - default: - wxFAIL_MSG( _T("unknown border style") ); - 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 @@ -1443,7 +1559,7 @@ void wxWindowMSW::OnInternalIdle() } #endif // !HAVE_TRACKMOUSEEVENT - if (wxUpdateUIEvent::CanUpdate(this)) + if (wxUpdateUIEvent::CanUpdate(this) && IsShown()) UpdateWindowUI(wxUPDATE_UI_FROMIDLE); } @@ -2220,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 @@ -2248,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(), @@ -3245,7 +3394,8 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l case WM_NCCALCSIZE: { wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive(); - if (theme && GetBorder() == wxBORDER_THEME) + 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); @@ -3263,9 +3413,9 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l { rect = *((RECT*)lParam); } - wxUxThemeHandle hTheme(this, L"EDIT"); + wxUxThemeHandle hTheme((wxWindow *)this, L"EDIT"); RECT rcClient = { 0, 0, 0, 0 }; - wxClientDC dc(this); + wxClientDC dc((wxWindow *)this); if (theme->GetThemeBackgroundContentRect( hTheme, GetHdcOf(dc), EP_EDITTEXT, ETS_NORMAL, @@ -3285,14 +3435,15 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l case WM_NCPAINT: { wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive(); - if (theme && GetBorder() == wxBORDER_THEME) + 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(this, L"EDIT"); - wxWindowDC dc(this); + 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; @@ -4507,6 +4658,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; } @@ -4872,8 +5027,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 ) { @@ -4896,8 +5054,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 ) @@ -4967,7 +5124,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()); @@ -6008,9 +6165,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;