У меня возникли проблемы с настройкой значка в трее с FMX (XE3, Windows). Я использую тот же код, который можно найти в бесчисленных потоках, но я не получил обработку сообщений для работы значка.FMX - Обработка сообщений Trayicon
Чтобы создать иллюстрацию, я создал testapp, который устанавливает данные TrayIcon в FormCreate и создает его с помощью кнопки. Он покажет правильный значок и правильную подсказку, процедура TrayMessage никогда не будет вызвана.
unit Unit2;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, Messages,
Windows, ShellAPI, FMX.Platform.Win;
const
WM_ICONTRAY = WM_USER + 1;
type
TForm2 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
TrayIconData: TNotifyIconData;
procedure TrayMessage(var Msg: TMessage); message WM_ICONTRAY;
end;
var
Form2: TForm2;
implementation
{$R *.fmx}
procedure TForm2.Button1Click(Sender: TObject);
begin
Shell_NotifyIcon(NIM_ADD, @TrayIconData);
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
with TrayIconData do
begin
cbSize := SizeOf;
Wnd := FmxHandleToHWND(self.Handle);
uID := 0;
uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP;
uCallbackMessage := WM_ICONTRAY;
hIcon := GetClassLong(FmxHandleToHWND(self.Handle), GCL_HICONSM);
StrPCopy(szTip, 'testapp');
end;
end;
procedure TForm2.TrayMessage(var Msg: TMessage);
begin
case Msg.lParam of
WM_LBUTTONDOWN: ShowMessage('LBUTTON');
WM_RBUTTONDOWN: ShowMessage('RBUTTON');
end;
end;
end.
Я создал тот же сценарий с VCL, и он работает как ожидалось. Единственное различие заключается в прямом использовании Form2.Handle вместо преобразования FMX (и Application.Handle для загрузки данных значков, но это не является частью проблемы в FMX). Может кто-то указать мне верное направление ?
Я сомневаюсь, что ваш обработчик 'WM_ICONTRAY' сообщения никогда не будет вызван. Это особая вещь для платформы Windows.Скорее найдите способ создания фиктивного окна с помощью насоса сообщений (если это можно сделать с помощью ['AllocateHWnd'] (http://docwiki.embarcadero.com/Libraries/XE4/en/System.Classes.AllocateHWnd) в FMX я не знаю, хотя). – TLama
Да, обработчик сообщений, не вызываемый, является проблемой. Использование окна, выделенного AllocateHWnd для обработки сообщения, действительно отлично работает, спасибо большое, я добавлю код в качестве ответа, если нет другого способа, вы можете также явно, если хотите. Однако мне все еще остается интересно, почему исходный код не работает, я знаю, что это специфичная платформа, но я не понимаю, почему это проблема в Windows. – DNR
Я предполагаю, что сообщения не отправляются из оконной процедуры, и никто из методов сообщения никогда не будет вызван. Я не удивлюсь, если это так, потому что, с теоретической точки зрения, подумайте о том, сколько методов сообщений вам нужно написать для одной вещи для всех разных платформ (с аналогичными механизмами обмена сообщениями, как у Windows) с использованием разных сообщений , или просто параметры. Это было бы грязно. – TLama