Domus
Domus

Reputation: 1279

How detect the mouse back and forward buttons in a Delphi FMX Windows form?

Has anyone found a way to detect the mouse back and forward buttons in a Delphi FMX form in Windows (and only Windows)?

I understand this works fine in a VCL application, using

procedure WMAppCommand(var Msg: Winapi.Messages.TMessage); message WM_APPCOMMAND;

but this has no effect in an FMX application.

If anyone already has worked out a solution to this, would very much appreciate a hint (or the code they used, of course).

Upvotes: 4

Views: 455

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 596527

FMX heavily filters window messages, only dispatching the few messages it actually uses for itself. WM_APPCOMMAND is not one of them, which is why a simple message handler does not work in FMX, like it does in VCL.

So, you are going to have to manually subclass the TForm's Win32 HWND directly, via SetWindowLongPtr(GWLP_WNDPROC) or SetWindowSubclass(), in order to intercept window messages before FMX sees them. See Subclassing controls.

An ideal place to do that subclassing is to override the TForm.CreateHandle() method. You can use FMX's FormToHWND() function to get the TForm's HWND after it has been created.

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;

Upvotes: 6

Related Questions