自绘菜单项

第一步:将所有菜单项设置为MF_OWNERDRAW,即自绘模式

第二步:在WM_MEASUREITEM消息中设置菜单项的大小

第三步:在WM_DRAWITEM消息中进行菜单项的绘制

问题首先出现在了第一步,我要绘制的是一个上下文菜单,即右键菜单,要将菜单项设置为MF_OWNERDRAW,需要用到ModifyMenu函数,起始由于ModifyMenu函数的参数设置错误,导致程序怎么也响应不了WM_MEASUREITEM和WM_DRAWITEM消息,所以建议在使用ModifyMenu时对返回值进行检查。

view plaincopy to clipboardprint?
void CMainWindow::OnRButtonDown(UINT nFlags, CPoint point)   
{   

    ClientToScreen(&point);   
    CMenu Menu;   
    Menu.LoadMenuW(IDR_MENU2);   
    CMenu *pMenu = Menu.GetSubMenu(0);   
    CString strText;   
    for (int i = 0; i < pMenu->GetMenuItemCount(); i++)   
    {   
        BOOL bModi = pMenu->ModifyMenuW(ID_123_456 + i, MF_BYCOMMAND|MF_OWNERDRAW, ID_123_456 + i);   
        if (!bModi)   
       {   
              TRACK("ModifyMenu fail!");   
       }   
        pMenu->GetMenuStringW(i, strText, MF_BYPOSITION);   
    }   
    pMenu->TrackPopupMenu(TPM_LEFTBUTTON|TPM_LEFTALIGN,   
        point.x,   
        point.y,   
        this);   
}  

void 
CMainWindow::OnRButtonDown(UINT nFlags, CPoint point)
{
    ClientToScreen(&point);
    CMenu Menu;
    Menu.LoadMenuW(IDR_MENU2);
    CMenu *pMenu = Menu.GetSubMenu(0);
    CString strText;
    for (int i = 0; i < pMenu->GetMenuItemCount(); i++)
    {
        BOOL bModi = pMenu->ModifyMenuW(ID_123_456 + i, MF_BYCOMMAND|MF_OWNERDRAW, ID_123_456 + i);
        if (!bModi)
       {
              TRACK("ModifyMenu fail!");
       }
        pMenu->GetMenuStringW(i, strText, MF_BYPOSITION);
    }
    pMenu->TrackPopupMenu(TPM_LEFTBUTTON|TPM_LEFTALIGN,
        point.x,
        point.y,
        this);
}

第一步的问题解决后,接在在第二步的WM_MEASUREITEM消息中设置菜单项的大小:

view plaincopy to clipboardprint?
void CMainWindow::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpmis)   
{   

    //lpmis->itemWidth = ::GetSystemMetrics(SM_CYMENU) * 4;   
    lpmis->itemWidth = 150;   
    lpmis->itemHeight = ::GetSystemMetrics(SM_CYMENU);   
}  

void 
CMainWindow::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpmis)
{
    //lpmis->itemWidth = ::GetSystemMetrics(SM_CYMENU) * 4;
    lpmis->itemWidth = 150;
    lpmis->itemHeight = ::GetSystemMetrics(SM_CYMENU);

在WM_MEASUREITEM消息中设置的菜单项大小会传入WM_DRAWITEM消息中,然后再在WM_DRAWITEM消息中根据菜单项的大小来进行重绘。

到第三步也遇到了几个问题,由于最初对WM_DRAWITEM消息中的LPDRAWITEMSTRUCT结构体不了解,以致写出的程序不管在什么时候都会作同一个绘制操作,先来看看WM_DRAWITEM消息的声明:

afx_msg void CMainWindow::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpdis);

在这个消息中有两个参数,在自绘菜单时,两个参数都要用到。其中nIDCtl,书上说是所属控件的ID,不太明白是什么意思,在MSDN看到,对于菜单发出的WM_DRAWITEM消息,nIDCtl为0。再说LPDRAWITEMSTRUCT结构体,该结构体中包含了菜单复选状态、选中状态以及菜单项的大小等信息。

下面是OnDrawItem消息的实现代码:

view plaincopy to clipboardprint?
void CMainWindow::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpdis)   
{   

    CBrush *brush = new CBrush;   
    CPen *pen = new CPen;   
    CString strText;   
    CDC *pDC = CDC::FromHandle(lpdis->hDC); //获取菜单项的设备句柄   
    //菜单项是否为选中状态   
    if ((lpdis->itemState & ODS_SELECTED))   
    {   
        //在菜单项上自绘矩形框的背景颜色   
        brush->CreateSolidBrush(RGB(182, 189,210));   
        //在菜单项自绘矩形的边框颜色   
        pen->CreatePen(PS_SOLID, 1, RGB(10,36,106));   
        //设置菜单项的文字背景颜色   
        pDC->SetBkColor(RGB(182,189,210));   
    }   
    else  
    {   
        brush->CreateSolidBrush(GetSysColor(COLOR_MENU));   
        pen->CreatePen(PS_SOLID, 0, GetSysColor(COLOR_MENU));   
        pDC->SetBkColor(GetSysColor(COLOR_MENU));   
    }   
    pDC->SelectObject(pen);   
    pDC->SelectObject(brush);   
    //在当前菜单项上画一个矩形框   
    pDC->Rectangle(lpdis->rcItem.left,   
        lpdis->rcItem.top,   
        lpdis->rcItem.right,   
        lpdis->rcItem.bottom);   
    /*--------------------------------------*/  
    //获取当前消息所在菜单项的文本   
    CMenu menu;   
    menu.Attach((HMENU)lpdis->hwndItem);   
    menu.GetMenuStringW(lpdis->itemID, strText,MF_BYCOMMAND);   
    /*--------------------------------------*/  
    //如果为菜单发出的DrawItem消息   
    if (nIDCtl == 0)   
    {   
        //在菜单项上输出菜单文本   
        pDC->TextOutW(lpdis->rcItem.left + 20, lpdis->rcItem.top + 4, strText.GetBuffer(0), strText.GetLength());   
    }   
    menu.Detach();   
    delete brush;   
    delete pen;   

我的代码:

void CMainDlg::OnBnClickedBtnExtensions()

{

       // TODO: Add your control notification handler code here

       int nExtensions =5;  //thenumber of extensions

       CMenu menu;

       menu.LoadMenu(IDR_MENU_EXTENSIONS);

       CMenu* pop=menu.GetSubMenu(0);

       //add bmp btn of menu

       CBitmap bmp;

       int nPos = 0;

       //beign autonomous learning

       bmp.LoadBitmap(IDB_BMP_BEGINLEARN);

       pop->SetMenuItemBitmaps(nPos,MF_BYPOSITION,&bmp,&bmp);

       bmp.Detach();

       nPos += 2;

       //stop autonomous learning

       bmp.LoadBitmap(IDB_BMP_STOPLEARN);

       pop->SetMenuItemBitmaps(nPos,MF_BYPOSITION,&bmp,&bmp);

       bmp.Detach();

       nPos += 2;

       //students status

       bmp.LoadBitmap(IDB_BMP_STUDENTSSTATUS);

       pop->SetMenuItemBitmaps(nPos,MF_BYPOSITION,&bmp,&bmp);

       bmp.Detach();

       nPos += 2;

       //send files

       bmp.LoadBitmap(IDB_BMP_SENDFILES);

       pop->SetMenuItemBitmaps(nPos,MF_BYPOSITION,&bmp,&bmp);

       bmp.Detach();

       nPos += 2;

       //recieve homeworks

       bmp.LoadBitmap(IDB_BMP_RECIEVEJOBS);

       pop->SetMenuItemBitmaps(nPos,MF_BYPOSITION,&bmp,&bmp);

       bmp.Detach();

       nPos += 2;

 

       HBRUSH m_BKBrush= ::CreateSolidBrush(RGB(241,245,246));

       MENUINFO mnInfo;

       memset(&mnInfo,0,sizeof(MENUINFO));

       mnInfo.cbSize=sizeof(MENUINFO);

       mnInfo.fMask=MIM_BACKGROUND;

       mnInfo.hbrBack=m_BKBrush;

       ::SetMenuInfo(pop->m_hMenu,&mnInfo);

 

       POINT ptMouse;

       GetCursorPos(&ptMouse);

       CRect Menurc,rect;

   this->GetWindowRect(&rect);

 

       if ((rect.left - MENU_WIDTH_NEARLY)>0)

       {

              pop->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON,/*ptMouse.x*/  \

                     (rect.left - MENU_WIDTH_NEARLY),/*ptMouse.y*/(rect.bottom - MENU_HEIGTH_TO_BOTTOM),this);

       }

       else

       {

              pop->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON,rect.right,(rect.bottom - MENU_HEIGTH_TO_BOTTOM),this);

       }

 

       pop->Detach();

       pop->DestroyMenu();

}

转:http://blog.sina.com.cn/s/blog_62bb83b10100jov2.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Matlab是一种强大的数值计算和科学编程软件,它提供了丰富的菜单项命令来进行各种操作和任务。以下是一些常用的Matlab菜单项命令的介绍: 1. File(文件)菜单: - New(新建):创建新的脚本、函数或其他Matlab文件。 - Open(打开):打开已存在的Matlab文件。 - Save(保存):保存当前编辑的Matlab文件。 - Save As(另存为):将当前文件另存为其他名称或格式。 - Import Data(导入数据):导入外部数据文件到Matlab工作空间。 - Export(导出):将Matlab数据导出为其他格式,如图像、文本等。 2. Edit(编辑)菜单: - Undo(撤销):撤销上一步操作。 - Cut(剪切):剪切选中的内容。 - Copy(复制):复制选中的内容。 - Paste(粘贴):粘贴剪切板中的内容。 - Find(查找):查找指定的文本或代码。 - Replace(替换):替换指定的文本或代码。 3. View(视图)菜单: - Command Window(命令窗口):显示或隐藏命令窗口。 - Editor/Debugger(编辑器/调试器):显示或隐藏Matlab编辑器和调试器。 - Workspace(工作空间):显示或隐藏工作空间窗口,用于查看和管理变量。 - Figure Palette(图形面板):显示或隐藏图形面板,用于创建和管理图形窗口。 - Toolbars(工具栏):显示或隐藏各种工具栏。 4. Insert(插入)菜单: - Figure(图形):插入新的图形窗口。 - Axes(坐标轴):在当前图形窗口中插入坐标轴。 - UI Control(用户界面控件):插入各种用户界面控件,如按钮、文本框等。 - UI Container(用户界面容器):插入容器,用于组织和布局用户界面控件。 5. Debug(调试)菜单: - Run(运行):运行当前脚本或函数。 - Stop(停止):停止当前正在运行的脚本或函数。 - Step(单步执行):逐行执行代码并暂停在每一行。 - Breakpoints(断点):设置断点以在指定位置暂停代码执行。 - Profiler(性能分析器):分析代码的性能和效率。 这些只是Matlab菜单项命令的一小部分,Matlab还提供了许多其他功能和命令,用于数据处理、绘图、数值计算、符号计算等。如果你有具体的需求或问题,我可以为你提供更详细的帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值