📄 traywnd.c
字号:
SelectObject(hDC,
hFontOld);
if (!Ret)
goto Cleanup;
/* Make sure the height is at least the size of a caption icon. */
if (hIconStart != NULL)
Size.cx += SmallIcon.cx + 4;
Size.cy = max(Size.cy,
SmallIcon.cy);
/* Create the bitmap */
hbmp = CreateCompatibleBitmap(hDCScreen,
Size.cx,
Size.cy);
if (hbmp == NULL)
goto Cleanup;
/* Caluclate the button rect */
rcButton.left = 0;
rcButton.top = 0;
rcButton.right = Size.cx;
rcButton.bottom = Size.cy;
/* Draw the button */
hbmpOld = SelectObject(hDC,
hbmp);
Flags = DC_TEXT | DC_INBUTTON;
if (hIconStart != NULL)
Flags |= DC_ICON;
Ret = DrawCaptionTemp(NULL,
hDC,
&rcButton,
This->hStartBtnFont,
hIconStart,
szStartCaption,
Flags);
SelectObject(hDC,
hbmpOld);
if (!Ret)
goto Cleanup;
/* We successfully created the bitmap! */
hBitmap = hbmp;
hbmp = NULL;
Cleanup:
if (hDCScreen != NULL)
{
ReleaseDC(NULL,
hDCScreen);
}
if (hbmp != NULL)
DeleteObject(hbmp);
if (hDC != NULL)
DeleteDC(hDC);
return hBitmap;
}
static VOID
ITrayWindowImpl_Create(IN OUT ITrayWindowImpl *This)
{
TCHAR szStartCaption[32];
InterlockedIncrement(&TrayWndCount);
if (!LoadString(hExplorerInstance,
IDS_START,
szStartCaption,
sizeof(szStartCaption) / sizeof(szStartCaption[0])))
{
szStartCaption[0] = TEXT('\0');
}
if (This->hStartBtnFont == NULL || This->hCaptionFont == NULL)
{
NONCLIENTMETRICS ncm;
/* Get the system fonts, we use the caption font,
always bold, though. */
ncm.cbSize = sizeof(ncm);
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
sizeof(ncm),
&ncm,
FALSE))
{
if (This->hCaptionFont == NULL)
{
ncm.lfCaptionFont.lfWeight = FW_NORMAL;
This->hCaptionFont = CreateFontIndirect(&ncm.lfCaptionFont);
}
if (This->hStartBtnFont == NULL)
{
ncm.lfCaptionFont.lfWeight = FW_BOLD;
This->hStartBtnFont = CreateFontIndirect(&ncm.lfCaptionFont);
}
}
}
/* Create the Start button */
This->hwndStart = CreateWindowEx(0,
WC_BUTTON,
szStartCaption,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
BS_PUSHBUTTON | BS_CENTER | BS_VCENTER | BS_BITMAP,
0,
0,
0,
0,
This->hWnd,
(HMENU)IDC_STARTBTN,
hExplorerInstance,
NULL);
if (This->hwndStart)
{
SendMessage(This->hwndStart,
WM_SETFONT,
(WPARAM)This->hStartBtnFont,
FALSE);
if (ITrayWindowImpl_CreateStartBtnImageList(This))
{
BUTTON_IMAGELIST bil;
/* Try to set the start button image. This requires the Common
Controls 6.0 to be present (XP and later) */
bil.himl = This->himlStartBtn;
bil.margin.left = bil.margin.right = 1;
bil.margin.top = bil.margin.bottom = 1;
bil.uAlign = BUTTON_IMAGELIST_ALIGN_LEFT;
if (!SendMessage(This->hwndStart,
BCM_SETIMAGELIST,
0,
(LPARAM)&bil))
{
/* Fall back to the deprecated method on older systems that don't
support Common Controls 6.0 */
ImageList_Destroy(This->himlStartBtn);
This->himlStartBtn = NULL;
goto SetStartBtnImage;
}
/* We're using the image list, remove the BS_BITMAP style and
don't center it horizontally */
SetWindowStyle(This->hwndStart,
BS_BITMAP | BS_RIGHT,
0);
ITrayWindowImpl_UpdateStartButton(This,
NULL);
}
else
{
HBITMAP hbmStart, hbmOld;
SetStartBtnImage:
hbmStart = ITrayWindowImpl_CreateStartButtonBitmap(This);
if (hbmStart != NULL)
{
ITrayWindowImpl_UpdateStartButton(This,
hbmStart);
hbmOld = (HBITMAP)SendMessage(This->hwndStart,
BM_SETIMAGE,
IMAGE_BITMAP,
(LPARAM)hbmStart);
if (hbmOld != NULL)
DeleteObject(hbmOld);
}
}
}
/* Load the saved tray window settings */
ITrayWindowImpl_RegLoadSettings(This);
/* Create and initialize the start menu */
This->hbmStartMenu = LoadBitmap(hExplorerInstance,
MAKEINTRESOURCE(IDB_STARTMENU));
This->StartMenuPopup = CreateStartMenu(ITrayWindow_from_impl(This),
&This->StartMenuBand,
This->hbmStartMenu,
0);
/* Load the tray band site */
if (This->TrayBandSite != NULL)
{
ITrayBandSite_Release(This->TrayBandSite);
}
This->TrayBandSite = CreateTrayBandSite(ITrayWindow_from_impl(This),
&This->hwndRebar,
&This->hwndTaskSwitch);
/* Create the tray notification window */
This->hwndTrayNotify = CreateTrayNotifyWnd(ITrayWindow_from_impl(This),
This->HideClock);
if (ITrayWindowImpl_UpdateNonClientMetrics(This))
{
ITrayWindowImpl_SetWindowsFont(This);
}
/* Move the tray window to the right position and resize it if neccessary */
ITrayWindowImpl_CheckTrayWndPosition(This);
/* Align all controls on the tray window */
ITrayWindowImpl_AlignControls(This,
NULL);
}
static HRESULT STDMETHODCALLTYPE
ITrayWindowImpl_QueryInterface(IN OUT ITrayWindow *iface,
IN REFIID riid,
OUT LPVOID *ppvObj)
{
ITrayWindowImpl *This;
if (ppvObj == NULL)
return E_POINTER;
This = impl_from_ITrayWindow(iface);
if (IsEqualIID(riid,
&IID_IUnknown))
{
*ppvObj = IUnknown_from_impl(This);
}
else if (IsEqualIID(riid,
&IID_IShellDesktopTray))
{
*ppvObj = IShellDesktopTray_from_impl(This);
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
ITrayWindowImpl_AddRef(iface);
return S_OK;
}
static ITrayWindowImpl *
ITrayWindowImpl_Construct(VOID)
{
ITrayWindowImpl *This;
This = HeapAlloc(hProcessHeap,
0,
sizeof(*This));
if (This == NULL)
return NULL;
ZeroMemory(This,
sizeof(*This));
This->lpVtbl = &ITrayWindowImpl_Vtbl;
This->lpVtblShellDesktopTray = &IShellDesktopTrayImpl_Vtbl;
This->Ref = 1;
This->Position = (DWORD)-1;
return This;
}
static HRESULT STDMETHODCALLTYPE
ITrayWindowImpl_Open(IN OUT ITrayWindow *iface)
{
ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
HRESULT Ret = S_OK;
HWND hWnd;
DWORD dwExStyle;
/* Check if there's already a window created and try to show it.
If it was somehow destroyed just create a new tray window. */
if (This->hWnd != NULL)
{
if (IsWindow(This->hWnd))
{
if (!IsWindowVisible(This->hWnd))
{
ITrayWindowImpl_CheckTrayWndPosition(This);
ShowWindow(This->hWnd,
SW_SHOW);
}
}
else
goto TryCreateTrayWnd;
}
else
{
RECT rcWnd;
TryCreateTrayWnd:
dwExStyle = WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE;
if (This->AlwaysOnTop)
dwExStyle |= WS_EX_TOPMOST;
if (This->Position != (DWORD)-1)
rcWnd = This->rcTrayWnd[This->Position];
else
{
ZeroMemory(&rcWnd,
sizeof(rcWnd));
}
hWnd = CreateWindowEx(dwExStyle,
szTrayWndClass,
NULL,
WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
WS_BORDER | WS_THICKFRAME,
rcWnd.left,
rcWnd.top,
rcWnd.right - rcWnd.left,
rcWnd.bottom - rcWnd.top,
NULL,
NULL,
hExplorerInstance,
This);
if (hWnd == NULL)
Ret = E_FAIL;
}
return Ret;
}
static HRESULT STDMETHODCALLTYPE
ITrayWindowImpl_Close(IN OUT ITrayWindow *iface)
{
ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
if (This->hWnd != NULL)
{
SendMessage(This->hWnd,
WM_APP_TRAYDESTROY,
0,
0);
}
return S_OK;
}
static HWND STDMETHODCALLTYPE
ITrayWindowImpl_GetHWND(IN OUT ITrayWindow *iface)
{
ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
return This->hWnd;
}
static BOOL STDMETHODCALLTYPE
ITrayWindowImpl_IsSpecialHWND(IN OUT ITrayWindow *iface,
IN HWND hWnd)
{
ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
return (hWnd == This->hWnd ||
(This->hWndDesktop != NULL && hWnd == This->hWndDesktop));
}
static BOOL STDMETHODCALLTYPE
ITrayWindowImpl_IsHorizontal(IN OUT ITrayWindow *iface)
{
ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
return ITrayWindowImpl_IsPosHorizontal(This);
}
static HFONT STDMETHODCALLTYPE
ITrayWIndowImpl_GetCaptionFonts(IN OUT ITrayWindow *iface,
OUT HFONT *phBoldCaption OPTIONAL)
{
ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
if (phBoldCaption != NULL)
*phBoldCaption = This->hStartBtnFont;
return This->hCaptionFont;
}
static HWND STDMETHODCALLTYPE
ITrayWindowImpl_DisplayProperties(IN OUT ITrayWindow *iface)
{
ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
if (This->hWndTrayProperties != NULL)
{
BringWindowToTop(This->hWndTrayProperties);
return This->hWndTrayProperties;
}
This->hWndTrayProperties = DisplayTrayProperties(ITrayWindow_from_impl(This));
return This->hWndTrayProperties;
}
static VOID
OpenCommonStartMenuDirectory(IN HWND hWndOwner,
IN LPCTSTR lpOperation)
{
TCHAR szDir[MAX_PATH];
if (SHGetSpecialFolderPath(hWndOwner,
szDir,
CSIDL_COMMON_STARTMENU,
FALSE))
{
ShellExecute(hWndOwner,
lpOperation,
NULL,
NULL,
szDir,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -