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:
@@ -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()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -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?") );
|
// this flag doesn't make sense then and will be ignored
|
||||||
}
|
wxFAIL_MSG( _T("wxFRAME_FLOAT_ON_PARENT but no parent?") );
|
||||||
else // don't float on parent, must not be owned
|
}
|
||||||
{
|
else
|
||||||
parent = NULL;
|
{
|
||||||
|
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 parent ? parent->GetHWND() : WXHWND(NULL);
|
return (WXHWND)hwndParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user