如何在 Delphi FMX Windows 窗体中检测鼠标后退和前进按钮?

Dom*_*mus 4 windows delphi mouseevent firemonkey

有没有人找到一种方法来检测Windows(并且仅限Windows)中Delphi FMX表单中的鼠标后退和前进按钮?

我知道这在 VCL 应用程序中工作得很好,使用

procedure WMAppCommand(var Msg: Winapi.Messages.TMessage); message WM_APPCOMMAND;
Run Code Online (Sandbox Code Playgroud)

但这在 FMX 应用程序中没有任何影响。

如果有人已经解决了这个问题,将非常感谢提示(或者他们使用的代码,当然)。

Rem*_*eau 5

FMX 严格过滤窗口消息,仅调度其实际使用的少数消息。WM_APPCOMMAND不是其中之一,这就是为什么简单的message处理程序不能像在 VCL 中那样在 FMX 中工作。

因此,您必须通过或直接手动子类化TForm的 Win32 ,以便在 FMX 看到窗口消息之前拦截它们。请参阅子类化控件HWNDSetWindowLongPtr(GWLP_WNDPROC)SetWindowSubclass()

进行子类化的理想位置是重写该TForm.CreateHandle()方法。创建后,您可以使用 FMX 的函数FormToHWND()来获取。TFormHWND

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;
Run Code Online (Sandbox Code Playgroud)