全局热键问题之二

kayoo 2012-03-02 09:11:58
因为我的程序需要多开,多开之后前面开的程序热键就失效了。为此我想用2个思路解决。
1、如果检测到已经注册热键F2,则开始注册热键F3,依次类推。也就是假如我开3个程序,控制他们的热键分别是F2,F3,F4.
2、要么就全都用同一个热键F2,同时可以隐藏或重现。
请问这2种思路如何实现?谢谢。
再次跟上个贴子中的Bo_Sys和kaikai_kk说声抱歉!
...全文
211 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
funxu 2012-03-02
  • 打赏
  • 举报
回复
RegisterHotKey(Handle,_HotKey,0,vk_F3); 成功返回非0,否则返回0
funxu 2012-03-02
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 lactoferrin 的回复:]
不要使用全局钩子,使用raw input
[/Quote]
没怎么接触过游戏编程,刚才查了下只找到了C#的资料,调试通过了,但悲摧的是delphi下的虾米都没有
gxgyj 2012-03-02
  • 打赏
  • 举报
回复
有返回值的
if not RegisterHotKey(...) then 失败
kayoo 2012-03-02
  • 打赏
  • 举报
回复
谢谢kaikai_kk的解答,这样的话问题只剩下一个了,就是多开的问题了,如funxu所说,感觉第2个思路更麻烦,那还是用第一个思路吧,放心我最多只注册3个,再多了也没必要了,因为我的程序一般只开2个。
想请问下那个RegisterHotKey的bool返回值怎么看?
if ..... then (这里填什么呢?)
RegisterHotKey(Handle,_HotKey,0,vk_F3);
Lactoferrin 2012-03-02
  • 打赏
  • 举报
回复
不要使用全局钩子,使用raw input
funxu 2012-03-02
  • 打赏
  • 举报
回复
2、要么就全都用同一个热键F2,同时可以隐藏或重现。
这种思路有两个,第一个是基于当前焦点,也就是只有当前焦点的程序响应,这个很简单局部热键即可
如果是所有程序都希望用一个热键来响应,那么可以考虑全局钩子,然后通过不断获取钩子截取的按键来判断自己需要实现的操作,但是这个方案有几个很不好的地方,首先钩子的加载与释放要严格控制,否则容易引起系统异常,循环获取钩子得到的按键需要占用很大的系统资源,因为这就好像写一个死循环
funxu 2012-03-02
  • 打赏
  • 举报
回复
RegisterHotKey有个bool返回值,表示注册成功与失败,失败就是已经有人注册了,或者查看GetLastError.来获取失败原因。另外建议系统热键很珍贵,所以还是不要随意这么注册下去

kaikai_kk 2012-03-02
  • 打赏
  • 举报
回复
没有装RzTrayIcon,用系统自带的托盘类,简单的做了一个,按F2隐藏/显示窗体和托盘图标
自己建个工程测试一下,达到效果了再移植到自己的程序上面去吧

在程序中注册热键就是用一个button,在click事件加上这2句即可:
UnRegisterHotKey(handle,_HotKey);
RegisterHotKey(Handle,_HotKey,0,vk_F2);//vk_F2变新热键


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
_HotKey:Integer;
procedure HotKey(var Msg:Tmessage);message WM_HOTKEY;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses ShellApi;

{$R *.dfm}

procedure doNotifyIconData(aType: String);
var
lpData: PNotifyIconData;
begin
lpData := new(PNotifyIconDataA);
lpData.cbSize := 88;
lpData.Wnd := Form1.Handle;
lpData.hIcon := Application.Icon.Handle;
lpData.uID :=0;
lpData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
if (aType = 'add') then
Shell_NotifyIcon(NIM_ADD, lpData)
else if (aType = 'del') then
Shell_NotifyIcon(NIM_DELETE, lpData);
dispose(lpData);
end;

procedure TForm1.HotKey(var Msg:Tmessage);
begin
if Msg.LParamHi=vk_F2 then
begin
if self.Visible then
begin
doNotifyIconData('del');
self.Visible:=false;
end else
begin
doNotifyIconData('add');
self.Visible:=true;
end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
_HotKey:=GlobalAddAtom('HotKey')-$C000;
RegisterHotKey(Handle,_HotKey,0,vk_F2); {取出用户设定的热键,把vk_F2变一下即可}
doNotifyIconData('add');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
UnRegisterHotKey(handle,_HotKey);
end;

end.
莫欺少年穷 2012-03-02
  • 打赏
  • 举报
回复
不会delphi,帮顶下吧
kaikai_kk 2012-03-02
  • 打赏
  • 举报
回复
LZ也不要放在心上,自己把问题搞懂了即又进步了,知识学到了就是自己的了
我们入门的时候,也经常受批评

即使不是多的话,也有可能跟别的软件热键产生冲突
这问题不用搞的太复杂,像QQ一样,在程序里面做个设置,让用户来设置快捷键
初始时快捷键是一样的,用户设置后就使用新的
kayoo 2012-03-02
  • 打赏
  • 举报
回复
再顺便问下怎么用同一个热键来隐藏或显现呢?比如假如是隐藏状态则F2显现,假如是显现状态则隐藏。谢谢

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧