MFC创建右键弹出菜单的方法

  • 时间:
  • 5185人关注

这篇文章主要介绍了MFC创建右键弹出菜单的方法,较为详细的分析了创建菜单资源及视类添加WM_RBUTTONDOWN消息的实现方法,是非常实用的技巧,具有一定参考借鉴价值,需要的朋友可以参考下,另外这篇文章主要知识点是关于MFC、创建、右键、弹出菜单、方法、MFC的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子资料:

教程详情电子资料
  • 教程类别:MFC
  • 编辑整理:厉奇邃
  • 教程字数:688字节
  • 阅读时间:大概14分钟
  • 下载本教程(DOC版)
  • C++ AMP:用Visual C++加速大规模并行计算
  • C++语言程序设计(第4版)
  • C++编程规范:101条规则、准则与最佳实践
  • C和C++代码精粹
  • C++那些事
  • 本文实例讲述了MFC创建右键弹出菜单的方法。分享给大家供大家参考。具体实现方法如下:

    ①、添加一个菜单资源,ID为IDM_RIGHTMENU。因为在显示右键菜单时顶级菜单是不显示的,所以可以给它设置任意文本。

    ②、给视类添加WM_RBUTTONDOWN消息,在该消息中处理右键弹出菜单。因为视类窗口始终覆盖在框架窗口之上,框架窗口接收不到鼠标消息,所以由视类捕获WM_RBUTTONDOWN消息。

     

    复制代码 代码如下:
    void CMenuView::OnRButtonDown(UINT nFlags, CPoint point)
    
    {
    
        // TODO: 在此添加消息处理程序代码和/或调用默认值

     

        CMenu menu;     menu.LoadMenuW(IDM_RIGHTMENU);//加载菜单资源     CMenu *pPopup=menu.GetSubMenu(0);     ClientToScreen(&point);//将客户区坐标转换为屏幕坐标

        //显示右键菜单,由视类窗口拥有。     pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,this);     //TrackPopupMenu的最后一个参数,可以为GetParent让父窗口既框架窗口拥有右键菜单,这样     //框架类窗口获得了对右键菜单中菜单项的命令响应,     CView::OnRButtonDown(nFlags, point); }

     

    ③、为右键菜单项添加命令消息响应函数(略)。

    希望本文所述对大家的基于MFC的VC++程序设计有所帮助。

    码农之家
    MFC Frame-Splitter模型实例原理解析

    19小时42分钟前回答

    MFC Frame-Splitter模型实例原理解析

    1. 新建一个SDI工程,去掉“Document/View architecture support”

    2. 添加 CTreeView 类的派生类 CLeftView 作为分隔器的左侧视图,添加 CListView 的派生类 CRightView 作为右边视图。可能需要 #include <afxcview.h>

    3. 在CLeftView类中添加成员变量 CTreeCtrl& m_tree; 在CRightView类中添加成员变量 CListCtrl& m_list; 并在构造函数中初始化

    CLeftView::CLeftView() :m_tree(GetTreeCtrl())
    {
    }
    CRightView::CRightView() :m_list(GetListCtrl())
    {
    }

    4. 在主框架类 CMainFrame 类的头文件中,去掉 CChildView 类变量,添加 CSplitterWnd m_split;CLeftView* m_pLeftView;CRightView* m_pRightView;在CMainFrame的cpp文件中去掉CChildView的相关代码。

    在CMainFrame类中添加虚函数OnCreateClient,该函数是在基类函数 CFrameWnd::OnCreate 执行的过程中回调OnCreateClient函数,主要用于创建视图类等客户区子窗口。

    在CLeftView类中添加虚函数OnInitUpdate,该函数创建类之后第一个进入的函数,类似对话框的OnInitDialog函数。再添加TVN_SELCHANGEED消息映射函数,并修改代码调用CRightView的Refresh函数。

    在CRightView类中添加虚函数OnInitUpdate,添加普通成员函数 Refresh。

    代码如下:

    MainFrm.cpp

    // MainFrm.cpp : CMainFrame 类的实现
    //
    
    #include "stdafx.h"
    #include "sp.h"
    
    #include "MainFrm.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    // CMainFrame
    
    IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
    
    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
      ON_WM_CREATE()
      ON_WM_SETFOCUS()
    END_MESSAGE_MAP()
    
    static UINT indicators[] =
    {
      ID_SEPARATOR,      // 状态行指示器
      ID_INDICATOR_CAPS,
      ID_INDICATOR_NUM,
      ID_INDICATOR_SCRL,
    };
    
    // CMainFrame 构造/析构
    
    CMainFrame::CMainFrame()
    {
      // TODO: 在此添加成员初始化代码
    }
    
    CMainFrame::~CMainFrame()
    {
    }
    
    BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
    {
      // TODO: 在此添加专用代码和/或调用基类
      if (!m_split.CreateStatic(this, 1, 2))
        return FALSE;
      m_split.CreateView(0, 0, RUNTIME_CLASS(CLeftView), CSize(150, 0), NULL);
      m_split.CreateView(0, 1, RUNTIME_CLASS(CRightView), CSize(0, 0), NULL);
      m_pLeftView = (CLeftView*)m_split.GetPane(0, 0);
      m_pRightView = (CRightView*)m_split.GetPane(0, 1);
      return TRUE;
    
      //  return CFrameWnd::OnCreateClient(lpcs, pContext);
    }
    
    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
      if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    
      // 创建一个视图以占用框架的工作区
      //if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
      //{
      //  TRACE0("未能创建视图窗口\n");
      //  return -1;
      //}
    
      if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
        !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
      {
        TRACE0("未能创建工具栏\n");
        return -1;   // 未能创建
      }
    
      if (!m_wndStatusBar.Create(this))
      {
        TRACE0("未能创建状态栏\n");
        return -1;   // 未能创建
      }
      m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
    
      // TODO: 如果不需要可停靠工具栏,则删除这三行
      m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
      EnableDocking(CBRS_ALIGN_ANY);
      DockControlBar(&m_wndToolBar);
    
    
      return 0;
    }
    
    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
      if( !CFrameWnd::PreCreateWindow(cs) )
        return FALSE;
      // TODO: 在此处通过修改
      // CREATESTRUCT cs 来修改窗口类或样式
    
      cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
      cs.lpszClass = AfxRegisterWndClass(0);
      
      return TRUE;
    }
    
    // CMainFrame 诊断
    
    #ifdef _DEBUG
    void CMainFrame::AssertValid() const
    {
      CFrameWnd::AssertValid();
    }
    
    void CMainFrame::Dump(CDumpContext& dc) const
    {
      CFrameWnd::Dump(dc);
    }
    #endif //_DEBUG
    
    
    // CMainFrame 消息处理程序
    
    void CMainFrame::OnSetFocus(CWnd* /*pOldWnd*/)
    {
      // 将焦点前移到视图窗口
    //  m_wndView.SetFocus();
      m_pLeftView->SetFocus();
    }
    
    BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
    {
      // 让视图第一次尝试该命令
      //if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
      //  return TRUE;
      CWnd* pWnd = GetFocus();
      if (pWnd && pWnd != this && pWnd->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
      {
        return TRUE;
      }
    
      // 否则,执行默认处理
      return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
    }

    LeftView.cpp

    // LeftView.cpp : 实现文件
    //
    
    #include "stdafx.h"
    #include "sp.h"
    #include "LeftView.h"
    
    
    // CLeftView
    
    IMPLEMENT_DYNCREATE(CLeftView, CTreeView)
    
    CLeftView::CLeftView() :m_tree(GetTreeCtrl())
    {
    
    }
    
    CLeftView::~CLeftView()
    {
    }
    
    BEGIN_MESSAGE_MAP(CLeftView, CTreeView)
      ON_NOTIFY_REFLECT(TVN_SELCHANGED, &CLeftView::OnTvnSelchanged)
    END_MESSAGE_MAP()
    
    
    // CLeftView 诊断
    
    #ifdef _DEBUG
    void CLeftView::AssertValid() const
    {
      CTreeView::AssertValid();
    }
    
    #ifndef _WIN32_WCE
    void CLeftView::Dump(CDumpContext& dc) const
    {
      CTreeView::Dump(dc);
    }
    #endif
    #endif //_DEBUG
    
    
    // CLeftView 消息处理程序
    
    
    void CLeftView::OnInitialUpdate()
    {
      CTreeView::OnInitialUpdate();
    
      // TODO: 在此添加专用代码和/或调用基类
      if (m_tree.GetChildItem(NULL))
        return;
      m_tree.ModifyStyle(0, TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS);
      HTREEITEM hItem = m_tree.InsertItem(_T("我的电脑"));
      char buf[100];
      DWORD len = GetLogicalDriveStringsA(sizeof(buf) / sizeof(buf[0]), buf);//获取的buf,例如c:\<null>d:\<null><null> 
      char *p = buf;
      CString str;
      while (*p)
      {
        str = p;
        int nLen = str.GetLength();
        if (nLen < 1)
          break;
        if ('\\' == str[nLen - 1])
          str = str.Left(nLen - 1);
        m_tree.InsertItem(str, hItem);
        p += nLen + 1;
      }
      m_tree.Expand(hItem, TVE_EXPAND);
    }
    
    #include "MainFrm.h"
    void CLeftView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult)
    {
      LPNMTREEVIEW p = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
      // TODO: 在此添加控件通知处理程序代码
      HTREEITEM hItem = p->itemNew.hItem;
      CString szPath;
      if (hItem != m_tree.GetRootItem())
        szPath = m_tree.GetItemText(hItem);
      CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
      pFrame->m_pRightView->Refresh(szPath);
    
      *pResult = 0;
    }

    RightView.cpp

    // RightView.cpp : 实现文件
    //
    
    #include "stdafx.h"
    #include "sp.h"
    #include "RightView.h"
    
    
    // CRightView
    
    IMPLEMENT_DYNCREATE(CRightView, CListView)
    
    CRightView::CRightView() :m_list(GetListCtrl())
    {
    
    }
    
    CRightView::~CRightView()
    {
    }
    
    BEGIN_MESSAGE_MAP(CRightView, CListView)
    END_MESSAGE_MAP()
    
    
    // CRightView 诊断
    
    #ifdef _DEBUG
    void CRightView::AssertValid() const
    {
      CListView::AssertValid();
    }
    
    #ifndef _WIN32_WCE
    void CRightView::Dump(CDumpContext& dc) const
    {
      CListView::Dump(dc);
    }
    #endif
    #endif //_DEBUG
    
    
    // CRightView 消息处理程序
    
    
    void CRightView::OnInitialUpdate()
    {
      CListView::OnInitialUpdate();
    
      // TODO: 在此添加专用代码和/或调用基类
      if (m_list.GetStyle() & LVS_REPORT)
        return;
      m_list.ModifyStyle(0, LVS_REPORT);
      m_list.InsertColumn(0, _T("名称"), 0, 120);
      m_list.InsertColumn(1, _T("大小"), 0, 120);
      m_list.InsertColumn(2, _T("类型"), 0, 120);
      m_list.InsertColumn(3, _T("修改日期"), 0, 120);
    }
    
    
    void CRightView::Refresh(CString szPath)
    {
      m_list.DeleteAllItems();
      if (szPath.IsEmpty())
        return;
      CFileFind ff;
      BOOL b = ff.FindFile(szPath + _T("/*.*"));
      int i = 0;
      while (b)
      {
        b = ff.FindNextFile();
        if (ff.IsDots())
          continue;
        m_list.InsertItem(i, ff.GetFileName());
        if (ff.IsDirectory())
          m_list.SetItemText(i, 2, _T("文件夹"));
        else
        {
          int nLen = ff.GetLength() / 1024;
          if (!nLen)
            nLen = 1;
          szPath.Format(_T("%d kb"), nLen);
          m_list.SetItemText(i, 1, szPath);
          m_list.SetItemText(i, 2, _T("文件"));
        }
        FILETIME ft;
        ff.GetLastWriteTime(&ft);
        COleDateTime time(ft);
        szPath.Format(_T("%d-%02d-%02d %02d:%02d:%02d"),
          time.GetYear(), time.GetMonth(), time.GetDay(), 
          time.GetHour(), time.GetMinute(), time.GetSecond());
        m_list.SetItemText(i, 3, szPath);
        ++i;
      }
    }

    运行结果:

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持码农之家。

    展开阅读

    上一篇:Qt学习教程之对话框消失动画效果

    下一篇:ShellExecute函数怎么使用

    相关内容

    • python提取wav文件的mfcc方法详解

      今天小编就为大家分享一篇利用python提取wav文件的mfcc方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

      06-08利用python提取wav文件的mfcc方法

      阅读更多
    • C++程序设计教程(第2版)

      C++程序设计教程(第2版)

      本书是主教材《C++程序设计教程(第二版)》的配套书。由于第二版主教材对第一版做了根本性的改动,使得本书也与第一版的《C++程序设计教程习题及解答》大相径庭。本书从习题练习出发,引导读者从机器运行的角度来思考问题,以编写出能够实战的程序代码。本书也是作者《C++程序设计教程(第二版)实验指导》一书的对照和补充。 全书突出C++编程能力培养,全局把握抽象编程观,潜窥语言和系统的内在特性,力图与同类书相区别。书中还介绍了

      大小:7.96 MBC++

      点击下载
    • 例说Visual C++ 6.0

      例说Visual C++ 6.0

      例说VisualC++6.0 丛书名:流行软件“例说”丛书 作者:冯彬 北京大学 出版日期:2000-06 VisualC++6.0是Microsoft公司推出的功能强大的Windows编程语言。本书通过大量的实例,由浅入深、循序渐进地介绍了VisualC++6.0的使用方法。首先介绍了VisualC++开发环境,然后举了一个常见的例子来说明使用VisualC++开发Windows应用程序的一般过程,接下来逐步讲述VisualC++的基本内容:MFC消息处理,图形学与绘图程序,模式对话框、无模式对话框及W

      大小:31.55 MBC++

      点击下载
    • 数据结构与算法分析(C++版/第二版)

      数据结构与算法分析(C++版/第二版)

      本书采用程序员最爱用的面向对象C+ +语言来描述数据结构和算法,并把数据结构原理和算法分析技术有机地结合在一起,系统介绍了各种类型的数据结构和排序、检索的各种方法。作者非常注意对每一种数据结构不同存储方法及有关算法进行分析比较。书中还引入了一些比较高级的数据结构与先进的算法分析技术,并介绍了可计算性理论的一般知识。本版的重要改进在于引入了参数化的模板,从而提高了算法中数据类型的通用性,支持高效的代码重用。

      大小:225 KB数据结构

      点击下载

    学习笔记

    34小时52分钟前回答

    梅尔频率倒谱系数(mfcc)及Python实现

    语音识别系统的第一步是进行特征提取,mfcc是描述短时功率谱包络的一种特征,在语音识别系统中被广泛应用。 一、mel滤波器 每一段语音信号被分为多帧,每帧信号都对应一个频谱(通过FFT变换实现),频谱表示频率与信号能量之间的关系。mel滤波器是指多个带通滤波器,在mel频率中带通滤波器的通带是等宽的,但在赫兹(Hertz)频谱内mel滤波器在低频处较密集切通带较窄,高频处较稀疏且通带较宽,旨在通过在较低频率处更具辨别性并且在较高频率处较少辨别性来模拟非线性人类耳朵对声音的感知。 赫兹频率和梅尔频率之间的关系为: 假设在梅尔频谱内,有M 个带通滤波器Hm(k),0≤mM,每个带通滤波……

    39小时5分钟前回答

    MFC列表控件CListCtrl使用方法示范

    CListCtrl 获取选中的某一行 POSITION ps = m_list.GetFirstSelectedItemPosition();int nSel = m_list.GetNextSelectedItem(ps);//选中的哪行的索引(based 0)// 或if(m_list.GetSelectedCount() 1) return;int nSel = m_list.GetSelectionMark(); CListCtrl控件失去焦点时仍保持高亮 1. 头文件中添加变量m_nSelItem int m_nSelItem; 2. 为ListCtrl控件添加NM_KILLFOCUS(失去焦点)和NM_SETFOCUS(得到焦点)消息 手动添加代码如下: 头文件中添加声明 afx_msg void OnNMKillfocusList(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnNMSetfocusList(NMHDR *pNMHDR, LRESULT *pResult); 源文件中添加映射 ON_NOTIFY(NM_KILLFOCUS, IDC_LISTCTRL, OnNMKillfocusList) ON_NOTIFY(NM_SETFOCUS, IDC_LISTCTRL, OnNMSetfocusList) 源文件中添加函数 void CPage……