1

私は自分のプログラムのnotifyIconを作成しています。将来的にはOSに依存しませんが、今のところwin-32部分を書いています。

WM_RBUTTONDOWN メッセージを受信した後に popupmenu を表示すると、メニューが表示されますが、このメニューはタスクバーの後ろにあります。タスクバーの前にある通常のメニューを作成する方法は?

問題は 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 の代わりに

4

1 に答える 1

2

メニューがタスクバーの後ろに表示される理由についてコメントすることはできませんが、それが起こるのを見たことがないので、コード内の他の何かについてコメントすることはできます. アイコン ハンドラーでは、WM_RBUTTONUPorWM_CONTEXTMENUおよび notを使用する必要がありWM_RBUTTONDOWNます。また、マウスがメニューの外でクリックされたときにポップアップメニューを正しく閉じないというよく知られた OS のバグに対処するには、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;
于 2013-03-05T16:14:45.057 に答える