近来笔者在一个项目中需要实现一个功能:模仿弹出菜单的隐藏方式,即鼠标在窗口的非PanelA区域点击时,使得PanelA隐藏。 经过思考,笔者想到通过处理鼠标的点击事件来实现相应功能。但是,究竟由谁来处理这个点击事件呢?如果窗口中包含多个句柄控件,则不能确定谁能获取到这个鼠标的点击事件,故而无法做出处理。 通过热心网友的帮忙,笔者了解到了window消息截获的实现方式,更棒的是:消息截获并不影响消息的正常处理。最终实现的效果非常完美。在此分享给有需要的朋友。下面是消息截获的实现代码。 1.对于有句柄的控件,可以用一下代码 interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls; type TForm1 = class(TForm) btn1: TButton; btn2: TButton; PageControl1: TPageControl; ts1: TTabSheet; ts2: TTabSheet; procedure FormCreate(Sender: TObject); procedure btn1Click(Sender: TObject); private { Private declarations } public { Public declarations } procedure AppMsg(var Msg: TMsg; var Handled: Boolean); end; var Form1: TForm1; implementation {$R *.dfm} { TForm1 } procedure TForm1.AppMsg(var Msg: TMsg; var Handled: Boolean); var i:integer; begin case Msg.message of WM_LBUTTONDOWN, WM_LBUTTONDBLCLK: begin //拦截PageControl控件的Tab标签切换事件 if Msg.hwnd=PageControl1.Handle then begin for i:=0 to PageControl1.PageCount-1 do begin if PtInRect(PageControl1.TabRect(i),PageControl1.ScreenToClient(Msg.pt)) then begin Handled:=true; ShowMessage(IntToStr(i)); end; end; end; //拦截Button按钮点击事件 if Msg.hwnd=btn1.Handle then begin Handled:=true; ShowMessage('bbbb'); end; end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin Application.OnMessage:=AppMsg; end; procedure TForm1.btn1Click(Sender: TObject); begin ShowMessage('aaaa'); end; end. 2.对于没有句柄的控件,可以通过矩形区域判断 var Pt: TPoint; MyRect: TRect; begin if (Msg.message = WM_LBUTTONUP) or (Msg.message = WM_RBUTTONUP) then begin GetCursorPos(Pt); MyRect.TopLeft.X := OwnButton5.ClientOrigin.x; MyRect.TopLeft.y := OwnButton5.ClientOrigin.y; MyRect.BottomRight.X := MyRect.TopLeft.X +OwnButton5.Width; MyRect.BottomRight.y := MyRect.TopLeft.y +OwnButton5.Height; if not PtInRect(MyRect,Pt) then Panel14.Visible := False; end; end; 需要注意的是:窗口销毁时,如果应用程序需要继续运行,则要在窗口销毁时解除消息截获,即Application.OnMessage:=nil;
|
请发表评论