Coder12345
Coder12345

Reputation: 3753

Resizing main menu for high DPI/font size

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.

Upvotes: 1

Views: 5829

Answers (5)

Dmitry Orlov
Dmitry Orlov

Reputation: 1

 #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;
 }

Upvotes: 0

Masoud.Ebrahimi
Masoud.Ebrahimi

Reputation: 309

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

Upvotes: 1

Sertac Akyuz
Sertac Akyuz

Reputation: 54772

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;

Upvotes: 3

David Heffernan
David Heffernan

Reputation: 612794

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.

Upvotes: 1

nullptr
nullptr

Reputation: 11058

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.

Upvotes: 3

Related Questions