📄 trayntfy.c
字号:
break;
case TCWM_GETMINIMUMSIZE:
{
This->IsHorizontal = (BOOL)wParam;
Ret = (LRESULT)TrayClockWnd_GetMinimumSize(This,
(BOOL)wParam,
(PSIZE)lParam) != 0;
break;
}
case TCWM_UPDATETIME:
{
Ret = (LRESULT)TrayClockWnd_ResetTime(This);
break;
}
case WM_NCCREATE:
{
LPCREATESTRUCT CreateStruct = (LPCREATESTRUCT)lParam;
This = (PTRAY_CLOCK_WND_DATA)CreateStruct->lpCreateParams;
This->hWnd = hwnd;
This->hWndNotify = CreateStruct->hwndParent;
SetWindowLongPtr(hwnd,
0,
(LONG_PTR)This);
return TRUE;
}
case WM_SETFONT:
{
TrayClockWnd_SetFont(This,
(HFONT)wParam,
(BOOL)LOWORD(lParam));
break;
}
case WM_CREATE:
TrayClockWnd_ResetTime(This);
break;
case WM_NCDESTROY:
TrayClockWnd_NCDestroy(This);
break;
case WM_SIZE:
{
SIZE szClient;
szClient.cx = LOWORD(lParam);
szClient.cy = HIWORD(lParam);
This->VisibleLines = TrayClockWnd_GetMinimumSize(This,
This->IsHorizontal,
&szClient);
This->CurrentSize = szClient;
InvalidateRect(This->hWnd,
NULL,
TRUE);
break;
}
default:
Ret = DefWindowProc(hwnd,
uMsg,
wParam,
lParam);
break;
}
}
return Ret;
}
static HWND
CreateTrayClockWnd(IN HWND hWndParent,
IN BOOL bVisible)
{
PTRAY_CLOCK_WND_DATA TcData;
DWORD dwStyle;
HWND hWnd = NULL;
TcData = HeapAlloc(hProcessHeap,
0,
sizeof(*TcData));
if (TcData != NULL)
{
ZeroMemory(TcData,
sizeof(*TcData));
TcData->IsHorizontal = TRUE;
/* 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,
szTrayClockWndClass,
NULL,
dwStyle,
0,
0,
0,
0,
hWndParent,
NULL,
hExplorerInstance,
(LPVOID)TcData);
if (hWnd == NULL)
{
HeapFree(hProcessHeap,
0,
TcData);
}
}
return hWnd;
}
static BOOL
RegisterTrayClockWndClass(VOID)
{
WNDCLASS wcTrayClock;
wcTrayClock.style = CS_DBLCLKS;
wcTrayClock.lpfnWndProc = TrayClockWndProc;
wcTrayClock.cbClsExtra = 0;
wcTrayClock.cbWndExtra = sizeof(PTRAY_CLOCK_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 = szTrayClockWndClass;
return RegisterClass(&wcTrayClock) != 0;
}
static VOID
UnregisterTrayClockWndClass(VOID)
{
UnregisterClass(szTrayClockWndClass,
hExplorerInstance);
}
/*
* TrayNotifyWnd
*/
static const TCHAR szTrayNotifyWndClass[] = TEXT("TrayNotifyWnd");
#define TRAY_NOTIFY_WND_SPACING_X 2
#define TRAY_NOTIFY_WND_SPACING_Y 2
typedef struct _TRAY_NOTIFY_WND_DATA
{
HWND hWnd;
HWND hWndTrayClock;
HWND hWndNotify;
SIZE szTrayClockMin;
SIZE szNonClient;
ITrayWindow *TrayWindow;
union
{
DWORD dwFlags;
struct
{
DWORD HideClock : 1;
DWORD IsHorizontal : 1;
};
};
} TRAY_NOTIFY_WND_DATA, *PTRAY_NOTIFY_WND_DATA;
static VOID
TrayNotifyWnd_UpdateStyle(IN OUT PTRAY_NOTIFY_WND_DATA This)
{
RECT rcClient = {0};
if (AdjustWindowRectEx(&rcClient,
GetWindowLong(This->hWnd,
GWL_STYLE),
FALSE,
GetWindowLong(This->hWnd,
GWL_EXSTYLE)))
{
This->szNonClient.cx = rcClient.right - rcClient.left;
This->szNonClient.cy = rcClient.bottom - rcClient.top;
}
else
This->szNonClient.cx = This->szNonClient.cy = 0;
}
static VOID
TrayNotifyWnd_Create(IN OUT PTRAY_NOTIFY_WND_DATA This)
{
This->hWndTrayClock = CreateTrayClockWnd(This->hWnd,
!This->HideClock);
TrayNotifyWnd_UpdateStyle(This);
}
static VOID
TrayNotifyWnd_NCDestroy(IN OUT PTRAY_NOTIFY_WND_DATA This)
{
SetWindowLongPtr(This->hWnd,
0,
0);
HeapFree(hProcessHeap,
0,
This);
}
static BOOL
TrayNotifyWnd_GetMinimumSize(IN OUT PTRAY_NOTIFY_WND_DATA This,
IN BOOL Horizontal,
IN OUT PSIZE pSize)
{
This->IsHorizontal = Horizontal;
if (!This->HideClock)
{
SIZE szClock = {0};
if (Horizontal)
{
szClock.cy = pSize->cy - This->szNonClient.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);
if (szClock.cx <= 0)
goto NoClock;
}
SendMessage(This->hWndTrayClock,
TCWM_GETMINIMUMSIZE,
(WPARAM)Horizontal,
(LPARAM)&szClock);
This->szTrayClockMin = szClock;
}
else
NoClock:
This->szTrayClockMin = This->szNonClient;
if (Horizontal)
{
pSize->cx = This->szNonClient.cx + (2 * TRAY_NOTIFY_WND_SPACING_X);
if (!This->HideClock)
pSize->cx += TRAY_NOTIFY_WND_SPACING_X + This->szTrayClockMin.cx;
}
else
{
pSize->cy = This->szNonClient.cy + (2 * TRAY_NOTIFY_WND_SPACING_Y);
if (!This->HideClock)
pSize->cy += TRAY_NOTIFY_WND_SPACING_Y + This->szTrayClockMin.cy;
}
return TRUE;
}
static VOID
TrayNotifyWnd_Size(IN OUT PTRAY_NOTIFY_WND_DATA This,
IN const SIZE *pszClient)
{
if (!This->HideClock)
{
POINT ptClock;
SIZE szClock;
if (This->IsHorizontal)
{
ptClock.x = pszClient->cx - TRAY_NOTIFY_WND_SPACING_X - This->szTrayClockMin.cx;
ptClock.y = TRAY_NOTIFY_WND_SPACING_Y;
szClock.cx = This->szTrayClockMin.cx;
szClock.cy = pszClient->cy - (2 * TRAY_NOTIFY_WND_SPACING_Y);
}
else
{
ptClock.x = TRAY_NOTIFY_WND_SPACING_X;
ptClock.y = pszClient->cy - TRAY_NOTIFY_WND_SPACING_Y - This->szTrayClockMin.cy;
szClock.cx = pszClient->cx - (2 * TRAY_NOTIFY_WND_SPACING_X);
szClock.cy = This->szTrayClockMin.cy;
}
SetWindowPos(This->hWndTrayClock,
NULL,
ptClock.x,
ptClock.y,
szClock.cx,
szClock.cy,
SWP_NOZORDER);
}
}
static LRESULT CALLBACK
TrayNotifyWndProc(IN HWND hwnd,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
PTRAY_NOTIFY_WND_DATA This = NULL;
LRESULT Ret = FALSE;
if (uMsg != WM_NCCREATE)
{
This = (PTRAY_NOTIFY_WND_DATA)GetWindowLongPtr(hwnd,
0);
}
if (This != NULL || uMsg == WM_NCCREATE)
{
switch (uMsg)
{
case TNWM_GETMINIMUMSIZE:
{
Ret = (LRESULT)TrayNotifyWnd_GetMinimumSize(This,
(BOOL)wParam,
(PSIZE)lParam);
break;
}
case TNWM_UPDATETIME:
{
if (This->hWndTrayClock != NULL)
{
/* Forward the message to the tray clock window procedure */
Ret = TrayClockWndProc(This->hWndTrayClock,
TCWM_UPDATETIME,
wParam,
lParam);
}
break;
}
case WM_SIZE:
{
SIZE szClient;
szClient.cx = LOWORD(lParam);
szClient.cy = HIWORD(lParam);
TrayNotifyWnd_Size(This,
&szClient);
break;
}
case WM_NCHITTEST:
/* We want the user to be able to drag the task bar when clicking the
tray notification window */
Ret = HTTRANSPARENT;
break;
case TNWM_SHOWCLOCK:
{
BOOL PrevHidden = This->HideClock;
This->HideClock = (wParam == 0);
if (This->hWndTrayClock != NULL && PrevHidden != This->HideClock)
{
ShowWindow(This->hWndTrayClock,
This->HideClock ? SW_HIDE : SW_SHOW);
}
Ret = (LRESULT)(!PrevHidden);
break;
}
case WM_NOTIFY:
{
const NMHDR *nmh = (const NMHDR *)lParam;
if (nmh->hwndFrom == This->hWndTrayClock)
{
/* Pass down notifications */
Ret = SendMessage(This->hWndNotify,
WM_NOTIFY,
wParam,
lParam);
}
break;
}
case WM_SETFONT:
{
if (This->hWndTrayClock != NULL)
{
SendMessage(This->hWndTrayClock,
WM_SETFONT,
wParam,
lParam);
}
goto HandleDefaultMessage;
}
case WM_NCCREATE:
{
LPCREATESTRUCT CreateStruct = (LPCREATESTRUCT)lParam;
This = (PTRAY_NOTIFY_WND_DATA)CreateStruct->lpCreateParams;
This->hWnd = hwnd;
This->hWndNotify = CreateStruct->hwndParent;
SetWindowLongPtr(hwnd,
0,
(LONG_PTR)This);
return TRUE;
}
case WM_CREATE:
TrayNotifyWnd_Create(This);
break;
case WM_NCDESTROY:
TrayNotifyWnd_NCDestroy(This);
break;
default:
HandleDefaultMessage:
Ret = DefWindowProc(hwnd,
uMsg,
wParam,
lParam);
break;
}
}
return Ret;
}
HWND
CreateTrayNotifyWnd(IN OUT ITrayWindow *TrayWindow,
IN BOOL bHideClock)
{
PTRAY_NOTIFY_WND_DATA TnData;
HWND hWndTrayWindow;
HWND hWnd = NULL;
hWndTrayWindow = ITrayWindow_GetHWND(TrayWindow);
if (hWndTrayWindow == NULL)
return NULL;
TnData = HeapAlloc(hProcessHeap,
0,
sizeof(*TnData));
if (TnData != NULL)
{
ZeroMemory(TnData,
sizeof(*TnData));
TnData->TrayWindow = TrayWindow;
TnData->HideClock = bHideClock;
/* Create the window. The tray window is going to move it to the correct
position and resize it as needed. */
hWnd = CreateWindowEx(WS_EX_STATICEDGE,
szTrayNotifyWndClass,
NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0,
0,
0,
0,
hWndTrayWindow,
NULL,
hExplorerInstance,
(LPVOID)TnData);
if (hWnd == NULL)
{
HeapFree(hProcessHeap,
0,
TnData);
}
}
return hWnd;
}
BOOL
RegisterTrayNotifyWndClass(VOID)
{
WNDCLASS wcTrayWnd;
BOOL Ret;
wcTrayWnd.style = CS_DBLCLKS;
wcTrayWnd.lpfnWndProc = TrayNotifyWndProc;
wcTrayWnd.cbClsExtra = 0;
wcTrayWnd.cbWndExtra = sizeof(PTRAY_NOTIFY_WND_DATA);
wcTrayWnd.hInstance = hExplorerInstance;
wcTrayWnd.hIcon = NULL;
wcTrayWnd.hCursor = LoadCursor(NULL,
IDC_ARROW);
wcTrayWnd.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
wcTrayWnd.lpszMenuName = NULL;
wcTrayWnd.lpszClassName = szTrayNotifyWndClass;
Ret = RegisterClass(&wcTrayWnd) != 0;
if (Ret)
{
Ret = RegisterTrayClockWndClass();
if (!Ret)
{
UnregisterClass(szTrayNotifyWndClass,
hExplorerInstance);
}
}
return Ret;
}
VOID
UnregisterTrayNotifyWndClass(VOID)
{
UnregisterTrayClockWndClass();
UnregisterClass(szTrayNotifyWndClass,
hExplorerInstance);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -