⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menu.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
   }
   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 + -