[EXPLORER] Split up the notification area into a few more manageable pieces.

This commit is contained in:
David Quintana 2018-01-24 14:41:06 +01:00
parent 4a910a12cc
commit 3d75cc0814
7 changed files with 2115 additions and 1947 deletions

View file

@ -16,9 +16,11 @@ list(APPEND SOURCE
startmnucust.cpp
startmnusite.cpp
startup.cpp
syspager.cpp
taskband.cpp
taskswnd.cpp
tbsite.cpp
trayclock.cpp
trayntfy.cpp
trayprop.cpp
traywnd.cpp

View file

@ -384,4 +384,16 @@ 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_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,203 @@
#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(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<IconWatcherData *> 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_ NOTIFYICONDATA *iconData);
bool RemoveIconFromWatcher(_In_ NOTIFYICONDATA *iconData);
IconWatcherData* GetListEntry(_In_opt_ 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<WPARAM>(source->hIcon);
uTimeout = source->uTimeout;
}
};
HWND m_hwndParent;
CTooltips * m_tooltips;
CAtlList<Info> m_queue;
CToolbar<InternalIconData> * m_toolbar;
InternalIconData * m_current;
bool m_currentClosed;
int m_timer;
public:
CBalloonQueue();
void Init(HWND hwndParent, CToolbar<InternalIconData> * 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<InternalIconData>, 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<CComMultiThreadModelNoCS>,
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);
public:
BOOL NotifyIconCmd(WPARAM wParam, LPARAM lParam);
void GetSize(IN BOOL IsHorizontal, IN PSIZE size);
void ResizeImagelist();
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)
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, IN BOOL bVisible);
};

View file

@ -0,0 +1,576 @@
/*
* ReactOS Explorer
*
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
* Copyright 2018 Ged Murphy <gedmurphy@reactos.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "precomp.h"
/*
* TrayClockWnd
*/
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_Y 0
CTrayClockWnd::CTrayClockWnd() :
hWndNotify(NULL),
hFont(NULL),
dwFlags(0),
LineSpacing(0),
VisibleLines(0)
{
ZeroMemory(&textColor, sizeof(textColor));
ZeroMemory(&rcText, sizeof(rcText));
ZeroMemory(&LocalTime, sizeof(LocalTime));
ZeroMemory(&CurrentSize, sizeof(CurrentSize));
ZeroMemory(LineSizes, sizeof(LineSizes));
ZeroMemory(szLines, sizeof(szLines));
}
CTrayClockWnd::~CTrayClockWnd() { }
LRESULT CTrayClockWnd::OnThemeChanged()
{
LOGFONTW clockFont;
HTHEME clockTheme;
HFONT hFont;
clockTheme = OpenThemeData(m_hWnd, L"Clock");
if (clockTheme)
{
GetThemeFont(clockTheme,
NULL,
CLP_TIME,
0,
TMT_FONT,
&clockFont);
hFont = CreateFontIndirectW(&clockFont);
GetThemeColor(clockTheme,
CLP_TIME,
0,
TMT_TEXTCOLOR,
&textColor);
if (this->hFont != NULL)
DeleteObject(this->hFont);
SetFont(hFont, FALSE);
}
else
{
/* We don't need to set a font here, our parent will use
* WM_SETFONT to set the right one when themes are not enabled. */
textColor = RGB(0, 0, 0);
}
CloseThemeData(clockTheme);
return TRUE;
}
LRESULT CTrayClockWnd::OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return OnThemeChanged();
}
BOOL CTrayClockWnd::MeasureLines()
{
HDC hDC;
HFONT hPrevFont;
UINT c, i;
BOOL bRet = TRUE;
hDC = GetDC();
if (hDC != NULL)
{
if (hFont)
hPrevFont = (HFONT) SelectObject(hDC, hFont);
for (i = 0; i < CLOCKWND_FORMAT_COUNT && bRet; i++)
{
if (szLines[i][0] != L'\0' &&
!GetTextExtentPointW(hDC, szLines[i], wcslen(szLines[i]),
&LineSizes[i]))
{
bRet = FALSE;
break;
}
}
if (hFont)
SelectObject(hDC, hPrevFont);
ReleaseDC(hDC);
if (bRet)
{
LineSpacing = 0;
/* calculate the line spacing */
for (i = 0, c = 0; i < CLOCKWND_FORMAT_COUNT; i++)
{
if (LineSizes[i].cx > 0)
{
LineSpacing += LineSizes[i].cy;
c++;
}
}
if (c > 0)
{
/* We want a spacing of 1/2 line */
LineSpacing = (LineSpacing / c) / 2;
}
return TRUE;
}
}
return FALSE;
}
WORD CTrayClockWnd::GetMinimumSize(IN BOOL Horizontal, IN OUT PSIZE pSize)
{
WORD iLinesVisible = 0;
UINT i;
SIZE szMax = { 0, 0 };
if (!LinesMeasured)
LinesMeasured = MeasureLines();
if (!LinesMeasured)
return 0;
for (i = 0; i < CLOCKWND_FORMAT_COUNT; i++)
{
if (LineSizes[i].cx != 0)
{
if (iLinesVisible > 0)
{
if (Horizontal)
{
if (szMax.cy + LineSizes[i].cy + (LONG) LineSpacing >
pSize->cy - (2 * TRAY_CLOCK_WND_SPACING_Y))
{
break;
}
}
else
{
if (LineSizes[i].cx > pSize->cx - (2 * TRAY_CLOCK_WND_SPACING_X))
break;
}
/* Add line spacing */
szMax.cy += LineSpacing;
}
iLinesVisible++;
/* 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);
}
}
szMax.cx += 2 * TRAY_CLOCK_WND_SPACING_X;
szMax.cy += 2 * TRAY_CLOCK_WND_SPACING_Y;
*pSize = szMax;
return iLinesVisible;
}
VOID CTrayClockWnd::UpdateWnd()
{
SIZE szPrevCurrent;
UINT BufSize, i;
INT iRet;
RECT rcClient;
ZeroMemory(LineSizes, sizeof(LineSizes));
szPrevCurrent = CurrentSize;
for (i = 0; i < CLOCKWND_FORMAT_COUNT; i++)
{
szLines[i][0] = L'\0';
BufSize = _countof(szLines[0]);
if (ClockWndFormats[i].IsTime)
{
iRet = GetTimeFormat(LOCALE_USER_DEFAULT,
g_TaskbarSettings.bShowSeconds ? ClockWndFormats[i].dwFormatFlags : TIME_NOSECONDS,
&LocalTime,
ClockWndFormats[i].lpFormat,
szLines[i],
BufSize);
}
else
{
iRet = GetDateFormat(LOCALE_USER_DEFAULT,
ClockWndFormats[i].dwFormatFlags,
&LocalTime,
ClockWndFormats[i].lpFormat,
szLines[i],
BufSize);
}
if (iRet != 0 && i == 0)
{
/* Set the window text to the time only */
SetWindowText(szLines[i]);
}
}
LinesMeasured = MeasureLines();
if (LinesMeasured &&
GetClientRect(&rcClient))
{
SIZE szWnd;
szWnd.cx = rcClient.right;
szWnd.cy = rcClient.bottom;
VisibleLines = GetMinimumSize(IsHorizontal, &szWnd);
CurrentSize = szWnd;
}
if (IsWindowVisible())
{
InvalidateRect(NULL, TRUE);
if (hWndNotify != NULL &&
(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);
}
}
}
VOID CTrayClockWnd::Update()
{
GetLocalTime(&LocalTime);
UpdateWnd();
}
UINT CTrayClockWnd::CalculateDueTime()
{
UINT uiDueTime;
/* Calculate the due time */
GetLocalTime(&LocalTime);
uiDueTime = 1000 - (UINT) LocalTime.wMilliseconds;
if (g_TaskbarSettings.bShowSeconds)
uiDueTime += (UINT) LocalTime.wSecond * 100;
else
uiDueTime += (59 - (UINT) LocalTime.wSecond) * 1000;
if (uiDueTime < USER_TIMER_MINIMUM || uiDueTime > USER_TIMER_MAXIMUM)
uiDueTime = 1000;
else
{
/* Add an artificial delay of 0.05 seconds to make sure the timer
doesn't fire too early*/
uiDueTime += 50;
}
return uiDueTime;
}
BOOL CTrayClockWnd::ResetTime()
{
UINT uiDueTime;
BOOL Ret;
/* Disable all timers */
if (IsTimerEnabled)
{
KillTimer(ID_TRAYCLOCK_TIMER);
IsTimerEnabled = FALSE;
}
if (IsInitTimerEnabled)
{
KillTimer(ID_TRAYCLOCK_TIMER_INIT);
}
uiDueTime = CalculateDueTime();
/* Set the new timer */
Ret = SetTimer(ID_TRAYCLOCK_TIMER_INIT, uiDueTime, NULL) != 0;
IsInitTimerEnabled = Ret;
/* Update the time */
Update();
return Ret;
}
VOID CTrayClockWnd::CalibrateTimer()
{
UINT uiDueTime;
BOOL Ret;
UINT uiWait1, uiWait2;
/* Kill the initialization timer */
KillTimer(ID_TRAYCLOCK_TIMER_INIT);
IsInitTimerEnabled = FALSE;
uiDueTime = CalculateDueTime();
if (g_TaskbarSettings.bShowSeconds)
{
uiWait1 = 1000 - 200;
uiWait2 = 1000;
}
else
{
uiWait1 = 60 * 1000 - 200;
uiWait2 = 60 * 1000;
}
if (uiDueTime > uiWait1)
{
/* The update of the clock will be up to 200 ms late, but that's
acceptable. We're going to setup a timer that fires depending
uiWait2. */
Ret = SetTimer(ID_TRAYCLOCK_TIMER, uiWait2, NULL) != 0;
IsTimerEnabled = Ret;
/* Update the time */
Update();
}
else
{
/* Recalibrate the timer and recalculate again when the current
minute/second ends. */
ResetTime();
}
}
LRESULT CTrayClockWnd::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
/* Disable all timers */
if (IsTimerEnabled)
{
KillTimer(ID_TRAYCLOCK_TIMER);
}
if (IsInitTimerEnabled)
{
KillTimer(ID_TRAYCLOCK_TIMER_INIT);
}
return TRUE;
}
LRESULT CTrayClockWnd::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
RECT rcClient;
HFONT hPrevFont;
INT iPrevBkMode;
UINT i, line;
PAINTSTRUCT ps;
HDC hDC = (HDC) wParam;
if (wParam == 0)
{
hDC = BeginPaint(&ps);
}
if (hDC == NULL)
return FALSE;
if (LinesMeasured &&
GetClientRect(&rcClient))
{
iPrevBkMode = SetBkMode(hDC, TRANSPARENT);
SetTextColor(hDC, textColor);
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;
i < CLOCKWND_FORMAT_COUNT && line < VisibleLines;
i++)
{
if (LineSizes[i].cx != 0)
{
TextOut(hDC,
rcClient.left + (CurrentSize.cx / 2) - (LineSizes[i].cx / 2) +
TRAY_CLOCK_WND_SPACING_X,
rcClient.top + TRAY_CLOCK_WND_SPACING_Y,
szLines[i],
wcslen(szLines[i]));
rcClient.top += LineSizes[i].cy + LineSpacing;
line++;
}
}
SelectObject(hDC, hPrevFont);
SetBkMode(hDC, iPrevBkMode);
}
if (wParam == 0)
{
EndPaint(&ps);
}
return TRUE;
}
VOID CTrayClockWnd::SetFont(IN HFONT hNewFont, IN BOOL bRedraw)
{
hFont = hNewFont;
LinesMeasured = MeasureLines();
if (bRedraw)
{
InvalidateRect(NULL, TRUE);
}
}
LRESULT CTrayClockWnd::DrawBackground(HDC hdc)
{
RECT rect;
GetClientRect(&rect);
DrawThemeParentBackground(m_hWnd, hdc, &rect);
return TRUE;
}
LRESULT CTrayClockWnd::OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
HDC hdc = (HDC) wParam;
if (!IsAppThemed())
{
bHandled = FALSE;
return 0;
}
return DrawBackground(hdc);
}
LRESULT CTrayClockWnd::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
switch (wParam)
{
case ID_TRAYCLOCK_TIMER:
Update();
break;
case ID_TRAYCLOCK_TIMER_INIT:
CalibrateTimer();
break;
}
return TRUE;
}
LRESULT CTrayClockWnd::OnGetMinimumSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
IsHorizontal = (BOOL) wParam;
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;
}
LRESULT CTrayClockWnd::OnSetFont(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
SetFont((HFONT) wParam, (BOOL) LOWORD(lParam));
return TRUE;
}
LRESULT CTrayClockWnd::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ResetTime();
return TRUE;
}
LRESULT CTrayClockWnd::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
SIZE szClient;
szClient.cx = LOWORD(lParam);
szClient.cy = HIWORD(lParam);
VisibleLines = GetMinimumSize(IsHorizontal, &szClient);
CurrentSize = szClient;
InvalidateRect(NULL, TRUE);
return TRUE;
}
HWND CTrayClockWnd::_Init(IN HWND hWndParent, IN BOOL bVisible)
{
IsHorizontal = TRUE;
hWndNotify = hWndParent;
/* 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)
dwStyle |= WS_VISIBLE;
Create(hWndParent, 0, NULL, dwStyle);
if (m_hWnd != NULL)
SetWindowTheme(m_hWnd, L"TrayNotify", NULL);
return m_hWnd;
};

View file

@ -0,0 +1,94 @@
#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<CComMultiThreadModelNoCS>,
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);
public:
LRESULT OnUpdateTime(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(TCWM_UPDATETIME, OnUpdateTime)
END_MSG_MAP()
HWND _Init(IN HWND hWndParent, IN BOOL bVisible);
};

File diff suppressed because it is too large Load diff