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/CMa... ============================================================================== --- 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/pre... ============================================================================== --- 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/tas... ============================================================================== --- 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/tra... ============================================================================== --- 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/tra... ============================================================================== --- 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);