经过一些挫折和谷歌搜索后,这应该工作:
用winAPI电话注册热键
RegisterHotKey(FmxHandletoHWND(form1.Handle),MOD_CONTRol,);
它返回true.
然后在表单的过程中捕获热键
procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
但这个从未被称为.
我之前习惯在vcl应用程序中这样做,所以我的猜测是firemonkey以不同的方式处理消息.
所以问题是:如何在firemonkey app中捕获全局热键?
编辑:应用该解决方案的一些示例.我创建了一个小班的单元
unit fire_hotkey;interfaceuses windows,messages,allocatehwnd;type TMsgHandler = procedure (var Msg: TMessage) of object; THotClass = class(TObject) fMsgHandlerHWND : HWND; proc:TMsgHandler; constructor Create; procedure init; destructor Destroy; overrIDe; end;implementation{ hotClass }constructor THotClass.Create;begin inherited;end;destructor THotClass.Destroy;begin ThreadDeallocateHWnd(fMsgHandlerHWND); inherited;end;procedure THotClass.init;begin fMsgHandlerHWND := ThreadAllocateHWnd(proc,true);end;end.
然后我的主窗体有一个处理热键事件的过程:
procedure TformEditor.WMHotKey(var Msg: TMessage);begin if Msg.Msg = WM_HOTKEY then begin //call lua function or sth //... end else Msg.Result := DefWindowProc(hotkeyGrabber.fMsgHandlerHWND,Msg.Msg,Msg.wParam,Msg.lParam);end;
并且有一个全球热键抓取:THotClass;在表单创建时初始化:
hotkeyGrabber:=THotClass.Create; hotkeyGrabber.proc:=WMHotKey; hotkeyGrabber.init;
在那之后你应该像通常的vcl应用程序一样注册热键,他们将是cought
http://www.swissdelphicenter.ch/torry/showcode.php?id=147
希望它有意义
解决此问题的最简单方法是通过调用CreateWindow创建自己的窗口.然后为该窗口实现一个窗口过程来处理WM_HOTKEY消息.
我已经包装了这样的低级API调用:
unit AllocateHWnd;interfaceuses System.SysUtils,System.Classes,System.SyncObJs,WinAPI.Messages,WinAPI.windows;function ThreadAllocateHWnd(AMethod: TWndMethod; MessageOnly: Boolean): HWND;procedure ThreadDeallocateHWnd(Wnd: HWND);implementationconst GWL_METHODCODE = SizeOf(Pointer)*0; GWL_METHODDATA = SizeOf(Pointer)*1; ThreadAllocateHWndClassname = 'MyCompanyname_ThreadAllocateHWnd';var ThreadAllocateHWndLock: TCriticalSection; ThreadAllocateHWndClassRegistered: Boolean;function ThreadAllocateHWndProc(Window: HWND; Message: UINT; wParam: WParaM; lParam: LParaM): LRESulT; stdcall;var Proc: TMethod; Msg: TMessage;begin Proc.Code := Pointer(getwindowlongPtr(Window,GWL_METHODCODE)); Proc.Data := Pointer(getwindowlongPtr(Window,GWL_METHODDATA)); if Assigned(TWndMethod(Proc)) then begin Msg.Msg := Message; Msg.wParam := wParam; Msg.lParam := lParam; Msg.Result := 0; TWndMethod(Proc)(Msg); Result := Msg.Result end else begin Result := DefWindowProc(Window,Message,wParam,lParam); end;end;function ThreadAllocateHWnd(AMethod: TWndMethod; MessageOnly: Boolean): HWND; procedure RegisterThreadAllocateHWndClass; var WndClass: TWndClass; begin if ThreadAllocateHWndClassRegistered then begin exit; end; ZeroMemory(@WndClass,SizeOf(WndClass)); WndClass.lpszClassname := ThreadAllocateHWndClassname; WndClass.hInstance := HInstance; WndClass.lpfnWndProc := @ThreadAllocateHWndProc; WndClass.cbWndExtra := SizeOf(TMethod); WinAPI.windows.RegisterClass(WndClass); ThreadAllocateHWndClassRegistered := True; end;begin ThreadAllocateHWndLock.Acquire; Try RegisterThreadAllocateHWndClass; if MessageOnly then begin Result := CreateWindow(ThreadAllocateHWndClassname,'',HWND_MESSAGE,HInstance,nil); end else begin Result := CreateWindowEx(WS_EX_TOolWINDOW,ThreadAllocateHWndClassname,WS_POPUP,nil); end; Win32Check(Result<>0); SetwindowLongPtr(Result,GWL_METHODDATA,NativeInt(TMethod(AMethod).Data)); SetwindowLongPtr(Result,GWL_METHODCODE,NativeInt(TMethod(AMethod).Code)); Finally ThreadAllocateHWndLock.Release; End;end;procedure ThreadDeallocateHWnd(Wnd: HWND);begin Win32Check(DestroyWindow(Wnd));end;initialization ThreadAllocateHWndLock := TCriticalSection.Create;finalization ThreadAllocateHWndLock.Free;end.
这是VCL AllocateHWnd的线程安全版本,它因在主线程外部无法使用而臭名昭着.
你需要做的是创建一个带有窗口过程的类,即实现TWndMethod的东西.它可以是实例方法或类方法.然后只需调用ThreadAllocateHWnd来创建窗口,并将该窗口传递给RegisterHotKey.什么时候解开它,取消注册你的热键,并通过调用ThreadDeallocateHWnd来销毁窗口.
总结以上是内存溢出为你收集整理的delphi – firemonkey和全球热键?全部内容,希望文章能够帮你解决delphi – firemonkey和全球热键?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)