Reputation: 1279
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
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