DELPHI的奇异菜单的编写
DELPHI的奇异菜单的编写
翻译者: 李均宇 email: e271828@163.net,okMyDelphi@163.net
Custom Menus, Text, Lines / Delphi 4, 5
自定义菜单,文本,线/ Delphi 4, 5
Fancy Menus, etc.
奇异菜单,等等
Custom Menus, Rotated Text, and Special Lines
自定义菜单,旋转文本,和特殊的线条
Before Delphi 4, it was difficult to customize a menu (add a bitmap, change a font, etc.), because owner drawing (i.e. custom drawing) - although implemented by Windows - was not exposed by the TMainMenu class. Since Delphi 4, however, this situation has been rectified, and we can have our way with menus.
在Delphi 4之前,要想自定义一个菜单是困难的(例如加上一个BMP图像,改变字体等),因为owner drawing事件(也就是custom drawing事件)-虽然是由Windows来执行,但是却并不在TMainMenu class中出现.自从Delphi 4开始后,
这种情况有了改变,我们于是有了可以自定义菜单的功能了.
This article will highlight some techniques you can use to customize the appearance of menus in your Delphi applications. Well discuss text placement, menu sizing, font assignment, and using bitmaps and shapes to enhance a menus appearance. Just for fun, this article also features techniques for creating rotated text and custom lines. All of the techniques discussed in this article are demonstrated in projects available for download。
这篇文章将主要着重论述可以用来自定义你的DELPHI应用程序中的菜单的外形的一些技术巧.我们将论述文本的放置,菜单的大小,字体的设置,以及用BMP文件和SHAPE控件来加强菜单的显示效果。仅仅出于娱乐的目的,这篇文章也将对旋转的文本和自定义线条的技巧进行特写。这篇文章所论述到的所有技巧都已在工程文件中通过了调试并且可以到网上下载这些工程文件。
Custom Fonts and Sizes
设置字体和大小
To create a custom menu, set the OwnerDraw property of the menu component -TMainMenu or TPopupMenu - to True, and provide event handlers for its OnDrawItem and OnMeasureItem events. For example, an OnMeasureItem event handler is declared like this:
为了创建一个自定义的菜单,将TmainMenu或TpopupMenu组件的OwnerDraw属性设为TRUE,并且创建它的OnDrawItem和OnMeasureItem的事件过程。例如,一个OnMeasureItem事件过程可以声明如下:
procedure TForm1.Option1MeasureItem(Sender: TObject;
ACanvas: TCanvas; var Width, Height: Integer);
Set the Width and Height variables to adjust the size of the menu item. The OnDrawItem event handler is where all the hard work is done; its where you draw your menu and make any special settings. To draw the menu option with Times New Roman font, for example, you should do something like this:
设置上面事件过程中的菜单项的Width 和Height变量到合适的大小.所有主要的事情都要由OnDrawItem事件来触发;它是你要重画菜单和作任何特殊设置的地方。举例,为了用Times New Roman字体来重画菜单项,你可以如下面这样做:
procedure TForm1.Times1DrawItem(Sender: TObject;
ACanvas: TCanvas; ARect: TRect; Selected: Boolean);
begin
ACanvas.Font.Name := Times New Roman;
ACanvas.TextOut(ARect.Left+1, ARect.Top+1,
(Sender as TMenuItem).Caption);
end;
This code is flawed, however. If its run, the menu caption will be drawn aligned with the left border of the menu. This isnt default Windows behavior; usually, theres a space to put bitmaps and checkmarks in the menu. Therefore, you should calculate the space needed for this checkmark with code like that shown in Figure 1. Figure 2 shows the resulting menu.
然而这段代码是有缺陷的。如果运行这段代码,菜单项的标题(caption)会在菜单项中靠左对齐.这并不是Windows的默认行为,通常,在菜单左边那儿有一个空间用来放置BMP图像和选择标志的。因此,你应该用代码计算要多少空间来放置这个选择标志的,就象Figure 1中显示的那样。Figure 2显示的是菜单的运行效果。
procedure TForm1.Times2DrawItem(Sender: TObject;
ACanvas: TCanvas; ARect: TRect; Selected: Boolean);
var
dwCheck : Integer;
MenuCaption : string;
begin
// Get the checkmark dimensions.
获取选择标志所需的像素数
dwCheck := GetSystemMetrics(SM_CXMENUCHECK);
// Adjust left position.
调整左边位置
ARect.Left := ARect.Left + LoWord(dwCheck) + 1;
MenuCaption := (Sender as TMenuItem).Caption;
// The font name is the menu caption.
ACanvas.Font.Name := Times New Roman;
// Draw the text.
画文本
DrawText(ACanvas.Handle, PChar(MenuCaption),
Length(MenuCaption), ARect, 0);
end;
Figure 1: This OnDrawItem event handler places menu item text correctly.
[译者省略掉所有的FigureS,以下同样]
Figure 2: A menu drawn with custom fonts.
If the text is too large to be drawn in the menu, Windows will cut it to fit. Therefore, you should set the menu item size so all the text can be drawn. This is the role of the OnMeasureItem event handler shown in Figure 3.
如果文本太长,Windows会自动裁剪长度来合适。因此,你应该设置菜单大小使所有的文本都可以显示出来。在OnMeasureItem事件中也应如此,这在Figure 3可以看到。
procedure TForm1.Times2MeasureItem(Sender: TObject;
ACanvas: TCanvas; var Width, Height: Integer);
begin
ACanvas.Font.Name := Times New Roman;
ACanvas.Font.Style := [];
// The width is the space of the menu check
这个长度是菜单的选择标志的长度
// plus the width of the item text.
再加上菜单项的长度
Width := GetSystemMetrics(SM_CXMENUCHECK) +
ACanvas.TextWidth((Sender as TMenuItem).Caption) + 2;
Height := ACanvas.TextHeight(
(Sender as TMenuItem).Caption) + 2;
end;
Figure 3: This OnMeasureItem event handler insures that an item fits in its menu.
Custom Shapes and Bitmaps
设置图形和位图
Its also possible to customize menu items by including bitmaps or other shapes. To add a bitmap, simply assign a bitmap file to the TMenuItem.Bitmap property - with the Object Inspector at design time, or with code at run time. To draw colored rectangles as the caption of a menu item, you could use the OnDrawItem event handler shown in Figure 4. Figure 5 shows the result.
用位图和其它图形来设置菜单是可能的事.要想添加一个位图,只需在设计时简单地在Object Inspector中把一个BMP文件赋给TmenuItem的Bitmap属性即可,或者运行时用代码赋值也可以。要想用一个有颜色的矩形来代替菜单标题,你可以使用OnDrawItem事件,例如在Figure 4中显示的那样。在Figure 5中显示的是结果。
procedure TForm1.ColorDrawItem(Sender: TObject;
ACanvas: TCanvas; ARect: TRect; Selected: Boolean);
var
dwCheck : Integer;
MenuColor : TColor;
begin
// Get the checkmark dimensions.
dwCheck := GetSystemMetrics(SM_CXMENUCHECK);
ARect.Left := ARect.Left + LoWord(dwCheck);
// Convert the caption of the menu item to a color.
将菜单项的标题转换为颜色
MenuColor :=
StringToColor((Sender as TMenuItem).Caption);
// Change the canvas brush color.
改变画布canvas的画笔颜色
ACanvas.Brush.Color := MenuColor;
// Draws the rectangle. If the item is selected,
画矩形,如果菜单项是被选择的
// draw a border.
画边框
if Selected then
ACanvas.Pen.Style := psSolid
else
ACanvas.Pen.Style := psClear;
ACanvas.Rectangle(ARect.Left, ARect.Top,
&nb
补充:软件开发 , Delphi ,