有没有人找到一种方法来检测 Windows(并且只有 Windows)中 Delphi FMX 表单中的鼠标后退和前进按钮?
我知道这在 VCL 应用程序中工作正常,使用
procedure WMAppCommand(var Msg: Winapi.Messages.TMessage); message WM_APPCOMMAND;
但这对 FMX 应用程序没有影响。如果有人已经为此制定了解决方案,将非常感谢提示(或他们使用的代码,当然)。
最佳答案
FMX 大量过滤窗口消息,只发送它实际使用的少数消息。 WM_APPCOMMAND
不是其中之一,这就是为什么简单的 message
处理程序在 FMX 中不起作用,就像在 VCL 中一样。
因此,您将不得不手动将 TForm
子类化。的 Win32 HWND
直接,通过 SetWindowLongPtr(GWLP_WNDPROC)
或 SetWindowSubclass()
,以便在 FMX 看到它们之前拦截窗口消息。见 Subclassing controls .
进行子类化的理想位置是覆盖 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;
关于windows - 如何检测 Delphi FMX Windows 窗体中的鼠标后退和前进按钮?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67143972/