BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Other elements in a menu bar

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Usage)
View previous topic :: View next topic  
Author Message
José
Guest





PostPosted: Fri May 18, 2007 2:44 pm    Post subject: Other elements in a menu bar Reply with quote



Can I include other elements in a menubar, for example:

File Edit [Button] X CheckBox Help
--
José
Back to top
JD
Guest





PostPosted: Fri May 18, 2007 8:09 pm    Post subject: Re: Other elements in a menu bar Reply with quote



José <jose (AT) 127 (DOT) 0.0.1> wrote:
Quote:

Can I include other elements in a menubar, for example:

File Edit [Button] X CheckBox Help

Not really but you can fake it using a TToolBar and a
TMainMenu and a little custom drawing. Note the the
TToolBar's Flat property needs to be set to true to get
hot tracking to work correctly and that you'll also need
to subclass it's WindowProc to catch WM_LBUTTONDOWN/UP.

Drop a TMainMenu on the form and design it as indicated above
where File, Edit and possibly Help have submenu items and
the [Button] and CheckBox do not have submenu items. How this
is going to work will also require that you reserve space for
the check on the CheckBox by padding the Item Caption with
leading spaces (required to get TToolBar to size the button's
rect large enough).

Then just assign the TMainMenu to the TToolBar's Menu property.
Note that if you make changes to the TMainMenu, you'll need to
reassign the TMainMenu to the TToolBar but you'll first have
to assign a null value to the property to clear out the old
stuff.

The last 2 things to do is to add an OnCustomDrawButton event
to the TToolBar and devise a method for this event to be able
to distinguish if it's drawing a menu item or a button or a
checkbox or another type of control.

I would do something like:

enum TMyMenuItemTypes
{
mitMenu = 0,
mitButton,
mitCheckBox,
mitCount
};

And then, using the Object Inspector, assign the numeric value
to the TMenuItem's Tag property for the top level items only.
For example:

File Edit [Button] X CheckBox Help
0 0 1 2 0
default default default


The code looks like:

private:
TPoint ClickPoint;
TWndMethod OldWndProc;
void __fastcall NewWndProc( TMessage &Message );
public:
__fastcall TForm2(TComponent* Owner);
__fastcall ~TForm2();

//-------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner) : TForm(Owner)
{
ClickPoint = Point( -1, -1 );
OldWndProc = ToolBar1->WindowProc;
ToolBar1->WindowProc = NewWndProc;
}
//-------------------------------------------------------------
__fastcall TForm2::~TForm2()
{
ToolBar1->WindowProc = OldWndProc;
}
//-------------------------------------------------------------
void __fastcall TForm2::NewWndProc( TMessage &Message )
{
if( Message.Msg == WM_LBUTTONDOWN )
{
::GetCursorPos( &ClickPoint );
ClickPoint = ToolBar1->ScreenToClient( ClickPoint );
ToolBar1->Invalidate();
}
else if( Message.Msg == WM_LBUTTONUP )
{
ClickPoint = Point( -1, -1 );
ToolBar1->Invalidate();
}
OldWndProc( Message );
}
//-------------------------------------------------------------
void __fastcall TForm2::ToolBar1CustomDrawButton(TToolBar *Sender, TToolButton *Button, TCustomDrawState State, bool &DefaultDraw)
{
TToolBar *Bar = static_cast<TToolBar*>( Sender );
TMenuItem *pItem = Bar->Menu->Items->Items[ Button->Index ];
TRect R = Rect( Button->Left, Button->Top, Button->Left + Button->Width, Button->Top + Button->Height );
TPoint P;
::GetCursorPos( &P );
P = Bar->ScreenToClient( P );
if( pItem->Tag == mitMenu )
{
if( PtInRect(R,P) )
{
Bar->Canvas->Brush->Color = clHighlight;
Bar->Canvas->Font->Color = clHighlightText;
}
else
{
Bar->Canvas->Brush->Color = Bar->Color;
Bar->Canvas->Font->Color = Bar->Font->Color;
}
Bar->Canvas->FillRect( R );
::DrawText( Bar->Canvas->Handle, Button->Caption.c_str(), -1, &R, DT_SINGLELINE | DT_CENTER | DT_VCENTER );
}
else
{
Bar->Canvas->Brush->Color = Bar->Color;
Bar->Canvas->Font->Color = Bar->Font->Color;
Bar->Canvas->FillRect( R );
if( pItem->Tag == mitButton )
{
if( PtInRect(R,P) )
{
if( PtInRect(R,ClickPoint) )
{
if( ::GetKeyState(VK_LBUTTON) & 0x80 )
{
Frame3D( Bar->Canvas, R, clBtnShadow, clBtnHighlight, 1 );
OffsetRect( R, 1, 1 );
}
else
{
ClickPoint = Point( -1, -1 );
Frame3D( Bar->Canvas, R, clBtnHighlight, clBtnShadow, 1 );
}
}
else Frame3D( Bar->Canvas, R, clBtnHighlight, clBtnShadow, 1 );
}
::DrawText( Bar->Canvas->Handle, Button->Caption.c_str(), -1, &R, DT_SINGLELINE | DT_CENTER | DT_VCENTER );
}
else if( pItem->Tag == mitCheckBox )
{
::DrawText( Bar->Canvas->Handle, Button->Caption.c_str(), -1, &R, DT_SINGLELINE | DT_CENTER | DT_VCENTER );
R.left += 4;
R.right = R.left + ::GetSystemMetrics( SM_CXMENUCHECK );
unsigned int Flags = 0;
if( pItem->Checked ) Flags |= DFCS_CHECKED;
::DrawFrameControl( Bar->Canvas->Handle, &R, DFC_BUTTON, Flags );
}
}
DefaultDraw = false;
}
//-------------------------------------------------------------
void __fastcall TForm2::MenuCheckBox1Click(TObject *Sender)
{
TMenuItem *pItem = static_cast<TMenuItem*>( Sender );
pItem->Checked = !pItem->Checked;
}
//-------------------------------------------------------------
void __fastcall TForm2::MenuButtonClick(TObject *Sender)
{
ShowMessage( "Menu Button Click" );
}
//-------------------------------------------------------------

The only issue that I have with the above is how the button
behaves. Normal button behavior is to execute the click when
the mouse is released and only then if the mouse is still
within the control. In this case, the OnClick event executes
as soon as a click is detected.

~ JD
Back to top
José
Guest





PostPosted: Sat May 19, 2007 8:18 pm    Post subject: Re: Other elements in a menu bar Reply with quote



On 18 May 2007 08:09:12 -0700, "JD" <nospam (AT) nospam (DOT) com> wrote in
borland.public.cppbuilder.vcl.components.using:

Quote:
Not really but you can fake it using a TToolBar and a
TMainMenu and a little custom drawing.

I presume you have been very helpful by providing a long program (did
you make it for me or had it been made before?)

However, I am afraid that I am still too stupid to understand it. And
just copying someone else's coding just doesn't work.

Thanks anyhow. I now know that it's not as easy as I hoped.
--
José
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Usage) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.