为Windows窗口标题栏添加新按钮

为Windows窗口标题栏添加新按钮,第1张

对于我们熟悉的标准windows窗口来讲 标题栏上一般包含有 个按钮 即最大化按钮 最小化按钮和关闭按钮 你想不想在Windows的窗口标题栏上添加一个新的自定义按钮 满足你的个性化需求 从而也使自己的窗口更具特色呢?

下面我们就讨论一下在delphi中如何给窗口的标题栏上添加新的按钮

一 实现起来要定义以下过程

定义DrawCaptButton过程 这个过程的功能是在指定的位置画出按钮

在过程中要使用win 函数GetSystemMetrics得到窗口的大小和标题按钮的大小 使用delphi函数Bounds定义一个矩形 这个矩形就是新按钮的位置 再定义一个小的矩形 这个矩形是为了填写文本 最后就调用delphi中比较有用的函数drawbuttonface把按钮画出来

每次我们对窗口进行 *** 作 例如 最大化 *** 作或最小化 *** 作 新按钮就会消失 为了解决这个问题 我们对所有的消息要进行处理 给每个消息编写一个过程对按钮进行重画

A 定义WMNCPaint(var Msg MNCPaint)过程 处理消息WM_NCPaint

B 定义WMNCActivate(var Msg MNCActivate)过程 处理消息WM_NCACTIVATE

C 定义WMSetText(var Msg MSetText)过程 处理消息WM_SETTEXT

D 定义WMNCHitTest(var Msg MNCHitTest)过程 处理消息WM_NCHITTEST

E 定义WMNCLButtonDown(var Msg : MNCLButtonDown)过程 处理消息WM_NCLBUTTONDOWN

   二 具体的源程序如下

我们结合源程序来讲述过程的实现 从中可以看出程序对win 函数的调用 以及drawbuttonface函数的使用方法

 unit Main interface

 uses Windows Buttons Messages SysUtils Classes Graphics Controls Forms Dialogstype TForm = class(TForm) procedure FormResize(Sender: TObject) private CaptionBtn : TRect procedure DrawCaptButton procedure WMNCPaint(var Msg : MNCPaint)message WM_NCPaint procedure WMNCActivate(var Msg : MNCActivate)message WM_NCACTIVATE procedure WMSetText(var Msg : MSetText)message WM_SETTEXT procedure WMNCHitTest(var Msg : MNCHitTest)message WM_NCHITTEST procedure WMNCLButtonDown(var Msg : MNCLButtonDown)message WM_NCLBUTTONDOWN public{ Public declarations } end

 varForm : TForm

implementation

const htCaptionBtn = htSizeLast +  {$R * DFM}

procedure TForm DrawCaptButtonfile://drawcapbuttton过程的具体实现 varxFrame yFrame xSize ySize : IntegerR : TRect beginxFrame := GetSystemMetrics(SM_CXFRAME)yFrame := GetSystemMetrics(SM_CYFRAME)file://把窗口的宽度置于变量xFrame 把窗口的高度置于变量yFramexSize:= GetSystemMetrics(SM_CXSIZE)ySize:= GetSystemMetrics(SM_CYSIZE)// 把标题栏按钮的宽度置于变量xSize 把标题栏按钮的高度置于变量ySizeCaptionBtn := Bounds(Width xFrame *xSize + yFrame + xSize ySize )file://定义出新的标题按钮的位置 值放在变量CaptionBtn中Canvas Handle := GetWindowDC(Self Handle)file://得到窗口的句柄 Canvas Font Name := Symbol Canvas Font Color := clBlueCanvas Font Style := [fsBold]Canvas Pen Color := clYellowCanvas Brush Color := clBtnFacefile://定义画布的字体 画笔 刷子等属性 tryDrawButtonFace(Canvas CaptionBtn bsAutoDetect False False False)file://在画布上画出定义的按钮

R := Bounds(Width xFrame * xSize + yFrame + xSize ySize )file://在新按钮上画出一个小矩形with CaptionBtn doCanvas TextRect(R R Left + R Top W )file://在上面画出的小矩形上填写一个字符 w 字符finallyReleaseDC(Self Handle Canvas Handle)Canvas Handle := file://容错处理 如果出现异常 把句柄释放掉endend

 procedure TForm WMNCPaint(var Msg : MNCPaint)//WMNCPaint过程的具体实现 该过程在绘制窗口时被调用 begininherited//继承默认的消息处理程序DrawCaptButton//对按钮进行重画 end

 procedure TForm (var Msg : MNCActivate) // WMNCActivate过程与WMNCPaint过程实现方法相同 该过程在窗口的非客户区要更改为激活状态或非激活状态时被调用 begininheritedDrawCaptButton end

 procedure TForm WMSetText(var Msg : MSetText) // WMSetText过程与WMNCPaint过程实现方法相同 该过程在设置窗口的文本时被调用 begininheritedDrawCaptButton end

 procedure TForm WMNCHitTest(var Msg : MNCHitTest) file:// WMNCHitTest过程与WMNCPaint过程实现方法相同 该过程在光标移动或鼠标按钮被按下或鼠标按钮被释放时调用 begininheritedwith Msg doif PtInRect(CaptionBtn Point(XPos Left YPos Top)) then Result := htCaptionBtn//判断鼠标所在位置是否在新按钮的矩形范围内 如果在返回新按钮的标识值end

 procedure TForm WMNCLButtonDown(var Msg : MNCLButtonDown)// WMNCLButtonDown过程与WMNCPaint过程实现方法相同 当光标处于窗口非客户区范围内鼠标左键被按下时调用该过程 begininheritedif (Msg HitTest = htCaptionBtn) then ShowMessage( 你点击的是标题栏上的新按钮 ) file://判断被点击的是否是新按钮 如果是显示上面的信息 在这里你可以按你的需要编写程序代码end procedure TForm FormResize(Sender: TObject)begin Perform(WM_NCACTIVATE Word(Active) ) file://如果窗口大小改变则重画标题栏end end

三 程序执行结果

如图 所示标题栏上出现一个新按钮

lishixinzhi/Article/program/Delphi/201311/25072

在这里,最关键的一点就是,大家不要被传统知识误导:真的认为它是一个按钮。有句柄(handle)的控件当然不能放在标题栏上了。有经验的程序员 用Spy++跟踪一下的话,马上就会发现其中的秘密。它并不是一个按钮,只不 过是处理成按钮的样子罢了。

在具体实例之前,我们应该知道几个关于标题栏的重要的消息:

WM_NCPAINT:重画标题栏消息。我们必须截住它,可以在这里重画按钮;

WM_NCLBUTTONDOWN:在标题栏上按下鼠标左键消息。我们可以截住它,在标题栏上画出按钮按下的样子,并且可以在其中进行自已的单击事件的处理,使得它像一个按钮;

WM_NCLBUTTONUP:在标题栏上释放鼠标左键消息。我们可以截住它,在标题栏上画出按钮d起的样子;

WM_NCLBUTTONDBLCLK:在标题栏上双击鼠标左键消息。我们可以截住它,当在按钮区域双击时,我们就该使其无效,从而避免窗体执行最大化和还原 *** 作。

WM_NCRBUTTONDOWN:在标题栏上按下鼠标右键消息。我们可以截住它,当在按钮区域双击时,我们就该使其无效,从而避免d出窗体按制菜单。

WM_NCMOUSEMOVE:在标题栏上移动鼠标消息。我们可以截住它,当鼠标移出按钮区域时,我们就必须画出按钮没有被按下,即凸起时的样子。

WM_NCACTIVATE:当标题栏在激活与非激活之间切换时收到该消息。我们可以截住它,当该窗口处理激活状态时,我们可以做一些事情,比如说将我们的标题栏按钮上的字体变灰或变黑来指示该窗口的当前状态。下面我没有加入该项功能,如果大家感兴趣的话,可以自己完成。

(大家从这里可以发现,标题栏的消息都是WM_NC开头的)

知道了原理之后,相信大家一定可以做出更漂亮的按钮来。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/bake/11682897.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-17
下一篇2023-05-17

发表评论

登录后才能评论

评论列表(0条)

    保存