• 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;

  • 相关阅读:
    php下的jsonp使用实例
    jquery ajax jsonp跨域调用实例代码
    js/ajax跨越访问-jsonp的原理和实例(javascript和jquery实现代码)
    jsonp实现跨域访问
    jsonp调用实例
    Jsonp和java操作例子
    JSONP实例
    跨平台移动开发工具:PhoneGap与Titanium全方位比拼
    混合开发模式下主流移动开发平台分析
    企业移动信息化应用开发模式选型指南
  • 原文地址:https://www.cnblogs.com/h2zZhou/p/5605863.html
Copyright © 2020-2023  润新知