第19期《在系统菜单上添加自己的菜单项》一文,大家都已经拜读了吧?实际上,诸如此类的问题还有很多,对于初学者来说,或许不知如何下手,因为初学者学习的参考书往往着重介绍某种编程语言,而没有详细讲解Windows的基础知识。大家一直在Windows的框框里,却不懂得消息、钩子,对API函数也不熟悉。所以,往往初学者自认为学好了一门语言,到真正使用的时候却一下子捉襟见肘起来了。因此,我建议初学者在学习时,再找一本诸如《Windows编程内幕》之类的书读一读,对提高自己的水平大有裨益哦。使用某个软件的时候,也要想一想,作者是如何实现软件的功能的,还应该站在作者的角度考虑一下,软件还有什么要改进的地方。这样,你的功夫就会越来越深啦! ReadBook是一款优秀的软件,我相信读者中也有不少人在使用它。关于它的病毒自我监测功能的实现,《电脑爱好者》已经讨论过了。今天,我想给大家谈谈它是如何在窗口的标题区添加按钮的。有可能我的实现方法和ReadBook的不一样,没关系,大家互相学习吧! 程序主要用到了几个消息,除了程序中消息函数定义的方法外,大家还要注意每一个消息函数中都调用了inherited,原因不用我饶舌了吧?程序中还调用了GetSystemMetrics、DrawButtonFace等几个函数。我本来在程序中详细地加了注释,不过我后来都删除了,因为Delphi的帮助文件可以说是最好的注释了。如果你有什么不懂之处,别忘了按“F1”键,怎么样,一切都写得清清楚楚的吧? 把下边的程序输进计算机,自己用帮助文件研究吧。记住,学习编程可不能偷懒哦。 unit Unit1; interface uses Windows, Buttons, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure FormResize(Sender: TObject); private { Private declarations } CaptionBtn:TRect; procedure DrawCaptButton; rocedure WMNCPaint(var Msg:TWMNCPaint);message WM_NCPaint; procedure WMNCActivate(var Msg:TWMNCActivate);message WM_NCActivate; procedure WMSetText(var Msg:TWMSetText);message WM_SetText; procedure WMNCHitTest(var Msg:TWMNCHitTest);message WM_NCHittest; procedure WMNCLButtonDown(var Msg:TWMNCLButtonDown);message WM_NCLButtonDown; public { Public declarations } end; var Form1: TForm1; implementation const htCaptionBtn=htSizeLast+1; {$R *.DFM} procedure TForm1.DrawCaptButton; var xFrame,yFrame,xSize,ySize:Integer; R:TRect; begin xFrame:=GetSystemMetrics(SM_CXFRAME); yFrame:=GetSystemMetrics(SM_CYFRAME); xSize:=GetSystemMetrics(SM_CXSIZE); ySize:=GetSystemMetrics(SM_CYSIZE); CaptionBtn:=Bounds(Width-xFrame-4*xSize+2,yFrame+2,xSize+1,ySize-4); Canvas.Handle:=GetWindowDC(Self.Handle); Canvas.Font.Name:='宋体'; Canvas.Font.Color:=clBlack; Canvas.Pen.Color:=clYellow; Canvas.Brush.Color:=clBtnFace; try DrawButtonFace(Canvas,CaptionBtn,1,bsAutoDetect,False,False,False); R:=Bounds(Width-xFrame-4*xSize+3,yFrame+3,xSize-2,ySize-7); with CaptionBtn do Canvas.TextRect(R,R.Left+2,R.Top+2,'?'); finally ReleaseDC(Self.Handle,Canvas.Handle); Canvas.Handle:=0; end; end; procedure TForm1.WMNCActivate(var Msg: TWMNCActivate); begin inherited; DrawCaptButton; end; procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest); begin inherited; with Msg do if PtInRect(CaptionBtn,Point(xPos-Left,yPos-Top)) then Result:=htCaptionBtn; end; procedure TForm1.WMNCLButtonDown(var Msg: TWMNCLButtonDown); begin inherited; if(Msg.HitTest=htCaptionBtn)then showmessage('成功了!'); end; procedure TForm1.WMNCPaint(var Msg: TWMNCPaint); begin inherited; DrawCaptButton; end; procedure TForm1.WMSetText(var Msg: TWMSetText); begin inherited; DrawCaptButton; end; procedure TForm1.FormResize(Sender: TObject); begin Perform(WM_NCACTIVATE,Word(Active),0); end; end. 仔细研究一下程序中有关计算的几个句子,试着改变某个数字看一看,这将有助于你理解程序。 本文中的程序在Windows98/WindowsMe环境下使用Delphi5/ Delphi6调试通过。 |