From 455bce68b505b89dd19ca994b67f671ee1dfa407 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Sun, 28 Jan 2018 14:21:45 +0200 Subject: [PATCH] [EXPLORER] -Make CSysPagerWnd, CTaskSwitchWnd, CTrayClockWnd and CTrayNotifyWnd proper com objects so that their lifetime is managed properly. --- base/shell/explorer/precomp.h | 24 +-- base/shell/explorer/syspager.cpp | 253 ++++++++++++++++++++++++++++-- base/shell/explorer/syspager.h | 207 ------------------------ base/shell/explorer/taskband.cpp | 20 ++- base/shell/explorer/taskswnd.cpp | 50 ++++-- base/shell/explorer/trayclock.cpp | 131 +++++++++++++++- base/shell/explorer/trayclock.h | 94 ----------- base/shell/explorer/trayntfy.cpp | 86 ++++++---- base/shell/explorer/traywnd.cpp | 15 +- 9 files changed, 490 insertions(+), 390 deletions(-) delete mode 100644 base/shell/explorer/syspager.h delete mode 100644 base/shell/explorer/trayclock.h diff --git a/base/shell/explorer/precomp.h b/base/shell/explorer/precomp.h index 2473096233e..5c9676be303 100644 --- a/base/shell/explorer/precomp.h +++ b/base/shell/explorer/precomp.h @@ -332,19 +332,18 @@ CreateStartMenuSite(IN OUT ITrayWindow *Tray, const IID & riid, PVOID * ppv); */ /* TrayClockWnd */ -#define TCWM_GETMINIMUMSIZE (WM_USER + 0x100) -#define TCWM_UPDATETIME (WM_USER + 0x101) +HRESULT CTrayClockWnd_CreateInstance(HWND hwndParent, REFIID riid, void **ppv); /* TrayNotifyWnd */ #define TNWM_GETMINIMUMSIZE (WM_USER + 0x100) -#define TNWM_SHOWTRAY (WM_USER + 0x103) #define TNWM_CHANGETRAYPOS (WM_USER + 0x104) #define NTNWM_REALIGN (0x1) -class CTrayNotifyWnd; +HRESULT CTrayNotifyWnd_CreateInstance(HWND hwndParent, REFIID riid, void **ppv); -HWND CreateTrayNotifyWnd(IN HWND hwndParent, CTrayNotifyWnd** ppinstance); +/* SysPagerWnd */ +HRESULT CSysPagerWnd_CreateInstance(HWND hwndParent, REFIID riid, void **ppv); /* * taskswnd.c @@ -353,8 +352,7 @@ HWND CreateTrayNotifyWnd(IN HWND hwndParent, CTrayNotifyWnd** ppinstance); #define TSWM_ENABLEGROUPING (WM_USER + 1) #define TSWM_UPDATETASKBARPOS (WM_USER + 2) -HWND -CreateTaskSwitchWnd(IN HWND hWndParent, IN OUT ITrayWindow *Tray); +HRESULT CTaskSwitchWnd_CreateInstance(IN HWND hWndParent, IN OUT ITrayWindow *Tray, REFIID riid, void **ppv); HRESULT Tray_OnStartMenuDismissed(ITrayWindow* Tray); @@ -362,16 +360,4 @@ Tray_OnStartMenuDismissed(ITrayWindow* Tray); HRESULT IsSameObject(IN IUnknown *punk1, IN IUnknown *punk2); -/* -* syspager.c -*/ - -#include "syspager.h" - -/* -* trayclock.c -*/ - -#include "trayclock.h" - #endif /* _EXPLORER_PRECOMP__H_ */ diff --git a/base/shell/explorer/syspager.cpp b/base/shell/explorer/syspager.cpp index c404d3a57f6..45f17023b97 100644 --- a/base/shell/explorer/syspager.cpp +++ b/base/shell/explorer/syspager.cpp @@ -29,6 +29,236 @@ typedef struct _SYS_PAGER_COPY_DATA NOTIFYICONDATA nicon_data; } SYS_PAGER_COPY_DATA, *PSYS_PAGER_COPY_DATA; +struct InternalIconData : NOTIFYICONDATA +{ + // Must keep a separate copy since the original is unioned with uTimeout. + UINT uVersionCopy; +}; + +struct IconWatcherData +{ + HANDLE hProcess; + DWORD ProcessId; + NOTIFYICONDATA IconData; + + IconWatcherData(CONST NOTIFYICONDATA *iconData) : + hProcess(NULL), ProcessId(0) + { + IconData.cbSize = sizeof(NOTIFYICONDATA); + IconData.hWnd = iconData->hWnd; + IconData.uID = iconData->uID; + IconData.guidItem = iconData->guidItem; + } + + ~IconWatcherData() + { + if (hProcess) + { + CloseHandle(hProcess); + } + } +}; + +class CIconWatcher +{ + CAtlList m_WatcherList; + CRITICAL_SECTION m_ListLock; + HANDLE m_hWatcherThread; + HANDLE m_WakeUpEvent; + HWND m_hwndSysTray; + bool m_Loop; + +public: + CIconWatcher(); + + virtual ~CIconWatcher(); + + bool Initialize(_In_ HWND hWndParent); + void Uninitialize(); + + bool AddIconToWatcher(_In_ CONST NOTIFYICONDATA *iconData); + bool RemoveIconFromWatcher(_In_ CONST NOTIFYICONDATA *iconData); + + IconWatcherData* GetListEntry(_In_opt_ CONST NOTIFYICONDATA *iconData, _In_opt_ HANDLE hProcess, _In_ bool Remove); + +private: + + static UINT WINAPI WatcherThread(_In_opt_ LPVOID lpParam); +}; + +class CBalloonQueue +{ +public: + static const int TimerInterval = 2000; + static const int BalloonsTimerId = 1; + static const int MinTimeout = 10000; + static const int MaxTimeout = 30000; + static const int CooldownBetweenBalloons = 2000; + +private: + struct Info + { + InternalIconData * pSource; + WCHAR szInfo[256]; + WCHAR szInfoTitle[64]; + WPARAM uIcon; + UINT uTimeout; + + Info(InternalIconData * source) + { + pSource = source; + StrNCpy(szInfo, source->szInfo, _countof(szInfo)); + StrNCpy(szInfoTitle, source->szInfoTitle, _countof(szInfoTitle)); + uIcon = source->dwInfoFlags & NIIF_ICON_MASK; + if (source->dwInfoFlags == NIIF_USER) + uIcon = reinterpret_cast(source->hIcon); + uTimeout = source->uTimeout; + } + }; + + HWND m_hwndParent; + + CTooltips * m_tooltips; + + CAtlList m_queue; + + CToolbar * m_toolbar; + + InternalIconData * m_current; + bool m_currentClosed; + + int m_timer; + +public: + CBalloonQueue(); + + void Init(HWND hwndParent, CToolbar * toolbar, CTooltips * balloons); + void Deinit(); + + bool OnTimer(int timerId); + void UpdateInfo(InternalIconData * notifyItem); + void RemoveInfo(InternalIconData * notifyItem); + void CloseCurrent(); + +private: + + int IndexOf(InternalIconData * pdata); + void SetTimer(int length); + void Show(Info& info); + void Close(IN OUT InternalIconData * notifyItem); +}; + +class CNotifyToolbar : + public CWindowImplBaseT< CToolbar, CControlWinTraits > +{ + HIMAGELIST m_ImageList; + int m_VisibleButtonCount; + + CBalloonQueue * m_BalloonQueue; + +public: + CNotifyToolbar(); + virtual ~CNotifyToolbar(); + + int GetVisibleButtonCount(); + int FindItem(IN HWND hWnd, IN UINT uID, InternalIconData ** pdata); + int FindExistingSharedIcon(HICON handle); + BOOL AddButton(IN CONST NOTIFYICONDATA *iconData); + BOOL SwitchVersion(IN CONST NOTIFYICONDATA *iconData); + BOOL UpdateButton(IN CONST NOTIFYICONDATA *iconData); + BOOL RemoveButton(IN CONST NOTIFYICONDATA *iconData); + VOID ResizeImagelist(); + +private: + VOID SendMouseEvent(IN WORD wIndex, IN UINT uMsg, IN WPARAM wParam); + LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnTooltipShow(INT uCode, LPNMHDR hdr, BOOL& bHandled); + +public: + BEGIN_MSG_MAP(CNotifyToolbar) + MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseEvent) + NOTIFY_CODE_HANDLER(TTN_SHOW, OnTooltipShow) + END_MSG_MAP() + + void Initialize(HWND hWndParent, CBalloonQueue * queue); +}; + +extern const WCHAR szSysPagerWndClass[]; + +class CSysPagerWnd : + public CComCoClass, + public CComObjectRootEx, + public CWindowImpl < CSysPagerWnd, CWindow, CControlWinTraits >, + public IOleWindow, + public CIconWatcher +{ + CNotifyToolbar Toolbar; + CTooltips m_Balloons; + CBalloonQueue m_BalloonQueue; + +public: + CSysPagerWnd(); + virtual ~CSysPagerWnd(); + + LRESULT DrawBackground(HDC hdc); + LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnGetInfoTip(INT uCode, LPNMHDR hdr, BOOL& bHandled); + LRESULT OnCustomDraw(INT uCode, LPNMHDR hdr, BOOL& bHandled); + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnCtxMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnBalloonPop(UINT uCode, LPNMHDR hdr, BOOL& bHandled); + LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnCopyData(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnSettingChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnGetMinimumSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + +public: + + HRESULT WINAPI GetWindow(HWND* phwnd) + { + if (!phwnd) + return E_INVALIDARG; + *phwnd = m_hWnd; + return S_OK; + } + + HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode) + { + return E_NOTIMPL; + } + + DECLARE_NOT_AGGREGATABLE(CSysPagerWnd) + + DECLARE_PROTECT_FINAL_CONSTRUCT() + BEGIN_COM_MAP(CSysPagerWnd) + COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) + END_COM_MAP() + + BOOL NotifyIcon(DWORD notify_code, _In_ CONST NOTIFYICONDATA *iconData); + void GetSize(IN BOOL IsHorizontal, IN PSIZE size); + + DECLARE_WND_CLASS_EX(szSysPagerWndClass, CS_DBLCLKS, COLOR_3DFACE) + + BEGIN_MSG_MAP(CSysPagerWnd) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_CONTEXTMENU, OnCtxMenu) + MESSAGE_HANDLER(WM_TIMER, OnTimer) + MESSAGE_HANDLER(WM_COPYDATA, OnCopyData) + MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChanged) + MESSAGE_HANDLER(TNWM_GETMINIMUMSIZE, OnGetMinimumSize) + NOTIFY_CODE_HANDLER(TTN_POP, OnBalloonPop) + NOTIFY_CODE_HANDLER(TBN_GETINFOTIPW, OnGetInfoTip) + NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw) + END_MSG_MAP() + + HRESULT Initialize(IN HWND hWndParent); +}; + CIconWatcher::CIconWatcher() : m_hWatcherThread(NULL), m_WakeUpEvent(NULL), @@ -1204,22 +1434,27 @@ LRESULT CSysPagerWnd::OnSettingChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, return 0; } -HWND CSysPagerWnd::_Init(IN HWND hWndParent) +LRESULT CSysPagerWnd::OnGetMinimumSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - DWORD dwStyle; + GetSize((BOOL)wParam, (PSIZE)lParam); + return 0; +} +HRESULT CSysPagerWnd::Initialize(IN HWND hWndParent) +{ /* 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 | WS_VISIBLE; - + DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE; Create(hWndParent, 0, NULL, dwStyle); - if (!m_hWnd) - { - return NULL; - } + return E_FAIL; SetWindowTheme(m_hWnd, L"TrayNotify", NULL); - return m_hWnd; + return S_OK; +} + +HRESULT CSysPagerWnd_CreateInstance(HWND hwndParent, REFIID riid, void **ppv) +{ + return ShellObjectCreatorInit(hwndParent, riid, ppv); } diff --git a/base/shell/explorer/syspager.h b/base/shell/explorer/syspager.h deleted file mode 100644 index 1df0798ebd4..00000000000 --- a/base/shell/explorer/syspager.h +++ /dev/null @@ -1,207 +0,0 @@ -#pragma once - -struct InternalIconData : NOTIFYICONDATA -{ - // Must keep a separate copy since the original is unioned with uTimeout. - UINT uVersionCopy; -}; - -struct IconWatcherData -{ - HANDLE hProcess; - DWORD ProcessId; - NOTIFYICONDATA IconData; - - IconWatcherData(CONST NOTIFYICONDATA *iconData) : - hProcess(NULL), ProcessId(0) - { - IconData.cbSize = sizeof(NOTIFYICONDATA); - IconData.hWnd = iconData->hWnd; - IconData.uID = iconData->uID; - IconData.guidItem = iconData->guidItem; - } - - ~IconWatcherData() - { - if (hProcess) - { - CloseHandle(hProcess); - } - } -}; - -class CIconWatcher -{ - CAtlList m_WatcherList; - CRITICAL_SECTION m_ListLock; - HANDLE m_hWatcherThread; - HANDLE m_WakeUpEvent; - HWND m_hwndSysTray; - bool m_Loop; - -public: - CIconWatcher(); - - virtual ~CIconWatcher(); - - bool Initialize(_In_ HWND hWndParent); - void Uninitialize(); - - bool AddIconToWatcher(_In_ CONST NOTIFYICONDATA *iconData); - bool RemoveIconFromWatcher(_In_ CONST NOTIFYICONDATA *iconData); - - IconWatcherData* GetListEntry(_In_opt_ CONST NOTIFYICONDATA *iconData, _In_opt_ HANDLE hProcess, _In_ bool Remove); - -private: - - static UINT WINAPI WatcherThread(_In_opt_ LPVOID lpParam); -}; - -class CBalloonQueue -{ -public: - static const int TimerInterval = 2000; - static const int BalloonsTimerId = 1; - static const int MinTimeout = 10000; - static const int MaxTimeout = 30000; - static const int CooldownBetweenBalloons = 2000; - -private: - struct Info - { - InternalIconData * pSource; - WCHAR szInfo[256]; - WCHAR szInfoTitle[64]; - WPARAM uIcon; - UINT uTimeout; - - Info(InternalIconData * source) - { - pSource = source; - StrNCpy(szInfo, source->szInfo, _countof(szInfo)); - StrNCpy(szInfoTitle, source->szInfoTitle, _countof(szInfoTitle)); - uIcon = source->dwInfoFlags & NIIF_ICON_MASK; - if (source->dwInfoFlags == NIIF_USER) - uIcon = reinterpret_cast(source->hIcon); - uTimeout = source->uTimeout; - } - }; - - HWND m_hwndParent; - - CTooltips * m_tooltips; - - CAtlList m_queue; - - CToolbar * m_toolbar; - - InternalIconData * m_current; - bool m_currentClosed; - - int m_timer; - -public: - CBalloonQueue(); - - void Init(HWND hwndParent, CToolbar * toolbar, CTooltips * balloons); - void Deinit(); - - bool OnTimer(int timerId); - void UpdateInfo(InternalIconData * notifyItem); - void RemoveInfo(InternalIconData * notifyItem); - void CloseCurrent(); - -private: - - int IndexOf(InternalIconData * pdata); - void SetTimer(int length); - void Show(Info& info); - void Close(IN OUT InternalIconData * notifyItem); -}; - -class CNotifyToolbar : - public CWindowImplBaseT< CToolbar, CControlWinTraits > -{ - HIMAGELIST m_ImageList; - int m_VisibleButtonCount; - - CBalloonQueue * m_BalloonQueue; - -public: - CNotifyToolbar(); - virtual ~CNotifyToolbar(); - - int GetVisibleButtonCount(); - int FindItem(IN HWND hWnd, IN UINT uID, InternalIconData ** pdata); - int FindExistingSharedIcon(HICON handle); - BOOL AddButton(IN CONST NOTIFYICONDATA *iconData); - BOOL SwitchVersion(IN CONST NOTIFYICONDATA *iconData); - BOOL UpdateButton(IN CONST NOTIFYICONDATA *iconData); - BOOL RemoveButton(IN CONST NOTIFYICONDATA *iconData); - VOID ResizeImagelist(); - -private: - VOID SendMouseEvent(IN WORD wIndex, IN UINT uMsg, IN WPARAM wParam); - LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnTooltipShow(INT uCode, LPNMHDR hdr, BOOL& bHandled); - -public: - BEGIN_MSG_MAP(CNotifyToolbar) - MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseEvent) - NOTIFY_CODE_HANDLER(TTN_SHOW, OnTooltipShow) - END_MSG_MAP() - - void Initialize(HWND hWndParent, CBalloonQueue * queue); -}; - -extern const WCHAR szSysPagerWndClass[]; - -class CSysPagerWnd : - public CComObjectRootEx, - public CWindowImpl < CSysPagerWnd, CWindow, CControlWinTraits >, - public CIconWatcher -{ - CNotifyToolbar Toolbar; - CTooltips m_Balloons; - CBalloonQueue m_BalloonQueue; - -public: - CSysPagerWnd(); - virtual ~CSysPagerWnd(); - - LRESULT DrawBackground(HDC hdc); - LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnGetInfoTip(INT uCode, LPNMHDR hdr, BOOL& bHandled); - LRESULT OnCustomDraw(INT uCode, LPNMHDR hdr, BOOL& bHandled); - LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnCtxMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnBalloonPop(UINT uCode, LPNMHDR hdr, BOOL& bHandled); - LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnCopyData(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnSettingChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - -public: - - BOOL NotifyIcon(DWORD notify_code, _In_ CONST NOTIFYICONDATA *iconData); - void GetSize(IN BOOL IsHorizontal, IN PSIZE size); - - DECLARE_WND_CLASS_EX(szSysPagerWndClass, CS_DBLCLKS, COLOR_3DFACE) - - BEGIN_MSG_MAP(CSysPagerWnd) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_CONTEXTMENU, OnCtxMenu) - MESSAGE_HANDLER(WM_TIMER, OnTimer) - MESSAGE_HANDLER(WM_COPYDATA, OnCopyData) - MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChanged) - NOTIFY_CODE_HANDLER(TTN_POP, OnBalloonPop) - NOTIFY_CODE_HANDLER(TBN_GETINFOTIPW, OnGetInfoTip) - NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw) - END_MSG_MAP() - - HWND _Init(IN HWND hWndParent); -}; diff --git a/base/shell/explorer/taskband.cpp b/base/shell/explorer/taskband.cpp index 6dd4d9e80df..d1c6ecd73c0 100644 --- a/base/shell/explorer/taskband.cpp +++ b/base/shell/explorer/taskband.cpp @@ -38,6 +38,7 @@ class CTaskBand : { CComPtr m_Tray; CComPtr m_Site; + CComPtr m_TasksWnd; HWND m_hWnd; @@ -250,23 +251,20 @@ public: TRACE("CTaskBand::SetSite(0x%p)\n", pUnkSite); hRet = IUnknown_GetWindow(pUnkSite, &hwndSite); - if (FAILED(hRet)) - { - TRACE("Querying site window failed: 0x%x\n", hRet); + if (FAILED_UNEXPECTEDLY(hRet)) return hRet; - } TRACE("CreateTaskSwitchWnd(Parent: 0x%p)\n", hwndSite); - HWND hwndTaskSwitch = CreateTaskSwitchWnd(hwndSite, m_Tray); - if (!hwndTaskSwitch) - { - ERR("CreateTaskSwitchWnd failed"); - return E_FAIL; - } + hRet = CTaskSwitchWnd_CreateInstance(hwndSite, m_Tray, IID_PPV_ARG(IUnknown, &m_TasksWnd)); + if (FAILED_UNEXPECTEDLY(hRet)) + return hRet; + + hRet = IUnknown_GetWindow(m_TasksWnd, &m_hWnd); + if (FAILED_UNEXPECTEDLY(hRet)) + return hRet; m_Site = pUnkSite; - m_hWnd = hwndTaskSwitch; return S_OK; } diff --git a/base/shell/explorer/taskswnd.cpp b/base/shell/explorer/taskswnd.cpp index 44d0e3e2155..18fa2c1e69d 100644 --- a/base/shell/explorer/taskswnd.cpp +++ b/base/shell/explorer/taskswnd.cpp @@ -193,7 +193,10 @@ public: }; class CTaskSwitchWnd : - public CWindowImpl < CTaskSwitchWnd, CWindow, CControlWinTraits > + public CComCoClass, + public CComObjectRootEx, + public CWindowImpl < CTaskSwitchWnd, CWindow, CControlWinTraits >, + public IOleWindow { CTaskToolbar m_TaskBar; @@ -1827,6 +1830,29 @@ public: return 0; } + HRESULT Initialize(IN HWND hWndParent, IN OUT ITrayWindow *tray) + { + m_Tray = tray; + m_IsGroupingEnabled = TRUE; /* FIXME */ + Create(hWndParent, 0, szRunningApps, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_TABSTOP); + if (!m_hWnd) + return E_FAIL; + return S_OK; + } + + HRESULT WINAPI GetWindow(HWND* phwnd) + { + if (!phwnd) + return E_INVALIDARG; + *phwnd = m_hWnd; + return S_OK; + } + + HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode) + { + return E_NOTIMPL; + } + DECLARE_WND_CLASS_EX(szTaskSwitchWndClass, CS_DBLCLKS, COLOR_3DFACE) BEGIN_MSG_MAP(CTaskSwitchWnd) @@ -1850,21 +1876,15 @@ public: MESSAGE_HANDLER(WM_KLUDGEMINRECT, OnKludgeItemRect) END_MSG_MAP() - HWND _Init(IN HWND hWndParent, IN OUT ITrayWindow *tray) - { - m_Tray = tray; - m_IsGroupingEnabled = TRUE; /* FIXME */ - return Create(hWndParent, 0, szRunningApps, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_TABSTOP); - } + DECLARE_NOT_AGGREGATABLE(CTaskSwitchWnd) + + DECLARE_PROTECT_FINAL_CONSTRUCT() + BEGIN_COM_MAP(CTaskSwitchWnd) + COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) + END_COM_MAP() }; -HWND -CreateTaskSwitchWnd(IN HWND hWndParent, IN OUT ITrayWindow *Tray) +HRESULT CTaskSwitchWnd_CreateInstance(IN HWND hWndParent, IN OUT ITrayWindow *Tray, REFIID riid, void **ppv) { - CTaskSwitchWnd * instance; - - // TODO: Destroy after the window is destroyed - instance = new CTaskSwitchWnd(); - - return instance->_Init(hWndParent, Tray); + return ShellObjectCreatorInit(hWndParent, Tray, riid, ppv); } diff --git a/base/shell/explorer/trayclock.cpp b/base/shell/explorer/trayclock.cpp index 10422147318..b2efa36689f 100644 --- a/base/shell/explorer/trayclock.cpp +++ b/base/shell/explorer/trayclock.cpp @@ -25,6 +25,123 @@ * TrayClockWnd */ +const struct +{ + BOOL IsTime; + DWORD dwFormatFlags; + LPCWSTR lpFormat; +} ClockWndFormats[] = { + { TRUE, 0, NULL }, + { FALSE, 0, L"dddd" }, + { FALSE, DATE_SHORTDATE, NULL } +}; +const UINT ClockWndFormatsCount = _ARRAYSIZE(ClockWndFormats); + +#define CLOCKWND_FORMAT_COUNT ClockWndFormatsCount + +extern const WCHAR szTrayClockWndClass[]; + +class CTrayClockWnd : + public CComCoClass, + public CComObjectRootEx, + public CWindowImpl < CTrayClockWnd, CWindow, CControlWinTraits >, + public IOleWindow +{ + HWND hWndNotify; + HFONT hFont; + COLORREF textColor; + RECT rcText; + SYSTEMTIME LocalTime; + + union + { + DWORD dwFlags; + struct + { + DWORD IsTimerEnabled : 1; + DWORD IsInitTimerEnabled : 1; + DWORD LinesMeasured : 1; + DWORD IsHorizontal : 1; + }; + }; + DWORD LineSpacing; + SIZE CurrentSize; + WORD VisibleLines; + SIZE LineSizes[CLOCKWND_FORMAT_COUNT]; + WCHAR szLines[CLOCKWND_FORMAT_COUNT][48]; + +public: + CTrayClockWnd(); + virtual ~CTrayClockWnd(); + +private: + LRESULT OnThemeChanged(); + LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + + BOOL MeasureLines(); + WORD GetMinimumSize(IN BOOL Horizontal, IN OUT PSIZE pSize); + VOID UpdateWnd(); + VOID Update(); + UINT CalculateDueTime(); + BOOL ResetTime(); + VOID CalibrateTimer(); + LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + VOID SetFont(IN HFONT hNewFont, IN BOOL bRedraw); + LRESULT DrawBackground(HDC hdc); + LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnGetMinimumSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnSetFont(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnTaskbarSettingsChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnNcLButtonDblClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + +public: + + HRESULT WINAPI GetWindow(HWND* phwnd) + { + if (!phwnd) + return E_INVALIDARG; + *phwnd = m_hWnd; + return S_OK; + } + + HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode) + { + return E_NOTIMPL; + } + + DECLARE_NOT_AGGREGATABLE(CTrayClockWnd) + + DECLARE_PROTECT_FINAL_CONSTRUCT() + BEGIN_COM_MAP(CTrayClockWnd) + COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) + END_COM_MAP() + + DECLARE_WND_CLASS_EX(szTrayClockWndClass, CS_DBLCLKS, COLOR_3DFACE) + + BEGIN_MSG_MAP(CTrayClockWnd) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) + MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged) + MESSAGE_HANDLER(WM_TIMER, OnTimer) + MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest) + MESSAGE_HANDLER(WM_SETFONT, OnSetFont) + MESSAGE_HANDLER(TNWM_GETMINIMUMSIZE, OnGetMinimumSize) + MESSAGE_HANDLER(TWM_SETTINGSCHANGED, OnTaskbarSettingsChanged) + MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK, OnNcLButtonDblClick) + END_MSG_MAP() + + HRESULT Initialize(IN HWND hWndParent); +}; + const WCHAR szTrayClockWndClass[] = L"TrayClockWClass"; #define ID_TRAYCLOCK_TIMER 0 @@ -578,7 +695,7 @@ LRESULT CTrayClockWnd::OnNcLButtonDblClick(UINT uMsg, WPARAM wParam, LPARAM lPar return TRUE; } -HWND CTrayClockWnd::_Init(IN HWND hWndParent) +HRESULT CTrayClockWnd::Initialize(IN HWND hWndParent) { IsHorizontal = TRUE; @@ -589,10 +706,16 @@ HWND CTrayClockWnd::_Init(IN HWND hWndParent) dwStyle |= WS_VISIBLE; Create(hWndParent, 0, NULL, dwStyle); + if (!m_hWnd) + return E_FAIL; - if (m_hWnd != NULL) - SetWindowTheme(m_hWnd, L"TrayNotify", NULL); + SetWindowTheme(m_hWnd, L"TrayNotify", NULL); - return m_hWnd; + return S_OK; }; + +HRESULT CTrayClockWnd_CreateInstance(HWND hwndParent, REFIID riid, void **ppv) +{ + return ShellObjectCreatorInit(hwndParent, riid, ppv); +} diff --git a/base/shell/explorer/trayclock.h b/base/shell/explorer/trayclock.h deleted file mode 100644 index 4c152098cda..00000000000 --- a/base/shell/explorer/trayclock.h +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once - -const struct -{ - BOOL IsTime; - DWORD dwFormatFlags; - LPCWSTR lpFormat; -} ClockWndFormats[] = { - { TRUE, 0, NULL }, - { FALSE, 0, L"dddd" }, - { FALSE, DATE_SHORTDATE, NULL } -}; -const UINT ClockWndFormatsCount = _ARRAYSIZE(ClockWndFormats); - -#define CLOCKWND_FORMAT_COUNT ClockWndFormatsCount - -extern const WCHAR szTrayClockWndClass[]; -class CTrayClockWnd : - public CComObjectRootEx, - public CWindowImpl < CTrayClockWnd, CWindow, CControlWinTraits > -{ - HWND hWndNotify; - HFONT hFont; - COLORREF textColor; - RECT rcText; - SYSTEMTIME LocalTime; - - union - { - DWORD dwFlags; - struct - { - DWORD IsTimerEnabled : 1; - DWORD IsInitTimerEnabled : 1; - DWORD LinesMeasured : 1; - DWORD IsHorizontal : 1; - }; - }; - DWORD LineSpacing; - SIZE CurrentSize; - WORD VisibleLines; - SIZE LineSizes[CLOCKWND_FORMAT_COUNT]; - WCHAR szLines[CLOCKWND_FORMAT_COUNT][48]; - -public: - CTrayClockWnd(); - virtual ~CTrayClockWnd(); - -private: - LRESULT OnThemeChanged(); - LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - - BOOL MeasureLines(); - WORD GetMinimumSize(IN BOOL Horizontal, IN OUT PSIZE pSize); - VOID UpdateWnd(); - VOID Update(); - UINT CalculateDueTime(); - BOOL ResetTime(); - VOID CalibrateTimer(); - LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - VOID SetFont(IN HFONT hNewFont, IN BOOL bRedraw); - LRESULT DrawBackground(HDC hdc); - LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnGetMinimumSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnSetFont(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnTaskbarSettingsChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnNcLButtonDblClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - -public: - DECLARE_WND_CLASS_EX(szTrayClockWndClass, CS_DBLCLKS, COLOR_3DFACE) - - BEGIN_MSG_MAP(CTrayClockWnd) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_PAINT, OnPaint) - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) - MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged) - MESSAGE_HANDLER(WM_TIMER, OnTimer) - MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest) - MESSAGE_HANDLER(WM_SETFONT, OnSetFont) - MESSAGE_HANDLER(TCWM_GETMINIMUMSIZE, OnGetMinimumSize) - MESSAGE_HANDLER(TWM_SETTINGSCHANGED, OnTaskbarSettingsChanged) - MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK, OnNcLButtonDblClick) - END_MSG_MAP() - - HWND _Init(IN HWND hWndParent); -}; \ No newline at end of file diff --git a/base/shell/explorer/trayntfy.cpp b/base/shell/explorer/trayntfy.cpp index 4004184a944..a5ce527b42b 100644 --- a/base/shell/explorer/trayntfy.cpp +++ b/base/shell/explorer/trayntfy.cpp @@ -31,11 +31,16 @@ static const WCHAR szTrayNotifyWndClass [] = TEXT("TrayNotifyWnd"); #define TRAY_NOTIFY_WND_SPACING_Y 1 class CTrayNotifyWnd : + public CComCoClass, public CComObjectRootEx, - public CWindowImpl < CTrayNotifyWnd, CWindow, CControlWinTraits > + public CWindowImpl < CTrayNotifyWnd, CWindow, CControlWinTraits >, + public IOleWindow { - CSysPagerWnd * m_pager; - CTrayClockWnd * m_clock; + CComPtr m_clock; + CComPtr m_pager; + + HWND m_hwndClock; + HWND m_hwndPager; HTHEME TrayTheme; SIZE szTrayClockMin; @@ -45,8 +50,8 @@ class CTrayNotifyWnd : public: CTrayNotifyWnd() : - m_pager(NULL), - m_clock(NULL), + m_hwndClock(NULL), + m_hwndPager(NULL), TrayTheme(NULL), IsHorizontal(FALSE) { @@ -98,11 +103,23 @@ public: LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - m_clock = new CTrayClockWnd(); - m_clock->_Init(m_hWnd); + HRESULT hr; - m_pager = new CSysPagerWnd(); - m_pager->_Init(m_hWnd); + hr = CTrayClockWnd_CreateInstance(m_hWnd, IID_PPV_ARG(IUnknown, &m_clock)); + if (FAILED_UNEXPECTEDLY(hr)) + return FALSE; + + hr = IUnknown_GetWindow(m_clock, &m_hwndClock); + if (FAILED_UNEXPECTEDLY(hr)) + return FALSE; + + hr = CSysPagerWnd_CreateInstance(m_hWnd, IID_PPV_ARG(IUnknown, &m_pager)); + if (FAILED_UNEXPECTEDLY(hr)) + return FALSE; + + hr = IUnknown_GetWindow(m_pager, &m_hwndPager); + if (FAILED_UNEXPECTEDLY(hr)) + return FALSE; return TRUE; } @@ -127,7 +144,7 @@ public: goto NoClock; } - m_clock->SendMessage(TCWM_GETMINIMUMSIZE, (WPARAM) IsHorizontal, (LPARAM) &szClock); + ::SendMessage(m_hwndClock, TNWM_GETMINIMUMSIZE, (WPARAM) IsHorizontal, (LPARAM) &szClock); szTrayClockMin = szClock; } @@ -144,7 +161,7 @@ public: szTray.cx = pSize->cx - 2 * TRAY_NOTIFY_WND_SPACING_X; } - m_pager->GetSize(IsHorizontal, &szTray); + ::SendMessage(m_hwndPager, TNWM_GETMINIMUMSIZE, (WPARAM) IsHorizontal, (LPARAM) &szTray); szTrayNotify = szTray; @@ -195,7 +212,7 @@ public: szClock.cy = szTrayClockMin.cy; } - m_clock->SetWindowPos( + ::SetWindowPos(m_hwndClock, NULL, ptClock.x, ptClock.y, @@ -216,7 +233,7 @@ public: ptPager.y = ContentMargin.cyTopHeight; } - m_pager->SetWindowPos( + ::SetWindowPos(m_hwndPager, NULL, ptPager.x, ptPager.y, @@ -287,16 +304,12 @@ public: LRESULT OnClockMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - if (m_clock != NULL) - return m_clock->SendMessageW(uMsg, wParam, lParam); - return TRUE; + return SendMessageW(m_hwndClock, uMsg, wParam, lParam); } LRESULT OnPagerMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - if (m_pager) - return m_pager->SendMessage(uMsg, wParam, lParam); - return TRUE; + return SendMessageW(m_hwndPager, uMsg, wParam, lParam); } LRESULT OnRealign(INT uCode, LPNMHDR hdr, BOOL& bHandled) @@ -305,6 +318,26 @@ public: return GetParent().SendMessage(WM_NOTIFY, 0, (LPARAM)hdr); } + HRESULT WINAPI GetWindow(HWND* phwnd) + { + if (!phwnd) + return E_INVALIDARG; + *phwnd = m_hWnd; + return S_OK; + } + + HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode) + { + return E_NOTIMPL; + } + + DECLARE_NOT_AGGREGATABLE(CTrayNotifyWnd) + + DECLARE_PROTECT_FINAL_CONSTRUCT() + BEGIN_COM_MAP(CTrayNotifyWnd) + COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) + END_COM_MAP() + DECLARE_WND_CLASS_EX(szTrayNotifyWndClass, CS_DBLCLKS, COLOR_3DFACE) BEGIN_MSG_MAP(CTrayNotifyWnd) @@ -323,18 +356,17 @@ public: MESSAGE_HANDLER(TNWM_GETMINIMUMSIZE, OnGetMinimumSize) END_MSG_MAP() - HWND _Init(IN HWND hwndParent) + HRESULT Initialize(IN HWND hwndParent) { DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - return Create(hwndParent, 0, NULL, dwStyle, WS_EX_STATICEDGE); + Create(hwndParent, 0, NULL, dwStyle, WS_EX_STATICEDGE); + if (!m_hWnd) + return E_FAIL; + return S_OK; } }; -HWND CreateTrayNotifyWnd(IN HWND hwndParent, CTrayNotifyWnd** ppinstance) +HRESULT CTrayNotifyWnd_CreateInstance(HWND hwndParent, REFIID riid, void **ppv) { - CTrayNotifyWnd * pTrayNotify = new CTrayNotifyWnd(); - // TODO: Destroy after the window is destroyed - *ppinstance = pTrayNotify; - - return pTrayNotify->_Init(hwndParent); + return ShellObjectCreatorInit(hwndParent, riid, ppv); } diff --git a/base/shell/explorer/traywnd.cpp b/base/shell/explorer/traywnd.cpp index ac449131b54..e0b5aba452a 100644 --- a/base/shell/explorer/traywnd.cpp +++ b/base/shell/explorer/traywnd.cpp @@ -209,7 +209,7 @@ class CTrayWindow : HWND m_TaskSwitch; HWND m_TrayNotify; - CTrayNotifyWnd* m_TrayNotifyInstance; + CComPtr m_TrayNotifyInstance; DWORD m_Position; HMONITOR m_Monitor; @@ -2048,6 +2048,11 @@ ChangePos: if (FAILED_UNEXPECTEDLY(hRet)) return FALSE; + /* Create the tray notification window */ + hRet = CTrayNotifyWnd_CreateInstance(m_hWnd, IID_PPV_ARG(IUnknown, &m_TrayNotifyInstance)); + if (FAILED_UNEXPECTEDLY(hRet)) + return FALSE; + /* Get the hwnd of the rebar */ hRet = IUnknown_GetWindow(m_TrayBandSite, &m_Rebar); if (FAILED_UNEXPECTEDLY(hRet)) @@ -2058,10 +2063,12 @@ ChangePos: if (FAILED_UNEXPECTEDLY(hRet)) return FALSE; - SetWindowTheme(m_Rebar, L"TaskBar", NULL); + /* Get the hwnd of the tray notification window */ + hRet = IUnknown_GetWindow(m_TrayNotifyInstance, &m_TrayNotify); + if (FAILED_UNEXPECTEDLY(hRet)) + return FALSE; - /* Create the tray notification window */ - m_TrayNotify = CreateTrayNotifyWnd(m_hWnd, &m_TrayNotifyInstance); + SetWindowTheme(m_Rebar, L"TaskBar", NULL); UpdateFonts();