delphi - 如何在 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;
解决方案
问题就像@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;
推荐阅读
- python - 使用 Openpyxl 在整个列/工作表上应用条件格式
- sql-server - 在 SSIS 包中获取 jobId 时出现语法错误
- arrays - 通过数组字段中的数组查找
- javascript - 检查页面加载是否使用 Response.Redirect 重定向页面
- ios - UIBezierPath 部分描边
- javascript - 将 HTML 中的组件标签链接到构造函数中传递的组件
- kubernetes - 如何在 Kubernetes 中对 LoadBalancer 类型的服务发出请求?
- java - 如何在netbeans中使用Serializable实现所有java类
- c# - c# Asp.net Web API 属性路由 404 错误
- html - 如何将元素 1 的颜色覆盖在主体或元素 2 的颜色上?