三星Galaxy S24系列AI手机热销中
全世界各行各业联合起来,internet一定要实现!

VC中进行自绘菜单的实现

2004-02-15 eNet&Ciweek

  在这里提供一个C++类(CCustomMenu),该类是Cmenu的子类,并且拥有自绘能力。它可以向你提供以下的功能:
  设置字体颜色。
  设置高亮度颜色。
  设置高亮度时的风格。
  设置选中时和在普通状态下的菜单显示的图标。
  设置显示图标大小。
  在CCustomMenu中定义了结构MENUDATA,你必须根据你的需要填充该结构,并且在增加菜单时提供该结构的指针(调用AppendMenu,InsertMenu)。下面是一个例子:

  1、定义CCustomMenu的实例,和MENUDATA结构变量。
  CCustomMenu m_cCustomMenu;

  MENUDATA menuData [8];

  2、调用CreateMenu()设置有关参数。

  m_customMenu.CreateMenu ();
  m_customMenu.SetIconSize (25,25);
  m_customMenu.SetHighlightStyle (Normal);
  m_customMenu.SetTextColor (RGB (255,0,0));
  m_customMenu.SetBackColor (RGB (255,255,255));
  m_customMenu.SetHighlightColor (RGB (0,0,255));

  3、设置MENUDATA变量,并增加菜单项。

  lstrcpy (menuData[0].menuText , "text1");
  menuData[0].menuIconNormal= IDI_ICON1;
  m_customMenu.AppendMenu (MF_OWNERDRAW,3,(LPCTSTR)menuData);  

  3、在你的窗口中重载OnMeasureItem(...)函数。

  void CMyView::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
  {
   if ( lpMeasureItemStruct->CtlType == ODT_MENU &&
   IsMenu((HMENU)lpMeasureItemStruct->itemID) &&
   (lpMeasureItemStruct->itemID == (UINT)m_hMenuSub) )
   {
   m_customMenu.MeasureItem (lpMeasureItemStruct);
}
   else
    Cview::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
  }

  下面的函数将帮助你设置菜单属性。  

   void SetTextColor (COLORREF );
   void SetBackColor (COLORREF);
   void SetHighlightColor (COLORREF);
   void SetIconSize (int, int);
   void SetHighlightStyle (HIGHLIGHTSTYLE ); // HIGHLIGHTSTYLE : enum {Normal, TextOnly}
   void SetHighlightTextColor (COLORREF);

  下面是文件代码:

  //*************************************************************************

  // CustomMenu.h : header file

  //  

  #if
  !defined(AFX_CUSTOMMENU_H__FE5B01C3_1E02_11D1_B87A_0060979CDF6D__INCLUDED_)
  #define AFX_CUSTOMMENU_H__FE5B01C3_1E02_11D1_B87A_0060979CDF6D__INCLUDED_
  #if _MSC_VER >= 1000
  #pragma once
  #endif // _MSC_VER >= 1000

  class MENUDATA
  {
  public:
   MENUDATA () { menuIconNormal = -1; menuIconSelected = -1;};
   char menuText[32];
   UINT menuIconNormal;
   UINT menuIconSelected;
  };  

  typedef enum {Normal,TextOnly} HIGHLIGHTSTYLE;

  ///////////////////////////////////////////////////////////////////////////
  //
  // CCustomMenu window
  class CCustomMenu : public Cmenu
  {
  // Construction
  public:
   CCustomMenu();
  // Attributes
  public:
  // Operations
  public:
  // Overrides
   // ClassWizard generated virtual function overrides
   //{{AFX_VIRTUAL(CCustomMenu)
   //}}AFX_VIRTUAL
  // Implementation

  public:
   virtual ~CCustomMenu();
   virtual void DrawItem( LPDRAWITEMSTRUCT);
   virtual void MeasureItem( LPMEASUREITEMSTRUCT );
   void SetTextColor (COLORREF );
   void SetBackColor (COLORREF);
   void SetHighlightColor (COLORREF);
   void SetIconSize (int, int);
   void SetHighlightStyle (HIGHLIGHTSTYLE );
   void SetHighlightTextColor (COLORREF); 

   // Generated message map functions

  protected:
   COLORREF m_crText;
   COLORREF m_clrBack;
   COLORREF m_clrText;
   COLORREF m_clrHilight;
   COLORREF m_clrHilightText;
   LOGFONT m_lf;
   Cfont m_fontMenu;
   UINT m_iMenuHeight;
   BOOL m_bLBtnDown;
   Cbrush m_brBackground,m_brSelect;
   Cpen m_penBack;
   int m_iconX,m_iconY;
   HIGHLIGHTSTYLE m_hilightStyle; 

   //{{AFX_MSG(CCustomMenu) 
   //}}AFX_MSG
  };

  //{{AFX_INSERT_LOCATION}}
  // Microsoft Developer Studio will insert additional declarations immediately before the previous line.  

  #endif //!defined(AFX_CUSTOMMENU_H__FE5B01C3_1E02_11D1_B87A_0060979CDF6D__INCLUDED_) 

  //************************************************************************* 
  // CustomMenu.cpp : implementation file
  //
  #include "stdafx.h"
  #include "CustomMenu.h"
  #ifdef _DEBUG
  #define new DEBUG_NEW
  #undef THIS_FILE
  static char THIS_FILE[] = __FILE__;
  #endif  

  /////////////////////////////////////////////////////////////////////////////
  // CCustomMenu  

  CCustomMenu::CCustomMenu()
  {
   m_clrText = GetSysColor (COLOR_MENUTEXT);
   m_clrBack = GetSysColor (COLOR_MENU);
   m_brBackground.CreateSolidBrush (m_clrBack);
   m_penBack.CreatePen (PS_SOLID,0,m_clrBack);
   m_crText = m_clrText;
   m_bLBtnDown = FALSE;
   m_iconX = GetSystemMetrics ( SM_CXMENUCHECK);
   m_iconY = GetSystemMetrics (SM_CYMENUCHECK );
   m_clrHilight = GetSysColor (COLOR_HIGHLIGHT);
   m_brSelect.CreateSolidBrush (m_clrHilight);
   m_clrHilightText = GetSysColor (COLOR_HIGHLIGHTTEXT);  

   ZeroMemory ((PVOID) &m_lf,sizeof (LOGFONT));
   NONCLIENTMETRICS nm;
   nm.cbSize = sizeof (NONCLIENTMETRICS);
   //Get the system metrics for the Captionfromhere
   VERIFY (SystemParametersInfo (SPI_GETNONCLIENTMETRICS,0,&nm,0));  

   m_lf = nm.lfMenuFont;
   m_iMenuHeight = nm.iMenuHeight;
   m_fontMenu.CreateFontIndirect (&m_lf);
  } 

  CCustomMenu::~CCustomMenu()
  {
   if ((HBRUSH) m_brBackground != NULL)   m_brBackground.DeleteObject ();
   if ((HFONT)m_fontMenu !=NULL)
   m_fontMenu.DeleteObject ();
   if ((HBRUSH)m_brSelect != NULL)
   m_brSelect.DeleteObject ();
  }  

  ///////////////////////////////////////////////////////////////////////////
  // CCustomMenu message handlers

  void CCustomMenu::DrawItem (LPDRAWITEMSTRUCT lpDIS)
  {
   ASSERT(lpDIS != NULL);  
   CDC* pDC = CDC::FromHandle(lpDIS->hDC);
   Crect rect;
   HICON hIcon;
   COLORREF crText = m_crText;
   // draw the colored rectangle portion
   rect.CopyRect(&lpDIS->rcItem);
   // draw the up/down/focused/disabled state
   UINT action = lpDIS->itemAction;
   UINT state = lpDIS->itemState;
   Cstring strText;
   LOGFONT lf;
   lf = m_lf;  

   Cfont dispFont;
   Cfont *pFont;
   //GetWindowText(strText);
   if (lpDIS->itemData != NULL)
   {
   strText = (((MENUDATA*) (lpDIS->itemData))->menuText);
   if ((((MENUDATA *)(lpDIS->itemData))->menuIconNormal) == -1)
   hIcon = NULL;
   else if (state & ODS_SELECTED)
   {
   if ((((MENUDATA *)(lpDIS->itemData))->menuIconSelected) != -1)
   hIcon = AfxGetApp ()->LoadIcon (((MENUDATA *)(lpDIS->itemData))->menuIconSelected);
   else
   hIcon = AfxGetApp()->LoadIcon (((MENUDATA*)(lpDIS->itemData))->menuIconNormal);

   }
   else

    hIcon = AfxGetApp()->LoadIcon (((MENUDATA*)(lpDIS->itemData))->menuIconNormal);
    TRACE1 ("Draw for %s\n", strText);
   }
   else
   {
   strText.Empty();
   hIcon = NULL;
   } 

   if ( (state & ODS_SELECTED) )
   {
   // draw the down edges
   Cpen *pOldPen = pDC->SelectObject (&m_penBack);
   //You need only Text highlight and that's what you get
   if (m_hilightStyle != Normal)
   {
   pDC->FillRect (rect,&m_brBackground);
   }
   else
   {
   pDC->FillRect (rect,&m_brSelect);

   }

   pDC->SelectObject (pOldPen);
   pDC->Draw3dRect (rect,GetSysColor (COLOR_3DHILIGHT),GetSysColor(COLOR_3DSHADOW));
   lf.lfWeight = FW_BOLD;
   if ((HFONT)dispFont != NULL)
   dispFont.DeleteObject ();
   dispFont.CreateFontIndirect (lf);
   crText = m_clrHilightText; 

   //While selected move the text a bit
   TRACE0 ("SELECT,SELECTED\n");
   }
   else
   {
   Cpen *pOldPen = pDC->SelectObject (&m_penBack);
   pDC->FillRect (rect,&m_brBackground);
   pDC->SelectObject (pOldPen);
   // draw the up edges
   pDC->Draw3dRect (rect,m_clrBack,m_clrBack);
   if ((HFONT)dispFont != NULL)
   dispFont.DeleteObject ();
   dispFont.CreateFontIndirect (lf); //Normal
   TRACE0 ("SELECT, NORMAL\n");
   }  

   // draw the text if there is any
   //We have to paint the text only if the image is nonexistant
   if (hIcon != NULL)
   {
   if(DrawIconEx (pDC->GetSafeHdc(),rect.left,rect.top,hIcon,
   (m_iconX)?m_iconX:32,(m_iconY)?m_iconY:32,0,NULL,DI_NORMAL))
   TRACE0("Wrote the icon successfully\n");
   else
   TRACE0 ("SORRY.NOGO\n");
   }
   //This is needed always so that we can have the space for check marks
   rect.left = rect.left +((m_iconX)?m_iconX:32);
   if ( !strText.IsEmpty())
   {
   //pFont->GetLogFont (lf);

   int iOldMode = pDC->GetBkMode();
   pDC->SetBkMode( TRANSPARENT);  
   pDC->SetTextColor( crText);
   pFont = pDC->SelectObject (&dispFont);
   TRACE1( "About To DrawText %s\n",strText);
   pDC->DrawText (strText,rect,DT_LEFT DT_SINGLELINE DT_VCENTER);
   TRACE0("Done\n");
   pDC->SetBkMode( iOldMode );
   pDC->SelectObject (pFont); //set it to the old font
   }
   dispFont.DeleteObject ();
  } 

  void CCustomMenu::MeasureItem( LPMEASUREITEMSTRUCT lpMIS )
  {
   CDC *pDC = AfxGetApp()->m_pMainWnd->GetDC();
   Cfont* pFont = pDC->SelectObject (&m_fontMenu);
   int iconX = 0,iconY= 0;
   TEXTMETRIC tm;
   pDC->GetTextMetrics (tm);
   pDC->SelectObject (pFont);
   AfxGetApp()->m_pMainWnd->ReleaseDC (pDC);  

   if (m_iconX)
   iconX = m_iconX;
   if (m_iconY)
   iconY = m_iconY; 

   lpMIS->itemWidth = iconX + tm.tmAveCharWidth * lstrlen(((MENUDATA*)(lpMIS->itemData))->menuText) +10;
   lpMIS->itemHeight = (iconY > (m_iMenuHeight+1))?iconY:m_iMenuHeight + 1;
  } 

  void CCustomMenu::SetIconSize (int width, int height)
  {
   m_iconX = width;
   m_iconY = height;
  }

  void CCustomMenu::SetTextColor (COLORREF clrText)
  {
   m_crText = clrText;
  } 

  void CCustomMenu::SetBackColor (COLORREF clrBack)

  {
   m_clrBack = clrBack;
   if ((HBRUSH)m_brBackground != NULL)
   m_brBackground.DeleteObject ();
   m_brBackground.CreateSolidBrush (clrBack);
  }  

  void CCustomMenu::SetHighlightColor (COLORREF clrHilight)
  {
   m_clrHilight = clrHilight;
   if ((HBRUSH)m_brSelect != NULL)
   m_brSelect.DeleteObject ();
   m_brSelect.CreateSolidBrush (clrHilight);
  }
  

  void CCustomMenu::SetHighlightTextColor (COLORREF clrHilightText)
  {
   m_clrHilightText = clrHilightText;
  }

  void CCustomMenu::SetHighlightStyle (HIGHLIGHTSTYLE hilightStyle)

  {
   m_hilightStyle = hilightStyle;
  }

  //*************************************************************************

相关频道: eNews

您对本文或本站有任何意见,请在下方提交,谢谢!

投稿信箱:tougao@enet16.com