对于我们熟悉的标准windows窗口来讲标题栏上一般包含有个按钮即最大化按钮最小化按钮和关闭按钮你想不想在Windows的窗口标题栏上添加一个新的自定义按钮满足你的个性化需求从而也使自己的窗口更具特色呢? 下面我们就讨论一下在delphi中如何给窗口的标题栏上添加新的按钮 一实现起来要定义以下过程 定义DrawCaptButton过程这个过程的功能是在指定的位置画出按钮 在过程中要使用win函数GetSystemMetrics得到窗口的大小和标题按钮的大小使用delphi函数Bounds定义一个矩形这个矩形就是新按钮的位置再定义一个小的矩形这个矩形是为了填写文本最后就调用delphi中比较有用的函数drawbuttonface把按钮画出来 每次我们对窗口进行操作例如最大化操作或最小化操作新按钮就会消失为了解决这个问题我们对所有的消息要进行处理给每个消息编写一个过程对按钮进行重画 A定义WMNCPaint(var MsgTWMNCPaint)过程处理消息WM_NCPaint B定义WMNCActivate(var Msg TWMNCActivate)过程处理消息WM_NCACTIVATE C定义WMSetText(var MsgTWMSetText)过程处理消息WM_SETTEXT D定义WMNCHitTest(var Msg TWMNCHitTest)过程处理消息WM_NCHITTEST E定义WMNCLButtonDown(var Msg : TWMNCLButtonDown)过程处理消息WM_NCLBUTTONDOWN 二 具体的源程序如下 我们结合源程序来讲述过程的实现从中可以看出程序对win函数的调用以及drawbuttonface函数的使用方法 unit Main; interface uses Windows Buttons Messages SysUtils Classes Graphics Controls Forms Dialogs; type TForm = class(TForm) procedure FormResize(Sender: TObject); private CaptionBtn : TRect; procedure DrawCaptButton; procedure 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 Form: TForm; implementation const htCaptionBtn = htSizeLast + ; {$R *DFM} procedure TFormDrawCaptButton; file://drawcapbuttton过程的具体实现 var xFrame yFrame xSize ySize : Integer; R : TRect; begin xFrame := GetSystemMetrics(SM_CXFRAME); yFrame := GetSystemMetrics(SM_CYFRAME); file://把窗口的宽度置于变量xFrame把窗口的高度置于变量yFrame xSize:= GetSystemMetrics(SM_CXSIZE); ySize:= GetSystemMetrics(SM_CYSIZE); // 把标题栏按钮的宽度置于变量xSize把标题栏按钮的高度置于变量ySize CaptionBtn := Bounds(Width xFrame *xSize + yFrame + xSize ySize ); file://定义出新的标题按钮的位置值放在变量CaptionBtn中 CanvasHandle := GetWindowDC(SelfHandle); file://得到窗口的句柄 CanvasFontName := Symbol; CanvasFontColor := clBlue; CanvasFontStyle := [fsBold]; CanvasPenColor := clYellow; CanvasBrushColor := clBtnFace; file://定义画布的字体画笔刷子等属性 try DrawButtonFace(Canvas CaptionBtn bsAutoDetect False False False); file://在画布上画出定义的按钮 R := Bounds(Width xFrame * xSize + yFrame + xSize ySize ); file://在新按钮上画出一个小矩形 with CaptionBtn do CanvasTextRect(R RLeft + RTop W); file://在上面画出的小矩形上填写一个字符w字符 finally ReleaseDC(SelfHandle CanvasHandle); CanvasHandle := ; file://容错处理如果出现异常把句柄释放掉 end; end; procedure TFormWMNCPaint(var Msg : TWMNCPaint); //WMNCPaint过程的具体实现该过程在绘制窗口时被调用 begin inherited;//继承默认的消息处理程序 DrawCaptButton;//对按钮进行重画 end; procedure TForm (var Msg : TWMNCActivate); // WMNCActivate过程与WMNCPaint过程实现方法相同该过程在窗口的非客户区要更改为激活状态或非激活状态时被调用 begin inherited; DrawCaptButton; end; procedure TFormWMSetText(var Msg : TWMSetText); // WMSetText过程与WMNCPaint过程实现方法相同该过程在设置窗口的文本时被调用 begin inherited; DrawCaptButton; end; procedure TFormWMNCHitTest(var Msg : TWMNCHitTest); file:// WMNCHitTest过程与WMNCPaint过程实现方法相同该过程在光标移动或鼠标按钮被按下或鼠标按钮被释放时调用 begin inherited; with Msg do if PtInRect(CaptionBtn Point(XPos Left YPos Top)) then Result := htCaptionBtn;//判断鼠标所在位置是否在新按钮的矩形范围内如果在返回新按钮的标识值 end; procedure TFormWMNCLButtonDown(var Msg : TWMNCLButtonDown); // WMNCLButtonDown过程与WMNCPaint过程实现方法相同当光标处于窗口非客户区范围内鼠标左键被按下时调用该过程 begin inherited; if (MsgHitTest = htCaptionBtn) then ShowMessage(你点击的是标题栏上的新按钮); file://判断被点击的是否是新按钮如果是显示上面的信息在这里你可以按你的需要编写程序代码 end; procedure TFormFormResize(Sender: TObject); begin Perform(WM_NCACTIVATE Word(Active) ); file://如果窗口大小改变则重画标题栏 end; end 三 程序执行结果 如图所示标题栏上出现一个新按钮 图 通过以上的示例过程相信你能根据自己的具体要求利用Delphi设计出别具特色的Windows窗口来! |