]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/toplevel.cpp
notify the timers outside of loop over m_timers to avoid crashes if a timer event...
[wxWidgets.git] / src / msw / toplevel.cpp
index d0e47ea963779007705bf202e56f843aff7608f3..17392121160a0d1d9f3b05e74f7d948fd12fb69c 100644 (file)
@@ -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;
@@ -969,7 +964,7 @@ wxString wxTopLevelWindowMSW::GetTitle() const
     return GetLabel();
 }
 
-void wxTopLevelWindowMSW::DoSelectAndSetIcon(const wxIconBundle& icons,
+bool wxTopLevelWindowMSW::DoSelectAndSetIcon(const wxIconBundle& icons,
                                              int smX,
                                              int smY,
                                              int i)
@@ -980,15 +975,29 @@ void wxTopLevelWindowMSW::DoSelectAndSetIcon(const wxIconBundle& icons,
     if ( icon.Ok() )
     {
         ::SendMessage(GetHwnd(), WM_SETICON, i, (LPARAM)GetHiconOf(icon));
+        return true;
     }
+
+    return false;
 }
 
 void wxTopLevelWindowMSW::SetIcons(const wxIconBundle& icons)
 {
     wxTopLevelWindowBase::SetIcons(icons);
 
-    DoSelectAndSetIcon(icons, SM_CXSMICON, SM_CYSMICON, ICON_SMALL);
-    DoSelectAndSetIcon(icons, SM_CXICON, SM_CYICON, ICON_BIG);
+    if ( icons.IsEmpty() )
+    {
+        // 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;
+    }
+
+    if ( !DoSelectAndSetIcon(icons, SM_CXSMICON, SM_CYSMICON, ICON_SMALL) &&
+            !DoSelectAndSetIcon(icons, SM_CXICON, SM_CYICON, ICON_BIG) )
+    {
+        wxFAIL_MSG( "icon bundle doesn't contain any suitable icon" );
+    }
 }
 
 bool wxTopLevelWindowMSW::EnableCloseButton(bool enable)
@@ -1083,7 +1092,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"));
@@ -1128,15 +1137,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
 
@@ -1178,49 +1195,14 @@ bool wxTopLevelWindowMSW::CanSetTransparent()
 
 void wxTopLevelWindowMSW::DoFreeze()
 {
-    if ( IsShown() )
-    {
-        for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
-              node;
-              node = node->GetNext() )
-        {
-            wxWindow *child = node->GetData();
-            if ( child->IsTopLevel() )
-                continue;
-
-            child->Freeze();
-        }
-    }
+    // 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()
 {
-    if ( IsShown() )
-    {
-        for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
-              node;
-              node = node->GetNext() )
-        {
-            wxWindow *child = node->GetData();
-            if ( child->IsTopLevel() )
-                continue;
-
-            child->Thaw();
-        }
-    }
-}
-
-
-void wxTopLevelWindowMSW::AddChild(wxWindowBase *child)
-{
-    // adding a child while frozen will assert when thawn, so freeze it as if
-    // it had been already present when we were frozen
-    if ( child && !child->IsTopLevel() && IsFrozen() )
-    {
-        child->Freeze();
-    }
-
-    wxTopLevelWindowBase::AddChild(child);
+    // intentionally empty -- see DoFreeze()
 }
 
 
@@ -1236,7 +1218,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 )
@@ -1259,7 +1241,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 )
@@ -1269,10 +1253,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();
     }