fixed several resource leaks related to MDI menus

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13532 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2002-01-13 01:26:04 +00:00
parent 28978e0c5a
commit 4e152a239b
3 changed files with 75 additions and 62 deletions

View File

@@ -66,7 +66,7 @@ public:
// just return a new class) // just return a new class)
virtual wxMDIClientWindow *OnCreateClient(void); virtual wxMDIClientWindow *OnCreateClient(void);
// WXHMENU GetWindowHMENU() const { return m_windowMenu; } // MDI windows menu
wxMenu* GetWindowMenu() const { return m_windowMenu; }; wxMenu* GetWindowMenu() const { return m_windowMenu; };
void SetWindowMenu(wxMenu* menu) ; void SetWindowMenu(wxMenu* menu) ;

View File

@@ -375,9 +375,6 @@ public:
// called when the window is about to be destroyed // called when the window is about to be destroyed
virtual void MSWDestroyWindow(); virtual void MSWDestroyWindow();
// Detach "Window" menu from menu bar so it doesn't get deleted
void MSWDetachWindowMenu();
// this function should return the brush to paint the window background // this function should return the brush to paint the window background
// with or 0 for the default brush // with or 0 for the default brush
virtual WXHBRUSH OnCtlColor(WXHDC hDC, virtual WXHBRUSH OnCtlColor(WXHDC hDC,

View File

@@ -112,9 +112,17 @@ inline bool IsMdiCommandId(int id)
return (id >= wxFIRST_MDI_CHILD) && (id <= wxLAST_MDI_CHILD); return (id >= wxFIRST_MDI_CHILD) && (id <= wxLAST_MDI_CHILD);
} }
// unpack the parameters of WM_MDIACTIVATE message
static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam, static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,
WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact); WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact);
// return the HMENU of the MDI menu
static inline HMENU GetMDIWindowMenu(wxMDIParentFrame *frame)
{
wxMenu *menu = frame->GetWindowMenu();
return menu ? GetHmenuOf(menu) : 0;
}
// =========================================================================== // ===========================================================================
// implementation // implementation
// =========================================================================== // ===========================================================================
@@ -221,17 +229,25 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
wxMDIParentFrame::~wxMDIParentFrame() wxMDIParentFrame::~wxMDIParentFrame()
{ {
DestroyChildren(); DestroyChildren();
// already delete by DestroyChildren() // already delete by DestroyChildren()
m_frameToolBar = NULL; m_frameToolBar = NULL;
m_frameStatusBar = NULL; m_frameStatusBar = NULL;
// ::DestroyMenu((HMENU)m_windowMenu);
if (m_windowMenu) if (m_windowMenu)
{ {
delete m_windowMenu; delete m_windowMenu;
m_windowMenu = (wxMenu*) NULL; m_windowMenu = (wxMenu*) NULL;
} }
// the MDI frame menubar is not automatically deleted by Windows unlike for
// the normal frames
if ( m_hMenu )
{
::DestroyMenu((HMENU)m_hMenu);
m_hMenu = NULL;
}
if ( m_clientWindow ) if ( m_clientWindow )
{ {
if ( m_clientWindow->MSWGetOldWndProc() ) if ( m_clientWindow->MSWGetOldWndProc() )
@@ -248,10 +264,7 @@ void wxMDIParentFrame::InternalSetMenuBar()
{ {
m_parentFrameActive = TRUE; m_parentFrameActive = TRUE;
wxMenu *menu = GetWindowMenu(); InsertWindowMenu(GetClientWindow(), m_hMenu, GetMDIWindowMenu(this));
HMENU subMenu = menu ? GetHmenuOf(menu) : 0;
InsertWindowMenu(GetClientWindow(), m_hMenu, subMenu);
} }
#endif // wxUSE_MENUS_NATIVE #endif // wxUSE_MENUS_NATIVE
@@ -269,6 +282,7 @@ void wxMDIParentFrame::SetWindowMenu(wxMenu* menu)
delete m_windowMenu; delete m_windowMenu;
m_windowMenu = (wxMenu*) NULL; m_windowMenu = (wxMenu*) NULL;
} }
if (menu) if (menu)
{ {
m_windowMenu = menu; m_windowMenu = menu;
@@ -706,10 +720,12 @@ wxMDIChildFrame::~wxMDIChildFrame()
{ {
DestroyChildren(); DestroyChildren();
// already delete by DestroyChildren() // already deleted by DestroyChildren()
m_frameToolBar = NULL; m_frameToolBar = NULL;
m_frameStatusBar = NULL; m_frameStatusBar = NULL;
RemoveWindowMenu(NULL, m_hMenu);
MSWDestroyWindow(); MSWDestroyWindow();
} }
@@ -775,12 +791,8 @@ void wxMDIChildFrame::InternalSetMenuBar()
{ {
wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent(); wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
// HMENU subMenu = GetSubMenu((HMENU)parent->GetWindowMenu(), 0); InsertWindowMenu(parent->GetClientWindow(),
HMENU subMenu = (HMENU) 0; m_hMenu, GetMDIWindowMenu(parent));
if (parent->GetWindowMenu())
subMenu = (HMENU) parent->GetWindowMenu()->GetHMenu();
InsertWindowMenu(parent->GetClientWindow(), m_hMenu, subMenu);
parent->m_parentFrameActive = FALSE; parent->m_parentFrameActive = FALSE;
} }
@@ -973,11 +985,8 @@ bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate),
if ( menuToSet ) if ( menuToSet )
{ {
HMENU subMenu = (HMENU) 0; MDISetMenu(parent->GetClientWindow(),
if (parent->GetWindowMenu()) menuToSet, GetMDIWindowMenu(parent));
subMenu = (HMENU) parent->GetWindowMenu()->GetHMenu();
MDISetMenu(parent->GetClientWindow(), menuToSet, subMenu);
} }
wxActivateEvent event(wxEVT_ACTIVATE, activated, m_windowId); wxActivateEvent event(wxEVT_ACTIVATE, activated, m_windowId);
@@ -1064,7 +1073,6 @@ bool wxMDIChildFrame::MSWTranslateMessage(WXMSG* msg)
void wxMDIChildFrame::MSWDestroyWindow() void wxMDIChildFrame::MSWDestroyWindow()
{ {
MSWDetachWindowMenu();
invalidHandle = GetHwnd(); invalidHandle = GetHwnd();
wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent(); wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
@@ -1148,9 +1156,7 @@ bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
m_windowStyle = style; m_windowStyle = style;
m_parent = parent; m_parent = parent;
ccs.hWindowMenu = (HMENU) 0; ccs.hWindowMenu = GetMDIWindowMenu(parent);
if (parent->GetWindowMenu())
ccs.hWindowMenu = (HMENU) parent->GetWindowMenu()->GetHMenu();
ccs.idFirstChild = wxFIRST_MDI_CHILD; ccs.idFirstChild = wxFIRST_MDI_CHILD;
DWORD msStyle = MDIS_ALLCHILDSTYLES | WS_VISIBLE | WS_CHILD | DWORD msStyle = MDIS_ALLCHILDSTYLES | WS_VISIBLE | WS_CHILD |
@@ -1321,29 +1327,39 @@ static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu)
static void RemoveWindowMenu(wxWindow *win, WXHMENU menu) static void RemoveWindowMenu(wxWindow *win, WXHMENU menu)
{ {
// Try to insert Window menu in front of Help, otherwise append it. HMENU hMenu = (HMENU)menu;
HMENU hmenu = (HMENU)menu;
int N = GetMenuItemCount(hmenu); if ( hMenu )
{
wxChar buf[1024];
int N = ::GetMenuItemCount(hMenu);
for ( int i = 0; i < N; i++ ) for ( int i = 0; i < N; i++ )
{ {
wxChar buf[256]; if ( !::GetMenuString(hMenu, i, buf, WXSIZEOF(buf), MF_BYPOSITION) )
int chars = GetMenuString(hmenu, i, buf, WXSIZEOF(buf), MF_BYPOSITION);
if ( chars == 0 )
{ {
wxLogLastError(wxT("GetMenuString")); wxLogLastError(wxT("GetMenuString"));
continue; continue;
} }
if ( wxStripMenuCodes(wxString(buf)).IsSameAs(_("Window")) ) if ( wxStrcmp(buf, _("&Window")) == 0 )
{ {
::RemoveMenu(hmenu, i, MF_BYPOSITION); if ( !::RemoveMenu(hMenu, i, MF_BYPOSITION) )
{
wxLogLastError(wxT("RemoveMenu"));
}
break; break;
} }
} }
}
// Does passing 0 for the window menu really work with WM_MDISETMENU? if ( win )
MDISetMenu(win, hmenu, 0); {
// we don't change the windows menu, but we update the main one
MDISetMenu(win, hMenu, NULL);
}
} }
static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam, static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,