自制菜单笔记

 


1. 绘制菜单
 1> 先用Cmenu::ModifyMenu编程实现传统菜单到自制菜单项的转化

 2> 添加响应WM_MEASUREITEM消息   // 在主框架中响应
  WM_MEASUREITEM的工作时填充itemWidth和itemHeight
    在这个消息中, 设置单个菜单项的宽度

  /*
   * MEASUREITEMSTRUCT for ownerdraw
   */
  typedef struct tagMEASUREITEMSTRUCT {
      UINT       CtlType;  // 菜单项取值 ODT_MENU
      UINT       CtlID;  // 指定了自绘控件的ID值,而对于菜单项则不需要使用该成员
      UINT       itemID;  // 表示菜单项ID
      UINT       itemWidth; // 指定宽,单位象素,一个菜单项目.在从消息返回之前,自绘菜单项的所有者必需填充这个成员。
      UINT       itemHeight; // 指定高,单位象素,一个菜单.在从消息返回之前,自绘菜单项的所有者必需填充这个成员。
      DWORD      itemData; //
  } MEASUREITEMSTRUCT, NEAR *PMEASUREITEMSTRUCT, FAR *LPMEASUREITEMSTRUCT;


  lpmis->itemWidth = ::GetSystemMetrics (SM_CYMENU) * 4;  // 菜单宽度
     lpmis->itemHeight = ::GetSystemMetrics (SM_CYMENU);  // 菜单高度
  SM_CYMENU是系统给顶层菜单画的菜单栏的高度.

  
 3> 添加响应WM_DRAWITEM消息   // 在主框架中响应

  typedef struct tagDRAWITEMSTRUCT {
   UINT CtlType;   // 菜单项取值 ODT_MENU                        
   UINT CtlID;   // 指定了自绘控件的ID值,而对于菜单项则不需要使用该成员
   UINT itemID;   // 表示菜单项ID
   UINT itemAction;  // 指定绘制行为
   UINT itemState;  // 指定了当前绘制操作完成后,所绘项的可见状态
   HWND hwndItem;   // 菜单句柄
   HDC hDC;   // 指定了绘制操作所使用的设备环境
   RECT rcItem;   // 指定了将被绘制的矩形区域。这个矩形区域就是上面hDC的作用范围。
   ULONG_PTR itemData;
  } DRAWITEMSTRUCT;


例子:
 
// 顶层的弹出菜单
void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
 if (0 == nIndex)
 {
  pPopupMenu->ModifyMenu(0, MF_OWNERDRAW | MF_BYPOSITION | MF_GRAYED);
 }


 CFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
}

// 顶层菜单
void CMainFrame::OnInitMenu(CMenu* pMenu)
{
 CFrameWnd::OnInitMenu(pMenu);
}


void CMainFrame::OnMeasureItem (int nIDCtl, LPMEASUREITEMSTRUCT lpmis)
{

    lpmis->itemWidth = ::GetSystemMetrics (SM_CYMENU) * 4; // 菜单宽度
    lpmis->itemHeight = ::GetSystemMetrics (SM_CYMENU) - 3;  // 菜单高度
}

void CMainFrame::OnDrawItem (int nIDCtl, LPDRAWITEMSTRUCT lpdis)
{

 CDC dc;
 dc.Attach(lpdis->hDC);

 CString strText = _T("    新建");
 COLORREF clColor = 0;

 if (lpdis->itemState & ODS_GRAYED)  // 灰化
 {
  clColor = ::GetSysColor(COLOR_GRAYTEXT);
 }
 else if (lpdis->itemState & ODS_SELECTED)     // 选中
 {
  clColor = RGB(255, 255, 255);
 }
 else if (lpdis->itemState & ODS_DISABLED)
 {
 // clColor = ::GetSysColor(COLOR_D)
 }
 else
 {
  clColor = RGB(0, 0, 0);
 }
 

 

 

 CBrush *pBrush = new CBrush ( ::GetSysColor ( (lpdis->itemState & ODS_SELECTED) ?
        COLOR_HIGHLIGHT : COLOR_MENU)
      ); // 高亮颜色 菜单颜色
 
 // 为选中的菜单项绘制外边框
   // dc.FrameRect (&(lpdis->rcItem), pBrush);
 dc.FillRect(&(lpdis->rcItem), pBrush);
 delete pBrush;

 

 dc.SetTextColor(clColor);
 dc.SetBkMode(TRANSPARENT);
 dc.TextOut(lpdis->rcItem.left, lpdis->rcItem.top, strText);

 dc.Detach();
}

 

2. 层叠菜单

3. 上下文菜单(右键弹出式菜单)

 ON_WM_CONTEXTMENU()

 void CChildView::OnContextMenu(CWnd* pWnd, CPoint point)
 {
         CMenu menu;
         menu.LoadMenu (IDR_CONTEXTMENU);
         CMenu* pContextMenu = menu.GetSubMenu (0);

         for (int i=0; i<5; i++)
             pContextMenu->ModifyMenu (ID_COLOR_RED + i,
                 MF_BYCOMMAND | MF_OWNERDRAW, ID_COLOR_RED + i);

         pContextMenu->TrackPopupMenu (TPM_LEFTALIGN |
     TPM_LEFTBUTTON |
                TPM_RIGHTBUTTON,
     point.x,
     point.y,
     AfxGetMainWnd ());

  CWnd::OnContextMenu (pWnd, point);
 }

你可能感兴趣的:(编程,框架,工作,struct,delete,menu)