转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
DELPHI的奇异菜单的编写         ★★★★

DELPHI的奇异菜单的编写

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1710 更新时间:2009/4/23 18:38:56



                                  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. We''''ll discuss text placement, menu sizing, font assignment, and using bitmaps and shapes to enhance a menu''''s 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; it''''s 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 it''''s run, the menu caption will be drawn aligned with the left border of the menu. This isn''''t default Windows behavior; usually, there''''s 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
设置图形和位图
It''''s 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,
                    ARect.Right, ARect.Bottom);
end;

Figure 4: Using the OnDrawItem event to draw colored rectangles on menu items. 
Figure 5: A menu featuring colored rectangles as items.

There''''s just one catch. If you''''re using Delphi 5, you must set the menu''''s AutoHotkeys property to maManual. If you leave it as the default, maAutomatic, Delphi will add an ampersand character (&) to the caption, which will break this code. Another solution is to remove the ampersand with the StripHotKey function.
比较流行的做法是,如果你用的是Delphi 5,你应设置菜单的AutoHotkeys属性为maManual。如果你不这样做,而让缺省值maAutomatic留着,Delphi会自动添加一个&号给标题,这将破坏这些代码。另一个解决办法是用StripHotKey函数来移去&号。
Another way to use the OnDrawItem and OnMeasureItem events is to write text vertically on a menu (as shown in Figure 7). To do this, you must create a rotated font. This is only possible using the Windows API function CreateFont or CreateLogFont (see the "Rotated Text" tip later in this article). Then you must draw it in the OnDrawItem event handler. This event is fired every time a menu item is drawn, so if a menu has 20 items, it will be drawn 20 times. To make it faster, the vertical text will be drawn only when the menu item is selected (since there''''s is only one menu item selected at a time). Figure 6 shows how this is implemented with code, and Figure 7 shows the run-time result.
OnDrawItem和OnMeasureItem事件的另一个用途是用来在菜单侧旁写垂直的文字(例如在Figure 7显示的那样)。为了做到这样,你必须创建一个旋转的字体。唯一办法是用Windows API的CreateFont或者CreateLogFont函数(稍后看本文中的“旋转的文字”技巧)。于是你必须在OnDrawItem事件中重画它。这个事件在菜单项被拉出时执行,所以如果一个菜单有20项,那么它将被执行20次。为了使它快些,这垂直的文字可以在菜单项被选择时才重画一次(虽然每次只有一个菜单项被选择)。Figure 6显示的是代码如何执行,而Figure 7显示的是运行结果。

procedure TForm1.VerticalDrawItem(Sender: TObject;
  ACanvas: TCanvas; ARect: TRect; Selected: Boolean);
var
  lf : TLogFont;
  OldFont : HFont;
  clFore, clBack : LongInt;
  Rectang : TRect;
  dwCheck : LongInt;
  MenuHeight : Integer;
begin
  dwCheck := GetSystemMetrics(SM_CXMENUCHECK);
  // This will be done once, when the item is selected.
当菜单项被选中时,这将被执行
   if Selected then begin
    // Create a rotated font.
创建一个旋转的字体
    FillChar(lf, SizeOf(lf), 0);
    lf.lfHeight := -14;
    lf.lfEscapement := 900;
    lf.lfOrientation := 900;
    lf.lfWeight := Fw_Bold;
    StrPCopy(lf.lfFaceName, ''''Arial'''');
    // Select this font to draw.
选取这个字体来画
    OldFont := SelectObject(ACanvas.Handle,
               &

[1] [2] [3]  下一页


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台