يمكنك إرسال إشارة إلى نظام التشغيل Windows مستكشف لجعله تحديث systray الرموز ؟

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

سؤال

هذه المشكلة يعاني منها لفترة طويلة و هو مزعج حقا.

في كل مرة كنت تسجيل الدخول بعد إعادة تشغيل الكمبيوتر/دورة الطاقة المستكشف يأخذ بعض الوقت لكي تظهر.لقد اتخذت الخطوة من انتظار جميع الخدمات الحذاء ثم تسجيل الدخول, ولكن لا تجعل أي فرق.والنتيجة هي دائما نفسها:بعض الرموز لا تظهر حتى لو كانت التطبيقات قد بدأت.

لقد حفرت قليلا على التعليمات البرمجية التي تجعل من تطبيق واحد "عصا" أيقونة في هناك ، ولكن هل هناك استدعاء API التي يمكن للمرء القيام بذلك explorer إعادة يقرأ كل هذا الرمز المعلومات ؟ مثل إبطال أو رسم أو شيء من هذا القبيل ؟


على ما يبدو ، يبدو أن جون كان على حق و انه لا يمكن أن تفعل ذلك.

لقد تابعت بوب Dizzle وعلامة فدية رمز وبناء هذا (دلفي) رمز:

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()
و لا تزال لا تظهر.

أي اقتراحات أخرى ؟

هل كانت مفيدة؟

المحلول

نلقي نظرة على هذا بلوق الدخول: تحديث ناحية إعلام شريط المهام.أنا باستخدام هذا الرمز إلى تحديث نظام صينية للتخلص من اليتامى الرموز وأنها تعمل تماما.بلوق دخول المفيد جدا ويعطي تفسير كبير من الخطوات المؤلف تؤدى إلى اكتشاف حل له.

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

نصائح أخرى

اثنين من التفاصيل الهامة لأي شخص باستخدام لويس الجواب (من تحديث ناحية إعلام شريط المهام) على ويندوز 7 أو ويندوز 8:

أولا, كما كان الجواب ينعكس تظهر نافذة بعنوان "منطقة الإعلام" في XP هو الآن بعنوان "المستخدم الترويج منطقة الإعلام" في ويندوز 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 في صينية النظام ، والتأكد من أنها تبقى في حق الدولة.

ستلاحظ في بعض الأحيان عندما explorer.exe تعطل بعض الرموز لا تعود الى الظهور - هذا ليس لأن العملية قد تحطمت ، ببساطة أن تطبيقها لم يضع notifyicon في systray عندما مثيل جديد من explorer.exe بدأت تصل.مرة أخرى, انها التطبيق الذي هو المسؤول.

آسف ليس لدي أخبار لك!

غطيت هذه المسألة العام الماضي على Codeaholic مدونة في مقال بعنوان [Delphi] تحديث SysTray.

الحل هو دلفي ActiveX/COM DLL.التحميل الرابط لا يزال يعمل (على الرغم من كم أنا لا أعرف بلدي المكونات عضوية قد انقضى.)

يمكنني استخدام التالية C++ كود الحصول على مقبض الإطار إلى إطار الدرج. ملاحظة: هذا فقط وقد تم اختبار على ويندوز 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");
}

@تخطي R ، وأي شخص آخر يريد أن يفعل ذلك في ج مع هذا رمز التحقق جمعت في الآونة الأخيرة (الأخيرة) مينغو على ويندوز 10 64 بت (ولكن مع مينغو 32 بت حزمة تثبيت), ويبدو أن العمل في نظام التشغيل Windows XP / 2003 للتخلص من التي لا معنى لها رموز منطقة الإعلام.

أنا ركبت مينغو عبر تشوكولاتيي, مثل هذا:

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

(الأميال الخاص بك قد تختلف عن ذلك ، فإن المترجم كان ثم تثبيتها هنا:

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

ثم بسيط

gcc refresh_notification_area.c

أسفرت عن a.exe التي تحل قديمة منطقة الإعلام أيقونة مشكلة على ويندوز 2003 (32 بت).

الكود مقتبس من @ستيفن Klancher أعلاه هو (ملاحظة هذه قد تعمل فقط على ويندوز XP/2003 التي تتحقق أغراض بلدي):

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

}

بعد الكثير من المرات يحاول وجدت أن هناك ثلاث مسائل يجب أن تعرف:

  • الأم خفية صينية نافذة NotifyIconOverflowWindow, بخلاف Shell_TrayWnd.
  • يجب عدم استخدام caption المعلمة FindWindowEx لتجد نافذة ، لأن هذه هي الكثير من langue إصدارات نظام التشغيل ويندوز ، فهي لا تكون دائما بنفس العنوان الواضح.
  • استخدام spy++ من Visual Studio أو تقديم ضمان ما تريد.

حتى لقد غيرت رمز من @ستيفن Klancher و @لويس ديفيز شكرا لكم يا رفاق.

التعليمة البرمجية التالية عملت بالنسبة لي.

#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);
        }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top