1

I have an issue with font height in standard main menu/popup menu when it contains images. Looks like this.

Large Font Issue

When there are no images, there are no problems as displayed above. Main menu uses TImageList with image width/height set to 16.

So I want to preserve image size at 16x16 and center it, to get something like this:

Large Font Issue corrected

How can I read the font height of the main menu and adjust images in TImageList accordingly? One idea I have is to copy images from one TImageList to another with larger image width/height but I still need to determine proper size from the font size. How do I do that?

UPDATE

I solved this by examining SystemParametersInfo - SPI_GETNONCLIENTMETRICS value and using the iMenuHeight value for TImageList Width/Height. As images are deleted after changing Width/Height, I copied another to another TImageList. Works exactly as it should. Thank you everyone for your most helpful answers.

UPDATE 2

After examining the problem futher the solution which I marked as correct down there is giving better result so I switched to that one instead. Tested on Win7 and XP, appears to be working properly.

2
  • Which Delphi version? Which OS? Frankly Delphi RTL menu code sucks. Sort of works on XP, but hopeless on Vista+. I always replace it on Vista+ with my own code that lets the system draw the menus and so does it right. Commented Dec 29, 2013 at 12:53
  • I use 2010 version and OS is... all of them. XP, Vista, Win7 and 8. I already can fix the above with resizing image size but I most likely need the way to determine font size that the menu uses. Commented Dec 29, 2013 at 12:54

5 Answers 5

3

You can get the height of Screen.MenuFont by selecting it to a temporary DC:

function GetMenuFontHeight: Integer; var DC: HDC; SaveObj: HGDIOBJ; Size: TSize; begin DC := GetDC(HWND_DESKTOP); try SaveObj := SelectObject(DC, Screen.MenuFont.Handle); GetTextExtentPoint32(DC, '|', 1, Size); // the character doesn't really matter Result := Size.cy; SelectObject(DC, SaveObj); finally ReleaseDC(HWND_DESKTOP, DC); end; end; 
Sign up to request clarification or add additional context in comments.

5 Comments

That's fine for XP, and Windows Classic, but not relevant to themed menus. I think.
@David - That's what the VCL use as the menu font. I think.. Edit: I can verify setting font name of Screen.FontMenu, the menu appearance changes (W7 aero).
Not for themed menus, Vista+. That uses the theme API. Although the Delphi RTL moronically does user drawn when you have images and screws it up in many different ways. Instead of doing the sensible thing and letting the system draw the menus.
AFAIK, best measuremement string is 'Wy'.
@Free - It really doesn't matter (you can test for '.'). Since I've realized it on W2K I test it on every OS (Not W8 yet).
3

Well, Canvas.GetTextHeight('gh') usually helps to get height of text. But in case of different DPI, you can simply scale by Screen.PixelsPerInch / 96.0.

1 Comment

Thanks for the answer but it does not return font size set for menu items in Windows but font used on the labels of the form. In this case it returns 16 but it should return 24 or so.
1

The text height is probably not what you need to use. I suggest that you use icons whose square dimension is equal to the prevailing small icon size. That's the system metric whose ID is SM_CXSMICON. Retrieve the value by calling GetSystemMetrics passing that ID.

4 Comments

Setting a custom menu font in windows does not effect the small icon size though.
@SertacAkyuz No, it does not. This deals with DPI settings. Probably also need HIGHDPIAWARE. If the user selects a large menu font size in XP, then you really need to fix the broken Delphi VCL menu code.
I solved it by using SPI_GETNONCLIENTMETRICS from SystemParametersInfo and using iMenuHeight value and placing that into TImageList Height/Width (and copying 16x16 images inside). Gives me the perfect height of each menu item as it should be.
@Coder12345 That's unlikely to be relevant for themed Vista+ menus, IIRC
1

You can use Power Menu Component with many advanced features Download from here : http://elvand.com/downloads/DELPHI/PowerMenu.zip

Delphi7-XE2 size=193 KB

2 Comments

Thanks but I am not really looking for replacement component for main menu. Standard main menu works just fine.
does it work with Delphi XE4? And what are some of it's features?
0
 #include <windows.h> int GetMainMenuHeight(void) { NONCLIENTMETRICS Rec; Rec.cbSize = sizeof(Rec); if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, Rec.cbSize, &Rec.cbSize, 0)) return Rec.iMenuHeight; else return -1; } 

1 Comment

Could you please explain what the code you are showing does.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.