Author: tfaber
Date: Sun Dec 23 14:37:22 2012
New Revision: 57978
URL:
http://svn.reactos.org/svn/reactos?rev=57978&view=rev
Log:
[EXPLORER_NEW]
- Add support for task bar theming
- Add notification area support
- Add support for window flashing
- Hide minimized windows
- Based on Andrew Green's GSoC branch (3/3)
Modified:
trunk/reactos/base/shell/explorer-new/CMakeLists.txt
trunk/reactos/base/shell/explorer-new/precomp.h
trunk/reactos/base/shell/explorer-new/taskswnd.c
trunk/reactos/base/shell/explorer-new/trayntfy.c
trunk/reactos/base/shell/explorer-new/traywnd.c
Modified: trunk/reactos/base/shell/explorer-new/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer-new/CM…
==============================================================================
--- trunk/reactos/base/shell/explorer-new/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/base/shell/explorer-new/CMakeLists.txt [iso-8859-1] Sun Dec 23 14:37:22
2012
@@ -17,6 +17,19 @@
add_executable(explorer_new ${SOURCE})
target_link_libraries(explorer_new uuid)
set_module_type(explorer_new win32gui UNICODE)
-add_importlibs(explorer_new advapi32 gdi32 user32 comctl32 ole32 oleaut32 shell32 shlwapi
version msvcrt kernel32 ntdll)
+add_importlibs(explorer_new
+ advapi32
+ gdi32
+ user32
+ comctl32
+ ole32
+ oleaut32
+ shell32
+ shlwapi
+ version
+ uxtheme
+ msvcrt
+ kernel32
+ ntdll)
add_pch(explorer_new precomp.h)
add_cd_file(TARGET explorer_new DESTINATION reactos FOR all)
Modified: trunk/reactos/base/shell/explorer-new/precomp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer-new/pr…
==============================================================================
--- trunk/reactos/base/shell/explorer-new/precomp.h [iso-8859-1] (original)
+++ trunk/reactos/base/shell/explorer-new/precomp.h [iso-8859-1] Sun Dec 23 14:37:22 2012
@@ -17,7 +17,9 @@
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
-
+#include <uxtheme.h>
+
+#include "tmschema.h"
#include "resource.h"
#include "comcsup.h"
#include "todo.h"
@@ -384,6 +386,11 @@
CreateTrayNotifyWnd(IN OUT ITrayWindow *TrayWindow,
IN BOOL bHideClock);
+VOID
+TrayNotify_NotifyMsg(IN HWND hwnd,
+ IN WPARAM wParam,
+ IN LPARAM lParam);
+
/*
* taskswnd.c
*/
Modified: trunk/reactos/base/shell/explorer-new/taskswnd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer-new/ta…
==============================================================================
--- trunk/reactos/base/shell/explorer-new/taskswnd.c [iso-8859-1] (original)
+++ trunk/reactos/base/shell/explorer-new/taskswnd.c [iso-8859-1] Sun Dec 23 14:37:22
2012
@@ -20,10 +20,6 @@
#include <precomp.h>
-/* By default we don't use DrawCaptionTemp() because it causes some minimal
- drawing glitches with the toolbar custom painting code */
-#define TASK_USE_DRAWCAPTIONTEMP 1
-
/* Set DUMP_TASKS to 1 to enable a dump of the tasks and task groups every
5 seconds */
#define DUMP_TASKS 0
@@ -47,14 +43,6 @@
struct
{
-#if TASK_USE_DRAWCAPTIONTEMP != 0
-
- /* DisplayTooltip is TRUE when the group button text didn't fit into
- the button. */
- DWORD DisplayTooltip : 1;
-
-#endif
-
DWORD IsCollapsed : 1;
};
};
@@ -65,26 +53,15 @@
HWND hWnd;
PTASK_GROUP Group;
INT Index;
-
-#if !(TASK_USE_DRAWCAPTIONTEMP != 0)
-
INT IconIndex;
-#endif
+
union
{
DWORD dwFlags;
struct
{
-
-#if TASK_USE_DRAWCAPTIONTEMP != 0
-
- /* DisplayTooltip is TRUE when the window text didn't fit into the
- button. */
- DWORD DisplayTooltip : 1;
-
-#endif
/* IsFlashing is TRUE when the task bar item should be flashing. */
DWORD IsFlashing : 1;
@@ -113,9 +90,11 @@
PTASK_ITEM TaskItems;
PTASK_ITEM ActiveTaskItem;
+ HTHEME TaskBandTheme;
HWND hWndToolbar;
UINT TbButtonsPerLine;
WORD ToolbarBtnCount;
+ HIMAGELIST TaskIcons;
union
{
@@ -139,12 +118,6 @@
static VOID TaskSwitchWnd_UpdateButtonsSize(IN OUT PTASK_SWITCH_WND This,
IN BOOL bRedrawDisabled);
-#if TASK_USE_DRAWCAPTIONTEMP != 0
-
-#define TaskSwitchWnd_GetWndTextFromTaskItem(a,b) NULL
-
-#else /* !TASK_USE_DRAWCAPTIONTEMP */
-
static LPTSTR
TaskSwitchWnd_GetWndTextFromTaskItem(IN OUT PTASK_SWITCH_WND This,
IN PTASK_ITEM TaskItem)
@@ -161,7 +134,6 @@
return NULL;
}
-#endif
#if DUMP_TASKS != 0
static VOID
@@ -408,19 +380,44 @@
/* FIXME: Implement */
}
+static HICON
+TaskSwitchWnd_GetWndIcon(HWND hwnd)
+{
+ HICON hIcon = 0;
+
+ SendMessageTimeout(hwnd, WM_GETICON, ICON_SMALL2, 0, SMTO_ABORTIFHUNG, 1000,
(PDWORD_PTR)&hIcon);
+
+ if (!hIcon)
+ SendMessageTimeout(hwnd, WM_GETICON, ICON_SMALL, 0, SMTO_ABORTIFHUNG, 1000,
(PDWORD_PTR)&hIcon);
+
+ if (!hIcon)
+ SendMessageTimeout(hwnd, WM_GETICON, ICON_BIG, 0, SMTO_ABORTIFHUNG, 1000,
(PDWORD_PTR)&hIcon);
+
+ if (!hIcon)
+ hIcon = (HICON)GetClassLongPtr(hwnd, GCL_HICONSM);
+
+ if (!hIcon)
+ hIcon = (HICON)GetClassLongPtr(hwnd, GCL_HICON);
+
+ return hIcon;
+}
static INT
TaskSwitchWnd_UpdateTaskItemButton(IN OUT PTASK_SWITCH_WND This,
IN PTASK_ITEM TaskItem)
{
TBBUTTONINFO tbbi;
+ HICON icon;
ASSERT(TaskItem->Index >= 0);
tbbi.cbSize = sizeof(tbbi);
- tbbi.dwMask = TBIF_BYINDEX | TBIF_STATE | TBIF_TEXT;
+ tbbi.dwMask = TBIF_BYINDEX | TBIF_STATE | TBIF_TEXT | TBIF_IMAGE;
tbbi.fsState = TBSTATE_ENABLED;
if (This->ActiveTaskItem == TaskItem)
tbbi.fsState |= TBSTATE_CHECKED;
+
+ if (TaskItem->RenderFlashed)
+ tbbi.fsState |= TBSTATE_MARKED;
/* Check if we're updating a button that is the last one in the
line. If so, we need to set the TBSTATE_WRAP flag! */
@@ -433,6 +430,10 @@
tbbi.pszText = TaskSwitchWnd_GetWndTextFromTaskItem(This,
TaskItem);
+ icon = TaskSwitchWnd_GetWndIcon(TaskItem->hWnd);
+ TaskItem->IconIndex =
ImageList_ReplaceIcon(This->TaskIcons,TaskItem->IconIndex,icon);
+ tbbi.iImage = TaskItem->IconIndex;
+
if (!SendMessage(This->hWndToolbar,
TB_SETBUTTONINFO,
(WPARAM)TaskItem->Index,
@@ -444,6 +445,39 @@
DbgPrint("Updated button %d for hwnd 0x%p\n", TaskItem->Index,
TaskItem->hWnd);
return TaskItem->Index;
+}
+
+static VOID
+TaskSwitchWnd_RemoveIcon(IN OUT PTASK_SWITCH_WND This,
+ IN PTASK_ITEM TaskItem)
+{
+ TBBUTTONINFO tbbi;
+ PTASK_ITEM currentTaskItem,LastItem;
+
+ if (TaskItem->IconIndex==-1)
+ return;
+
+ tbbi.cbSize = sizeof(tbbi);
+ tbbi.dwMask = TBIF_IMAGE;
+
+ currentTaskItem = This->TaskItems;
+ LastItem = currentTaskItem + This->TaskItemCount;
+ while (currentTaskItem != LastItem)
+ {
+ if (currentTaskItem->IconIndex > TaskItem->IconIndex)
+ {
+ currentTaskItem->IconIndex--;
+ tbbi.iImage = currentTaskItem->IconIndex;
+
+ SendMessage(This->hWndToolbar,
+ TB_SETBUTTONINFO,
+ currentTaskItem->Index,
+ (LPARAM)&tbbi);
+ }
+ currentTaskItem++;
+ }
+
+ ImageList_Remove(This->TaskIcons, TaskItem->IconIndex);
}
static PTASK_ITEM
@@ -541,6 +575,7 @@
{
TBBUTTON tbBtn;
INT iIndex;
+ HICON icon;
if (TaskItem->Index >= 0)
{
@@ -556,7 +591,10 @@
TaskItem->Group);
}
- tbBtn.iBitmap = 0;
+ icon = TaskSwitchWnd_GetWndIcon(TaskItem->hWnd);
+ TaskItem->IconIndex = ImageList_AddIcon(This->TaskIcons, icon);
+
+ tbBtn.iBitmap = TaskItem->IconIndex;
tbBtn.fsState = TBSTATE_ENABLED | TBSTATE_ELLIPSES;
tbBtn.fsStyle = BTNS_CHECK | BTNS_NOPREFIX | BTNS_SHOWTEXT;
tbBtn.dwData = TaskItem->Index;
@@ -612,6 +650,7 @@
{
TaskSwitchWnd_BeginUpdate(This);
+ TaskSwitchWnd_RemoveIcon(This, TaskItem);
iIndex = TaskItem->Index;
if (SendMessage(This->hWndToolbar,
TB_DELETEBUTTON,
@@ -1107,7 +1146,9 @@
TaskSwitchWnd_FlashTaskItem(IN OUT PTASK_SWITCH_WND This,
IN OUT PTASK_ITEM TaskItem)
{
- /* FIXME: Implement */
+ TaskItem->RenderFlashed = 1;
+ TaskSwitchWnd_UpdateTaskItemButton(This,
+ TaskItem);
}
static BOOL
@@ -1151,6 +1192,7 @@
else if (TaskItem->Index >= 0)
{
UpdateTaskItem:
+ TaskItem->RenderFlashed = 0;
TaskSwitchWnd_UpdateTaskItemButton(This,
TaskItem);
}
@@ -1384,6 +1426,18 @@
}
return Ret;
+}
+
+static VOID
+TaskSwitchWnd_UpdateTheme(IN OUT PTASK_SWITCH_WND This)
+{
+ if (This->TaskBandTheme)
+ CloseThemeData(This->TaskBandTheme);
+
+ if (IsThemeActive())
+ This->TaskBandTheme = OpenThemeData(This->hWnd, L"TaskBand");
+ else
+ This->TaskBandTheme = NULL;
}
static VOID
@@ -1410,11 +1464,16 @@
HMODULE hShell32;
SIZE BtnSize;
+ SetWindowTheme(This->hWndToolbar, L"TaskBand", NULL);
+ TaskSwitchWnd_UpdateTheme(This);
/* Identify the version we're using */
SendMessage(This->hWndToolbar,
TB_BUTTONSTRUCTSIZE,
sizeof(TBBUTTON),
0);
+
+ This->TaskIcons = ImageList_Create(16, 16, ILC_COLOR32, 0, 1000);
+ SendMessage(This->hWndToolbar, TB_SETIMAGELIST, 0,
(LPARAM)This->TaskIcons);
/* Calculate the default button size. Don't save this in
This->ButtonSize.cx so that
the actual button width gets updated correctly on the first recalculation */
@@ -1497,6 +1556,7 @@
}
}
+ CloseThemeData(This->TaskBandTheme);
TaskSwitchWnd_DeleteAllTasks(This);
}
@@ -1778,16 +1838,10 @@
TaskSwichWnd_HandleItemPaint(IN OUT PTASK_SWITCH_WND This,
IN OUT NMTBCUSTOMDRAW *nmtbcd)
{
- HFONT hCaptionFont, hBoldCaptionFont;
LRESULT Ret = CDRF_DODEFAULT;
PTASK_GROUP TaskGroup;
PTASK_ITEM TaskItem;
-#if TASK_USE_DRAWCAPTIONTEMP != 0
-
- UINT uidctFlags = DC_TEXT | DC_ICON | DC_NOSENDMSG;
-
-#endif
TaskItem = FindTaskItemByIndex(This,
(INT)nmtbcd->nmcd.dwItemSpec);
TaskGroup = FindTaskGroupByIndex(This,
@@ -1798,97 +1852,32 @@
if (TaskItem != NULL && IsWindow(TaskItem->hWnd))
{
- hCaptionFont = ITrayWindow_GetCaptionFonts(This->Tray,
- &hBoldCaptionFont);
- if (nmtbcd->nmcd.uItemState & CDIS_CHECKED)
- hCaptionFont = hBoldCaptionFont;
-
-#if TASK_USE_DRAWCAPTIONTEMP != 0
-
- /* Make sure we don't draw on the button edges */
- InflateRect(&nmtbcd->nmcd.rc,
- -GetSystemMetrics(SM_CXEDGE),
- -GetSystemMetrics(SM_CYEDGE));
-
- if ((nmtbcd->nmcd.uItemState & CDIS_MARKED) &&
TaskItem->RenderFlashed)
- {
- /* This is a slight glitch. We have to move the rectangle so that
- the button content appears to be pressed. However, when flashing
- is enabled, we can see a light line at the top and left inner
- border. We need to fill that area with the flashing color. Note
- that since we're using DrawCaptionTemp() the flashing color is
- COLOR_ACTIVECAPTION, not COLOR_HIGHLIGHT! */
- FillRect(nmtbcd->nmcd.hdc,
- &nmtbcd->nmcd.rc,
- (HBRUSH)(COLOR_ACTIVECAPTION + 1));
-
- /* Make the button content appear pressed. This however draws a bit
- into the right and bottom border of the button edge, making it
- look a bit odd. However, selecting a clipping region to prevent
- that from happening causes problems with DrawCaptionTemp()! */
- OffsetRect(&nmtbcd->nmcd.rc,
- 1,
- 1);
-
- /* Render flashed */
- uidctFlags |= DC_ACTIVE;
- }
- else
- {
- uidctFlags |= DC_INBUTTON;
- if (nmtbcd->nmcd.uItemState & CDIS_CHECKED)
- uidctFlags |= DC_ACTIVE;
- }
-
- if (DrawCapTemp != NULL)
- {
- /* Draw the button content */
- TaskItem->DisplayTooltip = !DrawCapTemp(TaskItem->hWnd,
- nmtbcd->nmcd.hdc,
- &nmtbcd->nmcd.rc,
- hCaptionFont,
- NULL,
- NULL,
- uidctFlags);
- }
-
- return CDRF_SKIPDEFAULT;
-
-#else /* !TASK_USE_DRAWCAPTIONTEMP */
-
/* Make the entire button flashing if neccessary */
if (nmtbcd->nmcd.uItemState & CDIS_MARKED)
{
- if (TaskItem->RenderFlashed)
+ Ret = TBCDRF_NOBACKGROUND;
+ if (!This->TaskBandTheme)
{
- nmtbcd->hbrMonoDither = GetSysColorBrush(COLOR_HIGHLIGHT);
- nmtbcd->clrTextHighlight = GetSysColor(COLOR_HIGHLIGHTTEXT);
- nmtbcd->nHLStringBkMode = TRANSPARENT;
-
- /* We don't really need to set clrMark because we set the
- background mode to TRANSPARENT! */
- nmtbcd->clrMark = GetSysColor(COLOR_HIGHLIGHT);
-
- Ret |= TBCDRF_USECDCOLORS;
+ SelectObject(nmtbcd->nmcd.hdc,
GetSysColorBrush(COLOR_HIGHLIGHT));
+ Rectangle(nmtbcd->nmcd.hdc,
+ nmtbcd->nmcd.rc.left,
+ nmtbcd->nmcd.rc.top,
+ nmtbcd->nmcd.rc.right,
+ nmtbcd->nmcd.rc.bottom);
}
else
- Ret |= TBCDRF_NOMARK;
- }
-
- /* Select the font we want to use */
- SelectObject(nmtbcd->nmcd.hdc,
- hCaptionFont);
- return Ret | CDRF_NEWFONT;
-
-#endif
-
+ {
+ DrawThemeBackground(This->TaskBandTheme, nmtbcd->nmcd.hdc,
TDP_FLASHBUTTON, 0, &nmtbcd->nmcd.rc, 0);
+ }
+ nmtbcd->clrText = GetSysColor(COLOR_HIGHLIGHTTEXT);
+ return Ret;
+ }
}
}
else if (TaskGroup != NULL)
{
/* FIXME: Implement painting for task groups */
}
-
return Ret;
}
@@ -1907,22 +1896,7 @@
switch (nmtbcd->nmcd.dwDrawStage)
{
-#if TASK_USE_DRAWCAPTIONTEMP != 0
-
case CDDS_ITEMPREPAINT:
- /* We handle drawing in the post-paint stage so that we
- don't have to draw the button edges, etc */
- Ret = CDRF_NOTIFYPOSTPAINT;
- break;
-
- case CDDS_ITEMPOSTPAINT:
-
-#else /* !TASK_USE_DRAWCAPTIONTEMP */
-
- case CDDS_ITEMPREPAINT:
-
-#endif
-
Ret = TaskSwichWnd_HandleItemPaint(This,
nmtbcd);
break;
@@ -1940,6 +1914,16 @@
}
return Ret;
+}
+
+static VOID
+TaskSwitchWnd_DrawBackground(HWND hwnd,
+ HDC hdc)
+{
+ RECT rect;
+
+ GetClientRect(hwnd, &rect);
+ DrawThemeParentBackground(hwnd, hdc, &rect);
}
static LRESULT CALLBACK
@@ -1961,6 +1945,12 @@
{
switch (uMsg)
{
+ case WM_THEMECHANGED:
+ TaskSwitchWnd_UpdateTheme(This);
+ break;
+ case WM_ERASEBKGND:
+ TaskSwitchWnd_DrawBackground(hwnd, (HDC)wParam);
+ break;
case WM_SIZE:
{
SIZE szClient;
Modified: trunk/reactos/base/shell/explorer-new/trayntfy.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer-new/tr…
==============================================================================
--- trunk/reactos/base/shell/explorer-new/trayntfy.c [iso-8859-1] (original)
+++ trunk/reactos/base/shell/explorer-new/trayntfy.c [iso-8859-1] Sun Dec 23 14:37:22
2012
@@ -19,6 +19,669 @@
*/
#include <precomp.h>
+#include <docobj.h>
+
+/*
+ * SysPagerWnd
+ */
+static const TCHAR szSysPagerWndClass[] = TEXT("SysPager");
+
+typedef struct _NOTIFY_ITEM
+{
+ struct _NOTIFY_ITEM *next;
+ INT Index;
+ INT IconIndex;
+ NOTIFYICONDATA iconData;
+} NOTIFY_ITEM, *PNOTIFY_ITEM, **PPNOTIFY_ITEM;
+
+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;
+
+
+static PNOTIFY_ITEM
+SysPagerWnd_CreateNotifyItemData(IN OUT PSYS_PAGER_WND_DATA This)
+{
+ PNOTIFY_ITEM *findNotifyPointer = &This->NotifyItems;
+ PNOTIFY_ITEM notifyItem;
+
+ notifyItem = malloc(sizeof(*notifyItem));
+ if (notifyItem == NULL)
+ return NULL;
+
+ ZeroMemory(notifyItem, sizeof(*notifyItem));
+ 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;
+ 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);
+ }
+
+ /* TODO: support NIF_TIP */
+
+ 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--;
+ free(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);
+ }
+ }
+ }
+ }
+}
+
+static VOID
+SysPagerWnd_DrawBackground(IN HWND hwnd,
+ IN HDC hdc)
+{
+ RECT rect;
+
+ GetClientRect(hwnd, &rect);
+ DrawThemeParentBackground(hwnd, hdc, &rect);
+}
+
+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);
+
+ if (!parent)
+ return 0;
+
+ return SendMessage(parent, msg, wParam, lParam);
+ }
+
+ return DefSubclassProc(hWnd, msg, wParam, lParam);
+}
+
+static VOID
+SysPagerWnd_Create(IN OUT PSYS_PAGER_WND_DATA This)
+{
+ This->hWndToolbar = CreateWindowEx(0,
+ TOOLBARCLASSNAME,
+ NULL,
+ WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN |
+ TBSTYLE_FLAT | TBSTYLE_TOOLTIPS |
TBSTYLE_WRAPABLE |
+ TBSTYLE_TRANSPARENT |
+ CCS_TOP | CCS_NORESIZE | CCS_NODIVIDER,
+ 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, 0, 1000);
+ SendMessage(This->hWndToolbar, TB_SETIMAGELIST, 0,
(LPARAM)This->SysIcons);
+
+ BtnSize.cx = BtnSize.cy = 18;
+ //BtnSize.cx = GetSystemMetrics(SM_CXMINIMIZED);
+ //This->ButtonSize.cy = BtnSize.cy = GetSystemMetrics(SM_CYSIZE) + (2 *
GetSystemMetrics(SM_CYEDGE));
+ SendMessage(This->hWndToolbar,
+ TB_SETBUTTONSIZE,
+ 0,
+ MAKELONG(BtnSize.cx, BtnSize.cy));
+ /*SysPagerWnd_AddButton(This);*/
+
+ 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)
+ {
+ DWORD trayCommand;
+ NOTIFYICONDATA *iconData;
+ HWND parentHWND;
+ RECT windowRect;
+ parentHWND = GetParent(This->hWnd);
+ parentHWND = GetParent(parentHWND);
+ GetClientRect(parentHWND, &windowRect);
+
+ trayCommand = *(DWORD *) (((BYTE *)cpData->lpData) + 4);
+ iconData = (NOTIFYICONDATA *) (((BYTE *)cpData->lpData) + 8);
+
+ switch (trayCommand)
+ {
+ 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;
+ }
+ }
+ 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:
+ SysPagerWnd_DrawBackground(hwnd,(HDC)wParam);
+ return 0;
+
+ 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_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);
+ }
+ }
+
+ 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;
+ }
+
+ Ret = DefWindowProc(hwnd,
+ uMsg,
+ wParam,
+ lParam);
+ break;
+ }
+ }
+
+ return Ret;
+}
+
+static HWND
+CreateSysPagerWnd(IN HWND hWndParent,
+ IN BOOL bVisible)
+{
+ PSYS_PAGER_WND_DATA TcData;
+ DWORD dwStyle;
+ HWND hWnd = NULL;
+
+ TcData = HeapAlloc(hProcessHeap,
+ 0,
+ sizeof(*TcData));
+ if (TcData != NULL)
+ {
+ ZeroMemory(TcData, sizeof(*TcData));
+
+ /* 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,
+ TcData);
+
+ if (hWnd == NULL)
+ {
+ HeapFree(hProcessHeap,
+ 0,
+ TcData);
+ }
+ }
+
+ SetWindowTheme(hWnd, L"TrayNotify", NULL);
+
+ 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
@@ -92,6 +755,7 @@
HWND hWnd;
HWND hWndNotify;
HFONT hFont;
+ COLORREF textColor;
RECT rcText;
SYSTEMTIME LocalTime;
@@ -112,6 +776,49 @@
SIZE LineSizes[CLOCKWND_FORMAT_COUNT];
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 = CreateFontIndirect(&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)
@@ -483,6 +1190,8 @@
iPrevBkMode = SetBkMode(hDC,
TRANSPARENT);
+ SetTextColor(hDC, This->textColor);
+
hPrevFont = SelectObject(hDC,
This->hFont);
@@ -532,6 +1241,16 @@
}
}
+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,
@@ -551,6 +1270,12 @@
{
switch (uMsg)
{
+ case WM_THEMECHANGED:
+ TrayClockWnd_UpdateTheme(This);
+ break;
+ case WM_ERASEBKGND:
+ TrayClockWnd_DrawBackground(hwnd, (HDC)wParam);
+ break;
case WM_PAINT:
case WM_PRINTCLIENT:
{
@@ -621,6 +1346,7 @@
SetWindowLongPtr(hwnd,
0,
(LONG_PTR)This);
+ TrayClockWnd_UpdateTheme(This);
return TRUE;
}
@@ -714,6 +1440,7 @@
TcData);
}
}
+ SetWindowTheme(hWnd, L"TrayNotify", NULL);
return hWnd;
@@ -760,9 +1487,13 @@
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 +1506,43 @@
} TRAY_NOTIFY_WND_DATA, *PTRAY_NOTIFY_WND_DATA;
static VOID
-TrayNotifyWnd_UpdateStyle(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)))
- {
- This->szNonClient.cx = rcClient.right - rcClient.left;
- This->szNonClient.cy = rcClient.bottom - rcClient.top;
- }
+TrayNotifyWnd_UpdateTheme(IN OUT PTRAY_NOTIFY_WND_DATA This)
+{
+ LONG_PTR style;
+
+ if (This->TrayTheme)
+ CloseThemeData(This->TrayTheme);
+
+ if (IsThemeActive())
+ This->TrayTheme = OpenThemeData(This->hWnd, L"TrayNotify");
else
- This->szNonClient.cx = This->szNonClient.cy = 0;
+ This->TrayTheme = 0;
+
+ if (This->TrayTheme)
+ {
+ style = GetWindowLongPtr(This->hWnd, GWL_EXSTYLE);
+ style = style & ~WS_EX_STATICEDGE;
+ SetWindowLongPtr(This->hWnd, GWL_EXSTYLE, style);
+
+ GetThemeMargins(This->TrayTheme,
+ NULL,
+ TNP_BACKGROUND,
+ 0,
+ TMT_CONTENTMARGINS,
+ NULL,
+ &This->ContentMargin);
+ }
+ else
+ {
+ style = GetWindowLongPtr(This->hWnd, GWL_EXSTYLE);
+ style = style | WS_EX_STATICEDGE;
+ SetWindowLongPtr(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 +1551,10 @@
This->hWndTrayClock = CreateTrayClockWnd(This->hWnd,
!This->HideClock);
- TrayNotifyWnd_UpdateStyle(This);
+ This->hWndSysPager = CreateSysPagerWnd(This->hWnd,
+ !This->HideClock);
+
+ TrayNotifyWnd_UpdateTheme(This);
}
static VOID
@@ -818,21 +1573,26 @@
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,22 +1606,44 @@
}
else
NoClock:
- This->szTrayClockMin = This->szNonClient;
+ This->szTrayClockMin = szClock;
if (Horizontal)
{
- pSize->cx = This->szNonClient.cx + (2 * TRAY_NOTIFY_WND_SPACING_X);
+ 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 = 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,6 +1679,55 @@
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 LRESULT
+TrayNotifyWnd_DrawBackground(IN HWND hwnd,
+ IN UINT uMsg,
+ IN WPARAM wParam,
+ IN LPARAM lParam)
+{
+ PTRAY_NOTIFY_WND_DATA This = (PTRAY_NOTIFY_WND_DATA)GetWindowLongPtr(hwnd, 0);
+ RECT rect;
+ HDC hdc = (HDC)wParam;
+
+ GetClientRect(hwnd, &rect);
+
+ DrawThemeParentBackground(hwnd, hdc, &rect);
+ DrawThemeBackground(This->TrayTheme, hdc, TNP_BACKGROUND, 0, &rect, 0);
+
+ return 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);
}
}
@@ -919,6 +1750,14 @@
{
switch (uMsg)
{
+ case WM_THEMECHANGED:
+ TrayNotifyWnd_UpdateTheme(This);
+ return 0;
+ case WM_ERASEBKGND:
+ return TrayNotifyWnd_DrawBackground(hwnd,
+ uMsg,
+ wParam,
+ lParam);
case TNWM_GETMINIMUMSIZE:
{
Ret = (LRESULT)TrayNotifyWnd_GetMinimumSize(This,
@@ -1112,6 +1951,7 @@
UnregisterClass(szTrayNotifyWndClass,
hExplorerInstance);
}
+ RegisterSysPagerWndClass();
}
return Ret;
@@ -1122,6 +1962,8 @@
{
UnregisterTrayClockWndClass();
+ UnregisterSysPagerWndClass();
+
UnregisterClass(szTrayNotifyWndClass,
hExplorerInstance);
}
Modified: trunk/reactos/base/shell/explorer-new/traywnd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer-new/tr…
==============================================================================
--- trunk/reactos/base/shell/explorer-new/traywnd.c [iso-8859-1] (original)
+++ trunk/reactos/base/shell/explorer-new/traywnd.c [iso-8859-1] Sun Dec 23 14:37:22 2012
@@ -43,6 +43,7 @@
const IShellDesktopTrayVtbl *lpVtblShellDesktopTray;
LONG Ref;
+ HTHEME TaskbarTheme;
HWND hWnd;
HWND hWndDesktop;
@@ -1025,6 +1026,12 @@
/* FIXME: Unload bands */
ITrayBandSite_Release(This->TrayBandSite);
This->TrayBandSite = NULL;
+ }
+
+ if (This->TaskbarTheme)
+ {
+ CloseThemeData(This->TaskbarTheme);
+ This->TaskbarTheme = NULL;
}
ITrayWindowImpl_Release(ITrayWindow_from_impl(This));
@@ -1113,6 +1120,7 @@
BOOL Horizontal;
HDWP dwp;
+ ITrayWindowImpl_UpdateStartButton(This, NULL);
if (prcClient != NULL)
{
rcClient = *prcClient;
@@ -1402,9 +1410,24 @@
}
static VOID
+ITrayWindowImpl_UpdateTheme(IN OUT ITrayWindowImpl *This)
+{
+ if (This->TaskbarTheme)
+ CloseThemeData(This->TaskbarTheme);
+
+ if (IsThemeActive())
+ This->TaskbarTheme = OpenThemeData(This->hWnd, L"Taskbar");
+ else
+ This->TaskbarTheme = 0;
+}
+
+static VOID
ITrayWindowImpl_Create(IN OUT ITrayWindowImpl *This)
{
TCHAR szStartCaption[32];
+
+ SetWindowTheme(This->hWnd, L"TaskBar", NULL);
+ ITrayWindowImpl_UpdateTheme(This);
InterlockedIncrement(&TrayWndCount);
@@ -1458,6 +1481,7 @@
NULL);
if (This->hwndStart)
{
+ SetWindowTheme(This->hwndStart, L"Start", NULL);
SendMessage(This->hwndStart,
WM_SETFONT,
(WPARAM)This->hStartBtnFont,
@@ -1538,6 +1562,7 @@
This->TrayBandSite = CreateTrayBandSite(ITrayWindow_from_impl(This),
&This->hwndRebar,
&This->hwndTaskSwitch);
+ SetWindowTheme(This->hwndRebar, L"TaskBar", NULL);
/* Create the tray notification window */
This->hwndTrayNotify = CreateTrayNotifyWnd(ITrayWindow_from_impl(This),
@@ -1883,6 +1908,74 @@
ITrayWindowImpl_Lock
};
+static int
+ITrayWindowImpl_DrawBackground(IN ITrayWindowImpl *This,
+ IN HDC dc)
+{
+ int backoundPart;
+ RECT rect;
+
+ GetClientRect(This->hWnd, &rect);
+ switch (This->Position)
+ {
+ case ABE_LEFT:
+ backoundPart = TBP_BACKGROUNDLEFT;
+ break;
+ case ABE_TOP:
+ backoundPart = TBP_BACKGROUNDTOP;
+ break;
+ case ABE_RIGHT:
+ backoundPart = TBP_BACKGROUNDRIGHT;
+ break;
+ case ABE_BOTTOM:
+ default:
+ backoundPart = TBP_BACKGROUNDBOTTOM;
+ break;
+ }
+ DrawThemeBackground(This->TaskbarTheme, dc, backoundPart, 0, &rect, 0);
+ return 0;
+}
+
+static int
+ITrayWindowImpl_DrawSizer(IN ITrayWindowImpl *This,
+ IN HRGN hRgn)
+{
+ HDC hdc;
+ RECT rect;
+ int backoundPart;
+
+ GetWindowRect(This->hWnd, &rect);
+ OffsetRect(&rect, -rect.left, -rect.top);
+
+ hdc = GetDCEx(This->hWnd, hRgn, DCX_WINDOW | DCX_INTERSECTRGN | DCX_PARENTCLIP);
+
+ switch (This->Position)
+ {
+ case ABE_LEFT:
+ backoundPart = TBP_SIZINGBARLEFT;
+ rect.left = rect.right - GetSystemMetrics(SM_CXSIZEFRAME);
+ break;
+ case ABE_TOP:
+ backoundPart = TBP_SIZINGBARTOP;
+ rect.top = rect.bottom - GetSystemMetrics(SM_CYSIZEFRAME);
+ break;
+ case ABE_RIGHT:
+ backoundPart = TBP_SIZINGBARRIGHT;
+ rect.right = rect.left + GetSystemMetrics(SM_CXSIZEFRAME);
+ break;
+ case ABE_BOTTOM:
+ default:
+ backoundPart = TBP_SIZINGBARBOTTOM;
+ rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZEFRAME);
+ break;
+ }
+
+ DrawThemeBackground(This->TaskbarTheme, hdc, backoundPart, 0, &rect, 0);
+
+ ReleaseDC(This->hWnd, hdc);
+ return 0;
+}
+
static DWORD WINAPI
RunFileDlgThread(IN OUT PVOID pParam)
{
@@ -1957,6 +2050,32 @@
switch (uMsg)
{
+ case WM_COPYDATA:
+ {
+ if (This->hwndTrayNotify)
+ {
+ TrayNotify_NotifyMsg(This->hwndTrayNotify,
+ wParam,
+ lParam);
+ }
+ return TRUE;
+ }
+ case WM_THEMECHANGED:
+ ITrayWindowImpl_UpdateTheme(This);
+ return 0;
+ case WM_NCPAINT:
+ if (!This->TaskbarTheme)
+ goto DefHandler;
+ return ITrayWindowImpl_DrawSizer(This,
+ (HRGN)wParam);
+ case WM_ERASEBKGND:
+ if (!This->TaskbarTheme)
+ goto DefHandler;
+ return ITrayWindowImpl_DrawBackground(This,
+ (HDC)wParam);
+ case WM_CTLCOLORBTN:
+ SetBkMode((HDC)wParam, TRANSPARENT);
+ return (LRESULT)GetStockObject(HOLLOW_BRUSH);
case WM_NCHITTEST:
{
RECT rcClient;
@@ -1996,30 +2115,23 @@
if (pt.y > rcClient.bottom)
return HTBOTTOM;
break;
-
- case ABE_BOTTOM:
- if (pt.y < rcClient.top)
- return HTTOP;
- break;
-
case ABE_LEFT:
if (pt.x > rcClient.right)
return HTRIGHT;
break;
-
case ABE_RIGHT:
if (pt.x < rcClient.left)
return HTLEFT;
break;
-
+ case ABE_BOTTOM:
default:
+ if (pt.y < rcClient.top)
+ return HTTOP;
break;
}
}
-
return HTBORDER;
}
-
case WM_MOVING:
{
POINT ptCursor;
@@ -2072,7 +2184,7 @@
case WM_SIZE:
{
RECT rcClient;
-
+ InvalidateRect(This->hWnd, NULL, TRUE);
if (wParam == SIZE_RESTORED && lParam == 0)
{
ITrayWindowImpl_ResizeWorkArea(This);