这个问题困扰了我很长一段时间,真的很烦人。
每次我在重新启动/重新启动后登录时,资源管理器都需要一些时间才能显示。
我采取了等待所有服务启动然后登录的步骤,但这没有任何区别。
结果总是相同的:即使应用程序已启动,某些图标也不会显示。
我对使一个应用程序“粘贴”图标的代码进行了一些研究,但是是否存在可以执行的 API 调用,以便资源管理器重新读取所有图标信息? 比如无效或重画之类的?
显然,看起来乔恩是对的,但这是不可能的。
我遵循 Bob Dizzle 和 Mark Ransom 代码并构建了这个(Delphi 代码):
procedure Refresh;
var
hSysTray: THandle;
begin
hSysTray := GetSystrayHandle;
SendMessage(hSysTray, WM_PAINT, 0, 0);
end;
function GetSystrayHandle: THandle;
var
hTray, hNotify, hSysPager: THandle;
begin
hTray := FindWindow('Shell_TrayWnd', '');
if hTray = 0 then
begin
Result := hTray;
exit;
end;
hNotify := FindWindowEx(hTray, 0, 'TrayNotifyWnd', '');
if hNotify = 0 then
begin
Result := hNotify;
exit;
end;
hSyspager := FindWindowEx(hNotify, 0, 'SysPager', '');
if hSyspager = 0 then
begin
Result := hSyspager;
exit;
end;
Result := FindWindowEx(hSysPager, 0, 'ToolbarWindow32', 'Notification Area');
end;
但无济于事。
我什至尝试过
InvalidateRect()
and still no show.
还有其他建议吗?
This problem has been afflicting me for quite a while and it's been really annoying.
Every time I login after a reboot/power cycle the explorer takes some time to show up.
I've taken the step of waiting for all the services to boot up and then I login, but it doesn't make any difference.
The result is always the same: Some of the icons do not show up even if the applications have started.
I've dug a bit on the code that makes one application "stick" an icon in there, but is there an API call that one can perform so explorer re-reads all that icon info? Like invalidate or redraw or something of the sort?
Apparently, it looks like Jon was right and it's not possible to do it.
I've followed Bob Dizzle and Mark Ransom code and build this (Delphi Code):
procedure Refresh;
var
hSysTray: THandle;
begin
hSysTray := GetSystrayHandle;
SendMessage(hSysTray, WM_PAINT, 0, 0);
end;
function GetSystrayHandle: THandle;
var
hTray, hNotify, hSysPager: THandle;
begin
hTray := FindWindow('Shell_TrayWnd', '');
if hTray = 0 then
begin
Result := hTray;
exit;
end;
hNotify := FindWindowEx(hTray, 0, 'TrayNotifyWnd', '');
if hNotify = 0 then
begin
Result := hNotify;
exit;
end;
hSyspager := FindWindowEx(hNotify, 0, 'SysPager', '');
if hSyspager = 0 then
begin
Result := hSyspager;
exit;
end;
Result := FindWindowEx(hSysPager, 0, 'ToolbarWindow32', 'Notification Area');
end;
But to no avail.
I've even tried with
InvalidateRect()
and still no show.
Any other suggestions?
发布评论
评论(9)
我使用以下 C++ 代码来获取托盘窗口的窗口句柄。 注意:仅在 Windows XP 上进行了测试。
I use the following C++ code to get the window handle to the tray window. Note: this has only been tested on Windows XP.
经过多次尝试,我发现有三个问题你必须要知道:
NotifyIconOverflowWindow
,而不是Shell_TrayWnd
。FindWindowEx
的caption
参数来查找窗口,因为Windows操作系统有很多语言版本,显然它们并不总是相同的标题。spy++
来查找或确定您想要的内容。所以,我更改了@Stephen Klancher 和@Louis Davis 的代码,谢谢你们。
以下代码对我有用。
After lots of times trying I found that there are three issues you must to know:
NotifyIconOverflowWindow
, other thanShell_TrayWnd
.caption
parameter ofFindWindowEx
to find a window, because these is lots of langue versions of Windows OS, they are not always be the same title Obviously.spy++
of Visual Studio to find or make assurance what you want.So, I changed code from @Stephen Klancher and @Louis Davis, thank you guys.
The following code worked for me.
@Skip R,以及任何其他想要用 C 语言执行此操作的人,此代码已在 Windows 10 64 位上的最近(最新)mingw 中验证编译(但安装了 mingw 32 位软件包),这似乎可以在 Windows XP 中使用/2003 摆脱陈旧的通知区域图标。
我通过 Chocolatey 安装了 mingw,如下所示:(
您的情况可能会有所不同,在我的系统上,编译器安装在此处:
然后一个简单的
生成一个 a.exe,它解决了我在 Windows 上遇到的陈旧通知区域图标问题2003(32 位)。
改编自上面的 @Stephen Klancher 的代码是(注意这可能仅适用于 Windows XP/2003,这满足了我的目的):
@Skip R, and anyone else wanting to do this in C, with this code verified compiled in a recent (most recent) mingw on Windows 10 64 bit (but with the mingw 32 bit package installed), this seems to work in Windows XP / 2003 to get rid of stale notification area icons.
I installed mingw via Chocolatey, like this:
(your mileage may vary on that, on my system, the compiler was then installed here:
and then a simple
yielded an a.exe which solved a stale notification area icon problem I was having on Windows 2003 (32 bit).
The code, adapted from @Stephen Klancher above is (note this may only work on Windows XP/2003, which fulfilled my purposes):
Powershell 解决方案,将其放入脚本中
然后使用
[pInvoke]::RefreshTrayArea()
重置Powershell solution, put this in your script
Then use
[pInvoke]::RefreshTrayArea()
to reset查看此博客条目:刷新任务栏通知区域。 我正在使用此代码刷新系统托盘以摆脱孤立的图标,它工作得很好。
该博客文章内容非常丰富,并且很好地解释了作者为发现解决方案而执行的步骤。
Take a look at this blog entry: REFRESHING THE TASKBAR NOTIFICATION AREA. I am using this code to refresh the system tray to get rid of orphaned icons and it works perfectly.
The blog entry is very informative and gives a great explanation of the steps the author performed to discover his solution.
去年,我在我的 Codeaholic 博客上发表了一篇题为 [Delphi] 更新 SysTray。
我的解决方案是 Delphi ActiveX/COM DLL。 下载链接仍然有效(尽管我不知道能持续多久,因为我的 PLUG 会员资格已失效.)
I covered this issue last year on my Codeaholic weblog in an article entitled [Delphi] Updating SysTray.
My solution is a Delphi ActiveX/COM DLL. The download link still works (though for how much longer I don't know as my PLUG membership has lapsed.)
据我所知,这是不可能的 Gustavo - 每个应用程序都应将其通知图标放入系统托盘中,并确保其保持正确的状态。
有时您会注意到,当 explorer.exe 崩溃时,某些图标不会重新出现 - 这并不是因为它们的进程崩溃了,而是因为当 explorer.exe 的新实例启动时,它们的应用程序没有将通知图标放入系统托盘中向上。 再次强调,是应用程序负责。
很抱歉没有给您带来更好的消息!
As far as I know that isn't possible Gustavo - it's up to each application to put its notifyicon in the systray, and ensure it's kept in the right state.
You'll notice sometimes when explorer.exe crashes that certain icons don't reappear - this isn't because their process has crashed, simply that their application hasn't put the notifyicon in the systray when the new instance of explorer.exe started up. Once again, it's the application that's responsible.
Sorry not to have better news for you!
在您的代码中包含以下代码以刷新系统托盘。
Include following code with yours to refresh System Tray.
对于任何使用路易斯答案的人来说,有两个重要细节(来自刷新任务栏通知区域) 在 Windows 7 或 Windows 8 上:
首先,正如答案所反映的那样,XP 中标题为“通知区域”的窗口现在在 Windows 7(实际上可能是 Vista)及更高版本中标题为“用户提升通知区域”。
其次,此代码不会清除当前隐藏的图标。 它们包含在一个单独的窗口中。 使用原始代码刷新可见图标,使用以下代码刷新隐藏图标。
对于只需要运行实用程序而不是代码来完成此操作的任何人,我使用此更新构建了一个简单的 exe:刷新通知区域
Two important details for anyone using Louis's answer (from REFRESHING THE TASKBAR NOTIFICATION AREA) on Windows 7 or Windows 8:
First, as the answer was reflected to show, the window titled "Notification Area" in XP is now titled "User Promoted Notification Area" in Windows 7 (actually probably Vista) and up.
Second, this code does not clear icons that are currently hidden. These are contained in a separate window. Use the original code to refresh visible icons, and the following to refresh hidden icons.
For anyone who just needs a utility to run to accomplish this, rather than code, I built a simple exe with this update: Refresh Notification Area