📄 traywnd.c
字号:
This->hWnd,
ptmp);
return cmdId;
}
static UINT
ITrayWindowImpl_TrackCtxMenu(IN OUT ITrayWindowImpl *This,
IN const TRAYWINDOW_CTXMENU *pMenu,
IN POINT *ppt OPTIONAL,
IN HWND hwndExclude OPTIONAL,
IN BOOL TrackUp,
IN PVOID Context OPTIONAL)
{
HMENU hPopup;
UINT cmdId = 0;
PVOID pcmContext = NULL;
hPopup = pMenu->CreateCtxMenu(This->hWnd,
&pcmContext,
Context);
if (hPopup != NULL)
{
cmdId = ITrayWindowImpl_TrackMenu(This,
hPopup,
ppt,
hwndExclude,
TrackUp,
TRUE);
pMenu->CtxMenuCommand(This->hWnd,
cmdId,
pcmContext,
Context);
}
return cmdId;
}
static VOID
ITrayWindowImpl_Free(ITrayWindowImpl *This)
{
HeapFree(hProcessHeap,
0,
This);
}
static ULONG STDMETHODCALLTYPE
ITrayWindowImpl_Release(IN OUT ITrayWindow *iface)
{
ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
ULONG Ret;
Ret = InterlockedDecrement(&This->Ref);
if (Ret == 0)
ITrayWindowImpl_Free(This);
return Ret;
}
static VOID
ITrayWindowImpl_Destroy(ITrayWindowImpl *This)
{
(void)InterlockedExchangePointer((PVOID*)&This->hWnd,
NULL);
if (This->himlStartBtn != NULL)
{
ImageList_Destroy(This->himlStartBtn);
This->himlStartBtn = NULL;
}
if (This->hCaptionFont != NULL)
{
DeleteObject(This->hCaptionFont);
This->hCaptionFont = NULL;
}
if (This->hStartBtnFont != NULL)
{
DeleteObject(This->hStartBtnFont);
This->hStartBtnFont = NULL;
}
if (This->hFont != NULL)
{
DeleteObject(This->hFont);
This->hFont = NULL;
}
if (This->StartMenuPopup != NULL)
{
IMenuPopup_Release(This->StartMenuPopup);
This->StartMenuPopup = NULL;
}
if (This->hbmStartMenu != NULL)
{
DeleteObject(This->hbmStartMenu);
This->hbmStartMenu = NULL;
}
if (This->StartMenuBand != NULL)
{
IMenuBand_Release(This->StartMenuBand);
This->StartMenuBand = NULL;
}
if (This->TrayBandSite != NULL)
{
/* FIXME: Unload bands */
ITrayBandSite_Release(This->TrayBandSite);
This->TrayBandSite = NULL;
}
ITrayWindowImpl_Release(ITrayWindow_from_impl(This));
if (InterlockedDecrement(&TrayWndCount) == 0)
PostQuitMessage(0);
}
static ULONG STDMETHODCALLTYPE
ITrayWindowImpl_AddRef(IN OUT ITrayWindow *iface)
{
ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
return InterlockedIncrement(&This->Ref);
}
static BOOL
ITrayWindowImpl_NCCreate(IN OUT ITrayWindowImpl *This)
{
ITrayWindowImpl_AddRef(ITrayWindow_from_impl(This));
return TRUE;
}
static VOID
ITrayWindowImpl_UpdateStartButton(IN OUT ITrayWindowImpl *This,
IN HBITMAP hbmStart OPTIONAL)
{
SIZE Size = {0};
if (This->himlStartBtn == NULL ||
!SendMessage(This->hwndStart,
BCM_GETIDEALSIZE,
0,
(LPARAM)&Size))
{
Size.cx = GetSystemMetrics(SM_CXEDGE);
Size.cy = GetSystemMetrics(SM_CYEDGE);
if (hbmStart == NULL)
{
hbmStart = (HBITMAP)SendMessage(This->hwndStart,
BM_GETIMAGE,
IMAGE_BITMAP,
0);
}
if (hbmStart != NULL)
{
BITMAP bmp;
if (GetObject(hbmStart,
sizeof(bmp),
&bmp) != 0)
{
Size.cx += max(bmp.bmWidth,
GetSystemMetrics(SM_CXMINIMIZED));
Size.cy += max(bmp.bmHeight,
GetSystemMetrics(SM_CYCAPTION));
}
else
{
/* Huh?! Shouldn't happen... */
goto DefSize;
}
}
else
{
DefSize:
Size.cx += GetSystemMetrics(SM_CXMINIMIZED);
Size.cy += GetSystemMetrics(SM_CYCAPTION);
}
}
/* Save the size of the start button */
This->StartBtnSize = Size;
}
static VOID
ITrayWindowImpl_AlignControls(IN OUT ITrayWindowImpl *This,
IN PRECT prcClient OPTIONAL)
{
RECT rcClient;
SIZE TraySize, StartSize;
POINT ptTrayNotify = {0};
BOOL Horizontal;
HDWP dwp;
if (prcClient != NULL)
{
rcClient = *prcClient;
}
else
{
if (!GetClientRect(This->hWnd,
&rcClient))
{
return;
}
}
Horizontal = ITrayWindowImpl_IsPosHorizontal(This);
/* We're about to resize/move the start button, the rebar control and
the tray notification control */
dwp = BeginDeferWindowPos(3);
if (dwp == NULL)
return;
/* Limit the Start button width to the client width, if neccessary */
StartSize = This->StartBtnSize;
if (StartSize.cx > rcClient.right)
StartSize.cx = rcClient.right;
if (This->hwndStart != NULL)
{
/* Resize and reposition the button */
dwp = DeferWindowPos(dwp,
This->hwndStart,
NULL,
0,
0,
StartSize.cx,
StartSize.cy,
SWP_NOZORDER | SWP_NOACTIVATE);
if (dwp == NULL)
return;
}
/* Determine the size that the tray notification window needs */
if (Horizontal)
{
TraySize.cx = 0;
TraySize.cy = rcClient.bottom;
}
else
{
TraySize.cx = rcClient.right;
TraySize.cy = 0;
}
if (This->hwndTrayNotify != NULL &&
SendMessage(This->hwndTrayNotify,
TNWM_GETMINIMUMSIZE,
(WPARAM)Horizontal,
(LPARAM)&TraySize))
{
/* Move the tray notification window to the desired location */
if (Horizontal)
ptTrayNotify.x = rcClient.right - TraySize.cx;
else
ptTrayNotify.y = rcClient.bottom - TraySize.cy;
dwp = DeferWindowPos(dwp,
This->hwndTrayNotify,
NULL,
ptTrayNotify.x,
ptTrayNotify.y,
TraySize.cx,
TraySize.cy,
SWP_NOZORDER | SWP_NOACTIVATE);
if (dwp == NULL)
return;
}
/* Resize/Move the rebar control */
if (This->hwndRebar != NULL)
{
POINT ptRebar = {0};
SIZE szRebar;
SetWindowStyle(This->hwndRebar,
CCS_VERT,
Horizontal ? 0 : CCS_VERT);
if (Horizontal)
{
ptRebar.x = StartSize.cx + GetSystemMetrics(SM_CXSIZEFRAME);
szRebar.cx = ptTrayNotify.x - ptRebar.x;
szRebar.cy = rcClient.bottom;
}
else
{
ptRebar.y = StartSize.cy + GetSystemMetrics(SM_CYSIZEFRAME);
szRebar.cx = rcClient.right;
szRebar.cy = ptTrayNotify.y - ptRebar.y;
}
dwp = DeferWindowPos(dwp,
This->hwndRebar,
NULL,
ptRebar.x,
ptRebar.y,
szRebar.cx,
szRebar.cy,
SWP_NOZORDER | SWP_NOACTIVATE);
}
if (dwp != NULL)
EndDeferWindowPos(dwp);
if (This->hwndTaskSwitch != NULL)
{
/* Update the task switch window configuration */
SendMessage(This->hwndTaskSwitch,
TSWM_UPDATETASKBARPOS,
0,
0);
}
}
static BOOL
ITrayWindowImpl_CreateStartBtnImageList(IN OUT ITrayWindowImpl *This)
{
HICON hIconStart;
SIZE IconSize;
if (This->himlStartBtn != NULL)
return TRUE;
IconSize.cx = GetSystemMetrics(SM_CXSMICON);
IconSize.cy = GetSystemMetrics(SM_CYSMICON);
/* Load the start button icon and create a image list for it */
hIconStart = LoadImage(hExplorerInstance,
MAKEINTRESOURCE(IDI_START),
IMAGE_ICON,
IconSize.cx,
IconSize.cy,
LR_SHARED | LR_DEFAULTCOLOR);
if (hIconStart != NULL)
{
This->himlStartBtn = ImageList_Create(IconSize.cx,
IconSize.cy,
ILC_COLOR32 | ILC_MASK,
1,
1);
if (This->himlStartBtn != NULL)
{
if (ImageList_AddIcon(This->himlStartBtn,
hIconStart) >= 0)
{
return TRUE;
}
/* Failed to add the icon! */
ImageList_Destroy(This->himlStartBtn);
This->himlStartBtn = NULL;
}
}
return FALSE;
}
static HBITMAP
ITrayWindowImpl_CreateStartButtonBitmap(IN OUT ITrayWindowImpl *This)
{
TCHAR szStartCaption[32];
HFONT hFontOld;
HDC hDC = NULL;
HDC hDCScreen = NULL;
SIZE Size, SmallIcon;
HBITMAP hbmpOld, hbmp = NULL;
HBITMAP hBitmap = NULL;
HICON hIconStart;
BOOL Ret;
UINT Flags;
RECT rcButton;
/* NOTE: This is the backwards compatibility code that is used if the
Common Controls Version 6.0 are not available! */
if (!LoadString(hExplorerInstance,
IDS_START,
szStartCaption,
sizeof(szStartCaption) / sizeof(szStartCaption[0])))
{
return NULL;
}
/* Load the start button icon */
SmallIcon.cx = GetSystemMetrics(SM_CXSMICON);
SmallIcon.cy = GetSystemMetrics(SM_CYSMICON);
hIconStart = LoadImage(hExplorerInstance,
MAKEINTRESOURCE(IDI_START),
IMAGE_ICON,
SmallIcon.cx,
SmallIcon.cy,
LR_SHARED | LR_DEFAULTCOLOR);
hDCScreen = GetDC(NULL);
if (hDCScreen == NULL)
goto Cleanup;
hDC = CreateCompatibleDC(hDCScreen);
if (hDC == NULL)
goto Cleanup;
hFontOld = SelectObject(hDC,
This->hStartBtnFont);
Ret = GetTextExtentPoint32(hDC,
szStartCaption,
_tcslen(szStartCaption),
&Size);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -