[EXPLORER-NEW]
[reactos.git] / base / shell / explorer-new / trayntfy.c
index 5d8cb77..49d4687 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <precomp.h>
+#include "precomp.h"
+//#include <docobj.h>
 
 /*
- * TrayClockWnd
- */ 
+ * SysPagerWnd
+ */
+static const TCHAR szSysPagerWndClass[] = TEXT("SysPager");
 
-static const TCHAR szTrayClockWndClass[] = TEXT("TrayClockWClass");
-static LPCTSTR s_szRegistryKey = _T("Software\\ReactOS\\Features\\Explorer");
-BOOL blShowSeconds;
+typedef struct _NOTIFY_ITEM
+{
+    struct _NOTIFY_ITEM *next;
+    INT Index;
+    INT IconIndex;
+    NOTIFYICONDATA iconData;
+} NOTIFY_ITEM, *PNOTIFY_ITEM, **PPNOTIFY_ITEM;
 
-#define ID_TRAYCLOCK_TIMER  0
-#define ID_TRAYCLOCK_TIMER_INIT 1
+typedef struct _SYS_PAGER_DATA
+{
+    HWND hWnd;
+    HWND hWndToolbar;
+    HIMAGELIST SysIcons;
+    PNOTIFY_ITEM NotifyItems;
+    INT ButtonCount;
+    INT VisibleButtonCount;
+} SYS_PAGER_WND_DATA, *PSYS_PAGER_WND_DATA;
+
+// Data comes from shell32/systray.cpp -> TrayNotifyCDS_Dummy
+typedef struct _SYS_PAGER_COPY_DATA
+{
+    DWORD           cookie;
+    DWORD           notify_code;
+    NOTIFYICONDATA  nicon_data;
+} SYS_PAGER_COPY_DATA, *PSYS_PAGER_COPY_DATA;
 
-static const struct
+static PNOTIFY_ITEM
+SysPagerWnd_CreateNotifyItemData(IN OUT PSYS_PAGER_WND_DATA This)
 {
-    BOOL IsTime;
-    DWORD dwFormatFlags;
-    LPCTSTR lpFormat;
-}ClockWndFormats[]= {
-{TRUE, 0, NULL},
-{FALSE, 0, TEXT("dddd")},
-{FALSE, DATE_SHORTDATE, NULL}
-};                                      
+    PNOTIFY_ITEM *findNotifyPointer = &This->NotifyItems;
+    PNOTIFY_ITEM notifyItem;
+
+    notifyItem = HeapAlloc(hProcessHeap,
+                           HEAP_ZERO_MEMORY,
+                           sizeof(*notifyItem));
+    if (notifyItem == NULL)
+        return NULL;
+
+    notifyItem->next = NULL;
+
+    while (*findNotifyPointer != NULL)
+    {
+        findNotifyPointer = &(*findNotifyPointer)->next;
+    }
+
+    *findNotifyPointer = notifyItem;
+
+    return notifyItem;
+}
+
+static PPNOTIFY_ITEM
+SysPagerWnd_FindPPNotifyItemByIconData(IN OUT PSYS_PAGER_WND_DATA This,
+                                       IN CONST NOTIFYICONDATA *iconData)
+{
+    PPNOTIFY_ITEM findNotifyPointer = &This->NotifyItems;
+
+    while (*findNotifyPointer != NULL)
+    {
+        if ((*findNotifyPointer)->iconData.hWnd == iconData->hWnd &&
+            (*findNotifyPointer)->iconData.uID == iconData->uID)
+        {
+            return findNotifyPointer;
+        }
+        findNotifyPointer = &(*findNotifyPointer)->next;
+    }
+
+    return NULL;
+}
+
+static PPNOTIFY_ITEM
+SysPagerWnd_FindPPNotifyItemByIndex(IN OUT PSYS_PAGER_WND_DATA This,
+                                    IN WORD wIndex)
+{
+    PPNOTIFY_ITEM findNotifyPointer = &This->NotifyItems;
+
+    while (*findNotifyPointer != NULL)
+    {
+        if ((*findNotifyPointer)->Index == wIndex)
+        {
+            return findNotifyPointer;
+        }
+        findNotifyPointer = &(*findNotifyPointer)->next;
+    }
+
+    return NULL;
+}
+
+static VOID
+SysPagerWnd_UpdateButton(IN OUT PSYS_PAGER_WND_DATA This,
+                         IN CONST NOTIFYICONDATA *iconData)
+{
+    TBBUTTONINFO tbbi = {0};
+    PNOTIFY_ITEM notifyItem;
+    PPNOTIFY_ITEM NotifyPointer;
+
+    NotifyPointer = SysPagerWnd_FindPPNotifyItemByIconData(This, iconData);
+    notifyItem = *NotifyPointer;
+
+    tbbi.cbSize = sizeof(tbbi);
+    tbbi.dwMask = TBIF_BYINDEX | TBIF_COMMAND;
+    tbbi.idCommand = notifyItem->Index;
+
+    if (iconData->uFlags & NIF_MESSAGE)
+    {
+        notifyItem->iconData.uCallbackMessage = iconData->uCallbackMessage;
+    }
+
+    if (iconData->uFlags & NIF_ICON)
+    {
+        tbbi.dwMask |= TBIF_IMAGE;
+        notifyItem->IconIndex = tbbi.iImage = ImageList_AddIcon(This->SysIcons, iconData->hIcon);
+    }
+
+    if (iconData->uFlags & NIF_TIP)
+    {
+        StringCchCopy(notifyItem->iconData.szTip, _countof(notifyItem->iconData.szTip), iconData->szTip);
+    }
+
+    if (iconData->uFlags & NIF_STATE)
+    {
+        if (iconData->dwStateMask & NIS_HIDDEN &&
+            (notifyItem->iconData.dwState & NIS_HIDDEN) != (iconData->dwState & NIS_HIDDEN))
+        {
+            tbbi.dwMask |= TBIF_STATE;
+            if (iconData->dwState & NIS_HIDDEN)
+            {
+                tbbi.fsState |= TBSTATE_HIDDEN;
+                This->VisibleButtonCount--;
+            }
+            else
+            {
+                tbbi.fsState &= ~TBSTATE_HIDDEN;
+                This->VisibleButtonCount++;
+            }
+        }
+
+        notifyItem->iconData.dwState &= ~iconData->dwStateMask;
+        notifyItem->iconData.dwState |= (iconData->dwState & iconData->dwStateMask);
+    }
+
+    /* TODO: support NIF_INFO, NIF_GUID, NIF_REALTIME, NIF_SHOWTIP */
+
+    SendMessage(This->hWndToolbar,
+                TB_SETBUTTONINFO,
+                (WPARAM)notifyItem->Index,
+                (LPARAM)&tbbi);
+}
+
+
+static VOID
+SysPagerWnd_AddButton(IN OUT PSYS_PAGER_WND_DATA This,
+                      IN CONST NOTIFYICONDATA *iconData)
+{
+    TBBUTTON tbBtn;
+    PNOTIFY_ITEM notifyItem;
+    TCHAR text[] = TEXT("");
+
+    notifyItem = SysPagerWnd_CreateNotifyItemData(This);
+
+    notifyItem->next = NULL;
+    notifyItem->Index = This->ButtonCount;
+    This->ButtonCount++;
+    This->VisibleButtonCount++;
+
+    notifyItem->iconData.hWnd = iconData->hWnd;
+    notifyItem->iconData.uID = iconData->uID;
+
+    tbBtn.fsState = TBSTATE_ENABLED;
+    tbBtn.fsStyle = BTNS_NOPREFIX;
+    tbBtn.dwData = notifyItem->Index;
+
+    tbBtn.iString = (INT_PTR)text;
+    tbBtn.idCommand = notifyItem->Index;
+
+    if (iconData->uFlags & NIF_MESSAGE)
+    {
+        notifyItem->iconData.uCallbackMessage = iconData->uCallbackMessage;
+    }
+
+    if (iconData->uFlags & NIF_ICON)
+    {
+        notifyItem->IconIndex = tbBtn.iBitmap = ImageList_AddIcon(This->SysIcons, iconData->hIcon);
+    }
+
+    /* TODO: support NIF_TIP */
+
+    if (iconData->uFlags & NIF_STATE)
+    {
+        notifyItem->iconData.dwState &= ~iconData->dwStateMask;
+        notifyItem->iconData.dwState |= (iconData->dwState & iconData->dwStateMask);
+        if (notifyItem->iconData.dwState & NIS_HIDDEN)
+        {
+            tbBtn.fsState |= TBSTATE_HIDDEN;
+            This->VisibleButtonCount--;
+        }
+
+    }
+
+    /* TODO: support NIF_INFO, NIF_GUID, NIF_REALTIME, NIF_SHOWTIP */
+
+    SendMessage(This->hWndToolbar,
+                TB_INSERTBUTTON,
+                notifyItem->Index,
+                (LPARAM)&tbBtn);
+
+    SendMessage(This->hWndToolbar,
+                TB_SETBUTTONSIZE,
+                0,
+                MAKELONG(16, 16));
+}
+
+static VOID
+SysPagerWnd_RemoveButton(IN OUT PSYS_PAGER_WND_DATA This,
+                         IN CONST NOTIFYICONDATA *iconData)
+{
+    PPNOTIFY_ITEM NotifyPointer;
+
+    NotifyPointer = SysPagerWnd_FindPPNotifyItemByIconData(This, iconData);
+    if (NotifyPointer)
+    {
+        PNOTIFY_ITEM deleteItem;
+        PNOTIFY_ITEM updateItem;
+        deleteItem = *NotifyPointer;
+
+        SendMessage(This->hWndToolbar,
+                    TB_DELETEBUTTON,
+                    deleteItem->Index,
+                    0);
+
+        *NotifyPointer = updateItem = deleteItem->next;
+
+        if (!(deleteItem->iconData.dwState & NIS_HIDDEN))
+            This->VisibleButtonCount--;
+        HeapFree(hProcessHeap,
+                 0,
+                 deleteItem);
+        This->ButtonCount--;
+
+        while (updateItem != NULL)
+        {
+            TBBUTTONINFO tbbi;
+            updateItem->Index--;
+            tbbi.cbSize = sizeof(tbbi);
+            tbbi.dwMask = TBIF_BYINDEX | TBIF_COMMAND;
+            tbbi.idCommand = updateItem->Index;
+
+            SendMessage(This->hWndToolbar,
+                        TB_SETBUTTONINFO,
+                        updateItem->Index,
+                        (LPARAM)&tbbi);
+
+            updateItem = updateItem->next;
+        }
+    }
+}
+
+static VOID
+SysPagerWnd_HandleButtonClick(IN OUT PSYS_PAGER_WND_DATA This,
+                              IN WORD wIndex,
+                              IN UINT uMsg,
+                              IN WPARAM wParam)
+{
+    PPNOTIFY_ITEM NotifyPointer;
+
+    NotifyPointer = SysPagerWnd_FindPPNotifyItemByIndex(This, wIndex);
+    if (NotifyPointer)
+    {
+        PNOTIFY_ITEM notifyItem;
+        notifyItem = *NotifyPointer;
+
+        if (IsWindow(notifyItem->iconData.hWnd))
+        {
+            if (uMsg == WM_MOUSEMOVE ||
+                uMsg == WM_LBUTTONDOWN ||
+                uMsg == WM_MBUTTONDOWN ||
+                uMsg == WM_RBUTTONDOWN)
+            {
+                PostMessage(notifyItem->iconData.hWnd,
+                            notifyItem->iconData.uCallbackMessage,
+                            notifyItem->iconData.uID,
+                            uMsg);
+            }
+            else
+            {
+                DWORD pid;
+                GetWindowThreadProcessId(notifyItem->iconData.hWnd, &pid);
+                if (pid == GetCurrentProcessId())
+                {
+                    PostMessage(notifyItem->iconData.hWnd,
+                                notifyItem->iconData.uCallbackMessage,
+                                notifyItem->iconData.uID,
+                                uMsg);
+                }
+                else
+                {
+                    SendMessage(notifyItem->iconData.hWnd,
+                                notifyItem->iconData.uCallbackMessage,
+                                notifyItem->iconData.uID,
+                                uMsg);
+                }
+            }
+        }
+    }
+}
 
-HRESULT RegGetDWord(HKEY hKey, LPCTSTR szValueName, DWORD * lpdwResult) 
+static VOID
+SysPagerWnd_DrawBackground(IN HWND hwnd,
+                           IN HDC hdc)
 {
-       LONG lResult;
-       DWORD dwDataSize = sizeof(DWORD);
-       DWORD dwType = 0;
+    RECT rect;
 
-       // Check input parameters...
-       if (hKey == NULL || lpdwResult == NULL) return E_INVALIDARG;
+    GetClientRect(hwnd, &rect);
+    DrawThemeParentBackground(hwnd, hdc, &rect);
+}
 
-       // Get dword value from the registry...
-       lResult = RegQueryValueEx(hKey, szValueName, 0, &dwType, (LPBYTE) lpdwResult, &dwDataSize );
+static LRESULT CALLBACK
+SysPagerWnd_ToolbarSubclassedProc(IN HWND hWnd,
+                                  IN UINT msg,
+                                  IN WPARAM wParam,
+                                  IN LPARAM lParam,
+                                  IN UINT_PTR uIdSubclass,
+                                  IN DWORD_PTR dwRefData)
+{
+    if (msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST)
+    {
+        HWND parent = GetParent(hWnd);
 
-       // Check result and make sure the registry value is a DWORD(REG_DWORD)...
-       if (lResult != ERROR_SUCCESS) return HRESULT_FROM_WIN32(lResult);
-       else if (dwType != REG_DWORD) return DISP_E_TYPEMISMATCH;
+        if (parent)
+        {
+            SendMessage(parent, msg, wParam, lParam);
+        }
+    }
 
-       return NOERROR;
+    return DefSubclassProc(hWnd, msg, wParam, lParam);
 }
 
-void LoadSettings(void)
+static VOID
+SysPagerWnd_Create(IN OUT PSYS_PAGER_WND_DATA This)
 {
-       HKEY hKey = NULL;
-       DWORD dwValue;
-
-       if (RegOpenKey(HKEY_CURRENT_USER, s_szRegistryKey, &hKey) == ERROR_SUCCESS)
-       {
-                RegGetDWord(hKey,  TEXT("blShowSeconds"), &dwValue);
-                if (dwValue == 1)
-                {
-                    blShowSeconds = TRUE;
-                }
-                else
-                {
-                    blShowSeconds = FALSE;
-                }
-
-               RegCloseKey(hKey);
-       }
+    DWORD styles = 
+        WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN |
+        TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | TBSTYLE_WRAPABLE | TBSTYLE_TRANSPARENT |
+        CCS_TOP | CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NODIVIDER;
+    DWORD exStyles = WS_EX_TOOLWINDOW;
+
+    This->hWndToolbar = CreateWindowEx(exStyles,
+                                       TOOLBARCLASSNAME,
+                                       NULL,
+                                       styles,
+                                       0,
+                                       0,
+                                       0,
+                                       0,
+                                       This->hWnd,
+                                       NULL,
+                                       hExplorerInstance,
+                                       NULL);
+    if (This->hWndToolbar != NULL)
+    {
+        SIZE BtnSize;
+        SetWindowTheme(This->hWndToolbar, L"TrayNotify", NULL);
+        /* Identify the version we're using */
+        SendMessage(This->hWndToolbar,
+                    TB_BUTTONSTRUCTSIZE,
+                    sizeof(TBBUTTON),
+                    0);
+
+        This->SysIcons = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 0, 1000);
+        SendMessage(This->hWndToolbar, TB_SETIMAGELIST, 0, (LPARAM)This->SysIcons);
+
+        BtnSize.cx = BtnSize.cy = 18;
+        SendMessage(This->hWndToolbar,
+                    TB_SETBUTTONSIZE,
+                    0,
+                    MAKELONG(BtnSize.cx, BtnSize.cy));
+
+        SetWindowSubclass(This->hWndToolbar,
+                          SysPagerWnd_ToolbarSubclassedProc,
+                          2,
+                          (DWORD_PTR)This);
+    }
 }
 
+static VOID
+SysPagerWnd_NCDestroy(IN OUT PSYS_PAGER_WND_DATA This)
+{
+    /* Free allocated resources */
+    SetWindowLongPtr(This->hWnd,
+                     0,
+                     0);
+    HeapFree(hProcessHeap,
+             0,
+             This);
+}
+
+static VOID
+SysPagerWnd_NotifyMsg(IN HWND hwnd,
+                      IN WPARAM wParam,
+                      IN LPARAM lParam)
+{
+    PSYS_PAGER_WND_DATA This = (PSYS_PAGER_WND_DATA)GetWindowLongPtr(hwnd, 0);
+
+    PCOPYDATASTRUCT cpData = (PCOPYDATASTRUCT)lParam;
+    if (cpData->dwData == 1)
+    {
+        SYS_PAGER_COPY_DATA * data;
+        NOTIFYICONDATA *iconData;
+        HWND parentHWND;
+        RECT windowRect;
+        parentHWND = GetParent(This->hWnd);
+        parentHWND = GetParent(parentHWND);
+        GetClientRect(parentHWND, &windowRect);
+
+        data = (PSYS_PAGER_COPY_DATA) cpData->lpData;
+        iconData = &data->nicon_data;
+
+        switch (data->notify_code)
+        {
+            case NIM_ADD:
+            {
+                PPNOTIFY_ITEM NotifyPointer;
+
+                NotifyPointer = SysPagerWnd_FindPPNotifyItemByIconData(This,
+                                                                       iconData);
+                if (!NotifyPointer)
+                {
+                    SysPagerWnd_AddButton(This, iconData);
+                }
+                break;
+            }
+            case NIM_MODIFY:
+            {
+                PPNOTIFY_ITEM NotifyPointer;
+
+                NotifyPointer = SysPagerWnd_FindPPNotifyItemByIconData(This,
+                                                                       iconData);
+                if (!NotifyPointer)
+                {
+                    SysPagerWnd_AddButton(This, iconData);
+                }
+                else
+                {
+                    SysPagerWnd_UpdateButton(This, iconData);
+                }
+                break;
+            }
+            case NIM_DELETE:
+            {
+                SysPagerWnd_RemoveButton(This, iconData);
+                break;
+            }
+            default:
+                TRACE("NotifyMessage received with unknown code %d.\n", data->notify_code);
+                break;
+        }
+        SendMessage(parentHWND,
+                    WM_SIZE,
+                    0,
+                    MAKELONG(windowRect.right - windowRect.left,
+                             windowRect.bottom - windowRect.top));
+    }
+}
+
+static void
+SysPagerWnd_GetSize(IN HWND hwnd,
+                    IN WPARAM wParam,
+                    IN PSIZE size)
+{
+    PSYS_PAGER_WND_DATA This = (PSYS_PAGER_WND_DATA)GetWindowLongPtr(hwnd, 0);
+    INT rows = 0;
+    TBMETRICS tbm;
+
+    if (wParam) /* horizontal */
+    {
+        rows = size->cy / 24;
+        if (rows == 0)
+            rows++;
+        size->cx = (This->VisibleButtonCount+rows - 1) / rows * 24;
+    }
+    else
+    {
+        rows = size->cx / 24;
+        if (rows == 0)
+            rows++;
+        size->cy = (This->VisibleButtonCount+rows - 1) / rows * 24;
+    }
+
+    tbm.cbSize = sizeof(tbm);
+    tbm.dwMask = TBMF_BARPAD | TBMF_BUTTONSPACING;
+    tbm.cxBarPad = tbm.cyBarPad = 0;
+    tbm.cxButtonSpacing = 0;
+    tbm.cyButtonSpacing = 0;
+
+    SendMessage(This->hWndToolbar,
+                TB_SETMETRICS,
+                0,
+                (LPARAM)&tbm);
+}
+
+static LRESULT CALLBACK
+SysPagerWndProc(IN HWND hwnd,
+                IN UINT uMsg,
+                IN WPARAM wParam,
+                IN LPARAM lParam)
+{
+    PSYS_PAGER_WND_DATA This = NULL;
+    LRESULT Ret = FALSE;
+
+    if (uMsg != WM_NCCREATE)
+    {
+        This = (PSYS_PAGER_WND_DATA)GetWindowLongPtr(hwnd, 0);
+    }
+
+    if (This != NULL || uMsg == WM_NCCREATE)
+    {
+        switch (uMsg)
+        {
+            case WM_ERASEBKGND:
+                if (!IsAppThemed())
+                    break;
+
+                SysPagerWnd_DrawBackground(hwnd, (HDC) wParam);
+                return TRUE;
+
+            case WM_NCCREATE:
+            {
+                LPCREATESTRUCT CreateStruct = (LPCREATESTRUCT)lParam;
+                This = CreateStruct->lpCreateParams;
+                This->hWnd = hwnd;
+                This->NotifyItems = NULL;
+                This->ButtonCount = 0;
+                This->VisibleButtonCount = 0;
+
+                SetWindowLongPtr(hwnd, 0, (LONG_PTR) This);
+
+                return TRUE;
+            }
+            case WM_CREATE:
+                SysPagerWnd_Create(This);
+                break;
+            case WM_NCDESTROY:
+                SysPagerWnd_NCDestroy(This);
+                break;
+
+            case WM_NOTIFY:
+            {
+                const NMHDR * nmh = (const NMHDR *) lParam;
+                if (nmh->code == TBN_GETINFOTIPW)
+                {
+                    NMTBGETINFOTIP * nmtip = (NMTBGETINFOTIP *) lParam;
+                    PPNOTIFY_ITEM ptr = SysPagerWnd_FindPPNotifyItemByIndex(This, nmtip->iItem);
+                    if (ptr)
+                    {
+                        PNOTIFY_ITEM item = *ptr;
+                        StringCchCopy(nmtip->pszText, nmtip->cchTextMax, item->iconData.szTip);
+                    }
+                }
+                else if (nmh->code == NM_CUSTOMDRAW)
+                {
+                    NMCUSTOMDRAW * cdraw = (NMCUSTOMDRAW *) lParam;
+                    switch (cdraw->dwDrawStage)
+                    {
+                    case CDDS_PREPAINT:
+                        return CDRF_NOTIFYITEMDRAW;
+
+                    case CDDS_ITEMPREPAINT:
+                        return TBCDRF_NOBACKGROUND | TBCDRF_NOEDGES | TBCDRF_NOOFFSET | TBCDRF_NOMARK | TBCDRF_NOETCHEDEFFECT;
+                    }
+                }
+
+                break;
+            }
+
+            case WM_SIZE:
+            {
+                SIZE szClient;
+                szClient.cx = LOWORD(lParam);
+                szClient.cy = HIWORD(lParam);
+
+                Ret = DefWindowProc(hwnd, uMsg, wParam, lParam);
+
+                if (This->hWndToolbar != NULL && This->hWndToolbar != hwnd)
+                {
+                    SetWindowPos(This->hWndToolbar, NULL, 0, 0, szClient.cx, szClient.cy, SWP_NOZORDER);
+                }
+
+                return Ret;
+            }
+
+            default:
+                if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)
+                {
+                    POINT pt;
+                    INT iBtn;
+
+                    pt.x = LOWORD(lParam);
+                    pt.y = HIWORD(lParam);
+
+                    iBtn = (INT)SendMessage(This->hWndToolbar,
+                                            TB_HITTEST,
+                                            0,
+                                            (LPARAM)&pt);
+
+                    if (iBtn >= 0)
+                    {
+                        SysPagerWnd_HandleButtonClick(This,iBtn,uMsg,wParam);
+                    }
+
+                    return 0;
+                }
+
+                break;
+        }
+    }
+
+    return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+static HWND
+CreateSysPagerWnd(IN HWND hWndParent,
+                  IN BOOL bVisible)
+{
+    PSYS_PAGER_WND_DATA SpData;
+    DWORD dwStyle;
+    HWND hWnd = NULL;
+
+    SpData = HeapAlloc(hProcessHeap,
+                       HEAP_ZERO_MEMORY,
+                       sizeof(*SpData));
+    if (SpData != NULL)
+    {
+        /* Create the window. The tray window is going to move it to the correct
+           position and resize it as needed. */
+        dwStyle = WS_CHILD | WS_CLIPSIBLINGS;
+        if (bVisible)
+            dwStyle |= WS_VISIBLE;
+
+        hWnd = CreateWindowEx(0,
+                              szSysPagerWndClass,
+                              NULL,
+                              dwStyle,
+                              0,
+                              0,
+                              0,
+                              0,
+                              hWndParent,
+                              NULL,
+                              hExplorerInstance,
+                              SpData);
+
+        if (hWnd != NULL)
+        {
+            SetWindowTheme(hWnd, L"TrayNotify", NULL);
+        }
+        else
+        {
+            HeapFree(hProcessHeap,
+                     0,
+                     SpData);
+        }
+    }
+
+    return hWnd;
+
+}
+
+static BOOL
+RegisterSysPagerWndClass(VOID)
+{
+    WNDCLASS wcTrayClock;
+
+    wcTrayClock.style = CS_DBLCLKS;
+    wcTrayClock.lpfnWndProc = SysPagerWndProc;
+    wcTrayClock.cbClsExtra = 0;
+    wcTrayClock.cbWndExtra = sizeof(PSYS_PAGER_WND_DATA);
+    wcTrayClock.hInstance = hExplorerInstance;
+    wcTrayClock.hIcon = NULL;
+    wcTrayClock.hCursor = LoadCursor(NULL, IDC_ARROW);
+    wcTrayClock.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
+    wcTrayClock.lpszMenuName = NULL;
+    wcTrayClock.lpszClassName = szSysPagerWndClass;
+
+    return RegisterClass(&wcTrayClock) != 0;
+}
+
+static VOID
+UnregisterSysPagerWndClass(VOID)
+{
+    UnregisterClass(szSysPagerWndClass,
+                    hExplorerInstance);
+}
+
+/*
+ * TrayClockWnd
+ */
+
+static const TCHAR szTrayClockWndClass[] = TEXT("TrayClockWClass");
+
+#define ID_TRAYCLOCK_TIMER  0
+#define ID_TRAYCLOCK_TIMER_INIT 1
+
+static const struct
+{
+    BOOL IsTime;
+    DWORD dwFormatFlags;
+    LPCTSTR lpFormat;
+} ClockWndFormats[] = {
+    { TRUE, 0, NULL },
+    { FALSE, 0, TEXT("dddd") },
+    { FALSE, DATE_SHORTDATE, NULL }
+};
+
 #define CLOCKWND_FORMAT_COUNT (sizeof(ClockWndFormats) / sizeof(ClockWndFormats[0]))
 
 #define TRAY_CLOCK_WND_SPACING_X    0
@@ -92,9 +748,10 @@ typedef struct _TRAY_CLOCK_WND_DATA
     HWND hWnd;
     HWND hWndNotify;
     HFONT hFont;
+    COLORREF textColor;
     RECT rcText;
     SYSTEMTIME LocalTime;
-       
+
     union
     {
         DWORD dwFlags;
@@ -113,6 +770,49 @@ typedef struct _TRAY_CLOCK_WND_DATA
     TCHAR szLines[CLOCKWND_FORMAT_COUNT][48];
 } TRAY_CLOCK_WND_DATA, *PTRAY_CLOCK_WND_DATA;
 
+static VOID
+TrayClockWnd_SetFont(IN OUT PTRAY_CLOCK_WND_DATA This,
+                     IN HFONT hNewFont,
+                     IN BOOL bRedraw);
+
+static VOID
+TrayClockWnd_UpdateTheme(IN OUT PTRAY_CLOCK_WND_DATA This)
+{
+    LOGFONTW clockFont;
+    HTHEME clockTheme;
+    HFONT hFont;
+
+    clockTheme = OpenThemeData(This->hWnd, L"Clock");
+
+    if (clockTheme)
+    {
+        GetThemeFont(clockTheme,
+                     NULL,
+                     CLP_TIME,
+                     0,
+                     TMT_FONT,
+                     &clockFont);
+
+        hFont = CreateFontIndirectW(&clockFont);
+
+        TrayClockWnd_SetFont(This,
+                             hFont,
+                             FALSE);
+
+        GetThemeColor(clockTheme,
+                      CLP_TIME,
+                      0,
+                      TMT_TEXTCOLOR,
+                      &This->textColor);
+    }
+    else
+    {
+        This->textColor = RGB(0,0,0);
+    }
+
+    CloseThemeData(clockTheme);
+}
+
 static BOOL
 TrayClockWnd_MeasureLines(IN OUT PTRAY_CLOCK_WND_DATA This)
 {
@@ -258,7 +958,7 @@ TrayClockWnd_UpdateWnd(IN OUT PTRAY_CLOCK_WND_DATA This)
         if (ClockWndFormats[i].IsTime)
         {
             iRet = GetTimeFormat(LOCALE_USER_DEFAULT,
-                                 ClockWndFormats[i].dwFormatFlags,
+                                 AdvancedSettings.bShowSeconds ? ClockWndFormats[i].dwFormatFlags : TIME_NOSECONDS,
                                  &This->LocalTime,
                                  ClockWndFormats[i].lpFormat,
                                  This->szLines[i],
@@ -276,11 +976,6 @@ TrayClockWnd_UpdateWnd(IN OUT PTRAY_CLOCK_WND_DATA This)
 
         if (iRet != 0 && i == 0)
         {
-                       if (blShowSeconds == FALSE)
-                       {
-                               (This->szLines[0][5] = '\0');
-                       };
-                       
             /* Set the window text to the time only */
             SetWindowText(This->hWnd,
                           This->szLines[i]);
@@ -318,7 +1013,7 @@ TrayClockWnd_UpdateWnd(IN OUT PTRAY_CLOCK_WND_DATA This)
 
             nmh.hwndFrom = This->hWnd;
             nmh.idFrom = GetWindowLongPtr(This->hWnd,
-                                          GWL_ID);
+                                          GWLP_ID);
             nmh.code = NTNWM_REALIGN;
 
             SendMessage(This->hWndNotify,
@@ -344,10 +1039,10 @@ TrayClockWnd_CalculateDueTime(IN OUT PTRAY_CLOCK_WND_DATA This)
     /* Calculate the due time */
     GetLocalTime(&This->LocalTime);
     uiDueTime = 1000 - (UINT)This->LocalTime.wMilliseconds;
-       if (blShowSeconds == TRUE)
-               uiDueTime += ( (UINT)This->LocalTime.wSecond) * 100;
-       else
-               uiDueTime += (59 - (UINT)This->LocalTime.wSecond) * 1000;
+    if (AdvancedSettings.bShowSeconds)
+        uiDueTime += (UINT)This->LocalTime.wSecond * 100;
+    else
+        uiDueTime += (59 - (UINT)This->LocalTime.wSecond) * 1000;
 
     if (uiDueTime < USER_TIMER_MINIMUM || uiDueTime > USER_TIMER_MAXIMUM)
         uiDueTime = 1000;
@@ -401,7 +1096,7 @@ TrayClockWnd_CalibrateTimer(IN OUT PTRAY_CLOCK_WND_DATA This)
 {
     UINT uiDueTime;
     BOOL Ret;
-       int intWait1, intWait2;
+    UINT uiWait1, uiWait2;
 
     /* Kill the initialization timer */
     KillTimer(This->hWnd,
@@ -409,26 +1104,26 @@ TrayClockWnd_CalibrateTimer(IN OUT PTRAY_CLOCK_WND_DATA This)
     This->IsInitTimerEnabled = FALSE;
 
     uiDueTime = TrayClockWnd_CalculateDueTime(This);
-       
-       if (blShowSeconds == TRUE) 
-       {
-               intWait1 = 1000-200;
-               intWait2 = 1000;
-       }
-       else
-       {
-               intWait1 = 60*1000-200;
-               intWait2 = 60*1000;
-       }
-
-    if (uiDueTime > intWait1)
+
+    if (AdvancedSettings.bShowSeconds)
+    {
+        uiWait1 = 1000 - 200;
+        uiWait2 = 1000;
+    }
+    else
+    {
+        uiWait1 = 60 * 1000 - 200;
+        uiWait2 = 60 * 1000;
+    }
+
+    if (uiDueTime > uiWait1)
     {
         /* The update of the clock will be up to 200 ms late, but that's
            acceptable. We're going to setup a timer that fires depending
-           intWait2. */   
+           uiWait2. */
         Ret = SetTimer(This->hWnd,
                        ID_TRAYCLOCK_TIMER,
-                                          intWait2,
+                       uiWait2,
                        NULL) != 0;
         This->IsTimerEnabled = Ret;
 
@@ -483,6 +1178,8 @@ TrayClockWnd_Paint(IN OUT PTRAY_CLOCK_WND_DATA This,
         iPrevBkMode = SetBkMode(hDC,
                                 TRANSPARENT);
 
+        SetTextColor(hDC, This->textColor);
+
         hPrevFont = SelectObject(hDC,
                                  This->hFont);
 
@@ -532,6 +1229,16 @@ TrayClockWnd_SetFont(IN OUT PTRAY_CLOCK_WND_DATA This,
     }
 }
 
+static VOID
+TrayClockWnd_DrawBackground(IN HWND hwnd,
+                            IN HDC hdc)
+{
+    RECT rect;
+
+    GetClientRect(hwnd, &rect);
+    DrawThemeParentBackground(hwnd, hdc, &rect);
+}
+
 static LRESULT CALLBACK
 TrayClockWndProc(IN HWND hwnd,
                  IN UINT uMsg,
@@ -539,7 +1246,6 @@ TrayClockWndProc(IN HWND hwnd,
                  IN LPARAM lParam)
 {
     PTRAY_CLOCK_WND_DATA This = NULL;
-    LRESULT Ret = FALSE;
 
     if (uMsg != WM_NCCREATE)
     {
@@ -551,6 +1257,15 @@ TrayClockWndProc(IN HWND hwnd,
     {
         switch (uMsg)
         {
+            case WM_THEMECHANGED:
+                TrayClockWnd_UpdateTheme(This);
+                break;
+            case WM_ERASEBKGND:
+                if (!IsAppThemed())
+                    break;
+
+                TrayClockWnd_DrawBackground(hwnd, (HDC) wParam);
+                return TRUE;
             case WM_PAINT:
             case WM_PRINTCLIENT:
             {
@@ -559,19 +1274,16 @@ TrayClockWndProc(IN HWND hwnd,
 
                 if (wParam == 0)
                 {
-                    hDC = BeginPaint(This->hWnd,
-                                     &ps);
+                    hDC = BeginPaint(This->hWnd, &ps);
                 }
 
                 if (hDC != NULL)
                 {
-                    TrayClockWnd_Paint(This,
-                                       hDC);
+                    TrayClockWnd_Paint(This, hDC);
 
                     if (wParam == 0)
                     {
-                        EndPaint(This->hWnd,
-                                 &ps);
+                        EndPaint(This->hWnd, &ps);
                     }
                 }
                 break;
@@ -592,23 +1304,18 @@ TrayClockWndProc(IN HWND hwnd,
 
             case WM_NCHITTEST:
                 /* We want the user to be able to drag the task bar when clicking the clock */
-                Ret = HTTRANSPARENT;
-                break;
+                return HTTRANSPARENT;
 
             case TCWM_GETMINIMUMSIZE:
             {
                 This->IsHorizontal = (BOOL)wParam;
 
-                Ret = (LRESULT)TrayClockWnd_GetMinimumSize(This,
-                                                           (BOOL)wParam,
-                                                           (PSIZE)lParam) != 0;
-                break;
+                return (LRESULT) TrayClockWnd_GetMinimumSize(This, (BOOL) wParam, (PSIZE) lParam) != 0;
             }
 
             case TCWM_UPDATETIME:
             {
-                Ret = (LRESULT)TrayClockWnd_ResetTime(This);
-                break;
+                return (LRESULT)TrayClockWnd_ResetTime(This);
             }
 
             case WM_NCCREATE:
@@ -618,9 +1325,8 @@ TrayClockWndProc(IN HWND hwnd,
                 This->hWnd = hwnd;
                 This->hWndNotify = CreateStruct->hwndParent;
 
-                SetWindowLongPtr(hwnd,
-                                 0,
-                                 (LONG_PTR)This);
+                SetWindowLongPtr(hwnd, 0, (LONG_PTR) This);
+                TrayClockWnd_UpdateTheme(This);
 
                 return TRUE;
             }
@@ -657,17 +1363,10 @@ TrayClockWndProc(IN HWND hwnd,
                                TRUE);
                 break;
             }
-
-            default:
-                Ret = DefWindowProc(hwnd,
-                                    uMsg,
-                                    wParam,
-                                    lParam);
-                break;
         }
     }
 
-    return Ret;
+    return DefWindowProc(hwnd, uMsg, wParam, lParam);
 }
 
 static HWND
@@ -677,16 +1376,12 @@ CreateTrayClockWnd(IN HWND hWndParent,
     PTRAY_CLOCK_WND_DATA TcData;
     DWORD dwStyle;
     HWND hWnd = NULL;
-       LoadSettings();
 
     TcData = HeapAlloc(hProcessHeap,
-                       0,
+                       HEAP_ZERO_MEMORY,
                        sizeof(*TcData));
     if (TcData != NULL)
     {
-        ZeroMemory(TcData,
-                   sizeof(*TcData));
-
         TcData->IsHorizontal = TRUE;
         /* Create the window. The tray window is going to move it to the correct
            position and resize it as needed. */
@@ -705,9 +1400,13 @@ CreateTrayClockWnd(IN HWND hWndParent,
                               hWndParent,
                               NULL,
                               hExplorerInstance,
-                              (LPVOID)TcData);
+                              TcData);
 
-        if (hWnd == NULL)
+        if (hWnd != NULL)
+        {
+            SetWindowTheme(hWnd, L"TrayNotify", NULL);
+        }
+        else
         {
             HeapFree(hProcessHeap,
                      0,
@@ -760,9 +1459,13 @@ typedef struct _TRAY_NOTIFY_WND_DATA
     HWND hWnd;
     HWND hWndTrayClock;
     HWND hWndNotify;
+    HWND hWndSysPager;
+    HTHEME TrayTheme;
     SIZE szTrayClockMin;
-    SIZE szNonClient;
+    SIZE szTrayNotify;
+    MARGINS ContentMargin;
     ITrayWindow *TrayWindow;
+    HFONT hFontClock;
     union
     {
         DWORD dwFlags;
@@ -775,22 +1478,43 @@ typedef struct _TRAY_NOTIFY_WND_DATA
 } TRAY_NOTIFY_WND_DATA, *PTRAY_NOTIFY_WND_DATA;
 
 static VOID
-TrayNotifyWnd_UpdateStyle(IN OUT PTRAY_NOTIFY_WND_DATA This)
+TrayNotifyWnd_UpdateTheme(IN OUT PTRAY_NOTIFY_WND_DATA This)
 {
-    RECT rcClient = { 0, 0, 0, 0 };
-
-    if (AdjustWindowRectEx(&rcClient,
-                           GetWindowLongPtr(This->hWnd,
-                                            GWL_STYLE),
-                           FALSE,
-                           GetWindowLongPtr(This->hWnd,
-                                            GWL_EXSTYLE)))
+    LONG_PTR style;
+
+    if (This->TrayTheme)
+        CloseThemeData(This->TrayTheme);
+
+    if (IsThemeActive())
+        This->TrayTheme = OpenThemeData(This->hWnd, L"TrayNotify");
+    else
+        This->TrayTheme = 0;
+
+    if (This->TrayTheme)
     {
-        This->szNonClient.cx = rcClient.right - rcClient.left;
-        This->szNonClient.cy = rcClient.bottom - rcClient.top;
+        style = GetWindowLong(This->hWnd, GWL_EXSTYLE);
+        style = style & ~WS_EX_STATICEDGE;
+        SetWindowLong(This->hWnd, GWL_EXSTYLE, style);
+
+        GetThemeMargins(This->TrayTheme,
+                        NULL,
+                        TNP_BACKGROUND,
+                        0,
+                        TMT_CONTENTMARGINS,
+                        NULL,
+                        &This->ContentMargin);
     }
     else
-        This->szNonClient.cx = This->szNonClient.cy = 0;
+    {
+        style = GetWindowLong(This->hWnd, GWL_EXSTYLE);
+        style = style | WS_EX_STATICEDGE;
+        SetWindowLong(This->hWnd, GWL_EXSTYLE, style);
+
+        This->ContentMargin.cxLeftWidth = 0;
+        This->ContentMargin.cxRightWidth = 0;
+        This->ContentMargin.cyTopHeight = 0;
+        This->ContentMargin.cyBottomHeight = 0;
+    }
 }
 
 static VOID
@@ -799,7 +1523,10 @@ TrayNotifyWnd_Create(IN OUT PTRAY_NOTIFY_WND_DATA This)
     This->hWndTrayClock = CreateTrayClockWnd(This->hWnd,
                                              !This->HideClock);
 
-    TrayNotifyWnd_UpdateStyle(This);
+    This->hWndSysPager = CreateSysPagerWnd(This->hWnd,
+                                           !This->HideClock);
+
+    TrayNotifyWnd_UpdateTheme(This);
 }
 
 static VOID
@@ -818,21 +1545,26 @@ TrayNotifyWnd_GetMinimumSize(IN OUT PTRAY_NOTIFY_WND_DATA This,
                              IN BOOL Horizontal,
                              IN OUT PSIZE pSize)
 {
+    SIZE szClock = { 0, 0 };
+    SIZE szTray = { 0, 0 };
+
     This->IsHorizontal = Horizontal;
+    if (This->IsHorizontal)
+        SetWindowTheme(This->hWnd, L"TrayNotifyHoriz", NULL);
+    else
+        SetWindowTheme(This->hWnd, L"TrayNotifyVert", NULL);
 
     if (!This->HideClock)
     {
-        SIZE szClock = { 0, 0 };
-
         if (Horizontal)
         {
-            szClock.cy = pSize->cy - This->szNonClient.cy - (2 * TRAY_NOTIFY_WND_SPACING_Y);
+            szClock.cy = pSize->cy - 2 * TRAY_NOTIFY_WND_SPACING_Y;
             if (szClock.cy <= 0)
                 goto NoClock;
         }
         else
         {
-            szClock.cx = pSize->cx - This->szNonClient.cx - (2 * TRAY_NOTIFY_WND_SPACING_X);
+            szClock.cx = pSize->cx - 2 * TRAY_NOTIFY_WND_SPACING_X;
             if (szClock.cx <= 0)
                 goto NoClock;
         }
@@ -846,23 +1578,45 @@ TrayNotifyWnd_GetMinimumSize(IN OUT PTRAY_NOTIFY_WND_DATA This,
     }
     else
 NoClock:
-        This->szTrayClockMin = This->szNonClient;
+        This->szTrayClockMin = szClock;
+
+    if (Horizontal)
+    {
+        szTray.cy = pSize->cy - 2 * TRAY_NOTIFY_WND_SPACING_Y;
+    }
+    else
+    {
+        szTray.cx = pSize->cx - 2 * TRAY_NOTIFY_WND_SPACING_X;
+    }
+
+    SysPagerWnd_GetSize(This->hWndSysPager,
+                        Horizontal,
+                        &szTray);
+
+    This->szTrayNotify = szTray;
 
     if (Horizontal)
     {
-        pSize->cx = This->szNonClient.cx + (2 * TRAY_NOTIFY_WND_SPACING_X);
+        pSize->cx = 2 * TRAY_NOTIFY_WND_SPACING_X;
 
         if (!This->HideClock)
             pSize->cx += TRAY_NOTIFY_WND_SPACING_X + This->szTrayClockMin.cx;
+
+        pSize->cx += szTray.cx;
     }
     else
     {
-        pSize->cy = This->szNonClient.cy + (2 * TRAY_NOTIFY_WND_SPACING_Y);
+        pSize->cy = 2 * TRAY_NOTIFY_WND_SPACING_Y;
 
         if (!This->HideClock)
             pSize->cy += TRAY_NOTIFY_WND_SPACING_Y + This->szTrayClockMin.cy;
+
+        pSize->cy += szTray.cy;
     }
 
+    pSize->cy += This->ContentMargin.cyTopHeight + This->ContentMargin.cyBottomHeight;
+    pSize->cx += This->ContentMargin.cxLeftWidth + This->ContentMargin.cxRightWidth;
+
     return TRUE;
 }
 
@@ -897,9 +1651,64 @@ TrayNotifyWnd_Size(IN OUT PTRAY_NOTIFY_WND_DATA This,
                      szClock.cx,
                      szClock.cy,
                      SWP_NOZORDER);
+
+        if (This->IsHorizontal)
+        {
+            ptClock.x -= This->szTrayNotify.cx;
+        }
+        else
+        {
+            ptClock.y -= This->szTrayNotify.cy;
+        }
+
+        SetWindowPos(This->hWndSysPager,
+                     NULL,
+                     ptClock.x,
+                     ptClock.y,
+                     This->szTrayNotify.cx,
+                     This->szTrayNotify.cy,
+                     SWP_NOZORDER);
+    }
+}
+
+static VOID
+TrayNotifyWnd_DrawBackground(IN HWND hwnd,
+                             IN HDC hdc)
+{
+    PTRAY_NOTIFY_WND_DATA This = (PTRAY_NOTIFY_WND_DATA)GetWindowLongPtr(hwnd, 0);
+    RECT rect;
+
+    GetClientRect(hwnd, &rect);
+
+    DrawThemeParentBackground(hwnd, hdc, &rect);
+    DrawThemeBackground(This->TrayTheme, hdc, TNP_BACKGROUND, 0, &rect, 0);
+}
+
+VOID
+TrayNotify_NotifyMsg(IN HWND hwnd,
+                     IN WPARAM wParam,
+                     IN LPARAM lParam)
+{
+    PTRAY_NOTIFY_WND_DATA This = (PTRAY_NOTIFY_WND_DATA)GetWindowLongPtr(hwnd, 0);
+    if (This->hWndSysPager)
+    {
+        SysPagerWnd_NotifyMsg(This->hWndSysPager,
+                              wParam,
+                              lParam);
     }
 }
 
+BOOL
+TrayNotify_GetClockRect(IN HWND hwnd,
+                        OUT PRECT rcClock)
+{
+    PTRAY_NOTIFY_WND_DATA This = (PTRAY_NOTIFY_WND_DATA)GetWindowLongPtr(hwnd, 0);
+    if (!IsWindowVisible(This->hWndTrayClock))
+        return FALSE;
+
+    return GetWindowRect(This->hWndTrayClock, rcClock);
+}
+
 static LRESULT CALLBACK
 TrayNotifyWndProc(IN HWND hwnd,
                   IN UINT uMsg,
@@ -907,24 +1716,27 @@ TrayNotifyWndProc(IN HWND hwnd,
                   IN LPARAM lParam)
 {
     PTRAY_NOTIFY_WND_DATA This = NULL;
-    LRESULT Ret = FALSE;
 
     if (uMsg != WM_NCCREATE)
     {
-        This = (PTRAY_NOTIFY_WND_DATA)GetWindowLongPtr(hwnd,
-                                                       0);
+        This = (PTRAY_NOTIFY_WND_DATA)GetWindowLongPtr(hwnd, 0);
     }
 
     if (This != NULL || uMsg == WM_NCCREATE)
     {
         switch (uMsg)
         {
+            case WM_THEMECHANGED:
+                TrayNotifyWnd_UpdateTheme(This);
+                return 0;
+            case WM_ERASEBKGND:
+                if (!This->TrayTheme)
+                    break;
+                TrayNotifyWnd_DrawBackground(hwnd, (HDC) wParam);
+                return 0;
             case TNWM_GETMINIMUMSIZE:
             {
-                Ret = (LRESULT)TrayNotifyWnd_GetMinimumSize(This,
-                                                            (BOOL)wParam,
-                                                            (PSIZE)lParam);
-                break;
+                return (LRESULT) TrayNotifyWnd_GetMinimumSize(This, (BOOL) wParam, (PSIZE) lParam);
             }
 
             case TNWM_UPDATETIME:
@@ -932,12 +1744,9 @@ TrayNotifyWndProc(IN HWND hwnd,
                 if (This->hWndTrayClock != NULL)
                 {
                     /* Forward the message to the tray clock window procedure */
-                    Ret = TrayClockWndProc(This->hWndTrayClock,
-                                           TCWM_UPDATETIME,
-                                           wParam,
-                                           lParam);
+                    return TrayClockWndProc(This->hWndTrayClock, TCWM_UPDATETIME, wParam, lParam);
                 }
-                break;
+                return 0;
             }
 
             case WM_SIZE:
@@ -947,17 +1756,14 @@ TrayNotifyWndProc(IN HWND hwnd,
                 szClient.cx = LOWORD(lParam);
                 szClient.cy = HIWORD(lParam);
 
-                TrayNotifyWnd_Size(This,
-                                   &szClient);
-                break;
+                TrayNotifyWnd_Size(This, &szClient);
+                return 0;
             }
 
             case WM_NCHITTEST:
                 /* We want the user to be able to drag the task bar when clicking the
                    tray notification window */
-                Ret = HTTRANSPARENT;
-                break;
-
+                return HTTRANSPARENT;
             case TNWM_SHOWCLOCK:
             {
                 BOOL PrevHidden = This->HideClock;
@@ -969,8 +1775,7 @@ TrayNotifyWndProc(IN HWND hwnd,
                                This->HideClock ? SW_HIDE : SW_SHOW);
                 }
 
-                Ret = (LRESULT)(!PrevHidden);
-                break;
+                return (LRESULT) (!PrevHidden);
             }
 
             case WM_NOTIFY:
@@ -980,12 +1785,9 @@ TrayNotifyWndProc(IN HWND hwnd,
                 if (nmh->hwndFrom == This->hWndTrayClock)
                 {
                     /* Pass down notifications */
-                    Ret = SendMessage(This->hWndNotify,
-                                      WM_NOTIFY,
-                                      wParam,
-                                      lParam);
+                    return SendMessage(This->hWndNotify, WM_NOTIFY, wParam, lParam);
                 }
-                break;
+                return 0;
             }
 
             case WM_SETFONT:
@@ -997,7 +1799,7 @@ TrayNotifyWndProc(IN HWND hwnd,
                                 wParam,
                                 lParam);
                 }
-                goto HandleDefaultMessage;
+                break;
             }
 
             case WM_NCCREATE:
@@ -1007,32 +1809,22 @@ TrayNotifyWndProc(IN HWND hwnd,
                 This->hWnd = hwnd;
                 This->hWndNotify = CreateStruct->hwndParent;
 
-                SetWindowLongPtr(hwnd,
-                                 0,
-                                 (LONG_PTR)This);
+                SetWindowLongPtr(hwnd, 0, (LONG_PTR) This);
 
                 return TRUE;
             }
 
             case WM_CREATE:
                 TrayNotifyWnd_Create(This);
-                break;
+                return 0;
 
             case WM_NCDESTROY:
                 TrayNotifyWnd_NCDestroy(This);
-                break;
-
-            default:
-HandleDefaultMessage:
-                Ret = DefWindowProc(hwnd,
-                                    uMsg,
-                                    wParam,
-                                    lParam);
-                break;
+                return 0;
         }
     }
 
-    return Ret;
+    return DefWindowProc(hwnd, uMsg, wParam, lParam);
 }
 
 HWND
@@ -1048,13 +1840,10 @@ CreateTrayNotifyWnd(IN OUT ITrayWindow *TrayWindow,
         return NULL;
 
     TnData = HeapAlloc(hProcessHeap,
-                       0,
+                       HEAP_ZERO_MEMORY,
                        sizeof(*TnData));
     if (TnData != NULL)
     {
-        ZeroMemory(TnData,
-                   sizeof(*TnData));
-
         TnData->TrayWindow = TrayWindow;
         TnData->HideClock = bHideClock;
 
@@ -1071,7 +1860,7 @@ CreateTrayNotifyWnd(IN OUT ITrayWindow *TrayWindow,
                               hWndTrayWindow,
                               NULL,
                               hExplorerInstance,
-                              (LPVOID)TnData);
+                              TnData);
 
         if (hWnd == NULL)
         {
@@ -1112,6 +1901,7 @@ RegisterTrayNotifyWndClass(VOID)
             UnregisterClass(szTrayNotifyWndClass,
                             hExplorerInstance);
         }
+        RegisterSysPagerWndClass();
     }
 
     return Ret;
@@ -1122,6 +1912,8 @@ UnregisterTrayNotifyWndClass(VOID)
 {
     UnregisterTrayClockWndClass();
 
+    UnregisterSysPagerWndClass();
+
     UnregisterClass(szTrayNotifyWndClass,
                     hExplorerInstance);
 }