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 » Adding a Scroll Bar to a Dynamic Control Bar Collapse All
Subject Author Date
Bill Olson Apr 25, 2012 - 2:34 AM

I have a control bar with a CExtResizableDialog attached.  Under some conditions, the window may be too small to see everything on the bar at once.  How do I create scroll bars for this control bar?  I found a sample for TestScrollDialog that was posted for someone else with a little bit of a different question.  You add m_wndScrollContainer in that example, but I’m not quite sure how to make that work with a dynamic control bar.


Thanks,


Bill

Bill Olson May 16, 2012 - 11:09 PM

OK, I added an nDesiredCmdID to the BarAlloc call.  I then get that ID with nCmdID = (UINT)m_pBarRight->GetDlgCtrlID();


That looks fine.  Just before calling ShowControlBar, I make the call to m_wndScrollRight.Create with the nCmdID.  I also tried it as the last command in OnCreate.


I get through OnCreate, but when OnSize is called, the program crashes.


I get an assert in void CExtControlBar::MaximizeOnRow() on line 11965


ASSERT( ::GetWindow( hWndChild, GW_HWNDNEXT ) == NULL );


hWndChild is non-zero, so it is getting initialized.


The comment a few lines above says:


// automatic child resizing - only one child is allowed


Thanks,


Bill

Technical Support May 23, 2012 - 11:47 AM

This is a very important limitation: CExtControlBar windows (including CExtDynamicControlBar) must contain one child window. This is important because bars switched into auto-hidden state or into dynamic tabbed/SDI/MDI document states are really just hidden bars and their single child windows are just temporarily moved into other containers implementing an auto-hide slider window or a document container window.

If you are using CExtNCSB-based window as a control bar child window, then you should invoke CExtNCSB constructor with both flag parameters set to true:

CYourClass::CYourClass( . . . )
    : CExtNCSB < CBaseOfYourClass > ( true, true )
    . . .
{
    . . .
}

The first flag makes scroll bars initialization delayed. The second flag creates one container window between your window and its parent control bar window. The scroll bars are also created in this dynamic container window. As a result, the control bar contains one child window. We believe this is what you really need.

Technical Support Apr 26, 2012 - 1:00 PM

Please create CExtScrollContainerWnd as a child of CExtControlBar. Then create a dialog inside CExtScrollContainerWnd.

Bill Olson Apr 27, 2012 - 3:10 AM

I found something similar in the TabPages example, but I couldn’t get it to work in my code.  My code is derrived from the Dynamic Inner and Outer Bar sample which uses CExtDynamicControlBar pointers.  The TabPages sample doesn’t use pointers.  I don’t know if that’s contributing to my problem or not.



My CMDIChildWnd derrived class has the following:



class CChildMyWnd : public CExtNCW < CMDIChildWnd >, public CExtDynamicBarSite

{

...



public:

    CExtDynamicControlBar * m_pBarPersistentInner;

    CExtDynamicControlBar *m_pBarRight;

    CExtScrollContainerWnd m_wndScrollRight;

    CDlgBarR m_DlgBarR;

...

};



Then in the OnCreate function:



...

    CExtDynamicBarSite::Install( this );

...

    strBarCaption.Format(_T("Control Window"));

    //if(!m_BarRight.Create(strBarCaption, this, ID_STDTR_DLGBAR_RIGHT))

    //{

    //    TRACE0("Failed to create m_BarRight\n");

    //    return -1;

    //}

    m_pBarRight = BarAlloc(strBarCaption,icon,0,NULL,true);

    m_pBarRight->m_nMdiMenuResourceID = IDR_MyTYPE;

    m_pBarRight->m_nMdiAccelTableResourceID = IDR_MAINFRAME;

    if(!m_wndScrollRight.Create(m_pBarRight, rectDefault ))

    {

        TRACE0("Failed to create m_wndScrollRight\n");

        return -1;

    }



    nCmdID = (UINT)m_pBarRight->GetDlgCtrlID();

    pCmdItem = g_CmdManager->CmdGetPtr(pApp->m_pszProfileName,nCmdID);

    ASSERT( pCmdItem != NULL );

    pCmdItem->StateSetBasic();

    if(!m_DlgBarStdR.CreateInsideBar(m_pBarRight))

    {

        ASSERT( FALSE );

        return -1;

    }

...



The CreateInsideBar call fails.  Here is the code in my dialog



bool CDlgBarR::CreateInsideBar(CExtControlBar * pBar)

{

    ASSERT_VALID( this );

    ASSERT_VALID( pBar );

    ASSERT( GetSafeHwnd() == NULL );

    ASSERT( pBar->GetSafeHwnd() != NULL );

    if( ! CExtResizableDialog::Create( IDD, pBar ) )

        return false;

    pBar->OnRepositionSingleChild();   //<------ ASSERTS in this call

    return true;

}



The assert happens on the line (in CExtControlBar)



ASSERT(::GetWindow(hWndChild, GW_HWNDNEXT) == NULL);



Obviously the scroll bar is causing something to go awry down here, but I’m stumped about how.  Unless I’m completely out to lunch...


Bill

Technical Support May 16, 2012 - 3:08 AM

The nDesiredCmdID parameter of the CExtDynamicBarSite::BarAlloc() allows you to specify a non-zero command identifier which you then can always use to get pointers to your bars and create bar child windows. I.e. bar child windows should be invoked after creating all bars or after loading bar states and dynamic bar site’s state.