Kirill K. Smirnov : systray: Avoid modifying non-existent tooltip windows of non-existent icon windows when application updates tip of hidden icon .

Alexandre Julliard julliard at winehq.org
Fri Feb 15 05:36:03 CST 2008


Module: wine
Branch: master
Commit: 7515f312f923d3f50f6650dd1fd47fe312057be9
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7515f312f923d3f50f6650dd1fd47fe312057be9

Author: Kirill K. Smirnov <lich at math.spbu.ru>
Date:   Thu Feb  7 15:23:52 2008 +0000

systray: Avoid modifying non-existent tooltip windows of non-existent icon windows when application updates tip of hidden icon.

---

 programs/explorer/systray.c |   83 +++++++++++++++++++++++++++----------------
 1 files changed, 52 insertions(+), 31 deletions(-)

diff --git a/programs/explorer/systray.c b/programs/explorer/systray.c
index 9ddfd4d..8fa7447 100644
--- a/programs/explorer/systray.c
+++ b/programs/explorer/systray.c
@@ -65,6 +65,7 @@ struct icon
     UINT           id;       /* the unique id given by the app */
     UINT           callback_message;
     BOOL           hidden;   /* icon display state */
+    WCHAR          tiptext[128]; /* Tooltip text. If empty => tooltip disabled */
 };
 
 static struct tray tray;
@@ -151,8 +152,7 @@ static LRESULT WINAPI adaptor_wndproc(HWND window, UINT msg,
 }
 
 
-/* listener code */
-
+/* Retrieves icon record by owner window and ID */
 static struct icon *get_icon(HWND owner, UINT id)
 {
     struct icon *this;
@@ -164,31 +164,65 @@ static struct icon *get_icon(HWND owner, UINT id)
     return NULL;
 }
 
-static void set_tooltip(struct icon *icon, WCHAR *szTip, BOOL modify)
+/* Creates tooltip window for icon. */
+static void create_tooltip(struct icon *icon)
 {
     TTTOOLINFOW ti;
+    static BOOL tooltips_initialized = FALSE;
+
+    /* Register tooltip classes if this is the first icon */
+    if (!tooltips_initialized)
+    {
+        INITCOMMONCONTROLSEX init_tooltip;
+
+        init_tooltip.dwSize = sizeof(INITCOMMONCONTROLSEX);
+        init_tooltip.dwICC = ICC_TAB_CLASSES;
+
+        InitCommonControlsEx(&init_tooltip);
+        tooltips_initialized = TRUE;
+    }
 
+    icon->tooltip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
+                                   WS_POPUP | TTS_ALWAYSTIP,
+                                   CW_USEDEFAULT, CW_USEDEFAULT,
+                                   CW_USEDEFAULT, CW_USEDEFAULT,
+                                   icon->window, NULL, NULL, NULL);
+
+    ZeroMemory(&ti, sizeof(ti));
     ti.cbSize = sizeof(TTTOOLINFOW);
     ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND;
     ti.hwnd = icon->window;
-    ti.hinst = 0;
     ti.uId = (UINT_PTR)icon->window;
-    ti.lpszText = szTip;
-    ti.lParam = 0;
-    ti.lpReserved = NULL;
+    ti.lpszText = icon->tiptext;
+    SendMessageW(icon->tooltip, TTM_ADDTOOLW, 0, (LPARAM)&ti);
+}
 
-    if (modify)
-        SendMessageW(icon->tooltip, TTM_UPDATETIPTEXTW, 0, (LPARAM)&ti);
-    else
-        SendMessageW(icon->tooltip, TTM_ADDTOOLW, 0, (LPARAM)&ti);
+/* Synchronize tooltip text with tooltip window */
+static void update_tooltip_text(struct icon *icon)
+{
+    TTTOOLINFOW ti;
+
+    ZeroMemory(&ti, sizeof(ti));
+    ti.cbSize = sizeof(TTTOOLINFOW);
+    ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND;
+    ti.hwnd = icon->window;
+    ti.uId = (UINT_PTR)icon->window;
+    ti.lpszText = icon->tiptext;
+
+    SendMessageW(icon->tooltip, TTM_UPDATETIPTEXTW, 0, (LPARAM)&ti);
 }
 
+/*
+ * Sets visibility status of tray icon. Creates/deletes icon window.
+ * Does not create/delete icon record.
+ *
+ * The purpose is similar to ShowWindow function.
+ */
 static BOOL display_icon(struct icon *icon, BOOL hide)
 {
     HMODULE x11drv = GetModuleHandleA("winex11.drv");
     RECT rect;
     static const WCHAR adaptor_windowname[] = /* Wine System Tray Adaptor */ {'W','i','n','e',' ','S','y','s','t','e','m',' ','T','r','a','y',' ','A','d','a','p','t','o','r',0};
-    static BOOL tooltps_initialized = FALSE;
 
     WINE_TRACE("id=0x%x, hwnd=%p, hide=%d\n", icon->id, icon->owner, hide);
 
@@ -224,28 +258,12 @@ static BOOL display_icon(struct icon *icon, BOOL hide)
     if (!hide_systray)
         ShowWindow(icon->window, SW_SHOWNA);
 
-    /* create icon tooltip */
-
-    /* Register tooltip classes if this is the first icon */
-    if (!tooltps_initialized)
-    {
-        INITCOMMONCONTROLSEX init_tooltip;
+    create_tooltip(icon);
 
-        init_tooltip.dwSize = sizeof(INITCOMMONCONTROLSEX);
-        init_tooltip.dwICC = ICC_TAB_CLASSES;
-
-        InitCommonControlsEx(&init_tooltip);
-        tooltps_initialized = TRUE;
-    }
-
-    icon->tooltip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
-                                   WS_POPUP | TTS_ALWAYSTIP,
-                                   CW_USEDEFAULT, CW_USEDEFAULT,
-                                   CW_USEDEFAULT, CW_USEDEFAULT,
-                                   icon->window, NULL, NULL, NULL);
     return TRUE;
 }
 
+/* Modifies an existing icon record */
 static BOOL modify_icon(NOTIFYICONDATAW *nid, BOOL modify_tooltip)
 {
     struct icon    *icon;
@@ -285,7 +303,9 @@ static BOOL modify_icon(NOTIFYICONDATAW *nid, BOOL modify_tooltip)
     }
     if (nid->uFlags & NIF_TIP)
     {
-        set_tooltip(icon, nid->szTip, modify_tooltip);
+        lstrcpynW(icon->tiptext, nid->szTip, sizeof(icon->tiptext)/sizeof(WCHAR));
+        if (!icon->hidden)
+            update_tooltip_text(icon);
     }
     if (nid->uFlags & NIF_INFO && nid->cbSize >= NOTIFYICONDATAA_V2_SIZE)
     {
@@ -294,6 +314,7 @@ static BOOL modify_icon(NOTIFYICONDATAW *nid, BOOL modify_tooltip)
     return TRUE;
 }
 
+/* Adds a new icon record to the list */
 static BOOL add_icon(NOTIFYICONDATAW *nid)
 {
     struct icon  *icon;




More information about the wine-cvs mailing list