Reputation: 73
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
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