X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2ccc5f110f4bd5e2fe2d400c2b3990f45dc1bcb3..8cbc59fe84f046685b873cf58f6c56debe59de1c:/src/msw/toplevel.cpp diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index 7c9fd6c588..3136e36631 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -78,17 +78,6 @@ static inline bool IsZoomed(HWND WXUNUSED(hwnd)) { return false; } LONG APIENTRY _EXPORT wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); -// ---------------------------------------------------------------------------- -// globals -// ---------------------------------------------------------------------------- - -// the name of the default wxWidgets class -#ifdef __WXWINCE__ -extern wxChar *wxCanvasClassName; -#else -extern const wxChar *wxCanvasClassName; -#endif - // ---------------------------------------------------------------------------- // wxTLWHiddenParentModule: used to manage the hidden parent window (we need a // module to ensure that the window is always deleted) @@ -139,7 +128,7 @@ void wxTopLevelWindowMSW::Init() m_fsIsMaximized = false; m_fsIsShowing = false; - m_winLastFocused = (wxWindow *)NULL; + m_winLastFocused = NULL; #if defined(__SMARTPHONE__) && defined(__WXWINCE__) m_MenuBarHWND = 0; @@ -494,7 +483,8 @@ bool wxTopLevelWindowMSW::CreateFrame(const wxString& title, exflags |= WS_EX_LAYOUTRTL; #endif - return MSWCreate(wxCanvasClassName, title.wx_str(), pos, sz, flags, exflags); + return MSWCreate(MSWGetRegisteredClassName(), + title.wx_str(), pos, sz, flags, exflags); } bool wxTopLevelWindowMSW::Create(wxWindow *parent, @@ -507,9 +497,6 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent, { bool ret wxDUMMY_INITIALIZE(false); - // init our fields - Init(); - wxSize sizeReal = size; if ( !sizeReal.IsFullySpecified() ) { @@ -548,7 +535,13 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent, // reuse the code in MSWGetStyle() but correct the results slightly for // the dialog - dlgTemplate->style = MSWGetStyle(style, &dlgTemplate->dwExtendedStyle); + // + // NB: we need a temporary variable as we can't pass pointer to + // dwExtendedStyle directly, it's not aligned correctly for 64 bit + // architectures + WXDWORD dwExtendedStyle; + dlgTemplate->style = MSWGetStyle(style, &dwExtendedStyle); + dlgTemplate->dwExtendedStyle = dwExtendedStyle; // all dialogs are popups dlgTemplate->style |= WS_POPUP; @@ -606,6 +599,8 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent, wxTopLevelWindowMSW::~wxTopLevelWindowMSW() { + SendDestroyEvent(); + #if defined(__SMARTPHONE__) || defined(__POCKETPC__) SHACTIVATEINFO* info = (SHACTIVATEINFO*) m_activateInfo; delete info; @@ -658,12 +653,21 @@ bool wxTopLevelWindowMSW::Show(bool show) m_maximizeOnShow = false; } + else if ( m_iconized ) + { + // iconize and show + nShowCmd = SW_MINIMIZE; + } else // just show { - if ( GetWindowStyle() & wxFRAME_TOOL_WINDOW ) - nShowCmd = SW_SHOWNA; - else - nShowCmd = SW_SHOW; + // we shouldn't use SW_SHOW which also activates the window for + // tool frames (as they shouldn't steal focus from the main window) + // nor for the currently disabled windows as they would be enabled + // as a side effect + if ( HasFlag(wxFRAME_TOOL_WINDOW) || !IsEnabled() ) + nShowCmd = SW_SHOWNA; + else + nShowCmd = SW_SHOW; } } else // hide @@ -737,7 +741,17 @@ bool wxTopLevelWindowMSW::IsMaximized() const void wxTopLevelWindowMSW::Iconize(bool iconize) { - DoShowWindow(iconize ? SW_MINIMIZE : SW_RESTORE); + if ( IsShown() ) + { + // change the window state immediately + DoShowWindow(iconize ? SW_MINIMIZE : SW_RESTORE); + } + else // hidden + { + // iconizing the window shouldn't show it so just remember that we need + // to become iconized when shown later + m_iconized = true; + } } bool wxTopLevelWindowMSW::IsIconized() const @@ -745,6 +759,9 @@ bool wxTopLevelWindowMSW::IsIconized() const #ifdef __WXWINCE__ return false; #else + if ( !IsShown() ) + return m_iconized; + // don't use m_iconized, it may be briefly out of sync with the real state // as it's only modified when we receive a WM_SIZE and we could be called // from an event handler from one of the messages we receive before it, @@ -965,25 +982,40 @@ wxString wxTopLevelWindowMSW::GetTitle() const return GetLabel(); } +bool wxTopLevelWindowMSW::DoSelectAndSetIcon(const wxIconBundle& icons, + int smX, + int smY, + int i) +{ + const wxSize size(::GetSystemMetrics(smX), ::GetSystemMetrics(smY)); + + const wxIcon icon = icons.GetIconOfExactSize(size); + if ( icon.Ok() ) + { + ::SendMessage(GetHwnd(), WM_SETICON, i, (LPARAM)GetHiconOf(icon)); + return true; + } + + return false; +} + void wxTopLevelWindowMSW::SetIcons(const wxIconBundle& icons) { wxTopLevelWindowBase::SetIcons(icons); -#if !defined(__WXMICROWIN__) - const wxIcon& sml = icons.GetIconOfExactSize(16); - if( sml.Ok() ) + if ( icons.IsEmpty() ) { - ::SendMessage( GetHwndOf( this ), WM_SETICON, ICON_SMALL, - (LPARAM)GetHiconOf(sml) ); + // FIXME: SetIcons(wxNullIconBundle) should unset existing icons, + // but we currently don't do that + wxASSERT_MSG( m_icons.IsEmpty(), "unsetting icons doesn't work" ); + return; } - const wxIcon& big = icons.GetIconOfExactSize(32); - if( big.Ok() ) + if ( !DoSelectAndSetIcon(icons, SM_CXSMICON, SM_CYSMICON, ICON_SMALL) && + !DoSelectAndSetIcon(icons, SM_CXICON, SM_CYICON, ICON_BIG) ) { - ::SendMessage( GetHwndOf( this ), WM_SETICON, ICON_BIG, - (LPARAM)GetHiconOf(big) ); + wxFAIL_MSG( "icon bundle doesn't contain any suitable icon" ); } -#endif // !__WXMICROWIN__ } bool wxTopLevelWindowMSW::EnableCloseButton(bool enable) @@ -1078,7 +1110,7 @@ void wxTopLevelWindowMSW::RequestUserAttention(int flags) #if defined(FLASHW_STOP) && defined(VK_XBUTTON1) && wxUSE_DYNLIB_CLASS // available in the headers, check if it is supported by the system typedef BOOL (WINAPI *FlashWindowEx_t)(FLASHWINFO *pfwi); - FlashWindowEx_t s_pfnFlashWindowEx = NULL; + static FlashWindowEx_t s_pfnFlashWindowEx = NULL; if ( !s_pfnFlashWindowEx ) { wxDynamicLibrary dllUser32(_T("user32.dll")); @@ -1123,15 +1155,23 @@ bool wxTopLevelWindowMSW::SetTransparent(wxByte alpha) { #if wxUSE_DYNLIB_CLASS typedef DWORD (WINAPI *PSETLAYEREDWINDOWATTR)(HWND, DWORD, BYTE, DWORD); - static PSETLAYEREDWINDOWATTR pSetLayeredWindowAttributes = NULL; + static PSETLAYEREDWINDOWATTR + pSetLayeredWindowAttributes = (PSETLAYEREDWINDOWATTR)-1; - if ( pSetLayeredWindowAttributes == NULL ) + if ( pSetLayeredWindowAttributes == (PSETLAYEREDWINDOWATTR)-1 ) { wxDynamicLibrary dllUser32(_T("user32.dll")); + + // use RawGetSymbol() and not GetSymbol() to avoid error messages under + // Windows 95: there is nothing the user can do about this anyhow pSetLayeredWindowAttributes = (PSETLAYEREDWINDOWATTR) - dllUser32.GetSymbol(wxT("SetLayeredWindowAttributes")); + dllUser32.RawGetSymbol(wxT("SetLayeredWindowAttributes")); + + // it's ok to destroy dllUser32 here, we link statically to user32.dll + // anyhow so it won't be unloaded } - if ( pSetLayeredWindowAttributes == NULL ) + + if ( !pSetLayeredWindowAttributes ) return false; #endif // wxUSE_DYNLIB_CLASS @@ -1170,6 +1210,20 @@ bool wxTopLevelWindowMSW::CanSetTransparent() return (os_type == wxOS_WINDOWS_NT && ver_major >= 5); } + +void wxTopLevelWindowMSW::DoFreeze() +{ + // do nothing: freezing toplevel window causes paint and mouse events + // to go through it any TLWs under it, so the best we can do is to freeze + // all children -- and wxWindowBase::Freeze() does that +} + +void wxTopLevelWindowMSW::DoThaw() +{ + // intentionally empty -- see DoFreeze() +} + + // ---------------------------------------------------------------------------- // wxTopLevelWindow event handling // ---------------------------------------------------------------------------- @@ -1182,7 +1236,7 @@ void wxTopLevelWindowMSW::OnActivate(wxActivateEvent& event) { // restore focus to the child which was last focused unless we already // have it - wxLogTrace(_T("focus"), _T("wxTLW %08x activated."), (int) m_hWnd); + wxLogTrace(_T("focus"), _T("wxTLW %p activated."), m_hWnd); wxWindow *winFocus = FindFocus(); if ( !winFocus || wxGetTopLevelParent(winFocus) != this ) @@ -1205,7 +1259,9 @@ void wxTopLevelWindowMSW::OnActivate(wxActivateEvent& event) if ( m_winLastFocused ) { // let it know that it doesn't have focus any more - m_winLastFocused->HandleKillFocus((WXHWND)NULL); + // But this will already be done via WM_KILLFOCUS, so we'll get two kill + // focus events if we call it explicitly. + // m_winLastFocused->HandleKillFocus((WXHWND)NULL); // and don't remember it if it's a child from some other frame if ( wxGetTopLevelParent(m_winLastFocused) != this ) @@ -1215,10 +1271,9 @@ void wxTopLevelWindowMSW::OnActivate(wxActivateEvent& event) } wxLogTrace(_T("focus"), - _T("wxTLW %08x deactivated, last focused: %08x."), - (int) m_hWnd, - (int) (m_winLastFocused ? GetHwndOf(m_winLastFocused) - : NULL)); + _T("wxTLW %p deactivated, last focused: %p."), + m_hWnd, + m_winLastFocused ? GetHwndOf(m_winLastFocused) : NULL); event.Skip(); }