delete the hidden TLW parent window from a module to ensure that it is done even if OnInit() returns FALSE; also create it without using wxTLW itself which actually simplifies the code

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@17442 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2002-10-02 23:32:23 +00:00
parent 1681cdd7f1
commit a275e42188
2 changed files with 116 additions and 48 deletions

View File

@@ -119,10 +119,6 @@ protected:
// the last focused child: we restore focus to it on activation // the last focused child: we restore focus to it on activation
wxWindow *m_winLastFocused; wxWindow *m_winLastFocused;
// the hidden parent window for the frames which shouldn't appear in the
// taskbar
static wxWindow *ms_hiddenParent;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };

View File

@@ -76,8 +76,30 @@ wxWindowList wxModelessWindows;
// the name of the default wxWindows class // the name of the default wxWindows class
extern const wxChar *wxCanvasClassName; extern const wxChar *wxCanvasClassName;
// the hidden parent for wxFRAME_NO_TASKBAR unowned frames // ----------------------------------------------------------------------------
wxWindow *wxTopLevelWindowMSW::ms_hiddenParent = NULL; // wxTLWHiddenParentModule: used to manage the hidden parent window (we need a
// module to ensure that the window is always deleted)
// ----------------------------------------------------------------------------
class wxTLWHiddenParentModule : public wxModule
{
public:
// module init/finalize
virtual bool OnInit();
virtual void OnExit();
// get the hidden window (creates on demand)
static HWND GetHWND();
private:
// the HWND of the hidden parent
static HWND ms_hwnd;
// the class used to create it
static const wxChar *ms_className;
DECLARE_DYNAMIC_CLASS(wxTLWHiddenParentModule)
};
// ============================================================================ // ============================================================================
// wxTopLevelWindowMSW implementation // wxTopLevelWindowMSW implementation
@@ -213,38 +235,32 @@ WXHWND wxTopLevelWindowMSW::MSWGetParent() const
// parent HWND or it would be always on top of its parent which is not what // parent HWND or it would be always on top of its parent which is not what
// we usually want (in fact, we only want it for frames with the // we usually want (in fact, we only want it for frames with the
// wxFRAME_FLOAT_ON_PARENT flag) // wxFRAME_FLOAT_ON_PARENT flag)
wxWindow *parent; HWND hwndParent = NULL;
if ( HasFlag(wxFRAME_FLOAT_ON_PARENT) ) if ( HasFlag(wxFRAME_FLOAT_ON_PARENT) )
{ {
parent = GetParent(); const wxWindow *parent = GetParent();
// this flag doesn't make sense then and will be ignored if ( !parent )
wxASSERT_MSG( parent,
_T("wxFRAME_FLOAT_ON_PARENT but no parent?") );
}
else // don't float on parent, must not be owned
{ {
parent = NULL; // this flag doesn't make sense then and will be ignored
wxFAIL_MSG( _T("wxFRAME_FLOAT_ON_PARENT but no parent?") );
} }
else
{
hwndParent = GetHwndOf(parent);
}
}
//else: don't float on parent, must not be owned
// now deal with the 2nd taskbar-related problem (see comments above in // now deal with the 2nd taskbar-related problem (see comments above in
// MSWGetStyle()) // MSWGetStyle())
if ( HasFlag(wxFRAME_NO_TASKBAR) && !parent ) if ( HasFlag(wxFRAME_NO_TASKBAR) && !hwndParent )
{ {
if ( !ms_hiddenParent ) // use hidden parent
{ hwndParent = wxTLWHiddenParentModule::GetHWND();
ms_hiddenParent = new wxTopLevelWindowMSW(NULL, -1, _T(""));
// we shouldn't leave it in wxTopLevelWindows or we wouldn't
// terminate the app when the last user-created frame is deleted --
// see ~wxTopLevelWindowMSW
wxTopLevelWindows.DeleteObject(ms_hiddenParent);
} }
parent = ms_hiddenParent; return (WXHWND)hwndParent;
}
return parent ? parent->GetHWND() : WXHWND(NULL);
} }
bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate, bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate,
@@ -451,15 +467,6 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent,
wxTopLevelWindowMSW::~wxTopLevelWindowMSW() wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
{ {
if ( this == ms_hiddenParent )
{
// stop [infinite] recursion which would otherwise happen when we do
// "delete ms_hiddenParent" below -- and we're not interested in doing
// anything of the rest below for that window because the rest of
// wxWindows doesn't even know about it
return;
}
if ( wxModelessWindows.Find(this) ) if ( wxModelessWindows.Find(this) )
wxModelessWindows.DeleteObject(this); wxModelessWindows.DeleteObject(this);
@@ -475,17 +482,6 @@ wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
::BringWindowToTop(GetHwndOf(parent)); ::BringWindowToTop(GetHwndOf(parent));
} }
} }
// if this is the last top-level window, we're going to exit and we should
// delete ms_hiddenParent now to avoid leaking it
if ( IsLastBeforeExit() )
{
if ( ms_hiddenParent )
{
delete ms_hiddenParent;
ms_hiddenParent = NULL;
}
}
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -796,3 +792,79 @@ wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
} }
} }
// ============================================================================
// wxTLWHiddenParentModule implementation
// ============================================================================
HWND wxTLWHiddenParentModule::ms_hwnd = NULL;
const wxChar *wxTLWHiddenParentModule::ms_className = NULL;
bool wxTLWHiddenParentModule::OnInit()
{
ms_hwnd = NULL;
ms_className = NULL;
return TRUE;
}
void wxTLWHiddenParentModule::OnExit()
{
if ( ms_hwnd )
{
if ( !::DestroyWindow(ms_hwnd) )
{
wxLogLastError(_T("DestroyWindow(hidden TLW parent)"));
}
ms_hwnd = NULL;
}
if ( ms_className )
{
if ( !::UnregisterClass(ms_className, wxGetInstance()) )
{
wxLogLastError(_T("UnregisterClass(\"wxTLWHiddenParent\")"));
}
ms_className = NULL;
}
}
/* static */
HWND wxTLWHiddenParentModule::GetHWND()
{
if ( !ms_hwnd )
{
if ( !ms_className )
{
static const wxChar *HIDDEN_PARENT_CLASS = _T("wxTLWHiddenParent");
WNDCLASS wndclass;
wxZeroMemory(wndclass);
wndclass.lpfnWndProc = DefWindowProc;
wndclass.hInstance = wxGetInstance();
wndclass.lpszClassName = HIDDEN_PARENT_CLASS;
if ( !::RegisterClass(&wndclass) )
{
wxLogLastError(_T("RegisterClass(\"wxTLWHiddenParent\")"));
}
else
{
ms_className = HIDDEN_PARENT_CLASS;
}
}
ms_hwnd = ::CreateWindow(ms_className, _T(""), 0, 0, 0, 0, 0, NULL,
(HMENU)NULL, wxGetInstance(), NULL);
if ( !ms_hwnd )
{
wxLogLastError(_T("CreateWindow(hidden TLW parent)"));
}
}
return ms_hwnd;
}