Разработчики, работающие с Delphi и использующие FMX для создания интерфейсов под Windows, иногда сталкиваются с проблемой обнаружения кликов кнопок "назад" и "вперед" на мыши. В VCL-приложениях это решается с помощью обработчика сообщений WM_APPCOMMAND, но в FMX-приложениях такой подход не работает.
Проблема
FMX-форма зачастую не реагирует на клики кнопок "назад" и "вперед" мыши, так как FMX-библиотека фильтрует оконные сообщения и не обрабатывает WM_APPCOMMAND.
Решение
Для решения данной проблемы необходимо вручную подклассировать HWND формы TForm с помощью функции SetWindowLongPtr(GWLP_WNDPROC) или SetWindowSubclass. Это позволит перехватить оконные сообщения до того, как их увидит FMX. Оптимальное место для выполнения подклассирования - перегрузка метода TForm.CreateHandle.
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
// здесь можно обработать сообщение
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;
Не забудьте добавить в раздел uses модуль Winapi.CommCtrl, который необходим для работы с подклассированием окон.
Комментарий
Обратите внимание, что иногда кнопки "назад" и "вперед" на мыши могут отправлять не сообщения WM_APPCOMMAND, а симулировать нажатия клавиш, например, VK_BROWSER_BACK и VK_BROWSER_FORWARD. В таком случае достаточно будет отследить события OnKeyDown или OnKeyUp соответственно.
Подтвержденный результат
Пользователь Domus отредактировал предложенный код, изменив procedure на function, добавив Result := DefSubclassProc(hWnd, uMsg, wParam, lParam) в конце функции и включив инициализацию InitCommonControlsEx. Эти изменения позволили коду работать без ошибок. Спасибо за помощь!
Разработчикам, столкнувшимся с аналогичной проблемой, рекомендуется следовать приведенному выше решению для эффективного обнаружения кликов кнопок "назад" и "вперед" в мыши для Delphi FMX-приложений под Windows.
Инструкция для разработчиков по решению проблемы обнаружения кликов кнопок 'назад' и 'вперед' мыши в Delphi FMX-приложениях под Windows.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS