* 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<CTrayClockWnd>,
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public CWindowImpl < CTrayClockWnd, CWindow, CControlWinTraits >,
+ public IOleWindow
+{
+ 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
#define ID_TRAYCLOCK_TIMER_INIT 1
-#define TRAY_CLOCK_WND_SPACING_X 0
+#define TRAY_CLOCK_WND_SPACING_X 5
#define TRAY_CLOCK_WND_SPACING_Y 0
CTrayClockWnd::CTrayClockWnd() :
- hWndNotify(NULL),
hFont(NULL),
dwFlags(0),
LineSpacing(0),
/* Increase maximum rectangle */
szMax.cy += LineSizes[i].cy;
- if (LineSizes[i].cx > szMax.cx - (2 * TRAY_CLOCK_WND_SPACING_X))
- szMax.cx = LineSizes[i].cx + (2 * TRAY_CLOCK_WND_SPACING_X);
+ if (LineSizes[i].cx > szMax.cx)
+ szMax.cx = LineSizes[i].cx;
}
}
{
InvalidateRect(NULL, TRUE);
- if (hWndNotify != NULL &&
- (szPrevCurrent.cx != CurrentSize.cx ||
- szPrevCurrent.cy != CurrentSize.cy))
+ if (szPrevCurrent.cx != CurrentSize.cx ||
+ szPrevCurrent.cy != CurrentSize.cy)
{
- NMHDR nmh;
-
- nmh.hwndFrom = m_hWnd;
- nmh.idFrom = GetWindowLongPtr(GWLP_ID);
- nmh.code = NTNWM_REALIGN;
-
- ::SendMessage(hWndNotify,
- WM_NOTIFY,
- (WPARAM) nmh.idFrom,
- (LPARAM) &nmh);
+ /* Ask the parent to resize */
+ NMHDR nmh = {GetParent(), 0, NTNWM_REALIGN};
+ GetParent().SendMessage(WM_NOTIFY, 0, (LPARAM) &nmh);
}
}
}
hPrevFont = (HFONT) SelectObject(hDC, hFont);
- rcClient.left = (rcClient.right / 2) - (CurrentSize.cx / 2);
rcClient.top = (rcClient.bottom / 2) - (CurrentSize.cy / 2);
- rcClient.right = rcClient.left + CurrentSize.cx;
rcClient.bottom = rcClient.top + CurrentSize.cy;
for (i = 0, line = 0;
if (LineSizes[i].cx != 0)
{
TextOut(hDC,
- rcClient.left + (CurrentSize.cx / 2) - (LineSizes[i].cx / 2) +
- TRAY_CLOCK_WND_SPACING_X,
+ (rcClient.right - LineSizes[i].cx) / 2,
rcClient.top + TRAY_CLOCK_WND_SPACING_Y,
szLines[i],
wcslen(szLines[i]));
return (LRESULT) GetMinimumSize((BOOL) wParam, (PSIZE) lParam) != 0;
}
-LRESULT CTrayClockWnd::OnUpdateTime(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
- return (LRESULT) ResetTime();
-}
-
LRESULT CTrayClockWnd::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return HTTRANSPARENT;
return TRUE;
}
-HWND CTrayClockWnd::_Init(IN HWND hWndParent, IN BOOL bVisible)
+LRESULT CTrayClockWnd::OnTaskbarSettingsChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
- IsHorizontal = TRUE;
+ BOOL bRealign = FALSE;
- hWndNotify = hWndParent;
+ TaskbarSettings* newSettings = (TaskbarSettings*)lParam;
+ if (newSettings->bShowSeconds != g_TaskbarSettings.bShowSeconds)
+ {
+ g_TaskbarSettings.bShowSeconds = newSettings->bShowSeconds;
+ bRealign = TRUE;
+ }
+
+ if (newSettings->sr.HideClock != g_TaskbarSettings.sr.HideClock)
+ {
+ g_TaskbarSettings.sr.HideClock = newSettings->sr.HideClock;
+ ShowWindow(g_TaskbarSettings.sr.HideClock ? SW_HIDE : SW_SHOW);
+ bRealign = TRUE;
+ }
+
+ if (bRealign)
+ {
+ /* Ask the parent to resize */
+ NMHDR nmh = {GetParent(), 0, NTNWM_REALIGN};
+ GetParent().SendMessage(WM_NOTIFY, 0, (LPARAM) &nmh);
+ Update();
+ }
+ return 0;
+}
+
+LRESULT CTrayClockWnd::OnNcLButtonDblClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ if (IsWindowVisible())
+ {
+ /* We get all WM_NCLBUTTONDBLCLK for the taskbar so we need to check if it is on the clock*/
+ RECT rcClock;
+ if (GetWindowRect(&rcClock))
+ {
+ POINT ptClick;
+ ptClick.x = MAKEPOINTS(lParam).x;
+ ptClick.y = MAKEPOINTS(lParam).y;
+ if (PtInRect(&rcClock, ptClick))
+ {
+ //FIXME: use SHRunControlPanel
+ ShellExecuteW(m_hWnd, NULL, L"timedate.cpl", NULL, NULL, SW_NORMAL);
+ }
+ }
+ }
+ return TRUE;
+}
+
+HRESULT CTrayClockWnd::Initialize(IN HWND hWndParent)
+{
+ IsHorizontal = TRUE;
/* Create the window. The tray window is going to move it to the correct
position and resize it as needed. */
DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS;
- if (bVisible)
+ if (!g_TaskbarSettings.sr.HideClock)
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<CTrayClockWnd>(hwndParent, riid, ppv);
+}