zoukankan      html  css  js  c++  java
  • Delphi中window消息截获的实现方式(1)

      近来笔者在一个项目中需要实现一个功能:模仿弹出菜单的隐藏方式,即鼠标在窗口的非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;

  • 相关阅读:
    开源项目记录
    Linux的磁盘分区(一)
    Linux下的用户权限
    HeapSort 堆排序
    git参考手册
    SGU 分类
    20130704
    七月三日

    20130629
  • 原文地址:https://www.cnblogs.com/h2zZhou/p/5605863.html
Copyright © 2011-2022 走看看