How to change the height of the main menu bar?

G

Guest

I am developing a Windows Forms application using VS.NET and C#. It is using
the MDI style interface. See earlier posting "How to change the font of the
main
menu in application window?" started 9/28/2004 in this discussion group.

Okay, now that I can change the font of the menu items on the main menu of the
application, I now need to take the next logical step. As I make the font
size of
the menu items larger, the height of the menu bar eventually needs to increase
as well to display the menu items without truncating the characters, top and
bottom.

How can I change the height of the main menu bar programmatically?

Thanks,
Dave
 
G

Guest

Sijin,

Sorry, but this link you provided just says how to modify the menu items in
a menu,
not how to change the height of the actual menu bar where MainMenu items are
placed.

Thanks anyway,
Dave
 
J

Jeffrey Tan[MSFT]

Hi Dave,

Based on my understanding, you want to apply a large font style to your
menu item, then adjust the menu item height to fit the font.

Actually, the MenuItem class's OnMeasureItem method gives us a chance to
arrange the menu item height and width, we may pass the font we want to
draw the e.Graphics.MeasureString method, then assign the result Size value
to MeasureItemEventArgs.ItemHeight and ItemWidth property. Then the height
and width will adjust with the font. Code like this:
private class MyMenuItem: MenuItem
{
public MyMenuItem()
{
this.OwnerDraw=true;
}

protected override void OnMeasureItem(MeasureItemEventArgs e)
{
string myCaption=this.Text ;
Console.WriteLine(myCaption);
Font myFont = new Font(FontFamily.GenericSerif, 25, FontStyle.Italic,
GraphicsUnit.Pixel);
Size mySize = e.Graphics.MeasureString(myCaption, myFont).ToSize();

e.ItemHeight=mySize.Height;
e.ItemWidth=mySize.Width;
}

protected override void OnDrawItem(DrawItemEventArgs e)
{
string myCaption="&"+this.Text;

Brush myBrush = System.Drawing.Brushes.Black;

Font myFont = new Font(FontFamily.GenericSerif, 25, FontStyle.Italic,
GraphicsUnit.Pixel);
StringFormat sf = new StringFormat();

if(e.State==DrawItemState.NoAccelerator)
{
sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Hide;
}
else
{
sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show;
}
Console.WriteLine(sf.HotkeyPrefix.ToString());

e.Graphics.FillRectangle(new SolidBrush(SystemColors.Control), e.Bounds);
e.Graphics.DrawString(myCaption, myFont, myBrush, e.Bounds.X, e.Bounds.Y,
sf);
}
}
==================================================
Please apply my suggestion above and let me know if it helps resolve your
problem.

Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
G

Guest

Jeffrey,

I know how to set the MenuItem size as we resolved that in my previous posting
(9/28/2004). The problem is with the top menu items in a menu, the ones added
to the MainMenu object. These are drawn onto the MENU BAR region, not the
drop
-down list. If the font is large enough, the characters are clipped when
drawn on
the menu bar.

So my question is, how can I programmatically change the MENU BAR height?
(The menu bar is usually a region located directly below the window title.)

Thanks,
Dave
 
J

Jeffrey Tan[MSFT]

Hi Dave,

Thanks for your feedback and details explaining!

I have understood your problem, and I will spend some time on it. I will
update you ASAP. Thanks for your understanding.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Dave,

We are still researching on this issue, thanks for your patience and
cooperation.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Dave,

Sorry for letting you wait for so long time.

After doing a lot of research, I found that because the main menu bar is
the non client area of a window, it is painted by Windows system. There is
not a easy way to change it height. If we really want to change the height,
we have to intercept the WM_NCPAINT message etc, then draw the non client
area ourselves, which is somewhat difficult.

So I think maybe you may find other way to fit your application need?
Anyway, if you have any concern, please feel free to tell me. Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
G

Guest

Jeffrey,

I understand that it might be difficult. Is there an article (or articles)
that you can point me to that explains the process for handling the
WM_NCPAINT message?

Thanks,
Dave
 
J

Jeffrey Tan[MSFT]

Hi Dave,

Thanks very much for your reply!

Ok, please wait a little more time, I will spend some time to find some
related resource for your. Thanks for your understanding.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan

Hi Dave,

Sorry for letting you wait for so long.

After doing a lot of research, I found that we should first handle
WM_NCCALCSIZE to decrease the client area size. Then the non-client area is
getting larger. Then we should handle the WM_NCPAINT message to paint the
menu and other non-client ourselves.
I have writen a little sample for you to show to handle these 2 messages.

[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}

enum WM_MESSAGE
{
WM_NCCALCSIZE = 131,
WM_NCPAINT = 133,
WM_NCHITTEST = 132,
WM_NCLBUTTONDOWN = 161,
}

[StructLayout(LayoutKind.Sequential)]
struct NCCALCSIZE_PARAMS
{
public RECT rgrc0, rgrc1, rgrc2;
public IntPtr lppos;
}
[StructLayout(LayoutKind.Sequential)]
struct WINDOWPOS
{
public IntPtr hwnd;
public IntPtr hwndInsertAfter;
public int x, y;
public int cx, cy;
public int flags;
}

[DllImport("User32.dll")]
private extern static IntPtr GetWindowDC( IntPtr hWnd );

[DllImport("User32.dll")]
private extern static int ReleaseDC( IntPtr hWnd, IntPtr hDC );

private Rectangle _rcButton = Rectangle.Empty;

protected override void WndProc(ref Message m)
{
switch ( m.Msg )
{
case (int)WM_MESSAGE.WM_NCCALCSIZE :

NCCALCSIZE_PARAMS csp;

csp = (NCCALCSIZE_PARAMS)Marshal.PtrToStructure( m.LParam,
typeof(NCCALCSIZE_PARAMS));
Font myFont = new Font(FontFamily.GenericSerif, 35, FontStyle.Italic,
GraphicsUnit.Pixel);
Graphics g=this.CreateGraphics();
Size mySize = g.MeasureString(this.menuItem1.Text, myFont).ToSize();
Console.WriteLine(mySize.Height.ToString());
Console.WriteLine(csp.rgrc0.Top.ToString());
csp.rgrc0.Top =
csp.rgrc0.Top -SystemInformation.MenuHeight+mySize.Height;

Console.WriteLine(csp.rgrc0.Top.ToString());
Marshal.StructureToPtr( csp, m.LParam, false );
break;

case (int)WM_MESSAGE.WM_NCPAINT :
{
IntPtr hDC = GetWindowDC( m.HWnd );
Graphics g1 = Graphics.FromHdc( hDC );
Font myFont1 = new Font(FontFamily.GenericSerif, 35, FontStyle.Italic,
GraphicsUnit.Pixel);
Size mySize1 = g1.MeasureString(this.menuItem1.Text, myFont1).ToSize();

g1.FillRectangle(new SolidBrush(SystemColors.Control), 0,
SystemInformation.CaptionHeight, this.ClientRectangle.Width,
mySize1.Height+5);
ReleaseDC( m.HWnd, hDC );
}
break;
}
base.WndProc (ref m);
}
This sample is not perfect, which need a lot work to be done. Hope it helps
you.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
G

Guest

Jeffrey,

Thanks for the information. I will try this out. If I have further
questions on this I will post a new specific question.

Thanks,
Dave

Jeffrey Tan said:
Hi Dave,

Sorry for letting you wait for so long.

After doing a lot of research, I found that we should first handle
WM_NCCALCSIZE to decrease the client area size. Then the non-client area is
getting larger. Then we should handle the WM_NCPAINT message to paint the
menu and other non-client ourselves.
I have writen a little sample for you to show to handle these 2 messages.

[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}

enum WM_MESSAGE
{
WM_NCCALCSIZE = 131,
WM_NCPAINT = 133,
WM_NCHITTEST = 132,
WM_NCLBUTTONDOWN = 161,
}

[StructLayout(LayoutKind.Sequential)]
struct NCCALCSIZE_PARAMS
{
public RECT rgrc0, rgrc1, rgrc2;
public IntPtr lppos;
}
[StructLayout(LayoutKind.Sequential)]
struct WINDOWPOS
{
public IntPtr hwnd;
public IntPtr hwndInsertAfter;
public int x, y;
public int cx, cy;
public int flags;
}

[DllImport("User32.dll")]
private extern static IntPtr GetWindowDC( IntPtr hWnd );

[DllImport("User32.dll")]
private extern static int ReleaseDC( IntPtr hWnd, IntPtr hDC );

private Rectangle _rcButton = Rectangle.Empty;

protected override void WndProc(ref Message m)
{
switch ( m.Msg )
{
case (int)WM_MESSAGE.WM_NCCALCSIZE :

NCCALCSIZE_PARAMS csp;

csp = (NCCALCSIZE_PARAMS)Marshal.PtrToStructure( m.LParam,
typeof(NCCALCSIZE_PARAMS));
Font myFont = new Font(FontFamily.GenericSerif, 35, FontStyle.Italic,
GraphicsUnit.Pixel);
Graphics g=this.CreateGraphics();
Size mySize = g.MeasureString(this.menuItem1.Text, myFont).ToSize();
Console.WriteLine(mySize.Height.ToString());
Console.WriteLine(csp.rgrc0.Top.ToString());
csp.rgrc0.Top =
csp.rgrc0.Top -SystemInformation.MenuHeight+mySize.Height;

Console.WriteLine(csp.rgrc0.Top.ToString());
Marshal.StructureToPtr( csp, m.LParam, false );
break;

case (int)WM_MESSAGE.WM_NCPAINT :
{
IntPtr hDC = GetWindowDC( m.HWnd );
Graphics g1 = Graphics.FromHdc( hDC );
Font myFont1 = new Font(FontFamily.GenericSerif, 35, FontStyle.Italic,
GraphicsUnit.Pixel);
Size mySize1 = g1.MeasureString(this.menuItem1.Text, myFont1).ToSize();

g1.FillRectangle(new SolidBrush(SystemColors.Control), 0,
SystemInformation.CaptionHeight, this.ClientRectangle.Width,
mySize1.Height+5);
ReleaseDC( m.HWnd, hDC );
}
break;
}
base.WndProc (ref m);
}
This sample is not perfect, which need a lot work to be done. Hope it helps
you.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Dave,

Thanks very much for your feedback!

This article below shows how to do the non-client drawing for window
caption:
http://www.codeproject.com/gdi/customcaption.asp

Althrough it is writen in C++, I think it still gives a lot of hint of how
to resolve the main menu bar issue. For your information.

Anyway, if still need help, please feel free to tell me, I will try my best
to help you, thanks!

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top