📄 menu.c
字号:
}
return ret;
}
UINT FASTCALL
IntGetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT fByPos, UINT gmdiFlags,
DWORD *gismc)
{
UINT x = 0;
UINT res = -1;
UINT sres;
PMENU_OBJECT SubMenuObject;
PMENU_ITEM MenuItem = MenuObject->MenuItemList;
while(MenuItem)
{
if(MenuItem->fState & MFS_DEFAULT)
{
if(!(gmdiFlags & GMDI_USEDISABLED) && (MenuItem->fState & MFS_DISABLED))
break;
if(fByPos & MF_BYPOSITION)
res = x;
else
res = MenuItem->wID;
if((*gismc < MAX_GOINTOSUBMENU) && (gmdiFlags & GMDI_GOINTOPOPUPS) &&
MenuItem->hSubMenu)
{
SubMenuObject = UserGetMenuObject(MenuItem->hSubMenu);
if(!SubMenuObject || (SubMenuObject == MenuObject))
break;
(*gismc)++;
sres = IntGetMenuDefaultItem(SubMenuObject, fByPos, gmdiFlags, gismc);
(*gismc)--;
if(sres > (UINT)-1)
res = sres;
}
break;
}
MenuItem = MenuItem->Next;
x++;
}
return res;
}
VOID FASTCALL
co_IntInitTracking(PWINDOW_OBJECT Window, PMENU_OBJECT Menu, BOOL Popup,
UINT Flags)
{
/* FIXME - hide caret */
if(!(Flags & TPM_NONOTIFY))
co_IntSendMessage(Window->hSelf, WM_SETCURSOR, (WPARAM)Window->hSelf, HTCAPTION);
/* FIXME - send WM_SETCURSOR message */
if(!(Flags & TPM_NONOTIFY))
co_IntSendMessage(Window->hSelf, WM_INITMENU, (WPARAM)Menu->MenuInfo.Self, 0);
}
VOID FASTCALL
co_IntExitTracking(PWINDOW_OBJECT Window, PMENU_OBJECT Menu, BOOL Popup,
UINT Flags)
{
if(!(Flags & TPM_NONOTIFY))
co_IntSendMessage(Window->hSelf, WM_EXITMENULOOP, 0 /* FIXME */, 0);
/* FIXME - Show caret again */
}
INT FASTCALL
IntTrackMenu(PMENU_OBJECT Menu, PWINDOW_OBJECT Window, INT x, INT y,
RECT lprect)
{
return 0;
}
BOOL FASTCALL
co_IntTrackPopupMenu(PMENU_OBJECT Menu, PWINDOW_OBJECT Window,
UINT Flags, POINT *Pos, UINT MenuPos, RECT *ExcludeRect)
{
co_IntInitTracking(Window, Menu, TRUE, Flags);
co_IntExitTracking(Window, Menu, TRUE, Flags);
return FALSE;
}
BOOL FASTCALL
IntSetMenuItemRect(PMENU_OBJECT Menu, UINT Item, BOOL fByPos, RECT *rcRect)
{
PMENU_ITEM mi;
if(IntGetMenuItemByFlag(Menu, Item, (fByPos ? MF_BYPOSITION : MF_BYCOMMAND),
&mi, NULL) > -1)
{
mi->Rect = *rcRect;
return TRUE;
}
return FALSE;
}
/*!
* Internal function. Called when the process is destroyed to free the remaining menu handles.
*/
BOOL FASTCALL
IntCleanupMenus(struct _EPROCESS *Process, PW32PROCESS Win32Process)
{
PEPROCESS CurrentProcess;
PLIST_ENTRY LastHead = NULL;
PMENU_OBJECT MenuObject;
CurrentProcess = PsGetCurrentProcess();
if (CurrentProcess != Process)
{
KeAttachProcess(&Process->Pcb);
}
while (Win32Process->MenuListHead.Flink != &(Win32Process->MenuListHead) &&
Win32Process->MenuListHead.Flink != LastHead)
{
LastHead = Win32Process->MenuListHead.Flink;
MenuObject = CONTAINING_RECORD(Win32Process->MenuListHead.Flink, MENU_OBJECT, ListEntry);
IntDestroyMenuObject(MenuObject, FALSE, TRUE);
}
if (CurrentProcess != Process)
{
KeDetachProcess();
}
return TRUE;
}
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
DWORD
STDCALL
NtUserBuildMenuItemList(
HMENU hMenu,
VOID* Buffer,
ULONG nBufSize,
DWORD Reserved)
{
DWORD res = -1;
PMENU_OBJECT Menu;
DECLARE_RETURN(DWORD);
DPRINT("Enter NtUserBuildMenuItemList\n");
UserEnterExclusive();
if(!(Menu = UserGetMenuObject(hMenu)))
{
RETURN( (DWORD)-1);
}
if(Buffer)
{
res = IntBuildMenuItemList(Menu, Buffer, nBufSize);
}
else
{
res = Menu->MenuInfo.MenuItemCount;
}
RETURN( res);
CLEANUP:
DPRINT("Leave NtUserBuildMenuItemList, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* @implemented
*/
DWORD STDCALL
NtUserCheckMenuItem(
HMENU hMenu,
UINT uIDCheckItem,
UINT uCheck)
{
PMENU_OBJECT Menu;
DECLARE_RETURN(DWORD);
DPRINT("Enter NtUserCheckMenuItem\n");
UserEnterExclusive();
if(!(Menu = UserGetMenuObject(hMenu)))
{
RETURN( (DWORD)-1);
}
RETURN( IntCheckMenuItem(Menu, uIDCheckItem, uCheck));
CLEANUP:
DPRINT("Leave NtUserCheckMenuItem, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
HMENU FASTCALL UserCreateMenu(BOOL PopupMenu)
{
PWINSTATION_OBJECT WinStaObject;
HANDLE Handle;
NTSTATUS Status;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
if (CsrProcess != CurrentProcess)
{
/*
* CsrProcess does not have a Win32WindowStation
*
*/
Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
KernelMode,
0,
&WinStaObject);
if (!NT_SUCCESS(Status))
{
DPRINT1("Validation of window station handle (0x%X) failed\n",
CurrentProcess->Win32WindowStation);
SetLastNtError(Status);
return (HMENU)0;
}
IntCreateMenu(&Handle, !PopupMenu);
ObDereferenceObject(WinStaObject);
}
else
{
IntCreateMenu(&Handle, !PopupMenu);
}
return (HMENU)Handle;
}
HMENU STDCALL
NtUserCreateMenu(BOOL PopupMenu)
{
DECLARE_RETURN(HMENU);
DPRINT("Enter NtUserCreateMenu\n");
UserEnterExclusive();
RETURN(UserCreateMenu(PopupMenu));
CLEANUP:
DPRINT("Leave NtUserCreateMenu, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* @implemented
*/
BOOL STDCALL
NtUserDeleteMenu(
HMENU hMenu,
UINT uPosition,
UINT uFlags)
{
PMENU_OBJECT Menu;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserDeleteMenu\n");
UserEnterExclusive();
if(!(Menu = UserGetMenuObject(hMenu)))
{
RETURN( FALSE);
}
RETURN( IntRemoveMenuItem(Menu, uPosition, uFlags, TRUE));
CLEANUP:
DPRINT("Leave NtUserDeleteMenu, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* @implemented
*/
BOOL FASTCALL UserDestroyMenu(HMENU hMenu)
{
PMENU_OBJECT Menu;
if(!(Menu = UserGetMenuObject(hMenu)))
{
return FALSE;
}
if(Menu->Process != PsGetCurrentProcess())
{
SetLastWin32Error(ERROR_ACCESS_DENIED);
return FALSE;
}
return IntDestroyMenuObject(Menu, FALSE, TRUE);
}
/*
* @implemented
*/
BOOL STDCALL
NtUserDestroyMenu(
HMENU hMenu)
{
PMENU_OBJECT Menu;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserDestroyMenu\n");
UserEnterExclusive();
if(!(Menu = UserGetMenuObject(hMenu)))
{
RETURN( FALSE);
}
if(Menu->Process != PsGetCurrentProcess())
{
SetLastWin32Error(ERROR_ACCESS_DENIED);
RETURN( FALSE);
}
RETURN( IntDestroyMenuObject(Menu, FALSE, TRUE));
CLEANUP:
DPRINT("Leave NtUserDestroyMenu, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* @implemented
*/
UINT STDCALL
NtUserEnableMenuItem(
HMENU hMenu,
UINT uIDEnableItem,
UINT uEnable)
{
PMENU_OBJECT Menu;
DECLARE_RETURN(UINT);
DPRINT("Enter NtUserEnableMenuItem\n");
UserEnterExclusive();
if(!(Menu = UserGetMenuObject(hMenu)))
{
RETURN(-1);
}
RETURN( IntEnableMenuItem(Menu, uIDEnableItem, uEnable));
CLEANUP:
DPRINT("Leave NtUserEnableMenuItem, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* @implemented
*/
DWORD STDCALL
NtUserInsertMenuItem(
HMENU hMenu,
UINT uItem,
BOOL fByPosition,
LPCMENUITEMINFOW UnsafeItemInfo)
{
PMENU_OBJECT Menu;
NTSTATUS Status;
ROSMENUITEMINFO ItemInfo;
DECLARE_RETURN(DWORD);
DPRINT("Enter NtUserInsertMenuItem\n");
UserEnterExclusive();
if(!(Menu = UserGetMenuObject(hMenu)))
{
RETURN( FALSE);
}
/* Try to copy the whole MENUITEMINFOW structure */
Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, sizeof(MENUITEMINFOW));
if (NT_SUCCESS(Status))
{
if (sizeof(MENUITEMINFOW) != ItemInfo.cbSize
&& FIELD_OFFSET(MENUITEMINFOW, hbmpItem) != ItemInfo.cbSize)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
RETURN( FALSE);
}
RETURN( IntInsertMenuItem(Menu, uItem, fByPosition, &ItemInfo));
}
/* Try to copy without last field (not present in older versions) */
Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, FIELD_OFFSET(MENUITEMINFOW, hbmpItem));
if (NT_SUCCESS(Status))
{
if (FIELD_OFFSET(MENUITEMINFOW, hbmpItem) != ItemInfo.cbSize)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
RETURN( FALSE);
}
ItemInfo.hbmpItem = (HBITMAP)0;
RETURN( IntInsertMenuItem(Menu, uItem, fByPosition, &ItemInfo));
}
SetLastNtError(Status);
RETURN( FALSE);
CLEANUP:
DPRINT("Leave NtUserInsertMenuItem, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* @unimplemented
*/
BOOL STDCALL
NtUserEndMenu(VOID)
{
UNIMPLEMENTED
return 0;
}
/*
* @implemented
*/
UINT STDCALL
NtUserGetMenuDefaultItem(
HMENU hMenu,
UINT fByPos,
UINT gmdiFlags)
{
PMENU_OBJECT Menu;
DWORD gismc = 0;
DECLARE_RETURN(UINT);
DPRINT("Enter NtUserGetMenuDefaultItem\n");
UserEnterExclusive();
if(!(Menu = UserGetMenuObject(hMenu)))
{
RETURN(-1);
}
RETURN( IntGetMenuDefaultItem(Menu, fByPos, gmdiFlags, &gismc));
CLEANUP:
DPRINT("Leave NtUserGetMenuDefaultItem, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* @implemented
*/
BOOL STDCALL
NtUserGetMenuBarInfo(
HWND hwnd,
LONG idObject,
LONG idItem,
PMENUBARINFO pmbi)
{
BOOL Res = TRUE;
PMENU_OBJECT MenuObject;
PMENU_ITEM mi;
PWINDOW_OBJECT WindowObject;
HMENU hMenu;
POINT Offset;
RECT Rect;
MENUBARINFO kmbi;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserGetMenuBarInfo\n");
UserEnterShared();
if (!(WindowObject = UserGetWindowObject(hwnd)))
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
RETURN(FALSE);
}
hMenu = (HMENU)WindowObject->IDMenu;
if (!(MenuObject = UserGetMenuObject(hMenu)))
{
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
RETURN(FALSE);
}
if (pmbi->cbSize != sizeof(MENUBARINFO))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
RETURN(FALSE);
}
kmbi.cbSize = sizeof(MENUBARINFO);
kmbi.fBarFocused = FALSE;
kmbi.fFocused = FALSE;
kmbi.hwndMenu = NULL;
switch (idObject)
{
case OBJID_MENU:
{
PMENU_OBJECT SubMenuObject;
kmbi.hMenu = hMenu;
if (idItem) /* Non-Zero-Based. */
{
if (IntGetMenuItemByFlag(MenuObject, idItem-1, MF_BYPOSITION, &mi, NULL) > -1)
kmbi.rcBar = mi->Rect;
else
{
Res = FALSE;
break;
}
}
else
{
/* If items is zero we assume info for the menu itself. */
if (!(IntGetClientOrigin(WindowObject, &Offset)))
{
Res = FALSE;
break;
}
Rect.left = Offset.x;
Rect.right = Offset.x + MenuObject->MenuInfo.Width;
Rect.top = Offset.y;
Rect.bottom = Offset.y + MenuObject->MenuInfo.Height;
kmbi.rcBar = Rect;
DPRINT("Rect top = %d bottom = %d left = %d right = %d \n",
Rect.top, Rect.bottom, Rect.left, Rect.right);
}
if (idItem)
{
if (idItem-1 == MenuObject->MenuInfo.FocusedItem)
kmbi.fFocused = TRUE;
}
if (MenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
kmbi.fBarFocused = TRUE;
SubMenuObject = UserGetMenuObject(MenuObject->MenuItemList->hSubMenu);
if(SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd;
DPRINT("OBJID_MENU, idItem = %d\n",idItem);
break;
}
case OBJID_CLIENT:
{
PMENU_OBJECT SubMenuObject, XSubMenuObject;
SubMenuObject = UserGetMenuObject(MenuObject->MenuItemList->hSubMenu);
if(SubMenuObject) kmbi.hMenu = SubMenuObject->MenuInfo.Self;
else
{
Res = FALSE;
DPRINT1("OBJID_CLIENT, No SubMenu!\n");
break;
}
if (idItem)
{
if (IntGetMenuItemByFlag(SubMenuObject, idItem-1, MF_BYPOSITION, &mi, NULL) > -1)
kmbi.rcBar = mi->Rect;
else
{
Res = FALSE;
break;
}
}
else
{
PWINDOW_OBJECT SubWinObj;
if (!(SubWinObj = UserGetWindowObject(SubMenuObject->MenuInfo.Wnd)))
{
Res = FALSE;
break;
}
if (!(IntGetClientOrigin(SubWinObj, &Offset)))
{
Res = FALSE;
break;
}
Rect.left = Offset.x;
Rect.right = Offset.x + SubMenuObject->MenuInfo.Width;
Rect.top = Offset.y;
Rect.bottom = Offset.y + SubMenuObject->MenuInfo.Height;
kmbi.rcBar = Rect;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -