Professional UI Solutions
Site Map   /  Register
 
 

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.

Forums » Prof-UIS Tech Support » Once more obout memory leaks Collapse All
Subject Author Date
Gevork Odabashyan Jun 3, 2010 - 1:12 AM

Hellow,


You don’t reply on my message in Docking BUG -3 (Memory leaks) ,  

www.prof-uis.com/prof-uis/tech-support/support-forum/docking-bug-3-memory-leaks-67640.aspx

so I remind about it once more.

As  I wrote  you really have a memory leaks for docking bars.

I know the reasons of this leaks (it’s two reasons).

If it will be need I can tell you about it.

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"