📄 traywnd.c
字号:
SW_SHOWNORMAL);
}
}
static BOOL STDMETHODCALLTYPE
ITrayWindowImpl_ExecContextMenuCmd(IN OUT ITrayWindow *iface,
IN UINT uiCmd)
{
ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
BOOL bHandled = TRUE;
switch (uiCmd)
{
case ID_SHELL_CMD_PROPERTIES:
ITrayWindow_DisplayProperties(iface);
break;
case ID_SHELL_CMD_OPEN_ALL_USERS:
OpenCommonStartMenuDirectory(This->hWnd,
TEXT("open"));
break;
case ID_SHELL_CMD_EXPLORE_ALL_USERS:
OpenCommonStartMenuDirectory(This->hWnd,
TEXT("explore"));
break;
case ID_LOCKTASKBAR:
if (SHRestricted(REST_CLASSICSHELL) == 0)
{
ITrayWindow_Lock(iface,
!This->Locked);
}
break;
default:
DbgPrint("ITrayWindow::ExecContextMenuCmd(%u): Unhandled Command ID!\n", uiCmd);
bHandled = FALSE;
break;
}
return bHandled;
}
static BOOL STDMETHODCALLTYPE
ITrayWindowImpl_Lock(IN OUT ITrayWindow *iface,
IN BOOL bLock)
{
BOOL bPrevLock;
ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
bPrevLock = This->Locked;
if (This->Locked != bLock)
{
This->Locked = bLock;
if (This->TrayBandSite != NULL)
{
if (!SUCCEEDED(ITrayBandSite_Lock(This->TrayBandSite,
bLock)))
{
/* Reset?? */
This->Locked = bLock;
}
}
}
return bPrevLock;
}
static const ITrayWindowVtbl ITrayWindowImpl_Vtbl =
{
/* IUnknown */
ITrayWindowImpl_QueryInterface,
ITrayWindowImpl_AddRef,
ITrayWindowImpl_Release,
/* ITrayWindow */
ITrayWindowImpl_Open,
ITrayWindowImpl_Close,
ITrayWindowImpl_GetHWND,
ITrayWindowImpl_IsSpecialHWND,
ITrayWindowImpl_IsHorizontal,
ITrayWIndowImpl_GetCaptionFonts,
ITrayWindowImpl_DisplayProperties,
ITrayWindowImpl_ExecContextMenuCmd,
ITrayWindowImpl_Lock
};
static LRESULT CALLBACK
TrayWndProc(IN HWND hwnd,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
ITrayWindowImpl *This = NULL;
LRESULT Ret = FALSE;
if (uMsg != WM_NCCREATE)
{
This = (ITrayWindowImpl*)GetWindowLongPtr(hwnd,
0);
}
if (This != NULL || uMsg == WM_NCCREATE)
{
if (This != NULL && This->StartMenuBand != NULL)
{
MSG Msg;
LRESULT lRet;
Msg.hwnd = hwnd;
Msg.message = uMsg;
Msg.wParam = wParam;
Msg.lParam = lParam;
if (IMenuBand_TranslateMenuMessage(This->StartMenuBand,
&Msg,
&lRet) == S_OK)
{
return lRet;
}
wParam = Msg.wParam;
lParam = Msg.lParam;
}
switch (uMsg)
{
case WM_NCHITTEST:
{
RECT rcClient;
POINT pt;
if (This->Locked)
{
/* The user may not be able to resize the tray window.
Pretend like the window is not sizeable when the user
clicks on the border. */
return HTBORDER;
}
if (GetClientRect(hwnd,
&rcClient) &&
MapWindowPoints(hwnd,
NULL,
(LPPOINT)&rcClient,
2) != 0)
{
pt.x = (SHORT)LOWORD(lParam);
pt.y = (SHORT)HIWORD(lParam);
if (PtInRect(&rcClient,
pt))
{
/* The user is trying to drag the tray window */
return HTCAPTION;
}
/* Depending on the position of the tray window, allow only
changing the border next to the monitor working area */
switch (This->Position)
{
case ABE_TOP:
if (pt.y > rcClient.bottom)
return HTBOTTOM;
break;
case ABE_BOTTOM:
if (pt.y < rcClient.top)
return HTTOP;
break;
case ABE_LEFT:
if (pt.x > rcClient.right)
return HTRIGHT;
break;
case ABE_RIGHT:
if (pt.x < rcClient.left)
return HTLEFT;
break;
default:
break;
}
}
return HTBORDER;
}
case WM_MOVING:
{
POINT ptCursor;
PRECT pRect = (PRECT)lParam;
/* We need to ensure that an application can not accidently
move the tray window (using SetWindowPos). However, we still
need to be able to move the window in case the user wants to
drag the tray window to another position or in case the user
wants to resize the tray window. */
if (!This->Locked && GetCursorPos(&ptCursor))
{
This->IsDragging = TRUE;
This->DraggingPosition = ITrayWindowImpl_GetDraggingRectFromPt(This,
ptCursor,
pRect,
&This->DraggingMonitor);
}
else
{
*pRect = This->rcTrayWnd[This->Position];
}
return TRUE;
}
case WM_SIZING:
{
PRECT pRect = (PRECT)lParam;
if (!This->Locked)
{
ITrayWindowImpl_CalculateValidSize(This,
This->Position,
pRect);
}
else
{
*pRect = This->rcTrayWnd[This->Position];
}
return TRUE;
}
case WM_WINDOWPOSCHANGING:
{
ITrayWindowImpl_ChangingWinPos(This,
(LPWINDOWPOS)lParam);
break;
}
case WM_SIZE:
{
RECT rcClient;
if (wParam == SIZE_RESTORED && lParam == 0)
{
/* Clip the tray window on multi monitor systems so the edges can't
overlap into another monitor */
ITrayWindowImpl_ApplyClipping(This,
TRUE);
if (!GetClientRect(This->hWnd,
&rcClient))
{
break;
}
}
else
{
rcClient.left = rcClient.top = 0;
rcClient.right = LOWORD(lParam);
rcClient.bottom = HIWORD(lParam);
}
ITrayWindowImpl_AlignControls(This,
&rcClient);
break;
}
case WM_ENTERSIZEMOVE:
This->InSizeMove = TRUE;
This->IsDragging = FALSE;
if (!This->Locked)
{
/* Remove the clipping on multi monitor systems while dragging around */
ITrayWindowImpl_ApplyClipping(This,
FALSE);
}
break;
case WM_EXITSIZEMOVE:
This->InSizeMove = FALSE;
if (!This->Locked)
{
/* Apply clipping */
PostMessage(This->hWnd,
WM_SIZE,
SIZE_RESTORED,
0);
}
break;
case WM_SYSCHAR:
switch (wParam)
{
case TEXT(' '):
{
/* The user pressed Alt+Space, this usually brings up the system menu of a window.
The tray window needs to handle this specially, since it normally doesn't have
a system menu. */
static const UINT uidDisableItem[] = {
SC_RESTORE,
SC_MOVE,
SC_SIZE,
SC_MAXIMIZE,
SC_MINIMIZE,
};
HMENU hSysMenu;
INT i;
UINT uId;
/* temporarily enable the system menu */
SetWindowStyle(hwnd,
WS_SYSMENU,
WS_SYSMENU);
hSysMenu = GetSystemMenu(hwnd,
FALSE);
if (hSysMenu != NULL)
{
/* Disable all items that are not relevant */
for (i = 0; i != sizeof(uidDisableItem) / sizeof(uidDisableItem[0]); i++)
{
EnableMenuItem(hSysMenu,
uidDisableItem[i],
MF_BYCOMMAND | MF_GRAYED);
}
EnableMenuItem(hSysMenu,
SC_CLOSE,
MF_BYCOMMAND |
(SHRestricted(REST_NOCLOSE) ? MF_GRAYED : MF_ENABLED));
/* Display the system menu */
uId = ITrayWindowImpl_TrackMenu(This,
hSysMenu,
NULL,
This->hwndStart,
This->Position != ABE_TOP,
FALSE);
if (uId != 0)
{
SendMessage(This->hWnd,
WM_SYSCOMMAND,
(WPARAM)uId,
0);
}
}
/* revert the system menu window style */
SetWindowStyle(hwnd,
WS_SYSMENU,
0);
break;
}
default:
goto DefHandler;
}
break;
case WM_NCRBUTTONUP:
/* We want the user to be able to get a context menu even on the nonclient
area (including the sizing border)! */
uMsg = WM_CONTEXTMENU;
wParam = (WPARAM)hwnd;
/* fall through */
case WM_CONTEXTMENU:
{
POINT pt, *ppt = NULL;
HWND hWndExclude = NULL;
/* Check if the administrator has forbidden access to context menus */
if (SHRestricted(REST_NOTRAYCONTEXTMENU))
break;
pt.x = (SHORT)LOWORD(lParam);
pt.y = (SHORT)HIWORD(lParam);
if (pt.x != -1 || pt.y != -1)
ppt = &pt;
else
hWndExclude = This->hwndStart;
if ((HWND)wParam == This->hwndStart)
{
/* Make sure we can't track the context menu if the start
menu is currently being shown */
if (!(SendMessage(This->hwndStart,
BM_GETSTATE,
0,
0) & BST_PUSHED))
{
ITrayWindowImpl_TrackCtxMenu(This,
&StartMenuBtnCtxMenu,
ppt,
hWndExclude,
This->Position == ABE_BOTTOM,
This);
}
}
else
{
/* See if the context menu should be handled by the task band site */
if (ppt != NULL && This->TrayBandSite != NULL)
{
HWND hWndAtPt;
POINT ptClient = *ppt;
/* Convert the coordinates to client-coordinates */
MapWindowPoints(NULL,
This->hWnd,
&ptClient,
1);
hWndAtPt = ChildWindowFromPoint(This->hWnd,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -