我正在为我的程序创建一个notifyIcon,将来它将是os独立的但是现在我正在编写win-32部分。
当我收到WM_RBUTTONDOWN消息后显示弹出菜单时,我显示一个菜单,但此菜单位于任务栏后面。如何创建一个位于任务栏前面的常规菜单?
问题在于fmx.popupmenu,假设它与VCL.popupmenu具有相同的行为是错误的吗?
编辑代码:
{$IFDEF MSWINDOWS}
Tray:=TPWTrayIcon.Create((handle));
{$ENDIF MSWINDOWS}
Tray.popupmenu:=pmTray;
constructor TPWTrayIcon.Create(pHANDLE:TFMXHandle);
Var
HIco: HICON;
p:tMenuitem;
begin
{$IFDEF MSWINDOWS}
FHandle := AllocateHWnd(HandleIconMessage);
AHandle := FmxHandleToHWND(pHandle);
try
Hico:= LoadIcon(MainInstance,'MAINICON');
tIcon.cbSize := sizeof(tIcon);//TNotifyIconData);
with tIcon do begin
Wnd := FHandle;
uID := 123;
//guidItem:=123;
uFlags := NIF_ICON or NIF_MESSAGE or NIF_GUID or NIF_TIP;
uCallbackMessage := WM_NOTIFYICON;
hIcon := HIco;
uVersion:=NOTIFYICON_VERSION_4;
end;
Shell_NotifyIcon(NIM_ADD, @tIcon);
Shell_NotifyIcon(NIM_SETVERSION, @tIcon);
except
end;
{$ENDIF MSWINDOWS}
end;
procedure TPWTrayIcon.HandleIconMessage(var Msg: TMessage);
var
tmpPoint:TPoint;
begin
if Msg.Msg = WM_NOTIFYICON then begin
case LOWORD(Msg.LParam )of
WM_RBUTTONDOWN:
if Assigned(PopUp) then begin
Cardinal(tmpPoint):=(GetMessagePos);
{EDIT: the following doesnt work in Firemonkey}
//SetForegroundWindow(Application.Handle);
//Application.ProcessMessages;
if SetForegroundWindow(AHANDLE) then
Popup.Popup(tmpPoint.X,tmpPoint.Y);
end;
end;
end;
修改:解决方法:
使用VCL.Menu。而不是Firemonkey.menus
答案 0 :(得分:2)
我无法评论为什么你的菜单出现在任务栏后面,因为我从未见过这种情况,但我可以在你的代码中评论其他内容。您的图标处理程序需要使用WM_RBUTTONUP
或WM_CONTEXTMENU
,而不是WM_RBUTTONDOWN
。此外,为了解决在菜单外单击鼠标时未正确关闭弹出菜单的众所周知的操作系统错误,您需要同时Popup()
和SetForegroundWindow()
包裹WM_NULL
但你只做了一半。
procedure TPWTrayIcon.HandleIconMessage(var Msg: TMessage);
var
tmpPoint: TPoint;
begin
if Msg.Msg = WM_NOTIFYICON then begin
case LOWORD(Msg.LParam) of
WM_RBUTTONUP: // or WM_CONTEXTMENU
if Assigned(PopUp) then begin
Cardinal(tmpPoint) := GetMessagePos;
SetForegroundWindow(AHANDLE);
Popup.Popup(tmpPoint.X, tmpPoint.Y);
PostMessage(AHANDLE, WM_NULL, 0, 0);
end;
end;
end;
end;