zoukankan      html  css  js  c++  java
  • FireMonkey下的WndProc实现

    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
      FMX.Platform.Win, FMX.Layouts, FMX.Memo;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
        FHwnd: HWND; // 保存窗口句柄
        FOldWndProc: LONG; // 保存原始的消息处理函数
      public
        { Public declarations }
        function WndProc(HWND: HWND; Msg: UINT; wParam: wParam; lParam: lParam): LRESULT;
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.fmx}
    function WindowProc(HWND: HWND; Msg: UINT; wParam: wParam; lParam: lParam): LRESULT; stdcall;
    begin
      // 因为在通常开发时,需要访问窗口内部的方法或控件等
      // 为了方便起见,所以在这里做一个消息转发
      Result := Form1.WndProc(HWND, Msg, wParam, lParam);
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      ShowMessage('Button1');
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      // 获得主窗口句柄,在FMX框架下,Handle已经不是本窗口的句柄了,需要转换一下
      FHwnd := FmxHandleToHwnd(Handle); // FMX平台提供的函数,但不适用于WIN以外的平台
      // 保存原始的WindowProc地址
      FOldWndProc := GetWindowLongPtr(FHwnd, GWL_WNDPROC); // 纯粹WINAPI函数
      // 获得消息处理权
      SetWindowLongPtr(FHwnd, GWL_WNDPROC, NativeInt(@WindowProc));
    end;
    
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      // 因为窗口销毁后无法再处理Windows传递来的消息,从而会发生内存访问错误
      // 所以在窗口销毁前要把消息处理权移交给原始的WindowProc
      SetWindowLongPtr(FHwnd, GWL_WNDPROC, FOldWndProc);
    end;
    
    function TForm1.WndProc(HWND: HWND; Msg: UINT; wParam: wParam;
      lParam: lParam): LRESULT;
    begin
      Result := 0;
      // 这里测试处理鼠标滚轮消息
      if Msg = WM_MOUSEWHEEL then
      begin
        Memo1.Lines.Add('亲~!你使用了鼠标滚轮哦~!');
        Exit; // 加上这句后,后续不再处理
      end;
      if Msg = WM_LBUTTONDOWN then
      begin
        Memo1.Lines.Add('亲~!你使用了WM_LBUTTONDOWN~!');
        //Exit; // 屏蔽这句后,后续接着处理。否则,不再执行点击鼠标按钮后的代码。
      end;
      Result := CallWindowProc(Ptr(FOldWndProc), HWND, Msg, wParam, lParam);
    end;
    
    end.

    参考:

    http://blog.csdn.net/aqtata/article/details/7710684

  • 相关阅读:
    获取到某一方法的调用者的类名、方法名、命名空间(转)
    JQ插件收集
    输出KnownColor枚举颜色值
    SQL 优化之该走索引却不走索引的分析
    oracle日期处理(一)
    ORACLE如何使用DBMS_METADATA.GET_DDL获取DDL语句
    案例分析:ora04031与ora04030错误分析与解决
    分区表、分区索引和全局索引部分总结
    Oracle性能调整指导纲要
    ORACLE常用SQL优化hint语句
  • 原文地址:https://www.cnblogs.com/findumars/p/3681758.html
Copyright © 2011-2022 走看看