如何最小化到 FMX 上的托盘
How to minimize to the tray on FMX
我正在为我工作的应用程序创建一个启动器。我希望当我最小化应用程序时,他会转到托盘。我设法用一个按钮创建图标(点击调用 proc),但我不知道调用 proc 需要什么事件,没有像 Onminized 这样的事件并且事件 OnHide 不影响。我看到一些关于使用 Hook 的帖子(我不太确定它是什么),我尝试了一下,但出现错误:
[dcc32 错误]UMain.pas(129):需要 E2036 变量。
这里要点:
procedure TfrmMain.FormCreate(Sender: TObject);
begin
SetWindowsHookEx(WH_CALLWNDPROC, @WndProc, 0, GetCurrentThreadId);
end;
更具体到@wndProc,我尝试删除@,但我得到了[dcc32 错误] UMain.pas(129): E2009 不兼容的类型:'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;
问题就像@RemyLebeau 说的那样。我是 Delphi(3 个月)
的新手
这是代码,我用了很多这个post的代码:FMX - Trayicon message handling
有效代码:
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;
我正在为我工作的应用程序创建一个启动器。我希望当我最小化应用程序时,他会转到托盘。我设法用一个按钮创建图标(点击调用 proc),但我不知道调用 proc 需要什么事件,没有像 Onminized 这样的事件并且事件 OnHide 不影响。我看到一些关于使用 Hook 的帖子(我不太确定它是什么),我尝试了一下,但出现错误: [dcc32 错误]UMain.pas(129):需要 E2036 变量。
这里要点:
procedure TfrmMain.FormCreate(Sender: TObject);
begin
SetWindowsHookEx(WH_CALLWNDPROC, @WndProc, 0, GetCurrentThreadId);
end;
更具体到@wndProc,我尝试删除@,但我得到了[dcc32 错误] UMain.pas(129): E2009 不兼容的类型:'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;
问题就像@RemyLebeau 说的那样。我是 Delphi(3 个月)
的新手
这是代码,我用了很多这个post的代码:FMX - Trayicon message handling
有效代码:
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;