关于网友提出的“ 一段看不明白道理的热键设置代码”问题疑问,本网通过在网上对“ 一段看不明白道理的热键设置代码”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:
问题: 一段看不明白道理的热键设置代码描述:
请各位前辈指点,下面的代码的注释都是我加上的,有些是我对程序的说明,有些是我要问题的问题。
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
通过拦截消息处理过程,自行处理WM_HOTKEY
1、Rsulte(应为Result)是要将CallWindowProc的返回值再传出去,作为MsgProc的返回值
2、只对WM_HOTKEY消息进行拦截,其他的放行,仍由OldProc处理
MsgProc 是他替换了FORM1的消息处理函数,if 那段是处理 自身定义 的热键消息,else 后面是用Form1原来的消息处理函数 OldProc 处理消息,CallWindowProc 只是把消息让OldProc 处理.