|
|
|
|
Forum
Please
Log In
to post a new message or reply to an existing one. If you are not registered, please
register.
NOTE: Some forums may be read-only if you are not currently subscribed to
our technical support services.
Subject |
Author |
Date |
|
Gevork Odabashyan
|
Jun 3, 2010 - 1:12 AM
|
|
|
Gevork Odabashyan
|
Jun 8, 2010 - 2:31 AM
|
I repeat the steps to reproduce memory leaks bug.
To reproduce bug follow the next steps:
- First of all, use MDI_DynamicBars-sud.exe sample from Prof-UIS 2.89 suit.
- The next is that I use Sysinternals Process Explorer under Windows XP to analyze process properties,
but the same results can be seen with the Windows XP Task Manager.
- For more clarity, hide all dynamic bars off the sample.
- Unhide one of the dynamic bars (for example Dynamic Bar 0) and switch it to the Docking state.
Switching Dynamic Bar 0 state from Docking to Tabbed and then backward to Docking state.
In results the number of USER Objects, GDI Objects and Handlers will increase.
The number of handles increase on every switchin loop - "Docking to Tabbed - Docking".
Switching loop number USER Objects Other objects
- 274 (some start value)
1 285
2 296 similarly as a USER Objects
3 307
... and so on ...
The reasons are the next:
When moving bar from Docking to Tabbed state you every time create new CExtDynamicMDIChildWnd,
and destroy it when move bar from Tabbed state to Docking state.
Every time you created CExtDynamicMDIChildWnd you supply it with:
1. shared menu
2. large and small icons
BUT not release this objects (menu and icons ) when destroy the window.
The proper place to do this is : BOOL CExtDynamicMDIChildWnd::DestroyWindow() {...}
This are extracts from the code where described above occure:
1. .......
if( m_nMdiMenuResourceID != 0 )
{
CMenu _menu;
if( g_ResourceManager->LoadMenu( _menu, m_nMdiMenuResourceID ) )
{
ASSERT( _menu.GetSafeHmenu() != NULL );
hMenuDefault = _menu.Detach();
} // if( g_ResourceManager->LoadMenu( _menu, m_nMdiMenuResourceID ) )
} // if( m_nMdiMenuResourceID != 0 )
.....
pWndMdiChild->SetHandles(
hMenuDefault,
hAccelTable
);
.....
2. LRESULT CExtDynamicMDIChildWnd::WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
...
if( message == WM_CREATE )
{
....
if( ! m_icon.IsEmpty() )
{
SetIcon( m_icon.ExtractHICON(), FALSE ); // NEW EXCTACT ICON 2.53
SetIcon( m_icon.ExtractHICON(), TRUE ); // NEW EXCTACT ICON 2.53
} // if( ! m_icon.IsEmpty() )
}
To avoid this leaks I release menu and icon objects every time by myself with ::DestroyMenu and ::DestroyIcon functions.
|
|
Technical Support
|
Jun 8, 2010 - 11:27 AM
|
Thank you for pointing us to right direction. We added the following property into the CExtDynamicMDIChildWnd class.
HICON m_hIconExtracted;
And we modified the following methods. CExtDynamicMDIChildWnd::CExtDynamicMDIChildWnd(
CExtDynamicControlBar * pBar
)
: m_pDBS( NULL )
, m_pBar( NULL )
, m_hWndHelperBar( NULL )
, m_hIconExtracted( NULL )
{
if( pBar != NULL )
AttachBar( pBar );
}
CExtDynamicMDIChildWnd::~CExtDynamicMDIChildWnd()
{
if( m_hMenuShared != NULL )
{
::DestroyMenu( m_hMenuShared );
m_hMenuShared = NULL;
}
if( m_hAccelTable != NULL )
{
::DestroyAcceleratorTable( m_hAccelTable );
m_hAccelTable = NULL;
}
if( m_hIconExtracted != NULL )
{
::DestroyIcon( m_hIconExtracted );
m_hIconExtracted = NULL;
}
}
LRESULT CExtDynamicMDIChildWnd::WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
{
if( message == WM_SETFOCUS )
{
ASSERT( m_hWndHelperBar != NULL );
if( ::IsWindow(m_hWndHelperBar) )
{
ASSERT_VALID( m_pBar );
ASSERT( m_pBar->GetSafeHwnd() == m_hWndHelperBar );
HWND hWndChild = m_pBar->OnQueryChildHWND();
if( hWndChild != NULL
&& ::GetParent(hWndChild) == m_hWnd
)
{
if( CExtControlBar::stat_QueryFocusChangingEnabled( m_pBar, hWndChild ) )
::SetFocus( hWndChild );
}
} // if( ::IsWindow(m_hWndHelperBar) )
return 0;
} // else if( message == WM_SETFOCUS )
if( (message == WM_SYSCOMMAND && wParam == SC_CLOSE)
|| message == WM_CLOSE
)
{ // closing messages
ASSERT( m_hWndHelperBar != NULL );
if( ::IsWindow(m_hWndHelperBar) )
{
ASSERT_VALID( m_pBar );
ASSERT( m_pBar->GetSafeHwnd() == m_hWndHelperBar );
m_pBar->BarStateSet(
CExtDynamicControlBar::__EDBS_DOCUMENT,
false
);
} // if( ::IsWindow(m_hWndHelperBar) )
return 0;
} // closing messages
LRESULT lResult = CMDIChildWnd::WindowProc( message, wParam, lParam );
if( message == WM_CREATE )
{
ASSERT_VALID( m_pBar );
ASSERT( m_pBar->GetSafeHwnd() == m_hWndHelperBar );
HWND hWndChild = ::GetWindow( m_pBar->GetSafeHwnd(), GW_CHILD );
ASSERT( hWndChild != NULL );
::__EXT_MFC_SetWindowLong( hWndChild, GWL_ID, AFX_IDW_PANE_FIRST );
::SetParent( hWndChild, m_hWnd );
if( ! m_icon.IsEmpty() )
{
ASSERT( m_hIconExtracted == NULL );
m_hIconExtracted = m_icon.ExtractHICON();
if( m_hIconExtracted != NULL )
{
SetIcon( m_hIconExtracted, FALSE );
SetIcon( m_hIconExtracted, TRUE );
}
} // if( ! m_icon.IsEmpty() )
CMenu * pSysMenu = GetSystemMenu( FALSE );
if( pSysMenu != NULL )
{
ASSERT_KINDOF(CMenu, pSysMenu);
pSysMenu->EnableMenuItem(
SC_CLOSE,
MF_BYCOMMAND
| ( m_pBar->_ClosingIsEnabled( m_pBar ) ? MF_ENABLED : MF_DISABLED )
);
} // if( pSysMenu != NULL )
} // if( message == WM_CREATE )
return lResult;
}
|
|
Technical Support
|
Jun 7, 2010 - 11:20 AM
|
It would be interesting to discuss your know reasons because we didn’t clarify the source of the problem yet.
|
|
Gevork Odabashyan
|
Jun 8, 2010 - 2:41 AM
|
Sorry for the incorrect insertion point,
See the answer above in my reply "Re: Once more obout memory leaks"
|
|