- separate tooltip area for each notify icon
authorMartin Fuchs <fuchs.martin@gmail.com>
Sun, 14 Mar 2004 21:02:55 +0000 (21:02 +0000)
committerMartin Fuchs <fuchs.martin@gmail.com>
Sun, 14 Mar 2004 21:02:55 +0000 (21:02 +0000)
- handle non-null terminated tooltip strings

svn path=/trunk/; revision=8737

reactos/subsys/system/explorer/taskbar/traynotify.cpp
reactos/subsys/system/explorer/taskbar/traynotify.h
reactos/subsys/system/explorer/utility/window.h

index 9fa62f6..c032ab4 100644 (file)
@@ -61,6 +61,16 @@ NotifyInfo::NotifyInfo()
 }
 
 
+ // WCHAR versions von NOTIFYICONDATA
+#define        NID_SIZE_W6      sizeof(NOTIFYICONDATAW)                                                                                // _WIN32_IE = 0x600
+#define        NID_SIZE_W5     (sizeof(NOTIFYICONDATAW)-sizeof(GUID))                                                  // _WIN32_IE = 0x500
+#define        NID_SIZE_W3     (sizeof(NOTIFYICONDATAW)-sizeof(GUID)-(128-64)*sizeof(WCHAR))   // _WIN32_IE < 0x500
+
+ // CHAR versions von NOTIFYICONDATA
+#define        NID_SIZE_A6      sizeof(NOTIFYICONDATAA)
+#define        NID_SIZE_A5     (sizeof(NOTIFYICONDATAA)-sizeof(GUID))
+#define        NID_SIZE_A3     (sizeof(NOTIFYICONDATAA)-sizeof(GUID)-(128-64)*sizeof(CHAR))
+
 NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid)
 {
        _hWnd = pnid->hWnd;
@@ -85,16 +95,33 @@ NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid)
 
         // store tool tip text
        if (pnid->uFlags & NIF_TIP)
-                // UNICODE version of NOTIFYICONDATA structure
-               if (pnid->cbSize == sizeof(NOTIFYICONDATAW) ||                          // _WIN32_IE = 0x600
-                       pnid->cbSize == sizeof(NOTIFYICONDATAW)-sizeof(GUID) || // _WIN32_IE = 0x500
-                       pnid->cbSize == sizeof(NOTIFYICONDATAW)-sizeof(GUID)-(128-64)*sizeof(WCHAR))// _WIN32_IE < 0x500
-                       _tipText = (LPCWSTR)pnid->szTip;
-                // ANSI version of NOTIFYICONDATA structure
-               else if (pnid->cbSize == sizeof(NOTIFYICONDATAA) ||                     // _WIN32_IE = 0x600
-                       pnid->cbSize == sizeof(NOTIFYICONDATAA)-sizeof(GUID) || // _WIN32_IE = 0x500
-                       pnid->cbSize == sizeof(NOTIFYICONDATAA)-sizeof(GUID)-(128-64)*sizeof(CHAR))     // _WIN32_IE < 0x400
-                       _tipText = (LPCSTR)pnid->szTip;
+               if (pnid->cbSize==NID_SIZE_W6 || pnid->cbSize==NID_SIZE_W5 || pnid->cbSize==NID_SIZE_W3)
+               { // UNICODE version of NOTIFYICONDATA structure
+                       LPCWSTR txt = (LPCWSTR)pnid->szTip;
+
+                        // get string length
+                       int max_len = pnid->cbSize==NID_SIZE_W3? 64: 128;
+
+                       int l = 0;
+                       for(; l<max_len; ++l)
+                               if (!txt[l])
+                                       break;
+
+                       _tipText.assign(txt, l);
+               } else if (pnid->cbSize==NID_SIZE_A6 || pnid->cbSize==NID_SIZE_A5 || pnid->cbSize==NID_SIZE_A3)
+               { // ANSI version of NOTIFYICONDATA structure
+                       LPCSTR txt = (LPCSTR)pnid->szTip;
+
+                        // get string length
+                       int max_len = pnid->cbSize==NID_SIZE_A3? 64: 128;
+
+                       int l = 0;
+                       for(int l=0; l<max_len; ++l)
+                               if (!txt[l])
+                                       break;
+
+                       _tipText.assign(txt, l);
+               }
 
        return *this;
 }
@@ -106,9 +133,8 @@ NotifyArea::NotifyArea(HWND hwnd)
 {
        _next_idx = 0;
        _clock_width = 0;
+       _last_icon_count = 0;
        _show_hidden = false;
-
-       _tooltip.add(_hwnd, _hwnd);     ///@todo use one area for each icon
 }
 
 LRESULT NotifyArea::Init(LPCREATESTRUCT pcs)
@@ -349,6 +375,24 @@ void NotifyArea::Refresh()
                        _sorted_icons.insert(entry);
        }
 
+        // sync tooltip areas to current icon number
+       if (_sorted_icons.size() != _last_icon_count) {
+               RECT rect = {2, 3, 2+16, 3+16};
+               size_t tt_idx = 0;
+
+               for(NotifyIconSet::const_iterator it=_sorted_icons.begin(); it!=_sorted_icons.end(); ++it) {
+                       _tooltip.add(_hwnd, tt_idx++, rect);
+
+                       rect.left += NOTIFYICON_DIST;
+                       rect.right += NOTIFYICON_DIST;
+               }
+
+               while(tt_idx < _last_icon_count)
+                       _tooltip.remove(_hwnd, tt_idx++);
+
+               _last_icon_count = _sorted_icons.size();
+       }
+
        SendMessage(GetParent(_hwnd), PM_RESIZE_CHILDREN, 0, 0);
 
        InvalidateRect(_hwnd, NULL, FALSE);     // refresh icon display
index 522f4e1..d5f780b 100644 (file)
@@ -94,6 +94,7 @@ protected:
        NotifyIconMap _icon_map;
        NotifyIconSet _sorted_icons;
        int             _next_idx;
+       size_t  _last_icon_count;
 
        ToolTip _tooltip;
 
index 02d7b90..8d615ab 100644 (file)
@@ -842,15 +842,43 @@ struct ToolTip : public WindowHandle
                SendMessage(_hwnd, TTM_ACTIVATE, active, 0);
        }
 
-       void add(HWND hparent, HWND htool, LPCTSTR txt=LPSTR_TEXTCALLBACK)
+       void add(HWND hparent, HWND htool, LPCTSTR txt=LPSTR_TEXTCALLBACK, LPARAM lparam=0)
        {
                TOOLINFO ti = {
-                       sizeof(TOOLINFO), TTF_SUBCLASS|TTF_IDISHWND/*|TTF_TRANSPARENT*/, hparent, (UINT)htool, {0,0,0,0}, 0, 0, 0
+                       sizeof(TOOLINFO), TTF_SUBCLASS|TTF_IDISHWND/*|TTF_TRANSPARENT*/, hparent, (UINT)htool,
+                       {0,0,0,0}, 0, (LPTSTR)txt, lparam
                };
-               ti.lpszText = (LPTSTR) txt;
 
                SendMessage(_hwnd, TTM_ADDTOOL, 0, (LPARAM)&ti);
        }
+
+       void add(HWND hparent, UINT id, const RECT& rect, LPCTSTR txt=LPSTR_TEXTCALLBACK, LPARAM lparam=0)
+       {
+               TOOLINFO ti = {
+                       sizeof(TOOLINFO), TTF_SUBCLASS/*|TTF_TRANSPARENT*/, hparent, id,
+                       {rect.left,rect.top,rect.right,rect.bottom}, 0, (LPTSTR)txt, lparam
+               };
+
+               SendMessage(_hwnd, TTM_ADDTOOL, 0, (LPARAM)&ti);
+       }
+
+       void remove(HWND hparent, HWND htool)
+       {
+               TOOLINFO ti = {
+                       sizeof(TOOLINFO), TTF_IDISHWND, hparent, (UINT)htool, {0,0,0,0}, 0, 0, 0
+               };
+
+               SendMessage(_hwnd, TTM_DELTOOL, 0, (LPARAM)&ti);
+       }
+
+       void remove(HWND hparent, UINT id)
+       {
+               TOOLINFO ti = {
+                       sizeof(TOOLINFO), 0, hparent, id, {0,0,0,0}, 0, 0, 0
+               };
+
+               SendMessage(_hwnd, TTM_DELTOOL, 0, (LPARAM)&ti);
+       }
 };