如何在真正的标题栏上画按钮并响应事件? (100分)

  • 主题发起人 主题发起人 Cursor
  • 开始时间 开始时间
C

Cursor

Unregistered / Unconfirmed
GUEST, unregistred user!
如何在真正的标题栏上画按钮并响应事件? 弄个假标题栏的方法请不要说了,要做得和<br>OICQ上的最小化按钮、READBOOK 上的满屏按钮那样。请给出完整的源程序!!!
 
&nbsp; &nbsp;将Form的最后一个属性WindowState设置一下。
 
wzs的盗版<br><br>&nbsp;6.在标题栏处画VCL控件(一行解决问题!!!)<br>----------------------------------------------<br>&nbsp; &nbsp;在 form 的onpaint 事件中 <br>&nbsp; &nbsp;控件.pointto(getdc(0),left,top);<br>&nbsp;
 
不是吧,要想在标题栏画东西应该响应WM_NCPAINT这个消息!
 
icewang:不明白我的意思?<br>wjiachun:如何在标题栏(最大化、最小化、关闭按钮的旁边)上画按钮?有pointto这个<br>    函数吗?<br>Bcbhua:是响应按钮的OnMouseOver/Click事件。
 
大家在使用某些软件的过程中,有没有注意到有些软件有一些很有趣的东西。比如说在<br>主窗口的标题栏上居然有一个按钮。在Internet中随处可见这样的小控件。按钮怎么可<br>以加入到非客户区(Client)呢? <br>&nbsp; &nbsp;在这里,最关键的一点就是,大家不要被传统知识误导:真的认为它是一个按钮。有<br>名柄(handle)的控件当然不能放在标题栏上了。有经验的程序员用Spy++跟踪一下的话,<br>马上就会发现其中的秘密。它并不是一个按钮,只不过是处理成按钮的样子罢了。 <br>既然知道了所以然,那么我们为什么不能自己来做一个呢,当然没问题,下面我们就用<br>Delphi来实现它,讲注意我的注解。 <br><br>具体实例之前,我们应该知道几个关于标题栏的重要的消息: <br>WM_NCPAINT:重画标题栏消息。我们必须截住它,可以在这里重画按钮; <br>WM_NCLBUTTONDOWN:在标题栏上按下鼠标左键消息。我们可以截住它,在标题栏上画出<br>按钮按下的样子,并且可以在其中进行自已的单击事件的处理,使得它像一个按钮; <br><br>WM_NCLBUTTONUP:在标题栏上释放鼠标左键消息。我们可以截住它,在标题栏上画出按<br>钮弹起的样子; <br><br>WM_NCLBUTTONDBLCLK:在标题栏上双击鼠标左键消息。我们可以截住它,当在按钮区域<br>双击时,我们就该使其无效,从而避免窗体执行最大化和还原操作。 <br><br>WM_NCRBUTTONDOWN:在标题栏上按下鼠标右键消息。我们可以截住它,当在按钮区域<br>双击时,我们就该使其无效,从而避免弹出窗体按制菜单。 <br><br>WM_NCMOUSEMOVE:在标题栏上移动鼠标消息。我们可以截住它,当鼠标移出按钮区域时,<br>我们就必须画出按钮没有被按下,即凸起时的样子。 <br><br>WM_NCACTIVATE:当标题栏在激活与非激活之间切换时收到该消息。我们可以截住它,<br>当该窗口处理激活状态时,我们可以做一些事情,比如说将我们的标题栏按钮上的字体<br>变灰或变黑来指示该窗口的当前状态。下面我没有加入该项功能,如果大家感兴趣的话,<br>可以自己完成。 <br><br>(大家从这里可以发现,标题栏的消息都是WM_NC开头的) <br>例子:<br>unit main;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, <br>Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls, Menus;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; &nbsp; procedure FormDestroy(Sender: TObject);<br><br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br><br>&nbsp; &nbsp; CBBtnRect: TRect; &nbsp; // Caption Bar Button Rectangle<br>&nbsp; &nbsp; CBBtnFont: TFont; &nbsp; // Caption Bar Button Font<br>&nbsp; &nbsp; procedure DrawCaptionBtn(uEdge: UINT);<br>&nbsp; &nbsp; // 当在标题栏上按下鼠标左按钮时进入该过程<br>procedure WMNcLButtonDown(var m: TMessage); <br>message WM_NCLBUTTONDOWN;<br>&nbsp; &nbsp; // 当在标题栏上放开鼠标左按钮时进入该过程<br>procedure WMNcLButtonUp(var m: TMessage); <br>message WM_NCLBUTTONUP;<br>&nbsp; &nbsp; // 当在标题栏上移动鼠标时进入该过程<br>procedure WMNcMouseMove(var m: TMessage); <br>message WM_NCMOUSEMOVE;<br>&nbsp; &nbsp; // 当在标题栏上双击鼠标左铵钮时进入该过程<br>procedure WMNcLButtonDBLClk<br>(var m: TMessage); message WM_NCLBUTTONDBLCLK;<br>&nbsp; &nbsp; // 当在标题栏上按下鼠标右按钮时进入该过程<br>procedure WMNcRButtonDown(var m: TMessage); <br>message WM_NCRBUTTONDOWN;<br>&nbsp; &nbsp; // 当画标题栏时进入该过程<br>procedure WMNcPaint(var m: TMessage); <br>message WM_NCPAINT;<br>&nbsp; &nbsp; // 当标题栏在激活与非激活之间切换时进入该过程<br>procedure WMNcActivate(var m: TMessage); <br>message WM_NCACTIVATE;<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br><br>procedure TForm1.DrawCaptionBtn(uEdge: UINT);<br>var<br>&nbsp; &nbsp;hCaptionDC: HDC; // 标题条Device Context<br>&nbsp; &nbsp;hOldFont: HFONT; // 原来的字体<br>&nbsp; &nbsp;r: TRect;<br>begin<br>&nbsp; &nbsp; &nbsp;hCaptionDC := GetWindowDC(Self.Handle);<br>&nbsp;// 注意不能用GetDC,那样的话,将得不到标题栏<br>&nbsp;// 的设备上下文<br>&nbsp; &nbsp; &nbsp;//画按钮的样子,如果uEdge=EDGE_RAIS,<br>则画出的样子为凸起;如果<br>//uEdge=EDGE_SUNKEN,则画出的样子为凹下。<br>&nbsp; &nbsp; &nbsp;DrawEdge(hCaptionDC, CBBtnRect, uEdge, <br>BF_RECT or BF_MIDDLE or<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BF_SOFT); <br><br>&nbsp; &nbsp; &nbsp;//设置标题栏的设备上下文为透明状态<br>&nbsp; &nbsp; &nbsp;SetBkMode(hCaptionDC, TRANSPARENT);<br><br>&nbsp; &nbsp; &nbsp;//设置标题栏设备上下文的字体<br>&nbsp; &nbsp; &nbsp;hOldFont:= SelectObject(hCaptionDC, CBBtnFont.Handle);<br><br>&nbsp; &nbsp; &nbsp;//画按钮<br>&nbsp; &nbsp; &nbsp;if uEdge = EDGE_RAISED then<br>&nbsp; &nbsp; &nbsp; &nbsp; DrawText(hCaptionDC, 'Caption Bar Button', <br>18, CBBtnRect, DT_CENTER)<br>&nbsp; &nbsp; &nbsp;else begin<br>&nbsp; &nbsp; &nbsp; &nbsp; r := CBBtnRect;<br>&nbsp; &nbsp; &nbsp; &nbsp; OffsetRect(r, 1, 1); <br>&nbsp; &nbsp; &nbsp; &nbsp; DrawText(hCaptionDC, 'Caption Bar Button', 18, r, DT_CENTER);<br>&nbsp; &nbsp; &nbsp;end;<br><br>&nbsp; &nbsp; &nbsp;//还原为原来的字体<br>&nbsp; &nbsp; &nbsp;SelectObject(hCaptionDC, hOldFont);<br>end;<br><br>procedure TForm1.WMNcActivate(var m: TMessage);<br>begin<br>&nbsp; &nbsp; &nbsp;inherited;<br>&nbsp; &nbsp; &nbsp;DrawCaptionBtn(EDGE_RAISED);<br>end;<br><br><br>procedure TForm1.WMNcPaint(var m: TMessage);<br>begin<br>&nbsp; &nbsp; &nbsp;inherited;<br>&nbsp; &nbsp; &nbsp;DrawCaptionBtn(EDGE_RAISED);<br>end;<br><br><br>procedure TForm1.WMNcLButtonDBLClk(var m: TMessage);<br>var<br>&nbsp; &nbsp;p: TPoint;<br>begin<br>&nbsp; &nbsp; &nbsp;p.x := LOWORD(m.lParam) - Self.Left;<br>&nbsp; &nbsp; &nbsp;p.y := HIWORD(m.lParam) - Self.Top;<br>&nbsp; &nbsp; &nbsp;if not PtInRect(CBBtnRect, p) then // 如果不在按钮区域内<br>&nbsp; &nbsp; &nbsp; &nbsp; inherited; &nbsp;// 执行默认的操作<br>end;<br><br>procedure TForm1.WMNcMouseMove(var m: TMessage);<br>var<br>&nbsp; &nbsp;p: TPoint;<br>begin<br>&nbsp; &nbsp; &nbsp;p.x := LOWORD(m.lParam) - Self.Left;<br>&nbsp; &nbsp; &nbsp;p.y := HIWORD(m.lParam) - Self.Top;<br>&nbsp; &nbsp; &nbsp;if not PtInRect(CBBtnRect, p) then // 如果不在按钮区域<br>&nbsp; &nbsp; &nbsp; &nbsp; DrawCaptionBtn(EDGE_RAISED)<br>&nbsp; &nbsp; &nbsp;else<br>&nbsp; &nbsp; &nbsp; &nbsp; inherited; // 执行默认的操作<br>end;<br><br><br>procedure TForm1.WMNcLButtonDown(var m: TMessage);<br>var<br>&nbsp; &nbsp;p: TPoint;<br>begin<br>&nbsp; &nbsp; &nbsp;p.x := LOWORD(m.lParam) - Self.Left;<br>&nbsp; &nbsp; &nbsp;p.y := HIWORD(m.lParam) - Self.Top;<br>&nbsp; &nbsp; &nbsp;if PtInRect(CBBtnRect, p) then &nbsp;// 如果按在了按钮区域<br>&nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Self.BringToFront;<br>&nbsp; &nbsp; &nbsp; &nbsp; DrawCaptionBtn(EDGE_SUNKEN);<br>&nbsp; &nbsp; &nbsp;end<br>&nbsp; &nbsp; &nbsp;else<br>&nbsp; &nbsp; &nbsp; &nbsp; inherited; // 执行默认的操作<br>end;<br><br><br>procedure TForm1.WMNcLButtonUp(var m: TMessage);<br>var<br>&nbsp; &nbsp;p: TPoint;<br>begin<br>&nbsp; &nbsp; &nbsp;p.x := LOWORD(m.lParam) - Self.Left;<br>&nbsp; &nbsp; &nbsp;p.y := HIWORD(m.lParam) - Self.Top;<br>&nbsp; &nbsp; &nbsp;if PtInRect(CBBtnRect, p) then // <br>如果在标题栏按钮区域释放鼠标<br>&nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp; DrawCaptionBtn(EDGE_RAISED);<br>&nbsp; &nbsp; &nbsp;end<br>&nbsp; &nbsp; &nbsp;else<br>&nbsp; &nbsp; &nbsp; &nbsp; inherited; // 执行默认的操作<br>end;<br><br><br>procedure TForm1.WMNcRButtonDown(var m: TMessage);<br>var<br>&nbsp; &nbsp;p: TPoint;<br>begin<br>&nbsp; &nbsp; &nbsp;p.x := LOWORD(m.lParam) - Self.Left;<br>&nbsp; &nbsp; &nbsp;p.y := HIWORD(m.lParam) - Self.Top;<br>&nbsp; &nbsp; &nbsp;if not PtInRect(CBBtnRect, p) then // 如果不在标题栏按钮区域<br>&nbsp; &nbsp; &nbsp; &nbsp; inherited; &nbsp;// 执行默认的操作<br>end;<br><br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; &nbsp; &nbsp;// 这个大小大家可以得用GetSystemMetrics<br>函数来进行更精确的计算。这里<br>&nbsp; &nbsp; &nbsp;// 只是用来示例<br>&nbsp; &nbsp; &nbsp;with CBBtnRect do<br>&nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; left := 100;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; top &nbsp;:= 6;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; right := 450;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bottom := 20;<br>&nbsp; &nbsp; &nbsp;end;<br><br>&nbsp; &nbsp; &nbsp;// 标题栏按钮字体。<br>&nbsp; &nbsp; &nbsp;CBBtnFont:= TFont.Create;<br>&nbsp; &nbsp; &nbsp;with CBBtnFont do<br>&nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Name := '宋体';<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Size := 9;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Color := clRed;<br>&nbsp; &nbsp; &nbsp;end;<br>end;<br><br><br>procedure TForm1.FormDestroy(Sender: TObject);<br>begin<br>&nbsp; &nbsp; &nbsp;CBBtnFont.Free;<br>end;<br><br>end.<br><br>
 
又来晚了,<br>让人抢去分了,
 
程云哥哥,你也来晚了<br>呵呵,我也是<br>我昨天才编了这个例子
 
分被人抢光了,,,,呜呜!!<br>俺也会!!!<br>
 
接受答案了.
 
宝贝——哈哈,我可不会
 
后退
顶部