Можете ли вы отправить сигнал в Проводник Windows, чтобы обновить значки systray?
эта проблема беспокоила меня довольно долго, и это было действительно раздражает.
каждый раз, когда я вхожу в систему после перезагрузки / цикла питания, проводник занимает некоторое время. Я сделал шаг, ожидая загрузки всех служб, а затем вошел в систему, но это не имеет никакого значения. Результат всегда один и тот же: некоторые значки не отображаются, даже если приложения запущены.
Я немного покопался в коде, который делает одно приложение "вставьте" значок там, но есть ли вызов API, который можно выполнить, чтобы explorer перечитал всю информацию об этом значке? Например, аннулировать или перерисовать или что-то в этом роде?
по-видимому, похоже, что Джон был прав, и это невозможно сделать.
я следовал коду Боба Дизла и Марка Рэнсома и построил это (код 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()
и все еще нет шоу.
любой другой предложения?
6 ответов
взгляните на эту запись в блог: ОБНОВЛЕНИЕ ОБЛАСТИ УВЕДОМЛЕНИЙ ПАНЕЛИ ЗАДАЧ. Я использую этот код для обновления системного трея, чтобы избавиться от осиротевших значков, и он отлично работает. Запись в блоге очень информативна и дает отличное объяснение шагов, которые автор выполнил, чтобы найти свое решение.
#define FW(x,y) FindWindowEx(x, NULL, y, L"")
void RefreshTaskbarNotificationArea()
{
HWND hNotificationArea;
RECT r;
GetClientRect(
hNotificationArea = FindWindowEx(
FW(FW(FW(NULL, L"Shell_TrayWnd"), L"TrayNotifyWnd"), L"SysPager"),
NULL,
L"ToolbarWindow32",
// L"Notification Area"), // Windows XP
L"User Promoted Notification Area"), // Windows 7 and up
&r);
for (LONG x = 0; x < r.right; x += 5)
for (LONG y = 0; y < r.bottom; y += 5)
SendMessage(
hNotificationArea,
WM_MOUSEMOVE,
0,
(y << 16) + x);
}
две важные детали для тех, кто использует ответ Луиса (от ОБНОВЛЕНИЕ ОБЛАСТИ УВЕДОМЛЕНИЙ ПАНЕЛИ ЗАДАЧ) В Windows 7 или Windows 8:
во-первых, как было отражено в ответе, окно под названием "область уведомлений" в XP теперь называется "область уведомлений пользователя" в Windows 7 (на самом деле, вероятно, Vista) и выше.
во-вторых, этот код не очищает значки, которые в настоящее время скрыты. Они содержатся в отдельном окне. Использовать оригинал код для обновления видимых значков и следующие для обновления скрытых значков.
//Hidden icons
GetClientRect(
hNotificationArea = FindWindowEx(
FW(NULL, L"NotifyIconOverflowWindow"),
NULL,
L"ToolbarWindow32",
L"Overflow Notification Area"),
&r);
for (LONG x = 0; x < r.right; x += 5)
for (LONG y = 0; y < r.bottom; y += 5)
SendMessage(
hNotificationArea,
WM_MOUSEMOVE,
0,
(y << 16) + x);
для тех, кому просто нужна утилита для запуска, чтобы выполнить это, а не код, я построил простой exe с этим обновлением:Обновить Область Уведомлений
включите следующий код с вашим, чтобы обновить системный трей.
public const int WM_PAINT = 0xF;
[DllImport("USER32.DLL")]
public static extern int SendMessage(IntPtr hwnd, int msg, int character,
IntPtr lpsText);
Send WM_PAINT Message to paint System Tray which will refresh it.
SendMessage(traynotifywnd, WM_PAINT, 0, IntPtr.Zero);
насколько я знаю, это невозможно, Густаво - это до каждого приложения, чтобы поместить его notifyicon в systray и убедиться, что он находится в правильном состоянии.
вы заметите иногда, когда explorer.exe аварийно завершает работу, что некоторые значки не появляются-это не потому, что их процесс разбился, просто их приложение не поместило notifyicon в systray, когда новый экземпляр explorer.exe запустился. Еще раз, это приложение, которое ответственный.
Извините, что у вас нет лучших новостей для вас!
я освещал этот вопрос в прошлом году на моем Codeaholic weblog в статье под названием [Delphi] Обновление SysTray.
мое решение является Delphi ActiveX/COM DLL. Ссылка для загрузки все еще работает (хотя сколько еще я не знаю, как мой PLUG членство истек.)
Я использую следующий код C++, чтобы получить дескриптор окна к окну поднос. Примечание: Это было протестировано только на Windows XP.
HWND FindSystemTrayIcons(void)
{
// the system tray icons are contained in a specific window hierarchy;
// use the Spy++ utility to see the chain
HWND hwndTray = ::FindWindow("Shell_TrayWnd", "");
if (hwndTray == NULL)
return NULL;
HWND hwndNotifyWnd = ::FindWindowEx(hwndTray, NULL, "TrayNotifyWnd", "");
if (hwndNotifyWnd == NULL)
return NULL;
HWND hwndSysPager = ::FindWindowEx(hwndNotifyWnd, NULL, "SysPager", "");
if (hwndSysPager == NULL)
return NULL;
return ::FindWindowEx(hwndSysPager, NULL, "ToolbarWindow32", "Notification Area");
}