冥界3大法王 发表于 2024-1-10 11:42

dephi在dll里边调热键出不来?

id4: Integer;





function load1(): Boolean;    //加载主窗口1 MainForm
begin
if MainForm = nil then
begin
    MainForm := TMainForm.Create(nil);
    MainForm.Visible := not MainForm.Visible;
    id4 := GlobalAddAtom('hotkey');
    RegisterHotKey(0, id4, MOD_CONTROL + MOD_SHIFT + MOD_ALT, VK_F4);       //Ctrl+Shift+Alt+F4


    if (GetAsyncKeyState(VK_CONTROL) < 0) and (GetAsyncKeyState(VK_SHIFT) < 0) and (GetAsyncKeyState(VK_MENU) and (GetAsyncKeyState(VK_F3)) < 0) then
    begin
      MainForm.Show;
    end;


end
else
begin
    MainForm := TMainForm.Create(nil);
    MainForm.Visible := not MainForm.Visible;
    id4 := GlobalAddAtom('hotkey');
    RegisterHotKey(0, id4, MOD_CONTROL + MOD_SHIFT + MOD_ALT, VK_F4);       //Ctrl+Shift+Alt+F4


    if (GetAsyncKeyState(VK_CONTROL) < 0) and (GetAsyncKeyState(VK_SHIFT) < 0) and (GetAsyncKeyState(VK_MENU) and (GetAsyncKeyState(VK_F3)) < 0) then
    begin
      MainForm.Show;
    end;
end;
end;
无报错信息,但也没达到预期效果。{:301_972:}{:301_974:}

DEATHTOUCH 发表于 2024-1-10 17:01

和RegisterHotKey第一个参数的句柄有没有关系?
https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-registerhotkey
没有设置句柄的话当前线程得处理这个消息。

冥界3大法王 发表于 2024-1-10 17:30

DEATHTOUCH 发表于 2024-1-10 17:01
和RegisterHotKey第一个参数的句柄有没有关系?
https://learn.microsoft.com/zh-cn/windows/win32/api/wi ...

写成0
或是改成id4都不报错,之后
ShowMessage(id4.tostring);
都是有回传值的,就是按键没动静。{:301_1006:}

DEATHTOUCH 发表于 2024-1-10 19:44

冥界3大法王 发表于 2024-1-10 17:30
写成0
或是改成id4都不报错,之后
ShowMessage(id4.tostring);


我的意思是你创建了窗口,那么应该把TMainForm的Handle(HWND类型)传给RegisterHotkey第一个参数
RegisterHotKey(MainForm.Handle, id4, MOD_CONTROL or MOD_SHIFT or MOD_ALT, VK_F4);

然后在TMainForm里面加一个消息处理函数
procedure HandleHotkey(var Message:TMessage); message WM_HOTKEY;

通过Message的参数判断不同的快捷键(如果注册了多个)

冥界3大法王 发表于 2024-1-10 21:02

DEATHTOUCH 发表于 2024-1-10 19:44
我的意思是你创建了窗口,那么应该把TMainForm的Handle(HWND类型)传给RegisterHotkey第一个参数
Regis ...

@DEATHTOUCH
现在运行的还算凑合吧。
但美中不足,得调用窗体初始化的代码(注册菜单的过程里调用了LoadForm)执行一次,然后那个热键才能调用。。。
也就是您四楼所说的代码

可是,我想要达成的效果是在dll里边注册热键。。。再调用DLL创建的窗体。
算了,明天做个录像,发到您的邮箱里。。还有源码。。。

DEATHTOUCH 发表于 2024-1-10 21:35

冥界3大法王 发表于 2024-1-10 21:02
@DEATHTOUCH
现在运行的还算凑合吧。
但美中不足,得调用窗体初始化的代码(注册菜单的过程里调用了Load ...
我可以给你提供一个思路,不过需要DLL和调用方进行配合,就像你需要的那样,在DLL的入口注册热键,然后在加载DLL的程序的WndProc函数里面处理WM_HOTKEY消息并调用DLL提供的函数。

这是一个非常简单的demo:

DLL代码

library dhklib;

uses
Windows;

var
atom_id:ATOM;

begin
atom_id:=GlobalAddAtomW('dllhotkey');
RegisterHotKey(0,atom_id,MOD_CONTROL or MOD_SHIFT, VK_F4);
end.   


加载方代码:

program dhkloader;

uses
Windows;

var
lib:THandle;
msg:TMsg;
begin
lib:=LoadLibrary('dhklib.dll');
while GetMessage(msg,0,0,0) do
begin
    if msg.message = WM_HOTKEY then
      Writeln('Got Hot Key');
end;
end.

显然这里的输出一行可以换成DLL提供的函数。

lies2014 发表于 2024-1-10 21:42

1、你定义的热键跟响应的热键不是同一个,定义F4,检测F3,就算其他地方没有问题也得不到正确结果
2、响应热键应该用消息,你代码中只有检测,没有响应,信号源都没过来,自然不会有结果
3、RegisterHotKey的第一个参数如果为null应该是注册自身句柄,不过没试过,如果有问题你将0改为handle应该可以

冥界3大法王 发表于 2024-1-10 21:48

DEATHTOUCH 发表于 2024-1-10 21:35
我可以给你提供一个思路,不过需要DLL和调用方进行配合,就像你需要的那样,在DLL的入口注册热键,然后在 ...

@DEATHTOUCH
感谢您的光临指导,还有其他的bug没解决。
那就是x64dbg退出时,卸载程序时触发的bug。


原生的x64dbg的结束逻辑是这样的:
关闭调试器=》卸载DLL(*.dp32/*.dp64)==>把打开过的文件记录到x32dbg.ini or x64dbg.ini中去
现在呢? 会出现两种下场:
不加杀进程吧,调试器卡死。。等一会之后MiniDump文件夹就生成一个。。。
。。。。。。。。加了呢? 1秒就退出了,但是我的打开文件历史记录呢?飞了。

DEATHTOUCH 发表于 2024-1-10 21:59

冥界3大法王 发表于 2024-1-10 21:48
@DEATHTOUCH
感谢您的光临指导,还有其他的bug没解决。
那就是x64dbg退出时,卸载程序时触发的bug。


这个就...
要不你上GitHub提issue或者给人修修bug?
或者想办法搞点hack操作

冥界3大法王 发表于 2024-1-10 22:23

DEATHTOUCH 发表于 2024-1-10 21:59
这个就...
要不你上GitHub提issue或者给人修修bug?
或者想办法搞点hack操作

@DEATHTOUCH
所以,我看破了这一点,所以说得语音视频。
我得给你全方位做操作表演,你才能彻底明白。
今天眼痛了,修复不少bug。明天吧。
页: [1]
查看完整版本: dephi在dll里边调热键出不来?