冥界3大法王 发表于 2023-8-17 16:30

Delphi能定义全局热键 (单键`) 吗?

好像不行吧? 我又试了下Ctrl+` 没报错,没反映呢?{:301_974:}

uses
   ShellAPI;
var
   id4: Integer;



procedure TMainForm.FormCreate(Sender: TObject);
begin
id4 := GlobalAddAtom('hotkey');
RegisterHotKey(Handle, id4, MOD_CONTROL , VkKeyScan(Char(192)));       //Ctrl+`
end;

end;



procedure TMainForm.hotykey(var msg: TMessage); // 这一块也加了一行!
var
begin
if (GetAsyncKeyState(VK_CONTROL) < 0) and(GetAsyncKeyState(VkKeyScan(Char(192)))) < 0) then//Ctrl+`
begin
ShowMessage('我是全局热键Ctrl+`');
end;
end;

ycdear 发表于 2023-8-17 17:37

应该可以的吧

burning 发表于 2023-8-17 19:44

Delphi都是老古董了而且也不更新了都不如lisp,你为什么还要学

DEATHTOUCH 发表于 2023-8-17 21:15

可以呢,不过前提是这个热键没被别的软件占用,你看看RegisterHotKey的返回值就知道了
还有不需要用GlobalAddAtom,除非你在DLL注册快捷键才要这玩意,一般给一个0~0xBFFF的值就行了

iokey 发表于 2023-8-17 22:24

可以的呀
private
    { Private declarations }
    procedure HotKeyDown(var msg: TMessage);message WM_HOTKEY;
public
    { Public declarations }

end;

var
Form1                                 : TForm1;
g_nHotKey:Integer;

procedure TForm1.FormCreate(Sender: TObject);
begin

g_nHotKey:=GlobalAddAtom('my_hot_key') - $C000;
if RegisterHotKey(Handle, g_nHotKey, MOD_CONTROL , 192) then
mmo1.Lines.Add('注册热键成功')
else
mmo1.Lines.Add('注册热键失败');
end;

procedure TForm1.HotKeyDown(var msg: TMessage);
begin
if (msg.LParamLo = MOD_CONTROL) and (msg.LParamHi = 192) then begin
    mmo1.Lines.Add('你按下了CTRL+~');
end;
end;



Delphi7 下测试有效果正常

冥界3大法王 发表于 2023-8-17 23:01

@iokey
@DEATHTOUCH
可是我确实是在dll中用啊(x64dbg的插件*.dp64)

DEATHTOUCH 发表于 2023-8-18 02:59

冥界3大法王 发表于 2023-8-17 23:01
@iokey
@DEATHTOUCH
可是我确实是在dll中用啊(x64dbg的插件*.dp64)
在DLL用看你怎么用的,如果说是插件的话,一般会有一个窗口句柄给你作为父窗口,那么你的这个热键ID是可以在你的TForm1类的成员变量里面的,所以其实用不用这个GlobalAddAtom问题不大的。

我找到了响应热键的方法,具体来说需要调用SetWindowLong(或SetWindowLongPtr)来设置一个新的窗口处理函数,然后在里面拦截WM_HOTKEY消息,给你个示例代码吧,还有问题再说:

var
old_winproc:WNDPROC;

function MyWndProc(Ahwnd: HWND; uMsg: UINT; wParam: WParam; lParam: LParam):LRESULT;stdcall;
begin
if (uMsg=WM_HOTKEY) and
    (
      (Lo(lparam)=MOD_CONTROL) and (Hi(lparam)=VK_K) // Ctrl+K
    )
then
begin
    ShowMessage('XXXXX');
    Exit(0);
end;
Result:=CallWindowProc(old_winproc,Ahwnd,uMsg,wParam,lParam);
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender:TObject);
begin
ShowMessage('Hello DLL form');
end;

procedure TForm1.FormCreate(Sender:TObject);
begin
if RegisterHotKey(Handle,123,MOD_CONTROL,VK_K) then   // ID = 123, Ctrl+K
    MessageBoxA(0,'OK','OK',0)
else
    MessageBoxA(0,'Error','Error',0);
NativeInt(old_winproc):=SetWindowLongPtr(Handle,GWL_WNDPROC,NativeInt(@MyWndProc));
end;

procedure TForm1.FormDestroy(Sender:TObject);
begin
UnregisterHotKey(Handle,123);// ID = 123
end;

happyxuexi 发表于 2023-8-18 06:21

burning 发表于 2023-8-17 19:44
Delphi都是老古董了而且也不更新了都不如lisp,你为什么还要学

Delphi11.3是最新版,可以开发全平台的程序,还是升级呢。

冥界3大法王 发表于 2023-8-18 09:01

happyxuexi 发表于 2023-8-18 06:21
Delphi11.3是最新版,可以开发全平台的程序,还是升级呢。

@happyxuexi
https://altd.embarcadero.com/releases/studio/Beta/Yukon/RADStudio_29.0.49571.4772.exe
我昨已经安装上了12.0 beta
最新特性,支持多行,支持番茄小助手的C++ Builder

冥界3大法王 发表于 2023-8-18 09:10

iokey 发表于 2023-8-17 22:24
可以的呀
private
    { Private declarations }


@iokey
下面差两个声明该咋写呢?

unit Unit7;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls;

type
TForm7 = class(TForm)
    Button1: TButton;
    mmo1: TMemo;
    procedure FormCreate(Sender: TObject);
private
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
public
    { Public declarations }
end;

var
Form7: TForm7;
g_nHotKey: Integer;

implementation

{$R *.dfm}

procedure TForm7.FormCreate(Sender: TObject);
begin
g_nHotKey := GlobalAddAtom('my_hot_key') - $C000;
if RegisterHotKey(Handle, g_nHotKey, MOD_CONTROL, 192) then
    mmo1.Lines.Add('注册热键成功')
else
    mmo1.Lines.Add('注册热键失败');
end;

procedure TForm7.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if (msg.LParamLo = MOD_CONTROL) and (msg.LParamHi = 192) then
begin
    mmo1.Lines.Add('你按下了CTRL+~');
end;
end;

end.


Unit7.pas(40): E2003 Undeclared identifier: 'LParamLo'
Unit7.pas(40): E2003 Undeclared identifier: 'LParamHi'
页: [1] 2
查看完整版本: Delphi能定义全局热键 (单键`) 吗?