Matheus Anselmo
Matheus Anselmo

Reputation: 73

How to minimize to the tray on FMX

I am creating a launcher for the apps of my work. I want that when I minimize the app, he goes to the tray. I manage to create the icon with a button (the click call the proc), but I don't know what events I need to call the proc, there is no event like Onminized and the event OnHide does not affect. I see some posts about using a Hook ( i am not pretty sure whats is), I try it, but I got an error: [dcc32 Error] UMain.pas(129): E2036 Variable required.

This point here:

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

More specific to @wndProc, i try to remove the @ and I got [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;

Upvotes: 1

Views: 1418

Answers (1)

Matheus Anselmo
Matheus Anselmo

Reputation: 73

The problem is like the @RemyLebeau said. I am pretty new on Delphi ( 3 months)
Here is the code, I used a lot of code of this post : FMX - Trayicon message handling

The code that works:

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;

Upvotes: 1

Related Questions