有人发现了在Delphi FMX表单中检测Windows(仅限Windows)鼠标前进和后退按钮的方法吗?
我知道在VCL应用程序中使用以下代码可以正常工作:
procedure WMAppCommand(var Msg: Winapi.Messages.TMessage); message WM_APPCOMMAND;
但这在FMX应用程序中没有任何效果。
如果有人已经解决了这个问题,非常感谢给一个提示(或者当然也可以提供他们使用的代码)。
有人发现了在Delphi FMX表单中检测Windows(仅限Windows)鼠标前进和后退按钮的方法吗?
我知道在VCL应用程序中使用以下代码可以正常工作:
procedure WMAppCommand(var Msg: Winapi.Messages.TMessage); message WM_APPCOMMAND;
FMX严格过滤窗口消息,仅会分发它实际使用的少量消息。 WM_APPCOMMAND
不在其中,这就是为什么像VCL中那样简单的 message
处理程序在FMX中无法工作。
因此,您需要手动子类化TForm
的Win32 HWND
,通过SetWindowLongPtr(GWLP_WNDPROC)
或SetWindowSubclass()
,以在FMX看到它们之前拦截窗口消息。请参见子类化控件。
理想的子类化位置是重写TForm.CreateHandle()
方法。您可以使用FMX的FormToHWND()
函数,在TForm
创建后获取其HWND
。
protected
procedure CreateHandle; override;
...
uses
FMX.Platform.Win, Winapi.Windows, Winapi.CommCtrl;
function MySubclassProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM;
uIdSubclass: UINT_PTR; dwRefData: DWORD_PTR): LRESULT; stdcall;
begin
case uMsg of
WM_APPCOMMAND: begin
// use TMyForm(dwRefData) as needed...
end;
WM_NCDESTROY:
RemoveWindowSubclass(hWnd, @MySubclassProc, uIdSubclass);
end;
Result := DefSubclassProc(hWnd, uMsg, wParam, lParam);
end;
procedure TMyForm.CreateHandle;
begin
inherited;
SetWindowSubclass(FormToHWND(Self), @MySubclassProc, 1, DWORD_PTR(Self));
end;
procedure InitStandardClasses;
var
ICC: TInitCommonControlsEx;
begin
ICC.dwSize := SizeOf(TInitCommonControlsEx);
ICC.dwICC := ICC_STANDARD_CLASSES;
InitCommonControlsEx(ICC);
end;
initialization
InitStandardClasses;