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

📄 menu.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
    {
      ROSMENUINFO MenuInfo;

      SendMessageW(Wnd, WM_INITMENU, (WPARAM)Menu, 0);

      MenuGetRosMenuInfo(&MenuInfo, Menu);
      
      if (0 == MenuInfo.Height)
        {
          /* app changed/recreated menu bar entries in WM_INITMENU
             Recalculate menu sizes else clicks will not work */
          SetWindowPos(Wnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
                       SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );

        }
    /* This makes the menus of applications built with Delphi work.
     * It also enables menus to be displayed in more than one window,
     * but there are some bugs left that need to be fixed in this case.
     */
      if(MenuInfo.Self == Menu)
      {
         MenuInfo.Wnd = Wnd;
         MenuSetRosMenuInfo(&MenuInfo);
      }
    }

  return TRUE;
}


/***********************************************************************
 *           MenuShowPopup
 *
 * Display a popup menu.
 */
static BOOL FASTCALL
MenuShowPopup(HWND WndOwner, HMENU Menu, UINT Id,
              INT X, INT Y, INT XAnchor, INT YAnchor )
{
  ROSMENUINFO MenuInfo;
  ROSMENUITEMINFO ItemInfo;
  UINT Width, Height;

  DPRINT("owner=%x hmenu=%x id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
         WndOwner, Menu, Id, X, Y, XAnchor, YAnchor);

  if (! MenuGetRosMenuInfo(&MenuInfo, Menu))
    {
      return FALSE;
    }

  if (NO_SELECTED_ITEM != MenuInfo.FocusedItem)
    {
      MenuInitRosMenuItemInfo(&ItemInfo);
      if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo))
        {
          ItemInfo.fMask |= MIIM_STATE;
          ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT);
          MenuSetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo);
        }
      MenuCleanupRosMenuItemInfo(&ItemInfo);
      MenuInfo.FocusedItem = NO_SELECTED_ITEM;
    }

  /* store the owner for DrawItem */
  MenuInfo.WndOwner = WndOwner;
  MenuSetRosMenuInfo(&MenuInfo);

  MenuPopupMenuCalcSize(&MenuInfo, WndOwner);

  /* adjust popup menu pos so that it fits within the desktop */

  Width = MenuInfo.Width + GetSystemMetrics(SM_CXBORDER);
  Height = MenuInfo.Height + GetSystemMetrics(SM_CYBORDER);

  if (GetSystemMetrics(SM_CXSCREEN ) < X + Width)
    {
      if (0 != XAnchor && X >= Width - XAnchor)
        {
          X -= Width - XAnchor;
        }
      if (GetSystemMetrics(SM_CXSCREEN) < X + Width)
        {
          X = GetSystemMetrics(SM_CXSCREEN) - Width;
        }
    }
  if (X < 0 )
    {
      X = 0;
    }

  if (GetSystemMetrics(SM_CYSCREEN) < Y + Height)
    {
      if (0 != YAnchor && Y >= Height + YAnchor)
        {
          Y -= Height + YAnchor;
        }
      if (GetSystemMetrics(SM_CYSCREEN) < Y + Height)
        {
          Y = GetSystemMetrics(SM_CYSCREEN) - Height;
        }
    }
  if (Y < 0 )
    {
      Y = 0;
    }


  /* NOTE: In Windows, top menu popup is not owned. */
  MenuInfo.Wnd = CreateWindowExW(0, POPUPMENU_CLASS_ATOMW, NULL,
                                 WS_POPUP, X, Y, Width, Height,
                                 WndOwner, 0, (HINSTANCE) GetWindowLongPtrW(WndOwner, GWLP_HINSTANCE),
                                 (LPVOID) MenuInfo.Self);
  if (NULL == MenuInfo.Wnd || ! MenuSetRosMenuInfo(&MenuInfo))
    {
      return FALSE;
    }
  if (NULL == TopPopup)
    {
      TopPopup = MenuInfo.Wnd;
    }

  /* Display the window */
  SetWindowPos(MenuInfo.Wnd, HWND_TOPMOST, 0, 0, 0, 0,
               SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  UpdateWindow(MenuInfo.Wnd);

  return TRUE;
}

/***********************************************************************
 *           MenuFindSubMenu
 *
 * Find a Sub menu. Return the position of the submenu, and modifies
 * *hmenu in case it is found in another sub-menu.
 * If the submenu cannot be found, NO_SELECTED_ITEM is returned.
 */
static UINT FASTCALL
MenuFindSubMenu(HMENU *Menu, HMENU SubTarget)
{
  ROSMENUINFO MenuInfo;
  ROSMENUITEMINFO ItemInfo;
  UINT i;
  HMENU SubMenu;
  UINT Pos;

  if ((HMENU) 0xffff == *Menu
      || ! MenuGetRosMenuInfo(&MenuInfo, *Menu))
    {
      return NO_SELECTED_ITEM;
    }

  MenuInitRosMenuItemInfo(&ItemInfo);
  for (i = 0; i < MenuInfo.MenuItemCount; i++)
    {
      if (! MenuGetRosMenuItemInfo(MenuInfo.Self, i, &ItemInfo))
        {
          MenuCleanupRosMenuItemInfo(&ItemInfo);
          return NO_SELECTED_ITEM;
        }
      if (0 == (ItemInfo.fType & MF_POPUP))
        {
          continue;
        }
      if (ItemInfo.hSubMenu == SubTarget)
        {
          MenuCleanupRosMenuItemInfo(&ItemInfo);
          return i;
        }
      SubMenu = ItemInfo.hSubMenu;
      Pos = MenuFindSubMenu(&SubMenu, SubTarget);
      if (NO_SELECTED_ITEM != Pos)
        {
          *Menu = SubMenu;
          return Pos;
        }
    }
  MenuCleanupRosMenuItemInfo(&ItemInfo);

  return NO_SELECTED_ITEM;
}

/***********************************************************************
 *           MenuSelectItem
 */
static void FASTCALL
MenuSelectItem(HWND WndOwner, PROSMENUINFO MenuInfo, UINT Index,
               BOOL SendMenuSelect, HMENU TopMenu)
{
  HDC Dc;
  ROSMENUITEMINFO ItemInfo;
  ROSMENUINFO TopMenuInfo;
  int Pos;

  DPRINT("owner=%x menu=%p index=0x%04x select=0x%04x\n", WndOwner, MenuInfo, Index, SendMenuSelect);

  if (NULL == MenuInfo || 0 == MenuInfo->MenuItemCount || NULL == MenuInfo->Wnd)
    {
      return;
    }

  if (MenuInfo->FocusedItem == Index)
    {
      return;
    }

  if (0 != (MenuInfo->Flags & MF_POPUP))
    {
      Dc = GetDC(MenuInfo->Wnd);
    }
  else
    {
      Dc = GetDCEx(MenuInfo->Wnd, 0, DCX_CACHE | DCX_WINDOW);
    }

  if (NULL == TopPopup)
    {
      TopPopup = MenuInfo->Wnd;
    }

  SelectObject(Dc, hMenuFont);
  MenuInitRosMenuItemInfo(&ItemInfo);
  /* Clear previous highlighted item */
  if (NO_SELECTED_ITEM != MenuInfo->FocusedItem)
    {
      if (MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo))
        {
          ItemInfo.fMask |= MIIM_STATE;
          ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT);
          MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
        }
      MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc, &ItemInfo,
                       MenuInfo->Height, ! (MenuInfo->Flags & MF_POPUP),
                       ODA_SELECT);
    }

  /* Highlight new item (if any) */
  MenuInfo->FocusedItem = Index;
  MenuSetRosMenuInfo(MenuInfo);
  if (NO_SELECTED_ITEM != MenuInfo->FocusedItem)
    {
      if (MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo))
        {
          if (0 == (ItemInfo.fType & MF_SEPARATOR))
            {
              ItemInfo.fMask |= MIIM_STATE;
              ItemInfo.fState |= MF_HILITE;
              MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
              MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc,
                               &ItemInfo, MenuInfo->Height, ! (MenuInfo->Flags & MF_POPUP),
                               ODA_SELECT);
            }
          if (SendMenuSelect)
            {
              SendMessageW(WndOwner, WM_MENUSELECT,
                           MAKELONG(ItemInfo.fType & MF_POPUP ? Index : ItemInfo.wID,
                                    ItemInfo.fType | ItemInfo.fState | MF_MOUSESELECT |
                                    (MenuInfo->Flags & MF_SYSMENU)), (LPARAM) MenuInfo->Self);
            }
        }
    }
  else if (SendMenuSelect)
    {
      if (NULL != TopMenu)
        {
          Pos = MenuFindSubMenu(&TopMenu, MenuInfo->Self);
          if (NO_SELECTED_ITEM != Pos)
            {
              if (MenuGetRosMenuInfo(&TopMenuInfo, TopMenu)
                  && MenuGetRosMenuItemInfo(TopMenu, Pos, &ItemInfo))
                {
                  SendMessageW(WndOwner, WM_MENUSELECT,
                               MAKELONG(Pos, ItemInfo.fType | ItemInfo.fState
                                             | MF_MOUSESELECT
                                             | (TopMenuInfo.Flags & MF_SYSMENU)),
                               (LPARAM) TopMenu);
                }
            }
        }
    }
  MenuCleanupRosMenuItemInfo(&ItemInfo);
  ReleaseDC(MenuInfo->Wnd, Dc);
}

/***********************************************************************
 *           MenuMoveSelection
 *
 * Moves currently selected item according to the Offset parameter.
 * If there is no selection then it should select the last item if
 * Offset is ITEM_PREV or the first item if Offset is ITEM_NEXT.
 */
static void FASTCALL
MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset)
{
  INT i;
  ROSMENUITEMINFO ItemInfo;
  INT OrigPos;

  DPRINT("hwnd=%x menu=%x off=0x%04x\n", WndOwner, MenuInfo, Offset);

  /* Prevent looping */
  if (0 == MenuInfo->MenuItemCount || 0 == Offset)
    return;
  else if (Offset < -1)
    Offset = -1;
  else if (Offset > 1)
    Offset = 1;

  MenuInitRosMenuItemInfo(&ItemInfo);

  OrigPos = MenuInfo->FocusedItem;
  if (OrigPos == NO_SELECTED_ITEM) /* NO_SELECTED_ITEM is not -1 ! */
    {
       OrigPos = 0;
       i = -1;
    }
  else
    {
      i = MenuInfo->FocusedItem;
    }

  do
    {
      /* Step */
      i += Offset;
      /* Clip and wrap around */
      if (i < 0)
        {
          i = MenuInfo->MenuItemCount - 1;
        }
      else if (i >= MenuInfo->MenuItemCount)
        {
          i = 0;
        }
      /* If this is a good candidate; */
      if (MenuGetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo) &&
          0 == (ItemInfo.fType & MF_SEPARATOR) &&
          0 == (ItemInfo.fState & (MFS_DISABLED | MFS_GRAYED)) )
        {
          MenuSelectItem(WndOwner, MenuInfo, i, TRUE, NULL);
          MenuCleanupRosMenuItemInfo(&ItemInfo);
          return;
        }
    } while (i != OrigPos);

  /* Not found */
  MenuCleanupRosMenuItemInfo(&ItemInfo);
}

/***********************************************************************
 *           MenuInitSysMenuPopup
 *
 * Grey the appropriate items in System menu.
 */
void FASTCALL
MenuInitSysMenuPopup(HMENU Menu, DWORD Style, DWORD ClsStyle, LONG HitTest )
{
  BOOL Gray;
  UINT DefItem;
  #if 0
  MENUITEMINFOW mii;
  #endif

  Gray = 0 == (Style & WS_THICKFRAME) || 0 != (Style & (WS_MAXIMIZE | WS_MINIMIZE));
  EnableMenuItem(Menu, SC_SIZE, (Gray ? MF_GRAYED : MF_ENABLED));
  Gray = 0 != (Style & WS_MAXIMIZE);
  EnableMenuItem(Menu, SC_MOVE, (Gray ? MF_GRAYED : MF_ENABLED));
  Gray = 0 == (Style & WS_MINIMIZEBOX) || 0 != (Style & WS_MINIMIZE);
  EnableMenuItem(Menu, SC_MINIMIZE, (Gray ? MF_GRAYED : MF_ENABLED));
  Gray = 0 == (Style & WS_MAXIMIZEBOX) || 0 != (Style & WS_MAXIMIZE);
  EnableMenuItem(Menu, SC_MAXIMIZE, (Gray ? MF_GRAYED : MF_ENABLED));
  Gray = 0 == (Style & (WS_MAXIMIZE | WS_MINIMIZE));
  EnableMenuItem(Menu, SC_RESTORE, (Gray ? MF_GRAYED : MF_ENABLED));
  Gray = 0 != (ClsStyle & CS_NOCLOSE);

  /* The menu item must keep its state if it's disabled */
  if (Gray)
    {
      EnableMenuItem(Menu, SC_CLOSE, MF_GRAYED);
    }

  /* Set default menu item */
  if(Style & WS_MINIMIZE)
  {
    DefItem = SC_RESTORE;
  }
  else
  {
    if(HitTest == HTCAPTION)
    {
      DefItem = ((Style & (WS_MAXIMIZE | WS_MINIMIZE)) ? SC_RESTORE : SC_MAXIMIZE);
    }
    else
    {
      DefItem = SC_CLOSE;
    }
  }
  #if 0
  mii.cbSize = sizeof(MENUITEMINFOW);
  mii.fMask |= MIIM_STATE;
  if((DefItem != SC_CLOSE) && GetMenuItemInfoW(Menu, DefItem, FALSE, &mii) &&
     (mii.fState & (MFS_GRAYED | MFS_DISABLED)))
  {
    DefItem = SC_CLOSE;
  }
  #endif
  SetMenuDefaultItem(Menu, DefItem, MF_BYCOMMAND);
}

/***********************************************************************
 *           MenuShowSubPopup
 *
 * Display the sub-menu of the selected item of this menu.
 * Return the handle of the submenu, or menu if no submenu to display.
 */
static HMENU FASTCALL
MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Flags)
{
  extern void FASTCALL NcGetSysPopupPos(HWND Wnd, RECT *Rect);
  RECT Rect;
  ROSMENUITEMINFO ItemInfo;
  ROSMENUINFO SubMenuInfo;
  HDC Dc;
  HMENU Ret;

  DPRINT("owner=%x menu=%p 0x%04x\n", WndOwner, MenuInfo, SelectFirst);

  if (NO_SELECTED_ITEM == MenuInfo->FocusedItem)
    {
      return MenuInfo->Self;
    }

  MenuInitRosMenuItemInfo(&ItemInfo);
  i

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -