14

この問題はかなり長い間私を悩ませてきました。

再起動/電源サイクル後にログインするたびに、エクスプローラーが表示されるまでに時間がかかります。すべてのサービスが起動するのを待ってからログインするという手順を実行しましたが、違いはありません。結果は常に同じです。アプリケーションが起動しても、一部のアイコンが表示されません。

1 つのアプリケーションにアイコンを「貼り付ける」コードを少し掘り下げましたが、エクスプローラーがすべてのアイコン情報を再読み取りできるように実行できる API 呼び出しはありますか? 無効にするか、再描画するか、そのようなものですか?


どうやら、ジョンが正しかったようで、それは不可能です。

Bob Dizzle と Mark Ransom のコードに従って、これをビルドしました (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;

しかし、役に立たない。

私も試してみました

InvalidateRect()
そしてまだショーはありません。

他の提案はありますか?

4

8 に答える 8

13

このブログ エントリをご覧ください:タスクバー通知領域の更新. このコードを使用してシステム トレイを更新し、孤立したアイコンを削除していますが、完全に機能します。ブログ エントリは非常に有益であり、著者が解決策を発見するために実行した手順についての優れた説明を提供します。

#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);
}
于 2009-06-27T14:33:02.797 に答える
13

Windows 7またはWindows 8でLouisの回答(タスクバー通知領域の更新から)を使用する人にとって2つの重要な詳細:

まず、回答が反映されているように、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 を作成しました:通知領域の更新

于 2013-08-03T23:54:23.437 に答える
4

システム トレイを更新するには、次のコードを含めます。

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);
于 2008-09-16T17:24:19.463 に答える
2

私の知る限り、それは不可能です。Gustavo - 通知アイコンをシステム トレイに配置し、適切な状態に保つのは各アプリケーション次第です。

explorer.exe がクラッシュしたときに、特定のアイコンが再表示されないことに気付くことがあります。これは、プロセスがクラッシュしたためではなく、explorer.exe の新しいインスタンスが開始されたときにアプリケーションが通知アイコンをシステム トレイに配置しなかったためです。上。繰り返しますが、責任があるのはアプリケーションです。

良いニュースがなくてごめんなさい!

于 2008-09-16T17:23:11.527 に答える
2

この問題については、昨年、Codeaholicウェブログの[Delphi] Updating SysTrayという記事で取り上げました。

私のソリューションは、Delphi ActiveX/COM DLL です。ダウンロード リンクは引き続き機能します (ただし、 PLUGメンバーシップが失効したため、いつまで続くかはわかりません)。

于 2009-06-27T14:45:29.310 に答える
1

次のC++コードを使用して、ウィンドウハンドルをトレイウィンドウに取得します。 注:これはWindowsXPでのみテストされています。

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

于 2008-09-16T17:35:23.307 に答える