Können Sie ein Signal an den Windows Explorer senden, um es die Systray-Icons zu machen auffrischen?

StackOverflow https://stackoverflow.com/questions/74723

Frage

Dieses Problem plagt mich wurde für eine ganze Weile und es ist wirklich ärgerlich.

Jedes Mal wenn ich anmelden nach einem Neustart / Leistungszyklus nimmt der Forscher einige Zeit zu zeigen. Ich habe den Schritt des Wartens für alle Dienste genommen booten und dann muss ich mich registrieren, aber es macht keinen Unterschied machen. Das Ergebnis ist immer das gleiche:. Einige Symbole zeigen, nicht einmal, wenn die Anwendungen gestartet haben

Ich habe ein bisschen auf dem Code ausgegraben, die dort eine Anwendung „Stick“ ein Symbol macht, aber gibt es einen API-Aufruf, dass man durchführen kann, so explorer wieder liest all das Symbol Informationen? Wie ungültig machen oder neu zu zeichnen oder etwas dergleichen?


Offenbar sieht es aus wie Jon war richtig, und es ist nicht möglich, es zu tun.

Ich habe folgte Bob Dizzle und Mark Ransom Code und bauen diese (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;

Aber ohne Erfolg.

Ich habe sogar versucht mit

InvalidateRect()
und noch nicht zeigen.

Alle anderen Vorschläge?

War es hilfreich?

Lösung

Werfen Sie einen Blick auf diesen Blog-Eintrag: Auffrischen der Taskbar Notification Area . Ich verwende diesen Code in der Taskleiste zu aktualisieren verwaiste Symbole, um loszuwerden, und es funktioniert perfekt. Der Blog-Eintrag ist sehr informativ und gibt eine große Erklärung der Schritte der Autor verrichtete seine Lösung zu entdecken.

#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);
}

Andere Tipps

Zwei wichtige Details für jedermann Louis Antwort mit (von REFRESHING der Taskleiste ) unter Windows 7 oder Windows 8:

Zuerst wird, wie die Antwort zu zeigen, wurde reflektiert, wird das Fenster mit dem Titel "Notification Area" in XP jetzt dem Titel "User Promoted Notification Area" in Windows 7 (eigentlich wahrscheinlich Vista) und höher.

Zweitens tut dieser Code nicht klar Symbole, die zur Zeit ausgeblendet. Diese werden in einem separaten Fenster enthalten ist. Verwenden Sie den ursprünglichen Code zu sichtbaren Symbole aufzufrischen, und die folgenden, um versteckte Symbole zu aktualisieren.

//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);

Für alle, die nur ein Dienstprogramm muss laufen, dies zu erreichen, anstatt Code, baute ich eine einfache exe mit diesem Update: Aktualisieren Notification Area

Fügen Sie mit Ihrem folgenden Code System Tray zu aktualisieren.

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);

Soweit ich weiß, dass nicht möglich Gustavo ist - es ist für jede Anwendung auf seine NotifyIcon im Systray zu stellen, und sicherzustellen, dass sie im richtigen Zustand gehalten wird.

Sie werden manchmal bemerken, wenn explorer.exe abstürzt, dass bestimmte Symbole nicht wieder angezeigt - das ist nicht, weil ihr Prozess abgestürzt ist, einfach, dass ihre Anwendung der NotifyIcon nicht im Systray setzen, wenn die neue Instanz von explorer .exe in Betrieb genommen. Noch einmal, es ist die Anwendung, die verantwortlich ist.

Leider bessere Nachrichten zu haben, nicht für Sie!

Ich deckte dieses Problem im vergangenen Jahr auf meinem Codeaholic Weblog in einem Titel Artikel [Delphi] aktualisiert SysTray .

Meine Lösung ist ein Delphi-ActiveX / COM-DLL. Der Download-Link funktioniert immer noch (wenn auch für wie lange, weiß ich nicht, wie mein STECKER Mitgliedschaft abgelaufen ist ).

Ich verwende den folgenden C ++ Code, um das Fenster-Handle auf das Tablett Fenster zu erhalten. . Hinweis: wurde dies nur unter Windows XP getestet

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");
}

@Skip R und alle andere wollen dies in C zu tun, mit diesem Code in einem aktuellen (letzten) mingw unter Windows 10 64-Bit überprüft zusammengestellt (aber mit dem mingw 32-Bit-Paket installiert ist), dies scheint zu funktionieren in Windows XP / 2003 zu den veralteten Infobereich Symbole loswerden.

Ich installierte mingw über Chocolatey, wie folgt aus:

choco install mingw --x86 --force --params "/exception:sjlj"

(Ihre Meilenzahl auf, dass auf meinem System variieren kann, wurde der Compiler dann hier installiert:

C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw32\bin\gcc.exe

und dann eine einfache

gcc refresh_notification_area.c

ergab eine a.exe, die einen schalen Symbol im Infobereich Problem löste ich auf Windows 2003 wurde (32 Bit).

Der Code, angepasst von @Stephen Klancher oben ist (beachten Sie, das nur unter Windows XP / 2003 arbeiten kann, die meine Zwecke erfüllt):

#include <windows.h>

#define FW(x,y) FindWindowEx(x, NULL, y, "")

int main ()
{

    HWND hNotificationArea;
    RECT r;

    //WinXP
    // technique found at:
    // https://stackoverflow.com/questions/74723/can-you-send-a-signal-to-windows-explorer-to-make-it-refresh-the-systray-icons#18038441
    GetClientRect(
        hNotificationArea = FindWindowEx(
            FW(FW(FW(NULL, "Shell_TrayWnd"), "TrayNotifyWnd"), "SysPager"),
            NULL,
            "ToolbarWindow32",
            "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);

  return 0;

}

Nach viele Male versucht, fand ich, dass es drei Dinge, die Sie müssen wissen:

  • Die Eltern von versteckten Fach Fenster ist NotifyIconOverflowWindow, andere als Shell_TrayWnd.
  • Sie sollten nicht caption Parameter von FindWindowEx verwenden, um ein Fenster zu finden, da diese vielen langue Versionen von Windows O sind, sind sie offensichtlich den gleichen Titel nicht immer sein.
  • Verwenden Sie spy++ von Visual Studio zu finden oder Sicherheit zu machen, was Sie wollen.

Also, ich geändert Code aus @Stephen Klancher und @Louis Davis, danke Jungs.

Der folgende Code für mich gearbeitet.

#define FW(x,y) FindWindowEx(x, NULL, y, L"")
void RefreshTaskbarNotificationArea()
{
    HWND hNotificationArea;
    RECT r;
    GetClientRect(hNotificationArea = FindWindowEx(FW(NULL, L"NotifyIconOverflowWindow"), NULL, L"ToolbarWindow32", NULL), &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);
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top