2013-03-05 34 views
0

我正在爲我的程序創建一個notifyIcon,將來它將是os獨立的,但現在我正在編寫win-32部分。在Firemonkey的任務欄前顯示NotifyIcon Popup

當我在收到WM_RBUTTONDOWN消息後顯示一個popup菜單時,我顯示一個菜單,但是此菜單位於任務欄後面。如何創建一個在任務欄前的常規菜單?

問題在於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

+1

你有沒有嘗試過,'TCustomTrayIcon'做了什麼?它將「應用程序」窗口設置在前面並處理隊列中的消息。所以嘗試添加'SetForegroundWindow(Application.Handle); Application.ProcessMessages;'在彈出菜單之前。 – TLama 2013-03-05 14:20:30

+0

我想這可以歸結爲我們如何將@ TLama的評論中的代碼翻譯成FMX。 – 2013-03-05 14:54:24

+1

從我現在刪除的答案:不要使用'GetCursorPos',使用'GetMessagePos'。請記住,人們使用鍵盤和鼠標。 – 2013-03-05 14:54:58

回答

2

我無法評論你的菜單出現在任務欄後面的原因,因爲我從未見過這種情況發生,但我可以在代碼中對其他內容發表評論。您的圖標處理程序需要使用WM_RBUTTONUPWM_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; 
+0

是的,thnx爲增加的信息。但主要問題尚未解決。 – 2013-03-06 07:59:05

相關問題