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

📄 menu.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
     {
        txtheight = DrawTextW( Dc, ItemInfo->dwTypeData, -1, &rc,
                                                  DT_SINGLELINE|DT_CALCRECT); 
        ItemInfo->Rect.right  += rc.right - rc.left;
        itemheight = max( max( itemheight, txtheight),
                                           GetSystemMetrics( SM_CYMENU) - 1);
        ItemInfo->Rect.right +=  2 * MenuCharSize.cx;
     } 
     else 
     {
        if ((p = strchrW( ItemInfo->dwTypeData, '\t' )) != NULL)
        {
          RECT tmprc = rc;
          LONG tmpheight;
          int n = (int)( p - ItemInfo->dwTypeData);
         /* Item contains a tab (only meaningful in popup menus) */
         /* get text size before the tab */
          txtheight = DrawTextW( Dc, ItemInfo->dwTypeData, n, &rc,
                                                  DT_SINGLELINE|DT_CALCRECT);
          txtwidth = rc.right - rc.left;
          p += 1; /* advance past the Tab */
         /* get text size after the tab */
          tmpheight = DrawTextW( Dc, p, -1, &tmprc, DT_SINGLELINE|DT_CALCRECT);
          ItemInfo->XTab += txtwidth;
          txtheight = max( txtheight, tmpheight);
          txtwidth += MenuCharSize.cx + /* space for the tab */
          tmprc.right - tmprc.left; /* space for the short cut */
        } 
        else 
        {
          txtheight = DrawTextW( Dc, ItemInfo->dwTypeData, -1, &rc,
                                                   DT_SINGLELINE|DT_CALCRECT);
          txtwidth = rc.right - rc.left;
          ItemInfo->XTab += txtwidth;
        }
        ItemInfo->Rect.right  += 2 + txtwidth;
        itemheight = max( itemheight, max( txtheight + 2, MenuCharSize.cy + 4));
     }
     if (hfontOld) SelectObject (Dc, hfontOld);
  } 
  else if( MenuBar)
  {
     itemheight = max( itemheight, GetSystemMetrics(SM_CYMENU)-1);
  }
  ItemInfo->Rect.bottom += itemheight;
  DPRINT("(%ld,%ld)-(%ld,%ld)\n", ItemInfo->Rect.left, ItemInfo->Rect.top, ItemInfo->Rect.right, ItemInfo->Rect.bottom);
}

/***********************************************************************
 *           MenuPopupMenuCalcSize
 *
 * Calculate the size of a popup menu.
 */
static void FASTCALL
MenuPopupMenuCalcSize(PROSMENUINFO MenuInfo, HWND WndOwner)
{
  ROSMENUITEMINFO ItemInfo;
  HDC Dc;
  int Start, i;
  int OrgX, OrgY, MaxX, MaxTab, MaxTabWidth;

  MenuInfo->Width = MenuInfo->Height = 0;
  if (0 == MenuInfo->MenuItemCount)
    {
      MenuSetRosMenuInfo(MenuInfo);
      return;
    }

  Dc = GetDC(NULL);
  SelectObject(Dc, hMenuFont);

  Start = 0;
  MaxX = 2 + 1;

  MenuInfo->maxBmpSize.cx = 0;
  MenuInfo->maxBmpSize.cy = 0;

  MenuInitRosMenuItemInfo(&ItemInfo);  
  while (Start < MenuInfo->MenuItemCount)
    {
      OrgX = MaxX;
      OrgY = 2;

      MaxTab = MaxTabWidth = 0;

      /* Parse items until column break or end of menu */
      for (i = Start; i < MenuInfo->MenuItemCount; i++)
	{
          if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo))
            {
              MenuCleanupRosMenuItemInfo(&ItemInfo);
              MenuSetRosMenuInfo(MenuInfo);
              return;
            }
          if (i != Start &&
              0 != (ItemInfo.fType & (MF_MENUBREAK | MF_MENUBARBREAK)))
            {
              break;
            }
          MenuCalcItemSize(Dc, &ItemInfo, MenuInfo, WndOwner, OrgX, OrgY, FALSE);
          if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo))
            {
              MenuCleanupRosMenuItemInfo(&ItemInfo);
              MenuSetRosMenuInfo(MenuInfo);
              return;
            }
// Not sure here,, The patch from wine removes this.
//          if (0 != (ItemInfo.fType & MF_MENUBARBREAK))
//            {
//              OrgX++;
//            }
          MaxX = max(MaxX, ItemInfo.Rect.right);
          OrgY = ItemInfo.Rect.bottom;
          if ((ItemInfo.Text) && 0 != ItemInfo.XTab)
	    {
              MaxTab = max(MaxTab, ItemInfo.XTab);
              MaxTabWidth = max(MaxTabWidth, ItemInfo.Rect.right - ItemInfo.XTab);
            }
        }

      /* Finish the column (set all items to the largest width found) */
      MaxX = max(MaxX, MaxTab + MaxTabWidth);
      while (Start < i)
        {
          if (MenuGetRosMenuItemInfo(MenuInfo->Self, Start, &ItemInfo))
            {
              ItemInfo.Rect.right = MaxX;
              if ((ItemInfo.Text) && 0 != ItemInfo.XTab)
                {
                  ItemInfo.XTab = MaxTab;
                }
              MenuSetRosMenuItemInfo(MenuInfo->Self, Start, &ItemInfo);
            }
          Start++;
	}
      MenuInfo->Height = max(MenuInfo->Height, OrgY);
    }

  MenuInfo->Width = MaxX;

  /* space for 3d border */
  MenuInfo->Height += 2;
  MenuInfo->Width += 2;

  ReleaseDC(NULL, Dc);
  MenuCleanupRosMenuItemInfo(&ItemInfo);
  MenuSetRosMenuInfo(MenuInfo);
}

/***********************************************************************
 *           MenuMenuBarCalcSize
 *
 * FIXME: Word 6 implements its own MDI and its own 'close window' bitmap
 * height is off by 1 pixel which causes lengthy window relocations when
 * active document window is maximized/restored.
 *
 * Calculate the size of the menu bar.
 */
static void FASTCALL
MenuMenuBarCalcSize(HDC Dc, LPRECT Rect, PROSMENUINFO MenuInfo, HWND WndOwner)
{
  ROSMENUITEMINFO ItemInfo;
  int Start, i, OrgX, OrgY, MaxY, HelpPos;

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

  DPRINT("left=%ld top=%ld right=%ld bottom=%ld\n",
         Rect->left, Rect->top, Rect->right, Rect->bottom);
  MenuInfo->Width = Rect->right - Rect->left;
  MenuInfo->Height = 0;
  MaxY = Rect->top + 1;
  Start = 0;
  HelpPos = -1;

  MenuInfo->maxBmpSize.cx = 0;
  MenuInfo->maxBmpSize.cy = 0;

  MenuInitRosMenuItemInfo(&ItemInfo);
  while (Start < MenuInfo->MenuItemCount)
    {
      if (! MenuGetRosMenuItemInfo(MenuInfo->Self, Start, &ItemInfo))
        {
          MenuCleanupRosMenuItemInfo(&ItemInfo);
          return;
        }
      OrgX = Rect->left;
      OrgY = MaxY;

      /* Parse items until line break or end of menu */
      for (i = Start; i < MenuInfo->MenuItemCount; i++)
	{
          if (-1 == HelpPos && 0 != (ItemInfo.fType & MF_RIGHTJUSTIFY))
            {
              HelpPos = i;
            }
          if (i != Start &&
              0 != (ItemInfo.fType & (MF_MENUBREAK | MF_MENUBARBREAK)))
            {
              break;
            }

          DPRINT("calling MENU_CalcItemSize org=(%d, %d)\n", OrgX, OrgY);
          MenuCalcItemSize(Dc, &ItemInfo, MenuInfo, WndOwner, OrgX, OrgY, TRUE);
          if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo))
            {
              MenuCleanupRosMenuItemInfo(&ItemInfo);
              return;
            }

          if (ItemInfo.Rect.right > Rect->right)
            {
              if (i != Start)
                {
                  break;
                }
              else
                {
                  ItemInfo.Rect.right = Rect->right;
                }
            }
          MaxY = max(MaxY, ItemInfo.Rect.bottom );
          OrgX = ItemInfo.Rect.right;
          if (i + 1 < MenuInfo->MenuItemCount)
            {
              if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i + 1, &ItemInfo))
                {
                  MenuCleanupRosMenuItemInfo(&ItemInfo);
                  return;
                }
            }
	}

/* FIXME: Is this really needed? */ /*NO! it is not needed, why make the
HBMMENU_MBAR_CLOSE, MINIMIZE & RESTORE, look the same size as the menu bar! */
#if 0
      /* Finish the line (set all items to the largest height found) */
      while (Start < i)
        {
          if (MenuGetRosMenuItemInfo(MenuInfo->Self, Start, &ItemInfo))
            {
              ItemInfo.Rect.bottom = MaxY;
              MenuSetRosMenuItemInfo(MenuInfo->Self, Start, &ItemInfo);
            }
          Start++;
        }
#else
     Start = i; /* This works! */
#endif
    }

  Rect->bottom = MaxY;
  MenuInfo->Height = Rect->bottom - Rect->top;
  MenuSetRosMenuInfo(MenuInfo);

  if (-1 != HelpPos)
    {
      /* Flush right all items between the MF_RIGHTJUSTIFY and */
      /* the last item (if several lines, only move the last line) */
      if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->MenuItemCount - 1, &ItemInfo))
        {
          MenuCleanupRosMenuItemInfo(&ItemInfo);
          return;
        }
      OrgY = ItemInfo.Rect.top;
      OrgX = Rect->right;
      for (i = MenuInfo->MenuItemCount - 1; HelpPos <= i; i--)
        {
          if (i < HelpPos)
            {
              break;				/* done */
            }
          if (ItemInfo.Rect.top != OrgY)
            {
              break;				/* Other line */
            }
          if (OrgX <= ItemInfo.Rect.right)
            {
              break;				/* Too far right already */
            }
          ItemInfo.Rect.left += OrgX - ItemInfo.Rect.right;
          ItemInfo.Rect.right = OrgX;
          OrgX = ItemInfo.Rect.left;
          MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo);
          if (HelpPos + 1 <= i &&
              ! MenuGetRosMenuItemInfo(MenuInfo->Self, i - 1, &ItemInfo))
            {
              MenuCleanupRosMenuItemInfo(&ItemInfo);
              return;
            }
        }
    }

  MenuCleanupRosMenuItemInfo(&ItemInfo);
}

/***********************************************************************
 *           DrawMenuBarTemp   (USER32.@)
 *
 * UNDOCUMENTED !!
 *
 * called by W98SE desk.cpl Control Panel Applet
 *
 * Not 100% sure about the param names, but close.
 *
 * @implemented
 */
DWORD WINAPI
DrawMenuBarTemp(HWND Wnd, HDC DC, LPRECT Rect, HMENU Menu, HFONT Font)
{
  ROSMENUINFO MenuInfo;
  ROSMENUITEMINFO ItemInfo;
  UINT i;
  HFONT FontOld = NULL;
  BOOL flat_menu = FALSE;
  
  SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0);
  
  if (NULL == Menu)
    {
      Menu = GetMenu(Wnd);
    }

  if (NULL == Font)
    {
      Font = hMenuFont;
    }

  if (NULL == Rect || ! MenuGetRosMenuInfo(&MenuInfo, Menu))
    {
      return GetSystemMetrics(SM_CYMENU);
    }

  DPRINT("(%x, %x, %p, %x, %x)\n", Wnd, DC, Rect, Menu, Font);

  FontOld = SelectObject(DC, Font);

  if (0 == MenuInfo.Height)
    {
      MenuMenuBarCalcSize(DC, Rect, &MenuInfo, Wnd);
    }

  Rect->bottom = Rect->top + MenuInfo.Height;

  FillRect(DC, Rect, GetSysColorBrush(flat_menu ? COLOR_MENUBAR : COLOR_MENU));

  SelectObject(DC, GetSysColorPen(COLOR_3DFACE));
  MoveToEx(DC, Rect->left, Rect->bottom, NULL);
  LineTo(DC, Rect->right, Rect->bottom);

  if (0 == MenuInfo.MenuItemCount)
    {
      SelectObject(DC, FontOld);
      return GetSystemMetrics(SM_CYMENU);
    }

  MenuInitRosMenuItemInfo(&ItemInfo);
  for (i = 0; i < MenuInfo.MenuItemCount; i++)
    {
      if (MenuGetRosMenuItemInfo(MenuInfo.Self, i, &ItemInfo))
        {
          MenuDrawMenuItem(Wnd, &MenuInfo, Wnd, DC, &ItemInfo,
                           MenuInfo.Height, TRUE, ODA_DRAWENTIRE);
        }
    }
  MenuCleanupRosMenuItemInfo(&ItemInfo);

  SelectObject(DC, FontOld);

  return MenuInfo.Height;
}


/***********************************************************************
 *           MenuDrawMenuBar
 *
 * Paint a menu bar. Returns the height of the menu bar.
 * called from [windows/nonclient.c]
 */
UINT MenuDrawMenuBar(HDC DC, LPRECT Rect, HWND Wnd, BOOL SuppressDraw)
{
  ROSMENUINFO MenuInfo;
  HFONT FontOld = NULL;
  HMENU Menu = GetMenu(Wnd);

  if (NULL == Rect || ! MenuGetRosMenuInfo(&MenuInfo, Menu))
    {
      return GetSystemMetrics(SM_CYMENU);
    }

  if (SuppressDraw)
    {
      FontOld = SelectObject(DC, hMenuFont);

      MenuMenuBarCalcSize(DC, Rect, &MenuInfo, Wnd);

      Rect->bottom = Rect->top + MenuInfo.Height;

      if (NULL != FontOld)
        {
          SelectObject(DC, FontOld);
        }
      return MenuInfo.Height;
    }
  else
    {
      return DrawMenuBarTemp(Wnd, DC, Rect, Menu, NULL);
    }
}

/***********************************************************************
 *           MenuInitTracking
 */
static BOOL FASTCALL
MenuInitTracking(HWND Wnd, HMENU Menu, BOOL Popup, UINT Flags)
{
  DPRINT("Wnd=%p Menu=%p\n", Wnd, Menu);

  HideCaret(0);

  /* Send WM_ENTERMENULOOP and WM_INITMENU message only if TPM_NONOTIFY flag is not specified */
  if (0 == (Flags & TPM_NONOTIFY))
    {
      SendMessageW(Wnd, WM_ENTERMENULOOP, Popup, 0);
    }

  SendMessageW(Wnd, WM_SETCURSOR, (WPARAM) Wnd, HTCAPTION);

  if (0 == (Flags & TPM_NONOTIFY))

⌨️ 快捷键说明

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