Entry No.
516
|
VCL - Standard - Menus - TMenuItem
If you assign an image list to a TMainMenu, and the height of your imagelist
is small compared to the height of your menu text, the text gets cramped
together and some of the text actually gets chopped off.
|
|
| 1.02 |
2.01 |
3.0 |
3.01 |
3.02 |
4.0 |
4.01 |
4.02 |
4.03 |
5.0 |
5.01 |
6.0 |
6.01 |
6.02 |
Kylix 1.0 |
| N/A | N/A | N/A | N/A | N/A | Exists | Exists | Exists | Exists | Exists | Exists | Exists | Exists | Exists | N/A |
|
|
|
Description | |
|
Reported by Luu Tran; checked by Reinier Sterkenburg
D4 is not respecting the system metrics settings for menu items. It seems
only to consider the height of the bitmap and not the text and proper vertical
spacing between menu items.
To reproduce, create an imagelist with dimension 16x16 or so. In Windows
Control panel, use Large Font display, and set menu text to MS Sans Serif
10. You will see your D4 menus with bitmaps are cramped vertically,
compared to regular menus. |
|
|
User-contributed comments | |
Luu Tran 24 Nov 2001 09:30 PM GMT |
The problem is procedure TMenuItem.MeasureItem only looks at the ImageList's height when ImageList is assigned and doesn't bother with the system's setting. This is fine normally but if your menu font is bigger than the glyphs, the text gets bunched together and doesn't look right. To see what I mean, go to Control Panel and change the menu font to something large, like 16pt then look at the menus in the Delphi IDE.
Here's a VCL hack to remedy this cosmetic bug
Delphi 4, update 3
Menus.pas
procedure TMenuItem.MeasureItem(ACanvas: TCanvas; var Width, Height: Integer);
---old
if GetParentComponent is TMainMenu then
begin
TopLevel := True;
GetMenuSize;
end
---new
GetMenuSize; always call getmenusize!
if GetParentComponent is TMainMenu then
begin
TopLevel := True;
end
---old
else if Assigned(ImageList) and ((ImageIndex > -1) or not TopLevel) then
begin
Width := ImageList.Width;
if not TopLevel then
Height := ImageList.Height;
DrawGlyph := True;
end
---new
else if Assigned(ImageList) and ((ImageIndex > -1) or not TopLevel) then
begin
Width:=ImageList.Width;
if not TopLevel then
// use ImageList's height only if larger than system's menu height!
if ImageList.Height>Height then Height:=ImageList.Height;
DrawGlyph := True;
end
|
Next, modify DrawItem to center the glyph vertically should it be smaller than the menuitem.
procedure TMenuItem.DrawItem(ACanvas: TCanvas; ARect: TRect; Selected: Boolean);
---old
if ParentMenu is TMenu then
Alignment := paLeft
else if ParentMenu is TPopupMenu then
Alignment := TPopupMenu(ParentMenu).Alignment
else
Alignment := paLeft;
GlyphRect.Left := ARect.Left + 1;
GlyphRect.Top := ARect.Top + //1
---new
if ParentMenu is TMenu then
Alignment := paLeft
else if ParentMenu is TPopupMenu then
Alignment := TPopupMenu(ParentMenu).Alignment
else
Alignment := paLeft;
GlyphRect.Left := ARect.Left + 1;
GlyphRect.Top := ARect.Top +
(Max( ImageList.Height, ARect.Bottom-ARect.Top+1) - ImageList.Height)
div 2;
|
Note: you need to add Math to the uses clause to use the Max function
CAVEATS: This SEEMS to work. I haven't done anything in the case of bitmap glyphs instead of ImageList. So far, I haven't seen any ill effect but that's always a possibility when hacking the VCL!
|
|