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 General Discussion » CExtControlBar questions Collapse All
Subject Author Date
Cory Albrecht Apr 1, 2003 - 5:57 PM

Hello,

With CExtControlBar, is there a simple way to intercept when the little hide button is pressed? I need to be able to set a checkbox in my user preferences dialog based on whether or not a specific bar is visible or not.

Also, I’ve noticed that the CBRS_GRIPPER style is what gives CExtControlBar-based bars their caption and hide button. Is there a simple way to give them a double line gripper handle like docking toolbars have? And perhaps a little down-arrow minimize button for a VisualStudio 6 look?

And I just noticed in my prog that when an MDI child is maximized, the minimize, restore and close buttons are right beside the last menu item instead of being all the way over by the right-hand side of the frame window. (See http://www.sentex.ca/~corya/menubar.gif for example.) I can’t seem to figure out what change I made to make this happen becasue they were in the proper place before, but for the life of me I can’t figure out what change it was that I made. How do I get the buttons back to where they should be? Help!

Sergiy Lavrynenko Apr 2, 2003 - 6:43 AM

Hi,

>>> With CExtControlBar, is there a simple way to intercept when
>>> the little hide button is pressed? I need to be able to set
>>> a checkbox in my user preferences dialog based on
>>> whether or not a specific bar is visible or not.

The buttons inside non client area of the control bar are not windows. They are instances of classes derived from the CExtBarNcAreaButton. There are no notification messages for handling their events. You can replace standard implementations of these buttons with your own and handle button clicks in the CExtBarNcAreaButton::OnNcAreaClicked(). Please use your own classes derived from CExtControlBar and override this method:

void CExtControlBar::OnNcAreaButtonsReinitialize()
{
INT nCountOfNcButtons = NcButtons_GetCount();
if( nCountOfNcButtons > 0 )
return;
NcButtons_Add( new CExtBarNcAreaButtonClose(this) );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
NcButtons_Add( new CExtBarNcAreaButtonAutoHide(this) );
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
// NcButtons_Add( new CExtBarNcAreaButtonExpand(this) );
NcButtons_Add( new CExtBarNcAreaButtonMenu(this) );
}

You should replace this line
NcButtons_Add( new CExtBarNcAreaButtonClose(this) );
with
NcButtons_Add( new CMyOwnImplOfNcAreaButtonClose(this) );

Your class CMyOwnImplOfNcAreaButtonClose should be derived from CExtBarNcAreaButtonClose. It should have overridden OnNcAreaClicked() where you may catch the click event.

>>> Also, I’ve noticed that the CBRS_GRIPPER style is what
>>> gives CExtControlBar-based bars their caption and hide button.
>>> Is there a simple way to give them a double line gripper handle
>>> like docking toolbars have? And perhaps a little down-arrow
>>> minimize button for a VisualStudio 6 look?

Painting of all the Prof-UIS windows is based on the global paint manager (g_PaintManager variable). g_PaintManager is a smart container for the CExtPaintManager-like object. You can install your own paint manager class (derived from CExtPaintManager or CExtPaintManagerXP) to re-paint anything.
Please create your own class derived from the CExtPaintManager. Then override PaintGripper() method.
Please see the code of CExtPaintManager::PaintGripper() for details. If m_bSideBar is true – we are painting the gripper of resizable bar (caption). If m_bFloating is true – we are painting the caption of any floating mini-frame window.

To replace the paint manager:
g_PaintManager.InstallPaintManager( new CMyPaintManager ).

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Question about MDI-child-frame’s min/max/close buttons:

I can not open URL with your image. Browser shows the “requested URL not found” message. Please send me a letter to l_sergiy@fossware.com with your test project and I will help you.

Regards, Sergiy.

Cory Albrecht Apr 2, 2003 - 11:16 PM

I found an easier way.

Instead of having to derive my own class from CExtControlBar and overriding OnNcAreaButtonsReinitialize(), I made few small modifications to the Prof-UIS code.

In the files extcontrolbar.cpp and ExtMiniDockFrameWnd.cpp I comment out all the references CExtControlBar::OnNcAreaButtonsReinitialize(). Then I added it to then end of CExtControlBar::Create(). This apparently causes no harm to any of the exmample programmes (I only tested the Win32 Unicode Debug version of them).

With all those references to OnNcAreaButtonsReinitialize() gone I can now use all the NcButton_[Add|SetAt|*] functions and dynamically change the buttons at any time (Or remove them if a context requires no nc-buttons). Before, that was inpossible with 0 nc-buttons because CExtControlBar::OnNcCalcSize() called OnNcAreaButtonsReinitialize() and that would add the default buttons back on, as would dragging the control bar to floating an dthen docking it again.

Now all I have to derive a new class from CExtBarNcAreaButtonClose and override OnNcAreaDraw() and then call NcDrawDefault() with the arrow type I want, and OnNcAreaClicked() to notify my programm that the controlbar has been hidden so it can update the user preferences.

Doing it this way also opens it up for the user to make buttons out of custom bitmaps since they don’t have to call NcDrawDefault(). (i sthere away to change the size of one of the nc-buttons or the caption/gripper? I haven’t looked for that, yet.)

If you would use this idea of mine in your next release, you could add a bunch of #defines (i.e. CBRS_NCBTN_CLOSE or CBRS_NCBTN_MINIMIZE) which would be added to the style param of the CExtControlBar::Create() so the user could specify which nc-buttons get placed initially on the controlbar’s caption/gripper.

Sergiy Lavrynenko Apr 3, 2003 - 2:09 AM

Hi,

I think your idea is quite complicated. At least you don’t have to modify ExtControlBar.cpp file for using NcButton_[Add|SetAt|*] as described.

About button sizes:

Release of VS.NET and MFC version 7.0 shows us one thing: MFC is still under construction :-) So adding your own CBRS_* flags is not good idea because their values potentially may match with new CBRS_* constants of future MFC versions.

Sizes of the resizable control bar caption and its non-client area buttons are based on the GetSystemMetrix() calls. So to change these sizes you need override all the control-bar’s non-client area managing code. This is not easy :-(

I think the easier alternate way is to use resizable bars without caption (gripper style is CBRS_GRIPPER) and insert caption like component into child window of a bar.

Regards, Sergiy.

Cory Albrecht Apr 3, 2003 - 2:00 PM

Hello,

>I think your idea is quite complicated. At least you don’t have to modify
>ExtControlBar.cpp file for using NcButton_[Add|SetAt|*] as described.

"Quite complictaed"? The changes to the Prof-UIS code I suggested is a total of 6 lines - 5 in one file and 1 line in another. 6 lines out of how many tens of thousands that make up Prof-UIS? And these extremely minimal alterations make no difference to any previous code that already uses Prof-UIS. None whatsoever. But the end result of these 6 lines is that Prof-UIS has greater functionality for the user. I do not understand how changing 6 lines would be complicated.

As for adding new CBRS_* constants, you are right about that. That was a bad idea. They just might conflict with new ones added by MS in the future.

Cory Albrecht Apr 2, 2003 - 11:45 AM

This information about CExtBarNcAreaButton and CExtPaintManager helps a lot, thanks muchly. BTW, before I found Prof-UIS, I was thinking that I would have to do all this by myself. :-( Or that the very least take many little bits from places like codeprojects.com and force them to work together. This is a great product.

As for the url, I noticed the same thing. :-) It looks fine in the message view window, but when clicked the ~ (tilde) somehow gets wrongly url-encoded. If you replace the %CB%9C with a ~ then everything works. (This looks like a UTF8 <-> ANSI conversion problem - from, to the other and back again not being the same as the original.)

Sergiy Lavrynenko Apr 3, 2003 - 1:54 AM

Please replace this function in the ExtMenuControlBar.h file:

void CExtMenuControlBar::_RecalcPositionsImpl()
{
CExtToolControlBar::_RecalcPositionsImpl();
if( g_bHideMenuBarExpandContentButton && m_pRightBtn != NULL )
{
ASSERT_VALID( m_pRightBtn );
if( m_pRightBtn->GetButtons().GetSize() == 0 )
m_pRightBtn->Show( FALSE );
}
CWnd * pWndParent = GetParent();
ASSERT_VALID( pWndParent );
BOOL bInDockBar = pWndParent->IsKindOf(RUNTIME_CLASS(CDockBar));
if( IsFloating() && bInDockBar )
return;
int nCountOfButtons = GetButtonsCount();
if( nCountOfButtons <= 1 )
return;
int nRightIndex = nCountOfButtons - 1;
CExtBarMdiRightButton * pRightTBB = DYNAMIC_DOWNCAST( CExtBarMdiRightButton, _GetButtonPtr(nRightIndex) );
if( pRightTBB == NULL && nCountOfButtons > 1 )
{
nRightIndex--;
pRightTBB = DYNAMIC_DOWNCAST( CExtBarMdiRightButton, _GetButtonPtr(nRightIndex) );
}
if( pRightTBB == NULL )
return;
if( !pRightTBB->IsVisible() )
return;
ASSERT( nRightIndex >= 1 );
#ifdef _DEBUG
CExtBarButton * pPrevTBB = _GetButtonPtr( nRightIndex - 1 );
ASSERT_VALID( pPrevTBB );
ASSERT( pPrevTBB->IsVisible() );
#endif // _DEBUG
CExtBarButton * pExpandTBB = NULL;
CRect rcBtnExpand(0,0,0,0);
int nAlignMargin = 0;
BOOL bHorz = bInDockBar
? IsDockedHorizontally()
: ( (m_dwStyle & (CBRS_ALIGN_TOP|CBRS_ALIGN_BOTTOM)) ? true : false );
CRect rcClient;
GetClientRect( &rcClient );
if( nRightIndex < (nCountOfButtons-1) )
{ // if content-expand button exists
pExpandTBB = _GetButtonPtr( nRightIndex + 1 );
ASSERT_VALID( pExpandTBB );
ASSERT( pExpandTBB->IsKindOf( RUNTIME_CLASS(CExtBarContentExpandButton)) );
if( pExpandTBB->IsVisible() )
{
rcBtnExpand = pExpandTBB->Rect();
nAlignMargin = bHorz ? rcBtnExpand.left : rcBtnExpand.top;
} // if( pExpandTBB->IsVisible() )
else
{
pExpandTBB = NULL;
nAlignMargin = bHorz ? rcClient.right : rcClient.bottom;
} // else from if( pExpandTBB->IsVisible() )
nAlignMargin -= __MENUBAR_RIGHT_ADJUST_GAP;
} // if content-expand button exists
else
{ // if content-expand button DOES NOT exists
nAlignMargin = bHorz ? rcClient.right : rcClient.bottom;
nAlignMargin -= __MENUBAR_RIGHT_ADJUST_GAP;
} // if content-expand button DOES NOT exists
CRect rcBtnRight = pRightTBB->Rect();
if( bHorz && rcBtnRight.right >= nAlignMargin )
return;
if( (!bHorz) && rcBtnRight.bottom >= nAlignMargin )
return;
if( bHorz )
rcBtnRight.OffsetRect( nAlignMargin - rcBtnRight.right, 0 );
else
rcBtnRight.OffsetRect( 0, nAlignMargin - rcBtnRight.bottom );
if( pExpandTBB == NULL )
{
pRightTBB->SetRect(rcBtnRight);
return;
}
ASSERT( !rcBtnExpand.IsRectEmpty() );
CRect rcBtnExpand2(
bHorz ? rcBtnRight.left : rcBtnExpand.left,
bHorz ? rcBtnExpand.top : rcBtnRight.top,
bHorz ? rcBtnRight.left + rcBtnExpand.Width() : rcBtnExpand.left + rcBtnExpand.Width() ,
bHorz ? rcBtnExpand.top + rcBtnExpand.Height() : rcBtnRight.top + rcBtnExpand.Height()
);
rcBtnRight.OffsetRect(
bHorz ? rcBtnExpand.right - rcBtnRight.right : 0,
bHorz ? 0 : rcBtnExpand.bottom - rcBtnRight.bottom
);
pRightTBB->SetRect(rcBtnRight);
pExpandTBB->SetRect(rcBtnExpand2);
if( g_bHideMenuBarExpandContentButton )
pExpandTBB->Show( FALSE );
}

Cory Albrecht Apr 3, 2003 - 2:05 PM

>Please replace this function in the ExtMenuControlBar.h file:
>
>void CExtMenuControlBar::_RecalcPositionsImpl()
>{
...
>}

Ah, great. That new code works perfectly. Thank you for taking the time to rewrite the function.