一段看不明白道理的热键设置代码

来源:互联网  时间:2016/8/24 16:38:00

关于网友提出的“ 一段看不明白道理的热键设置代码”问题疑问,本网通过在网上对“ 一段看不明白道理的热键设置代码”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:

问题: 一段看不明白道理的热键设置代码
描述:

请各位前辈指点,下面的代码的注释都是我加上的,有些是我对程序的说明,有些是我要问题的问题。


unit Unit1; 
{$mode objfpc}{$H+}
interface
uses
  Classes, Windows, Messages, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs;
type
  { TForm1 }
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { private declarations }
    procedure Hook;
    procedure Unhook;
  public
    { public declarations }
     procedure ProcessHotKey(HK: LongInt);
  end; 
var
  Form1: TForm1;
type
    TMWndProc = Windows.WNDPROC;
var
  OldProc: TMWndProc;
  function MsgProc(Handle: HWnd; Msg: UInt; WParam: Windows.WParam;
                   LParam: Windows.LParam): LResult; stdcall;
implementation
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
  {注册热键}
  RegisterHotKey(Handle, 0, MOD_WIN, VK_A);
  {问题:这个Hook想不明白,想不明白这个程序为什么可以设置得到热键的}
  Hook;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
  Unhook;
  {注销热键}
  UnregisterHotKey(Handle, 0);
end;
procedure TForm1.Hook;
begin
     {获取窗口回调函数的地址,目的是为了当调用了自己定义的回调函数时进行恢复,这样就不会破坏原窗口的消息传递}
     OldProc := TMWndProc(Windows.GetWindowLong(Handle, GWL_WNDPROC));
     {为窗口设置新的回调函数}
     Windows.SetWindowLong(Handle, GWL_WNDPROC, LongInt(@MsgProc));
end;
procedure TForm1.Unhook;
begin
     {Assigned 函式在参数不为nil时传回True}
     if Assigned(OldProc) then
        {为窗口设置回原来的回调函数} {问题,是不是在本程序关闭时才设置这个?}
        Windows.SetWindowLong(Handle, GWL_WNDPROC, LongInt(OldProc));
     OldProc := nil;
end;
procedure TForm1.ProcessHotKey(HK: LongInt);
begin
     // HK is a virtual key code, process it here
end;
function MsgProc(Handle: HWnd; Msg: UInt; WParam: Windows.WParam;
    LParam: Windows.LParam): LResult; stdcall;
begin
  begin
    if Msg = WM_HOTKEY then
      Form1.ProcessHotKey(HIWORD(LParam))
      ShowMessage('设置热键成功')
    else
      {CallWindowProc将消息信息传送给指定的窗口过程}
      {问题1:Rsulte这个返回值有什么用呢,为什么要这样用呢?}
      {问题2:为什么要把这个消息指定给窗口过程OldProc}
      Rsulte := Windows.CallWindowProc(OldProc, Handle, Msg, WParam, LParam);
  end;
end;
initialization
  {$I Unit1.lrs}
end.

解决方案1:

Handle指的是窗体的句柄,以及窗体所属的类

解决方案2:

Windows.SetWindowLong(Handle, GWL_WNDPROC, LongInt(@MsgProc));
是FORM1的handle  

解决方案3:

通过拦截消息处理过程,自行处理WM_HOTKEY
1、Rsulte(应为Result)是要将CallWindowProc的返回值再传出去,作为MsgProc的返回值
2、只对WM_HOTKEY消息进行拦截,其他的放行,仍由OldProc处理

解决方案4:

MsgProc 是他替换了FORM1的消息处理函数,if 那段是处理 自身定义 的热键消息,else 后面是用Form1原来的消息处理函数 OldProc 处理消息,CallWindowProc 只是把消息让OldProc 处理.

上一篇关于热键的问题
下一篇请问HOOK[0]STORE和HOOK[0]CHANGE分别是什么意思??
明星图片
相关文章
《 一段看不明白道理的热键设置代码》由码蚁之家搜集整理于网络,
联系邮箱:mxgf168#qq.com(#改为@)