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 » Control-bars serialization problem/bug Collapse All
Subject Author Date
Offer Har Sep 22, 2008 - 8:46 AM

I started to get crashes when the bars states were loading from the registry. I traced the problem back to the function CExtControlBar::InternalFriendlyFrameWnd::SetOuterDockState and found out that for some reason there were 20 (!) bars with the ID AFX_IDW_DOCKBAR_FLOAT saved, and when they are loaded, in the last pass I got a crash in the highlighted line::



    for( i = 0; i < state.m_arrBarInfo.GetSize(); i++ )
    {
        CControlBarInfo * pInfo = (CControlBarInfo *)
            state.m_arrBarInfo[i];
        TRACE("\n%d]pInfo: %d ptr: %X hwnd: %X",i,pInfo->m_nBarID, pInfo->m_pBar, pInfo->m_pBar->GetSafeHwnd());
        ASSERT( pInfo != NULL );
        if( pInfo->m_pBar == NULL )
            continue;
        if(        (! pInfo->m_pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) ) <= THIS CRASHED
            ||    ( ((CExtControlBar*)pInfo->m_pBar)->IsFixedMode() )
            ||    ( ((CExtControlBar*)pInfo->m_pBar)->IsFixedDockStyle() )
            )
        {
...

What I did, was to remove this piece of code from the function:



        if( pInfo->m_bFloating )
        {
            // need to create floating frame to match
            CMiniDockFrameWnd * pDockFrame =
                CreateFloatingFrame(
                    pInfo->m_bHorz ?
                        CBRS_ALIGN_TOP : CBRS_ALIGN_LEFT
                    );
            ASSERT( pDockFrame != NULL) ;
            CRect rcWnd( pInfo->m_pointPos, CSize(10, 10) );
            pDockFrame->CalcWindowRect( &rcWnd );
            pDockFrame->SetWindowPos(
                NULL,
                rcWnd.left, rcWnd.top, 0, 0,
                SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE
                );
            CDockBar * pDockBar = (CDockBar *)
                pDockFrame->GetDlgItem( AFX_IDW_DOCKBAR_FLOAT );
            ASSERT( pDockBar != NULL );
            ASSERT_KINDOF( CDockBar, pDockBar );
            pInfo->m_pBar = pDockBar;
//             if( pInfo->m_bVisible )
//                 _mapCFV.SetAt( pDockFrame, 0 );
        } // if( pInfo->m_bFloating )
        else // regular dock bar or toolbar
...


Without this code, there are no crashes, and it seems that all the menus and bars are loaded properly.


1. Can you please explain what this piece of code is for?


2. Is it reasonable that I will have 20 bars with the same ID AFX_IDW_DOCKBAR_FLOAT?


3. What does it crash when this happen?


Thanks,

Ron.


 


 


 

Technical Support Sep 23, 2008 - 5:45 AM

When you see a floating toolbar on the desktop, you really see three windows:

1) Floating mini frame window. This is the CMiniDockFrameWnd window in MFC. This is the CExtMiniDockFrameWnd window in Prof-UIS.

2) There is only one child window inside floating mini frame window - the dock bar. This is the CDockBar window. It’s dialog control identifier is the This is the AFX_IDW_DOCKBAR_FLOAT
window value. The CDockBar class is derived from the CControlBar class. Nevertheless dock bars are inner components of both Prof-UIS and MFC, they are also control bars and both MFC and Prof-UIS save their states.

3) The child of dock bar is toolbar window which was switched into floating state.

This is the rule of both MFC and Prof-UIS: the parent window of re-dockable toolbar window is always dock bar window. There are four dock bars inside main frame window. They are created and docked near main frame’s sides. Their dialog control identifiers:
AFX_IDW_DOCKBAR_TOP, AFX_IDW_DOCKBAR_BOTTOM,
AFX_IDW_DOCKBAR_LEFT and
AFX_IDW_DOCKBAR_RIGHT. But all the dock bar windows in all the floating mini frames are having the AFX_IDW_DOCKBAR_FLOAT dialog control identifier. The dock bar windows are non-re-dockable control bars. The main frame’s dock bars are parent windows for control bars docked inside main frame window. The dock bar windows inside all the floating mini frame windows are parents for floating control bars. Both toolbars and dock bars are MFC control bars. Both MFC and Prof-UIS save state of all the control bars including dock bars. All the control bars must have unique dialog control identifiers. But AFX_IDW_DOCKBAR_FLOAT is the exception in both MFC and Prof-UIS. There is another similar exception in Prof-UIS
only: dynamic row/column like containers and tab containers for resizable control bars in Prof-UIS are also resizable control bars and they also have non-unique dialog control identifiers. But resizable control bars in Prof-UIS have their own state serialization and layouting/drag-n-dropping algorithms not based on MFC source code.

The assertion/crash described in your message can occur if you have created some toolbar or resizable control bar using the AFX_IDW_DOCKBAR_FLOAT dialog control identifier. This is not acceptable. Please check dialog control identifiers of all your control bars first of all. They should be unique. You will never have problems with them if their dialog control identifiers will be less than 29000.

Offer Har Sep 23, 2008 - 1:03 PM

This is from MSND:


_APS_NEXT_COMMAND_VALUE is the next symbol value that will be used for a command identification. The valid range for command symbol values is 0x8000 to 0xDFFF.


From here:


http://msdn.microsoft.com/en-us/library/6t3612sk(VS.71).aspx#@lt;/p>

Technical Support Sep 24, 2008 - 4:55 AM

MFC defines a set of its identifiers closer to 65535. Visual Studio resource editors can also generate identifiers close to 65535 but most of generated values start from 1 and growing. That is why we have used a range of identifiers 29000-32000 in Prof-UIS resources. The generated by Visual Studio identifiers should not intersect with Prof-UIS identifiers and it’s hardly possible because all the customer projects we ever saw has less than 10000 private identifiers. So, if your identifiers are less than 29000, then everything will be OK and they will not intersect with Prof-UIS nor with MFC.

Offer Har Sep 24, 2008 - 8:40 AM

But Microsoft defines command values to start after 0x8000 , please look into TN20 : http://msdn.microsoft.com/en-us/library/t2zechd4(VS.71).aspx#@lt;/p>

Which means that all the commands should start after 32,768


So, mayeb what you mean is that if my commands are after 32,768 that it should be fine...?

Technical Support Sep 25, 2008 - 12:51 PM

We are using a range lesser than 29000 in Prof-UIS based projects. If you use a range greater than 32000 like Microsoft advices, everything will be OK as well.


Offer Har Sep 23, 2008 - 1:01 PM

One thing that we do not understand:


You say that the dialog control identifiers should be less than 29000. However, this ID is the command ID that used in the menus to show/hide this dialog control bar.


As far as we know, commands IDs should be in the range of more then 32768. How can these two mechanisms will work? looks like there is a conflict here.


Please advise.

Offer Har Sep 23, 2008 - 12:24 PM

Dear Support,


We continued to investigate the code, and I don’t have any control bars using these numbers, and still I get crashes in this piece of code.


It looks like the pInfo->m_pBar is invalid - the CControlBar’s hWnd is 0xfeeefeee - which means it was deleted at one point.


How can this be possible?


We are now posponing a product release because of this bug, please try and give us some support on this ASAP.


Thanks,


Ron.

Technical Support Sep 24, 2008 - 4:56 AM

We suspect the problem is really caused by creating new/removing old control bars due to development process. Although Prof-UIS should not crash when loading states of not-existing control bars, we would like to ask you to remove the control bar state of your application from the system registry and try to run it several times. It would be interesting to know whether the assertions/crashes still occur?

Offer Har Sep 24, 2008 - 8:43 AM

OK - I will try this approach - but I think that Prof-UIS should be more forgiving, and not crash the application if a control-bar is not found. Please try and make it fail-safe.


Thanks,


Ron.

Offer Har Sep 23, 2008 - 9:29 AM

Another question - why do you create CMiniDockFrameWnd and not CExtMiniDockFrameWnd? This is from the same piece of code I commented off:


        if( pInfo->m_bFloating )         {             // need to create floating frame to match             CMiniDockFrameWnd * pDockFrame =                 CreateFloatingFrame(                     pInfo->m_bHorz ?                         CBRS_ALIGN_TOP : CBRS_ALIGN_LEFT                     );             ASSERT( pDockFrame != NULL) ; ...

Technical Support Sep 24, 2008 - 4:56 AM

The CExtMiniDockFrameWnd class is derived from the CMiniDockFrameWnd class. The CFrameWnd::CreateFloatingFrame() method uses the CRuntimeClass* m_pFloatingFrameClass; property of the CFrameWnd () class for instantiating the CMiniDockFrameWnd object. Prof-UIS replaces this run-time information object with reference to the run-time class of the CExtMiniDockFrameWnd class (inside invocation of the CExtControlBar::FrameEnableDocking() static method). As a result, all the instances of floating mini frame windows are the CExtMiniDockFrameWnd windows. Besides, the CExtMiniDockFrameWnd class type is very required by all the Prof-UIS control bars. The CExtMiniDockFrameWnd windows have skinned caption and borders. So, if you see skinned floating mini frame windows, then they are instances of the CExtMiniDockFrameWnd class.

Offer Har Sep 23, 2008 - 7:10 AM

Thank you for the explanation.


I think I understand my problem, but I would like to verify it with you: When I create my toolbars, I derive them from CExtToolControlBar, and call its Create, which is actualy a call to CExtControlBar::Create. The default ID in this function is AFX_IDW_DIALOGBAR, so I just added some static increasing number to bypass all my toolbars having the same ID. I guess this lead to the IDs created being more then 29000, maybe overlapping other used values, and to the assertions. Can this be my problem?


Can you please explain what does this default value in the CExtControlBar::Create means? fromExtControlBar.h:


    virtual BOOL Create(
        __EXT_MFC_SAFE_LPCTSTR lpszWindowName,
        CWnd * pParentWnd,
	    UINT nID = AFX_IDW_DIALOGBAR,
        DWORD dwStyle =
            WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS
            |CBRS_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS
            |CBRS_FLYBY|CBRS_SIZE_DYNAMIC
            |CBRS_HIDE_INPLACE
        );

Thanks,


Ron.