【发布时间】:2020-01-02 21:59:40
【问题描述】:
我正在为我的工作应用程序创建一个启动器。我希望当我最小化应用程序时,他会去托盘。我设法用按钮创建图标(单击调用 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 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;
【问题讨论】:
-
您不能对
SetWindowsHookEx()回调使用非静态类方法。所以你的TfrmMain.WndProc()不会为此工作。您需要改为使用独立函数或类静态方法。话虽如此,我根本不建议使用SetWindowsHookEx()来完成这项任务。使用SetWindowsLongPtr(GWL_WNDPROC)或更好的SetWindowSubclass()直接挂钩表单的FMX 创建的HWND。见FMX - Trayicon message handling -
请注意,任务栏右侧时钟旁边区域的正式名称是notification area。
-
@RemyLebeau 感谢您的 cmets。我试图理解,但没有走得太远。我复制了你的样本并放了一条节目信息和一个
frmMain.WindowState := TWindowState.wsMaximized;。但是当我将鼠标放在图标托盘上并且应用程序未最小化时,它们只会触发。因此,我尝试将我的 proc(WndProc 提早提到)并且无法做到这一点,我知道 CODE 是什么,所以我将WM_ICONTRAY更改为WM_SIZE。什么也没发生,有什么想法吗? -
是的,我是白痴,对不起。我刚刚滚动了一点你链接的帖子并得到了我需要的东西(点击后响应)。现在的问题是,我不知道如何使我的表单处于活动状态或恢复正常。我尝试在 proc 中使用命令
wsMaximazied并且没有任何操作,(他被最大化,但他没有走到前面。我需要单击任务栏)。但我认为这不是一个大问题,也许是另一篇文章。 ai是怎么发完帖子的? (只需编辑即可解决?)
标签: delphi hook firemonkey