首页 > 解决方案 > 如何在 FMX 上最小化到托盘

问题描述

我正在为我的工作应用程序创建一个启动器。我希望当我最小化应用程序时,他会去托盘。我设法用按钮创建图标(单击调用 proc),但我不知道我需要调用 proc 什么事件,没有像 Onminized 这样的事件并且事件 OnHide 不影响。我看到一些关于使用 Hook 的帖子(我不太确定是什么),我尝试了一下,但出现错误: [dcc32 Error] UMain.pas(129): E2036 Variable required。

这一点在这里:

 procedure TfrmMain.FormCreate(Sender: TObject);
            begin
                SetWindowsHookEx(WH_CALLWNDPROC, @WndProc, 0, GetCurrentThreadId);               
             end;

更具体到 @wndProc,我尝试删除 @ 并得到 [dcc32 Error] UMain.pas(129): E2009 Incompatible types: 'regular procedure and method pointer'

   Type...

       function WndProc(Code: integer; WParam, LParam: LongInt): LRESULT; stdcall;
    var
            WndProcHook: THandle;
    const 
            WM_TRAYICON =WM_USER+1;

------------------------------------------------------

    procedure TfrmMain.FormCreate(Sender: TObject);

                begin
                SetWindowsHookEx(WH_CALLWNDPROC, @WndProc, 0, GetCurrentThreadId);
                .... 
                end; 
        function TfrmMain.WndProc(Code: integer; WParam, LParam: LongInt): LRESULT;    stdcall;
        var
          msg: TCWPRetStruct;
        begin;


          if (Code >= HC_ACTION) and (LParam > 0) then begin
            msg := PCWPRetStruct(LParam)^;
            if (msg.Message = WM_SIZE) and (msg.WParam = SIZE_MINIMIZED) then begin
              criaIcone;


            end;
          end;
          result := CallNextHookEx(WndProcHook, Code, WParam, LParam)
        end;
//
procedure TfrmMain.CriaIcone;
var
   NotifyIconData: TNotifyIconData;
begin
   with NotifyIconData do
   begin
    cbSize          := SizeOf;
      Wnd             := AllocateHWnd(WMTrayIcon);
      uID             := 0;
      uCallbackMessage:= WM_TRAYICON;
      uFlags          := NIF_ICON or NIF_TIP or NIF_MESSAGE;
      hIcon           := GetClassLong(FmxHandleToHWND(self.Handle),GCL_HICONSM);
      szTip           := 'Teste TrayIcon';
   end;
   Shell_NotifyIcon(NIM_ADD, @NotifyIconData);
end;

标签: delphihookfiremonkey

解决方案


问题就像@RemyLebeau 所说的那样。我对 Delphi 很陌生(3 个月)
这是代码,我使用了这篇文章的很多代码:FMX - Trayicon 消息处理

有效的代码:

type
....
      procedure FormCreate(Sender: TObject);
      procedure DestroyIcone;



  const
      WM_ICONTRAY = WM_USER + 1;

    private
        { Private declarations }
        create : integer;

        TrayWnd: HWND;
        TrayIconData: TNotifyIconData;
        TrayIconAdded: Boolean;
        procedure TrayWndProc(var Message: TMessage);
   implementation

procedure TfrmMain.FormCreate(Sender: TObject);  
    begin
        TrayWnd := AllocateHWnd(TRayWndProc); // Alocate the wndProc
      with TrayIconData do
      begin                // Instaciate
        cbSize := SizeOf;
        Wnd := TrayWnd;
          uID := 1;
        uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP;
        uCallbackMessage := WM_ICONTRAY;
        hIcon := GetClassLong(FmxHandleToHWND(self.Handle), GCL_HICONSM);
        StrPCopy(szTip, 'testapp');
      end;
    //creating the icon 
     if not  TrayIconAdded then
      TrayIconAdded := Shell_NotifyIcon(NIM_ADD, @TrayIconData) ;

procedure TfrmMain.TrayWndProc(var Message: TMessage);

begin
 if Message.MSG = WM_ICONTRAY then
  begin
      case Message.LParam of
     WM_LBUTTONDOWN:
                     begin
                      frmMain.Show;//If u use some frmMain.hide 
                      SetForegroundWindow(FmxHandleToHWND(frmMAin.Handle));
                      if TrayIconAdded then
                      begin
                      //Shell_NotifyIcon(NIM_DELETE, @TrayIconData);
                      TrayIconAdded := false;
                      ShowAppOnTaskbar(frmMain);
                      end;

                      end;

       WM_RBUTTONDOWN: ShowMessage('RolePlay , but can be a PopUpMenu');

      end;
     end
  else
    Message.Result := DefWindowProc(TrayWnd, Message.Msg, Message.WParam, Message.LParam);
end;

推荐阅读