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

📄 uicoolmenu.cpp

📁 vc座的资源管理器源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
  for (int i = 0; i < nToolbars; i++)
    LoadToolbar(arToolbarID[i]);
}

//////////////////
// Get menu font, creating if needed
//
CFont* CCoolMenuManager::GetMenuFont()
{
  if (!(HFONT)m_fontMenu) {
    NONCLIENTMETRICS info;
    info.cbSize = sizeof(info);
    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
    VERIFY(m_fontMenu.CreateFontIndirect(&info.lfMenuFont));
  }
  return &m_fontMenu;
}

//////////////////
// Handle WM_MEASUREITEM on behalf of frame: compute menu item size.
//
BOOL CCoolMenuManager::OnMeasureItem(LPMEASUREITEMSTRUCT lpms)
{
	ASSERT(lpms);
	CMyItemData* pmd = (CMyItemData*)lpms->itemData;
	ASSERT(pmd);
	if (lpms->CtlType != ODT_MENU || !pmd->IsMyItemData())
		return FALSE; // not handled by me
	// Addition: Philip Oldaker
	// Pass it on to the shell if lpcm has been set
	if (pmd->lpcm)
	{
		IContextMenu2 *lpcm2=NULL;
		HRESULT hr = pmd->lpcm->QueryInterface(IID_IContextMenu2,(LPVOID*)&lpcm2);
		if (SUCCEEDED(hr))
		{
			// switch context item data
			lpms->itemData = (DWORD)pmd->pContext;
			lpcm2->HandleMenuMsg(WM_MEASUREITEM,0,(LPARAM)lpms);
			// clean up
			lpms->itemData = (DWORD)pmd;
			lpcm2->Release();
		}
		return TRUE;
	}
	/////////////////////
	if (pmd->fType & MFT_SEPARATOR) {
	// separator: use half system height and zero width
	lpms->itemHeight = GetSystemMetrics(SM_CYMENU)>>1;
	lpms->itemWidth  = 0;

	} else {

    // compute size of text: use DrawText with DT_CALCRECT

    CWindowDC dc(NULL); // screen DC--I won't actually draw on it
    CRect rcText(0,0,0,0);
    CFont* pOldFont = dc.SelectObject(GetMenuFont());
    dc.DrawText(pmd->text, rcText, DT_MYSTANDARD|DT_CALCRECT);
    dc.SelectObject(pOldFont);

    // height of item is just height of a standard menu item
    lpms->itemHeight= max(GetSystemMetrics(SM_CYMENU), rcText.Height());

    // width is width of text plus a bunch of stuff
    int cx = rcText.Width();  // text width 
    cx += CXTEXTMARGIN<<1;    // L/R margin for readability
    cx += CXGAP;          // space between button and menu text
    cx += m_szButton.cx<<1;   // button width (L=button; R=empty margin)

    // whatever value I return in lpms->itemWidth, Windows will add the
    // width of a menu checkmark, so I must subtract to defeat Windows. Argh.
    //
    cx -= GetSystemMetrics(SM_CXMENUCHECK)-1;
    lpms->itemWidth = cx;   // done deal

    CMTRACE(_T("OnMeasureItem for '%s':\tw=%d h=%d\n"), (LPCTSTR)pmd->text,
      lpms->itemWidth, lpms->itemHeight);
  }
  return TRUE; // handled
}

/////////////////
// Handle WM_DRAWITEM on behalf of frame. Note: in all that goes
// below, can't assume rcItem.left=0 because of multi-column menus!
//
BOOL CCoolMenuManager::OnDrawItem(LPDRAWITEMSTRUCT lpds)
{
	ASSERT(lpds);

	// Omar L Francisco
	if (lpds->CtlType != ODT_MENU)
		return FALSE;
  
	// Omar L Francisco
	CMyItemData* pmd = (CMyItemData*)lpds->itemData;
	if (!pmd->IsMyItemData())
		return FALSE;
	// Addition: Philip Oldaker
	// Pass it on to the shell if this has been set
	if (pmd->lpcm)
	{
		IContextMenu2 *lpcm2=NULL;
		HRESULT hr = pmd->lpcm->QueryInterface(IID_IContextMenu2,(LPVOID*)&lpcm2);
		if (SUCCEEDED(hr))
		{
			lpds->itemData = (DWORD)pmd->pContext;
			lpcm2->HandleMenuMsg(WM_DRAWITEM,0,(LPARAM)lpds);
			lpds->itemData = (DWORD)pmd;
			lpcm2->Release();
		}
		return TRUE;
	}
	////////////////////////////////
  ASSERT(lpds->itemAction != ODA_FOCUS);
  ASSERT(lpds->hDC);
  CDC dc;
  dc.Attach(lpds->hDC);

  const CRect& rcItem = lpds->rcItem;
  if (pmd->fType & MFT_SEPARATOR) {
    // draw separator
    CRect rc = rcItem;                // copy rect
    rc.top += rc.Height()>>1;           // vertical center
    dc.DrawEdge(&rc, EDGE_ETCHED, BF_TOP);    // draw separator line

  } else {                          // not a separator

    CMTRACE(_T("OnDrawItem for '%s':\tw=%d h=%d\n"), (LPCTSTR)pmd->text,
      rcItem.Width(), rcItem.Height());

    BOOL bDisabled = lpds->itemState & ODS_GRAYED;
    BOOL bSelected = lpds->itemState & ODS_SELECTED;
    BOOL bChecked  = lpds->itemState & ODS_CHECKED;
    BOOL bHaveButn=FALSE;

    // Paint button, or blank if none
    CRect rcButn(rcItem.TopLeft(), m_szButton); // button rect
    rcButn += CPoint(0,                 // center vertically
      (rcItem.Height() - rcButn.Height())>>1 );

    int iButton = pmd->iButton;
    if (iButton >= 0  ||  iButton == USES_ICON) 
    {
      // this item has a button!
      bHaveButn = TRUE;

      // compute point to start drawing
      CSize sz = rcButn.Size() - m_szBitmap;
      sz.cx >>= 1;
      sz.cy >>= 1;
      CPoint p(rcButn.TopLeft() + sz);

      // draw disabled or normal
      if (!bDisabled) {
        // normal: fill BG depending on state
        PLFillRect(dc, rcButn, GetSysColor(
          (bChecked && !bSelected) ? COLOR_3DLIGHT : COLOR_MENU));

        // draw pushed-in or popped-out edge
        if (bSelected || bChecked) {
          CRect rc2 = rcButn;
          dc.DrawEdge(rc2, bChecked ? BDR_SUNKENOUTER : BDR_RAISEDINNER,
            BF_RECT);
        }

        // draw the button!
        if (iButton != USES_ICON)
        {
            m_ilButtons.Draw(&dc, iButton, p, ILD_TRANSPARENT);
        }
        else
        {
            dc.DrawState(p, CSize(0,0), pmd->hIcon, DSS_NORMAL, 
                (HBRUSH)NULL);
        }

      } else if (m_bUseDrawState) {
        // use DrawState to draw disabled button: must convert to icon
        if (iButton != USES_ICON)
        {
            HICON hIcon=m_ilButtons.ExtractIcon(iButton);
            ASSERT(hIcon);
            dc.DrawState(p, CSize(0,0), hIcon, DSS_DISABLED, (HBRUSH)NULL);
            DestroyIcon(hIcon);
        }
        else
        {
            dc.DrawState(p, CSize(0,0), pmd->hIcon, DSS_DISABLED, 
                (HBRUSH)NULL);
        }
      } else
        // use DrawEmbossed to draw disabeld button, w/color flag
        if (iButton != USES_ICON)
        {
            PLDrawEmbossed(dc, m_ilButtons, iButton, p,
              m_bDrawDisabledButtonsInColor);
        }
        else
        {
            int i = m_ilTemp.Add(pmd->hIcon);
            PLDrawEmbossed(dc, m_ilTemp, i, p, 
                m_bDrawDisabledButtonsInColor);
            m_ilTemp.Remove(i);
        }
    } else {
      // no button: look for custom checked/unchecked bitmaps
      CMenuItemInfo info;
      info.fMask = MIIM_CHECKMARKS;
      GetMenuItemInfo((HMENU)lpds->hwndItem,
        lpds->itemID, MF_BYCOMMAND, &info);
      if (bChecked || info.hbmpUnchecked) {
        bHaveButn = Draw3DCheckmark(dc, rcButn, bSelected,
          bChecked ? info.hbmpChecked : info.hbmpUnchecked);
      }
    }

    // Done with button, now paint text. First do background if needed.
    int cxButn = m_szButton.cx;       // width of button
    COLORREF colorBG = GetSysColor(bSelected ? COLOR_HIGHLIGHT : COLOR_MENU);
    if (bSelected || lpds->itemAction==ODA_SELECT) {
      // selected or selection state changed: paint text background
      CRect rcBG = rcItem;              // whole rectangle
      if (bHaveButn)                  // if there's a button:
        rcBG.left += cxButn + CXGAP;      //  don't paint over it!
      PLFillRect(dc, rcBG, colorBG);  // paint it!
    }

    // compute text rectangle and colors
    CRect rcText = rcItem;         // start w/whole item
    rcText.left += cxButn + CXGAP + CXTEXTMARGIN; // left margin
    rcText.right -= cxButn;        // right margin
    dc.SetBkMode(TRANSPARENT);       // paint transparent text
    COLORREF colorText = GetSysColor(bDisabled ?  COLOR_GRAYTEXT :
      bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT);

    // Now paint menu item text.  No need to select font,
    // because windows sets it up before sending WM_DRAWITEM
    //
    if (bDisabled && (!bSelected || colorText == colorBG)) {
      // disabled: draw hilite text shifted southeast 1 pixel for embossed
      // look. Don't do it if item is selected, tho--unless text color same
      // as menu highlight color. Got it?
      //
      DrawMenuText(dc, rcText + CPoint(1,1), pmd->text,
        GetSysColor(COLOR_3DHILIGHT));
    }
    DrawMenuText(dc, rcText, pmd->text, colorText); // finally!
  }
  dc.Detach();

  return TRUE; // handled
}

/////////////////
// Helper function to draw justified menu text. If the text contains a TAB,
// draw everything after the tab right-aligned
//
void CCoolMenuManager::DrawMenuText(CDC& dc, CRect rc, CString text,
  COLORREF color)
{
  CString left = text;
  CString right;
  int iTabPos = left.Find(_T('\t'));
  if (iTabPos >= 0) {
    right = left.Right(left.GetLength() - iTabPos - 1);
    left  = left.Left(iTabPos);
  }
  dc.SetTextColor(color);
  dc.DrawText(left, &rc, DT_MYSTANDARD);
  if (iTabPos > 0)
    dc.DrawText(right, &rc, DT_MYSTANDARD|DT_RIGHT);
}

#ifndef OBM_CHECK
#define OBM_CHECK 32760 // from winuser.h
#endif

//////////////////
// Draw 3D checkmark
//
//    dc        device context to draw in
//    rc        rectangle to center bitmap in
//    bSelected TRUE if button is also selected
//    hbmCheck    Checkmark bitmap to use, or NULL for default
//
BOOL CCoolMenuManager::Draw3DCheckmark(CDC& dc, const CRect& rc,
  BOOL bSelected, HBITMAP hbmCheck)
{
  // get checkmark bitmap if none, use Windows standard
  if (!hbmCheck) {
    CBitmap bm;
    VERIFY(bm.LoadOEMBitmap(OBM_CHECK));
    hbmCheck = (HBITMAP)bm.Detach();
    ASSERT(hbmCheck);
  }
  
  // center bitmap in caller's rectangle
  BITMAP bm;
  ::GetObject(hbmCheck, sizeof(bm), &bm);
  int cx = bm.bmWidth;
  int cy = bm.bmHeight;
  CRect rcDest = rc;
  CPoint p(0,0);
  CSize delta(CPoint((rc.Width() - cx)/2, (rc.Height() - cy)/2));
  if (rc.Width() > cx)
    rcDest = CRect(rc.TopLeft() + delta, CSize(cx, cy));
  else
    p -= delta;

  // select checkmark into memory DC
  CDC memdc;
  memdc.CreateCompatibleDC(&dc);
  HBITMAP hOldBM = (HBITMAP)::SelectObject(memdc, hbmCheck);

  // set BG color based on selected state
  COLORREF colorOld =
    dc.SetBkColor(GetSysColor(bSelected ? COLOR_MENU : COLOR_3DLIGHT));
  dc.BitBlt(rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
    &memdc, p.x, p.y, SRCCOPY);
  dc.SetBkColor(colorOld);

  ::SelectObject(memdc, hOldBM); // restore

  // draw pushed-in hilight.
  if (rc.Width() > cx)        // if room:
    rcDest.InflateRect(1,1);  // inflate checkmark by one pixel all around
  dc.DrawEdge(&rcDest, BDR_SUNKENOUTER, BF_RECT);

  return TRUE;
}

//////////////////
// Handle WM_INITMENUPOPUP on behalf of frame.
//
void CCoolMenuManager::OnInitMenuPopup(CMenu* pMenu,
  UINT nIndex, BOOL bSysMenu)
{
	// Addition: Philip Oldaker
	/////////////////////////
	// Let the shell handle it
	if (bSysMenu)
		return;
	for(UINT i=0;i < pMenu->GetMenuItemCount();i++)
	{
		CMyItemData* pmd = GetMyItemData(*pMenu,i,TRUE);
		if (pmd->IsMyItemData() && pmd->lpcm)
		{
			IContextMenu2 *lpcm2=NULL;
			HRESULT hr = pmd->lpcm->QueryInterface(IID_IContextMenu2,(LPVOID*)&lpcm2);
			if (SUCCEEDED(hr))
			{
				SetMyItemData((CMyItemData*)pmd->pContext,*pMenu,i,TRUE); 
				lpcm2->HandleMenuMsg(WM_INITMENUPOPUP,(WPARAM)pMenu->GetSafeHmenu(),0);
				SetMyItemData(pmd,*pMenu,i,TRUE); 
				lpcm2->Release();
			}
			return;
		}
	}
	//////////////////////
  if (m_bAutoAccel)
  {
    // check for new accels. If ASSERT bombs,
    // you forgot to call Install.
//    ASSERT_VALID(m_pFrame);
    
//    HACCEL hAccel = m_pFrame->GetDefaultAccelerator();
    HACCEL hAccel = NULL;
    
    if (hAccel != m_hAccel)
      LoadAccel(hAccel);

    // 12 Nov 1998  - Wang Jun - Fixes debug assert in system menu.
    // Check if click system menu.

⌨️ 快捷键说明

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