[EXPLORER] -Reload the theme data only when the orientation changes (we ended up...
[reactos.git] / reactos / base / shell / explorer / trayntfy.cpp
index 6bb1e23..d91e2f5 100644 (file)
@@ -26,7 +26,7 @@
 /*
  * SysPagerWnd
  */
-static const WCHAR szSysPagerWndClass [] = TEXT("SysPager");
+static const WCHAR szSysPagerWndClass [] = L"SysPager";
 
 // Data comes from shell32/systray.cpp -> TrayNotifyCDS_Dummy
 typedef struct _SYS_PAGER_COPY_DATA
@@ -37,7 +37,7 @@ typedef struct _SYS_PAGER_COPY_DATA
 } SYS_PAGER_COPY_DATA, *PSYS_PAGER_COPY_DATA;
 
 class CNotifyToolbar :
-    public CToolbar<NOTIFYICONDATA>
+    public CWindowImplBaseT< CToolbar<NOTIFYICONDATA>, CControlWinTraits >
 {
     static const int ICON_SIZE = 16;
 
@@ -82,17 +82,16 @@ public:
         return -1;
     }
 
-    VOID AddButton(IN CONST NOTIFYICONDATA *iconData)
+    BOOL AddButton(IN CONST NOTIFYICONDATA *iconData)
     {
         TBBUTTON tbBtn;
         NOTIFYICONDATA * notifyItem;
-        WCHAR text [] = TEXT("");
+        WCHAR text[] = L"";
 
         int index = FindItemByIconData(iconData, &notifyItem);
         if (index >= 0)
         {
-            UpdateButton(iconData);
-            return;
+            return UpdateButton(iconData);
         }
 
         notifyItem = new NOTIFYICONDATA();
@@ -132,16 +131,17 @@ public:
                 tbBtn.fsState |= TBSTATE_HIDDEN;
                 m_VisibleButtonCount--;
             }
-
         }
 
         /* TODO: support NIF_INFO, NIF_GUID, NIF_REALTIME, NIF_SHOWTIP */
 
         CToolbar::AddButton(&tbBtn);
         SetButtonSize(ICON_SIZE, ICON_SIZE);
+
+        return TRUE;
     }
 
-    VOID UpdateButton(IN CONST NOTIFYICONDATA *iconData)
+    BOOL UpdateButton(IN CONST NOTIFYICONDATA *iconData)
     {
         NOTIFYICONDATA * notifyItem;
         TBBUTTONINFO tbbi = { 0 };
@@ -149,8 +149,7 @@ public:
         int index = FindItemByIconData(iconData, &notifyItem);
         if (index < 0)
         {
-            AddButton(iconData);
-            return;
+            return AddButton(iconData);
         }
 
         tbbi.cbSize = sizeof(tbbi);
@@ -165,7 +164,7 @@ public:
         if (iconData->uFlags & NIF_ICON)
         {
             tbbi.dwMask |= TBIF_IMAGE;
-            tbbi.iImage = ImageList_AddIcon(m_ImageList, iconData->hIcon);
+            tbbi.iImage = ImageList_ReplaceIcon(m_ImageList, index, iconData->hIcon);
         }
 
         if (iconData->uFlags & NIF_TIP)
@@ -198,18 +197,42 @@ public:
         /* TODO: support NIF_INFO, NIF_GUID, NIF_REALTIME, NIF_SHOWTIP */
 
         SetButtonInfo(index, &tbbi);
+
+        return TRUE;
     }
 
-    VOID RemoveButton(IN CONST NOTIFYICONDATA *iconData)
+    BOOL RemoveButton(IN CONST NOTIFYICONDATA *iconData)
     {
         NOTIFYICONDATA * notifyItem;
 
         int index = FindItemByIconData(iconData, &notifyItem);
         if (index < 0)
-            return;
+            return FALSE;
+
+        if (!(notifyItem->dwState & NIS_HIDDEN))
+        {
+            m_VisibleButtonCount--;
+        }
 
-        DeleteButton(index);
         delete notifyItem;
+
+        ImageList_Remove(m_ImageList, index);
+
+        int count = GetButtonCount();
+
+        /* shift all buttons one index to the left -- starting one index right
+           from item to delete -- to preserve their correct icon and tip */
+        for (int i = index; i < count - 1; i++)
+        {
+            notifyItem = GetItemData(i + 1);
+            SetItemData(i, notifyItem);
+            UpdateButton(notifyItem);
+        }
+
+        /* Delete the right-most, now obsolete button */
+        DeleteButton(count - 1);
+
+        return TRUE;
     }
 
     VOID GetTooltipText(int index, LPTSTR szTip, DWORD cchTip)
@@ -247,7 +270,27 @@ private:
         NOTIFYICONDATA * notifyItem = GetItemData(wIndex);
 
         if (!::IsWindow(notifyItem->hWnd))
+        {
+            // We detect and destroy icons with invalid handles only on mouse move over systray, same as MS does.
+            // Alternatively we could search for them periodically (would waste more resources).
+            TRACE("destroying icon with invalid handle\n");
+
+            HWND parentHWND = GetParent();
+            parentHWND = ::GetParent(parentHWND);
+
+            RECT windowRect;
+            ::GetClientRect(parentHWND, &windowRect);
+
+            RemoveButton(notifyItem);
+
+            SendMessage(parentHWND,
+                WM_SIZE,
+                0,
+                MAKELONG(windowRect.right - windowRect.left,
+                         windowRect.bottom - windowRect.top));
+
             return;
+        }
 
         if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)
         {
@@ -262,10 +305,10 @@ private:
         if (pid == GetCurrentProcessId() ||
             (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST))
         {
-            PostMessage(notifyItem->hWnd,
-                        notifyItem->uCallbackMessage,
-                        notifyItem->uID,
-                        uMsg);
+            ::PostMessage(notifyItem->hWnd,
+                          notifyItem->uCallbackMessage,
+                          notifyItem->uID,
+                          uMsg);
         }
         else
         {
@@ -279,7 +322,7 @@ private:
     LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
     {
         POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
-        
+
         INT iBtn = HitTest(&pt);
 
         if (iBtn >= 0)
@@ -294,7 +337,7 @@ private:
     LRESULT OnTooltipShow(INT uCode, LPNMHDR hdr, BOOL& bHandled)
     {
         RECT rcTip, rcItem;
-        GetWindowRect(hdr->hwndFrom, &rcTip);
+        ::GetWindowRect(hdr->hwndFrom, &rcTip);
 
         SIZE szTip = { rcTip.right - rcTip.left, rcTip.bottom - rcTip.top };
 
@@ -310,13 +353,13 @@ private:
             if (hMon)
                 GetMonitorInfo(hMon, &monInfo);
             else
-                GetWindowRect(GetDesktopWindow(), &monInfo.rcMonitor);
+                ::GetWindowRect(GetDesktopWindow(), &monInfo.rcMonitor);
 
             GetItemRect(iBtn, &rcItem);
 
             POINT ptItem = { rcItem.left, rcItem.top };
             SIZE szItem = { rcItem.right - rcItem.left, rcItem.bottom - rcItem.top };
-            ClientToScreen(m_hWnd, &ptItem);
+            ClientToScreen(&ptItem);
 
             ptItem.x += szItem.cx / 2;
             ptItem.y -= szTip.cy;
@@ -358,7 +401,7 @@ public:
             TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | TBSTYLE_WRAPABLE | TBSTYLE_TRANSPARENT |
             CCS_TOP | CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NODIVIDER;
 
-        SubclassWindow(Create(hWndParent, styles));
+        SubclassWindow(CToolbar::Create(hWndParent, styles));
 
         SetWindowTheme(m_hWnd, L"TrayNotify", NULL);
 
@@ -405,10 +448,16 @@ public:
     LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
     {
         Toolbar.Initialize(m_hWnd);
+
+        // Explicitly request running applications to re-register their systray icons
+        ::SendNotifyMessageW(HWND_BROADCAST,
+                             RegisterWindowMessageW(L"TaskbarCreated"),
+                             0, 0);
+
         return TRUE;
     }
 
-    LRESULT NotifyMsg(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+    BOOL NotifyIconCmd(WPARAM wParam, LPARAM lParam)
     {
         PCOPYDATASTRUCT cpData = (PCOPYDATASTRUCT) lParam;
         if (cpData->dwData == 1)
@@ -417,6 +466,7 @@ public:
             NOTIFYICONDATA *iconData;
             HWND parentHWND;
             RECT windowRect;
+            BOOL ret = FALSE;
             parentHWND = GetParent();
             parentHWND = ::GetParent(parentHWND);
             ::GetClientRect(parentHWND, &windowRect);
@@ -424,32 +474,30 @@ public:
             data = (PSYS_PAGER_COPY_DATA) cpData->lpData;
             iconData = &data->nicon_data;
 
+            TRACE("NotifyIconCmd received. Code=%d\n", data->notify_code);
             switch (data->notify_code)
             {
             case NIM_ADD:
-            {
-                Toolbar.AddButton(iconData);
+                ret = Toolbar.AddButton(iconData);
                 break;
-            }
             case NIM_MODIFY:
-            {
-                Toolbar.UpdateButton(iconData);
+                ret = Toolbar.UpdateButton(iconData);
                 break;
-            }
             case NIM_DELETE:
-            {
-                Toolbar.RemoveButton(iconData);
+                ret = Toolbar.RemoveButton(iconData);
                 break;
-            }
             default:
-                TRACE("NotifyMessage received with unknown code %d.\n", data->notify_code);
-                break;
+                TRACE("NotifyIconCmd received with unknown code %d.\n", data->notify_code);
+                return FALSE;
             }
+
             SendMessage(parentHWND,
                 WM_SIZE,
                 0,
                 MAKELONG(windowRect.right - windowRect.left,
-                windowRect.bottom - windowRect.top));
+                         windowRect.bottom - windowRect.top));
+
+            return ret;
         }
 
         return TRUE;
@@ -533,12 +581,19 @@ public:
         return Ret;
     }
 
+    LRESULT OnCtxMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+    {
+        bHandled = TRUE;
+        return 0;
+    }
+
     DECLARE_WND_CLASS_EX(szSysPagerWndClass, CS_DBLCLKS, COLOR_3DFACE)
 
     BEGIN_MSG_MAP(CTaskSwitchWnd)
         MESSAGE_HANDLER(WM_CREATE, OnCreate)
         MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
         MESSAGE_HANDLER(WM_SIZE, OnSize)
+        MESSAGE_HANDLER(WM_CONTEXTMENU, OnCtxMenu)
         NOTIFY_CODE_HANDLER(TBN_GETINFOTIPW, OnGetInfoTip)
         NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw)
     END_MSG_MAP()
@@ -570,7 +625,7 @@ public:
  * TrayClockWnd
  */
 
-static const WCHAR szTrayClockWndClass [] = TEXT("TrayClockWClass");
+static const WCHAR szTrayClockWndClass[] = L"TrayClockWClass";
 
 #define ID_TRAYCLOCK_TIMER  0
 #define ID_TRAYCLOCK_TIMER_INIT 1
@@ -579,14 +634,14 @@ static const struct
 {
     BOOL IsTime;
     DWORD dwFormatFlags;
-    LPCTSTR lpFormat;
+    LPCWSTR lpFormat;
 } ClockWndFormats [] = {
-        { TRUE, 0, NULL },
-        { FALSE, 0, TEXT("dddd") },
-        { FALSE, DATE_SHORTDATE, NULL }
+    { TRUE, 0, NULL },
+    { FALSE, 0, L"dddd" },
+    { FALSE, DATE_SHORTDATE, NULL }
 };
 
-#define CLOCKWND_FORMAT_COUNT (sizeof(ClockWndFormats) / sizeof(ClockWndFormats[0]))
+#define CLOCKWND_FORMAT_COUNT (_ARRAYSIZE(ClockWndFormats))
 
 #define TRAY_CLOCK_WND_SPACING_X    0
 #define TRAY_CLOCK_WND_SPACING_Y    0
@@ -631,7 +686,7 @@ public:
         ZeroMemory(&LocalTime, sizeof(LocalTime));
         ZeroMemory(&CurrentSize, sizeof(CurrentSize));
         ZeroMemory(LineSizes, sizeof(LineSizes));
-        ZeroMemory(szLines, sizeof(LineSizes));
+        ZeroMemory(szLines, sizeof(szLines));
     }
     virtual ~CTrayClockWnd() { }
 
@@ -659,20 +714,19 @@ public:
                 0,
                 TMT_TEXTCOLOR,
                 &textColor);
+
+            if (this->hFont != NULL)
+                DeleteObject(this->hFont);
+
+            SetFont(hFont, FALSE);
         }
         else
         {
-            NONCLIENTMETRICS ncm = { 0 };
-            ncm.cbSize = sizeof(ncm);
-            SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, FALSE);
-
-            hFont = CreateFontIndirectW(&ncm.lfMessageFont);
-
+            /* We don't need to set a font here, our parent will use 
+              * WM_SETFONT to set the right one when themes are not enabled. */
             textColor = RGB(0, 0, 0);
         }
 
-        SetFont(hFont, FALSE);
-
         CloseThemeData(clockTheme);
 
         return TRUE;
@@ -687,20 +741,20 @@ public:
     {
         HDC hDC;
         HFONT hPrevFont;
-        INT c, i;
+        UINT c, i;
         BOOL bRet = TRUE;
 
-        hDC = GetDC(m_hWnd);
+        hDC = GetDC();
         if (hDC != NULL)
         {
             if (hFont)
                 hPrevFont = (HFONT) SelectObject(hDC, hFont);
 
-            for (i = 0; i != CLOCKWND_FORMAT_COUNT && bRet; i++)
+            for (i = 0; i < CLOCKWND_FORMAT_COUNT && bRet; i++)
             {
-                if (szLines[i][0] != TEXT('\0') &&
-                    !GetTextExtentPoint(hDC, szLines[i], _tcslen(szLines[i]),
-                    &LineSizes[i]))
+                if (szLines[i][0] != L'\0' &&
+                    !GetTextExtentPointW(hDC, szLines[i], wcslen(szLines[i]),
+                                         &LineSizes[i]))
                 {
                     bRet = FALSE;
                     break;
@@ -710,14 +764,14 @@ public:
             if (hFont)
                 SelectObject(hDC, hPrevFont);
 
-            ReleaseDC(m_hWnd, hDC);
+            ReleaseDC(hDC);
 
             if (bRet)
             {
                 LineSpacing = 0;
 
                 /* calculate the line spacing */
-                for (i = 0, c = 0; i != CLOCKWND_FORMAT_COUNT; i++)
+                for (i = 0, c = 0; i < CLOCKWND_FORMAT_COUNT; i++)
                 {
                     if (LineSizes[i].cx > 0)
                     {
@@ -728,7 +782,7 @@ public:
 
                 if (c > 0)
                 {
-                    /* We want a spaceing of 1/2 line */
+                    /* We want a spacing of 1/2 line */
                     LineSpacing = (LineSpacing / c) / 2;
                 }
 
@@ -742,7 +796,7 @@ public:
     WORD GetMinimumSize(IN BOOL Horizontal, IN OUT PSIZE pSize)
     {
         WORD iLinesVisible = 0;
-        INT i;
+        UINT i;
         SIZE szMax = { 0, 0 };
 
         if (!LinesMeasured)
@@ -751,9 +805,7 @@ public:
         if (!LinesMeasured)
             return 0;
 
-        for (i = 0;
-            i != CLOCKWND_FORMAT_COUNT;
-            i++)
+        for (i = 0; i < CLOCKWND_FORMAT_COUNT; i++)
         {
             if (LineSizes[i].cx != 0)
             {
@@ -795,28 +847,26 @@ public:
     }
 
 
-    VOID        UpdateWnd()
+    VOID UpdateWnd()
     {
         SIZE szPrevCurrent;
-        INT BufSize, iRet, i;
+        UINT BufSize, i;
+        INT iRet;
         RECT rcClient;
 
-        ZeroMemory(LineSizes,
-            sizeof(LineSizes));
+        ZeroMemory(LineSizes, sizeof(LineSizes));
 
         szPrevCurrent = CurrentSize;
 
-        for (i = 0;
-            i != CLOCKWND_FORMAT_COUNT;
-            i++)
+        for (i = 0; i < CLOCKWND_FORMAT_COUNT; i++)
         {
-            szLines[i][0] = TEXT('\0');
-            BufSize = sizeof(szLines[0]) / sizeof(szLines[0][0]);
+            szLines[i][0] = L'\0';
+            BufSize = _countof(szLines[0]);
 
             if (ClockWndFormats[i].IsTime)
             {
                 iRet = GetTimeFormat(LOCALE_USER_DEFAULT,
-                    AdvancedSettings.bShowSeconds ? ClockWndFormats[i].dwFormatFlags : TIME_NOSECONDS,
+                    TaskBarSettings.bShowSeconds ? ClockWndFormats[i].dwFormatFlags : TIME_NOSECONDS,
                     &LocalTime,
                     ClockWndFormats[i].lpFormat,
                     szLines[i],
@@ -853,7 +903,7 @@ public:
             CurrentSize = szWnd;
         }
 
-        if (IsWindowVisible(m_hWnd))
+        if (IsWindowVisible())
         {
             InvalidateRect(NULL, TRUE);
 
@@ -864,7 +914,7 @@ public:
                 NMHDR nmh;
 
                 nmh.hwndFrom = m_hWnd;
-                nmh.idFrom = GetWindowLongPtr(m_hWnd, GWLP_ID);
+                nmh.idFrom = GetWindowLongPtr(GWLP_ID);
                 nmh.code = NTNWM_REALIGN;
 
                 SendMessage(hWndNotify,
@@ -875,20 +925,20 @@ public:
         }
     }
 
-    VOID        Update()
+    VOID Update()
     {
         GetLocalTime(&LocalTime);
         UpdateWnd();
     }
 
-    UINT        CalculateDueTime()
+    UINT CalculateDueTime()
     {
         UINT uiDueTime;
 
         /* Calculate the due time */
         GetLocalTime(&LocalTime);
         uiDueTime = 1000 - (UINT) LocalTime.wMilliseconds;
-        if (AdvancedSettings.bShowSeconds)
+        if (TaskBarSettings.bShowSeconds)
             uiDueTime += (UINT) LocalTime.wSecond * 100;
         else
             uiDueTime += (59 - (UINT) LocalTime.wSecond) * 1000;
@@ -905,7 +955,7 @@ public:
         return uiDueTime;
     }
 
-    BOOL        ResetTime()
+    BOOL ResetTime()
     {
         UINT uiDueTime;
         BOOL Ret;
@@ -934,7 +984,7 @@ public:
         return Ret;
     }
 
-    VOID        CalibrateTimer()
+    VOID CalibrateTimer()
     {
         UINT uiDueTime;
         BOOL Ret;
@@ -946,7 +996,7 @@ public:
 
         uiDueTime = CalculateDueTime();
 
-        if (AdvancedSettings.bShowSeconds)
+        if (TaskBarSettings.bShowSeconds)
         {
             uiWait1 = 1000 - 200;
             uiWait2 = 1000;
@@ -996,7 +1046,8 @@ public:
     {
         RECT rcClient;
         HFONT hPrevFont;
-        int iPrevBkMode, i, line;
+        INT iPrevBkMode;
+        UINT i, line;
 
         PAINTSTRUCT ps;
         HDC hDC = (HDC) wParam;
@@ -1024,8 +1075,8 @@ public:
             rcClient.bottom = rcClient.top + CurrentSize.cy;
 
             for (i = 0, line = 0;
-                i != CLOCKWND_FORMAT_COUNT && line < VisibleLines;
-                i++)
+                 i < CLOCKWND_FORMAT_COUNT && line < VisibleLines;
+                 i++)
             {
                 if (LineSizes[i].cx != 0)
                 {
@@ -1034,7 +1085,7 @@ public:
                         TRAY_CLOCK_WND_SPACING_X,
                         rcClient.top + TRAY_CLOCK_WND_SPACING_Y,
                         szLines[i],
-                        _tcslen(szLines[i]));
+                        wcslen(szLines[i]));
 
                     rcClient.top += LineSizes[i].cy + LineSpacing;
                     line++;
@@ -1154,8 +1205,10 @@ public:
         MESSAGE_HANDLER(WM_SIZE, OnSize)
         MESSAGE_HANDLER(WM_PAINT, OnPaint)
         MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
+        MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged)
         MESSAGE_HANDLER(WM_TIMER, OnTimer)
         MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
+        MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
         MESSAGE_HANDLER(TCWM_GETMINIMUMSIZE, OnGetMinimumSize)
         MESSAGE_HANDLER(TCWM_UPDATETIME, OnUpdateTime)
 
@@ -1176,10 +1229,7 @@ public:
         Create(hWndParent, 0, NULL, dwStyle);
 
         if (m_hWnd != NULL)
-        {
             SetWindowTheme(m_hWnd, L"TrayNotify", NULL);
-            OnThemeChanged();
-        }
 
         return m_hWnd;
 
@@ -1284,25 +1334,17 @@ public:
         m_pager = new CSysPagerWnd();
         m_pager->_Init(m_hWnd, !HideClock);
 
-        OnThemeChanged();
-
         return TRUE;
     }
 
-    BOOL GetMinimumSize(IN BOOL Horizontal, IN OUT PSIZE pSize)
+    BOOL GetMinimumSize(IN OUT PSIZE pSize)
     {
         SIZE szClock = { 0, 0 };
         SIZE szTray = { 0, 0 };
 
-        IsHorizontal = Horizontal;
-        if (IsHorizontal)
-            SetWindowTheme(m_hWnd, L"TrayNotifyHoriz", NULL);
-        else
-            SetWindowTheme(m_hWnd, L"TrayNotifyVert", NULL);
-
         if (!HideClock)
         {
-            if (Horizontal)
+            if (IsHorizontal)
             {
                 szClock.cy = pSize->cy - 2 * TRAY_NOTIFY_WND_SPACING_Y;
                 if (szClock.cy <= 0)
@@ -1315,7 +1357,7 @@ public:
                     goto NoClock;
             }
 
-            m_clock->SendMessage(TCWM_GETMINIMUMSIZE, (WPARAM) Horizontal, (LPARAM) &szClock);
+            m_clock->SendMessage(TCWM_GETMINIMUMSIZE, (WPARAM) IsHorizontal, (LPARAM) &szClock);
 
             szTrayClockMin = szClock;
         }
@@ -1323,7 +1365,7 @@ public:
         NoClock:
         szTrayClockMin = szClock;
 
-        if (Horizontal)
+        if (IsHorizontal)
         {
             szTray.cy = pSize->cy - 2 * TRAY_NOTIFY_WND_SPACING_Y;
         }
@@ -1332,11 +1374,11 @@ public:
             szTray.cx = pSize->cx - 2 * TRAY_NOTIFY_WND_SPACING_X;
         }
 
-        m_pager->GetSize(Horizontal, &szTray);
+        m_pager->GetSize(IsHorizontal, &szTray);
 
         szTrayNotify = szTray;
 
-        if (Horizontal)
+        if (IsHorizontal)
         {
             pSize->cx = 2 * TRAY_NOTIFY_WND_SPACING_X;
 
@@ -1412,6 +1454,7 @@ public:
 
     LRESULT DrawBackground(HDC hdc)
     {
+        HRESULT res;
         RECT rect;
 
         GetClientRect(&rect);
@@ -1423,10 +1466,10 @@ public:
                 DrawThemeParentBackground(m_hWnd, hdc, &rect);
             }
 
-            DrawThemeBackground(TrayTheme, hdc, TNP_BACKGROUND, 0, &rect, 0);
+            res = DrawThemeBackground(TrayTheme, hdc, TNP_BACKGROUND, 0, &rect, 0);
         }
 
-        return TRUE;
+        return res;
     }
 
     LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
@@ -1442,11 +1485,11 @@ public:
         return DrawBackground(hdc);
     }
 
-    LRESULT NotifyMsg(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+    BOOL NotifyIconCmd(WPARAM wParam, LPARAM lParam)
     {
         if (m_pager)
         {
-            m_pager->NotifyMsg(uMsg, wParam, lParam, bHandled);
+            return m_pager->NotifyIconCmd(wParam, lParam);
         }
 
         return TRUE;
@@ -1454,15 +1497,26 @@ public:
 
     BOOL GetClockRect(OUT PRECT rcClock)
     {
-        if (!IsWindowVisible(m_clock->m_hWnd))
+        if (!m_clock->IsWindowVisible())
             return FALSE;
 
-        return GetWindowRect(m_clock->m_hWnd, rcClock);
+        return m_clock->GetWindowRect(rcClock);
     }
 
     LRESULT OnGetMinimumSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
     {
-        return (LRESULT) GetMinimumSize((BOOL) wParam, (PSIZE) lParam);
+        BOOL Horizontal = (BOOL) wParam;
+
+        if (Horizontal != IsHorizontal)
+        {
+            IsHorizontal = Horizontal;
+            if (IsHorizontal)
+                SetWindowTheme(m_hWnd, L"TrayNotifyHoriz", NULL);
+            else
+                SetWindowTheme(m_hWnd, L"TrayNotifyVert", NULL);
+        }
+
+        return (LRESULT) GetMinimumSize((PSIZE) lParam);
     }
 
     LRESULT OnUpdateTime(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
@@ -1529,6 +1583,12 @@ public:
         return FALSE;
     }
 
+    LRESULT OnCtxMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+    {
+        bHandled = TRUE;
+        return 0;
+    }
+
     DECLARE_WND_CLASS_EX(szTrayNotifyWndClass, CS_DBLCLKS, COLOR_3DFACE)
 
     BEGIN_MSG_MAP(CTaskSwitchWnd)
@@ -1539,6 +1599,7 @@ public:
         MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
         MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
         MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
+        MESSAGE_HANDLER(WM_CONTEXTMENU, OnCtxMenu) // FIXME: This handler is not necessary in Windows
         MESSAGE_HANDLER(TNWM_GETMINIMUMSIZE, OnGetMinimumSize)
         MESSAGE_HANDLER(TNWM_UPDATETIME, OnUpdateTime)
         MESSAGE_HANDLER(TNWM_SHOWCLOCK, OnShowClock)
@@ -1570,11 +1631,10 @@ HWND CreateTrayNotifyWnd(IN OUT ITrayWindow *Tray, BOOL bHideClock, CTrayNotifyW
     return pTrayNotify->_Init(Tray, bHideClock);
 }
 
-VOID
-TrayNotify_NotifyMsg(CTrayNotifyWnd* pTrayNotify, WPARAM wParam, LPARAM lParam)
+BOOL
+TrayNotify_NotifyIconCmd(CTrayNotifyWnd* pTrayNotify, WPARAM wParam, LPARAM lParam)
 {
-    BOOL bDummy;
-    pTrayNotify->NotifyMsg(0, wParam, lParam, bDummy);
+    return pTrayNotify->NotifyIconCmd(wParam, lParam);
 }
 
 BOOL