IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> MFC菜单(笔记) -> 正文阅读

[C++知识库]MFC菜单(笔记)

一、菜单的分类

菜单属于框架。

从资源视图进入下图

?弹式菜单:点击后弹出菜单项。其ID无法编辑,Popup属性为True。

?非弹式菜单:无法弹出菜单选项。其ID可编辑,?Popup属性为False

二、菜单响应命令路由

新建一弹式菜单,并为其设置一非弹式菜单Demo

为Demo添加一事件处理程序

依次为应用、框架、文档、视图添加处理程序。

并分别为其添加一个消息框(由于一些类没有MessageBox,因而用全局的)?

void CMFC程序App::OnTestDemo()
{
	// TODO: 在此添加命令处理程序代码
    AfxMessageBox(TEXT("APP"));
}
void CMainFrame::OnTestDemo()
{
	// TODO: 在此添加命令处理程序代码
	AfxMessageBox(TEXT("Frame"));
}
void CMFC程序Doc::OnTestDemo()
{
	// TODO: 在此添加命令处理程序代码
	AfxMessageBox(TEXT("DOC"));
}
void CMFC程序View::OnTestDemo()
{
	// TODO: 在此添加命令处理程序代码
	MessageBox(TEXT("View"));
}

?而后验证,

?直接点击弹出view。

?注释view部分相关处理程序后,再次点击。

同理,注释文档部分,点击。

在注释框架部分,点击。

然而实际并不是如此。

实际路由情况:?

frame首先接收到,但是不处理->view处理了则中断。未处理->doc处理了则中断。未处理->view

->frame处理了则中断。未处理->app处理(不处理则该按钮为灰色,无法点击)

三、消息分类

命令消息:WM_COMMAND,只有菜单中才有。菜单处理函数选中

标准消息:WM_XXXX,属性->消息。CWnd子类才能接收到标准消息。

通告消息:点击控件,执行处理函数。


CWnd:可以接受任何消息。

CCmdTarget:不能接收标准消息。

四、菜单的静态操作

菜单栏的静态操作可分为:禁用(灰色)、选中(打勾)、默认项(加粗)。

为了方便,本次让框架类处理事件,并在其OnCreate方法中修改让其启动就触发。

选中

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		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);

	//获取菜单
	CMenu* menu = GetMenu();
	//获取子菜单
	CMenu* fileMenu = menu->GetSubMenu(0);//GetMenu属于CWnd,从0开始指代每一个菜单子菜单。此处获取第一栏
	//标志“新建”
	//参数,怎么确定的参数(位置、ID等)|标志该项目
	//此处通过位置确定
	fileMenu->CheckMenuItem(0, MF_BYPOSITION | MF_CHECKED);
	//标志“打开”
	//参数,怎么确定的参数(位置、ID)|标志该项目
	//此处通过ID确定
	fileMenu->CheckMenuItem(ID_FILE_OPEN, MF_BYCOMMAND | MF_CHECKED);

	return 0;
}

默认项

一个菜单项只有一个默认项

//设置默认项,一个菜单项只有一个默认项
	//默认项“保存”
	//参数,怎么确定的参数(TRUE:位置,FALSE:ID)
	//此处通过位置确定
	fileMenu->SetDefaultItem(2, TRUE);

禁用

MF_DISABLED:菜单项无效,但不变灰。

MF_GRAYED:菜单项无效,但变灰。

新版本中,MF_DISABLED与?MF_GRAYED无区别,都会变灰。

首先需要将CFrameWnd::m_bAutoMenuEnable设置FALSE,避免它内部自动更新。与构造函数总设置。

CMainFrame::CMainFrame() noexcept
{
	// TODO: 在此添加成员初始化代码
	m_bAutoMenuEnable = FALSE;
}
	//设置禁用项
	//首先需要将CFrameWnd::m_bAutoMenuEnable设置false
	//禁用“另存为”
	//参数,怎么确定的参数(位置、ID)|禁用该项目

	fileMenu->EnableMenuItem(3, MF_BYPOSITION|MF_DISABLED);
	//禁用“打印”,分隔符要占位
	fileMenu->EnableMenuItem(5, MF_BYPOSITION | MF_GRAYED);

五、菜单项的替换

OnCreate中,通过SetMenu(NULL)即可移除菜单栏。

现在对MFC.rc中Menu文件夹插入新的Menu。

为其设置新的窗口内容,记住其ID。

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		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);

	//移除菜单项目
	SetMenu(NULL);
	CMenu menu2;
	//加载菜单
	menu2.LoadMenuW(IDR_MENU1);//输入菜单ID
	SetMenu(&menu2);
	//Detach():将对象从Windows菜单CMenu中分离,并返回句柄。
	//使得该对象不会随着该函数结束后一同被消除
	menu2.Detach();
	return 0;
}

此处注意,分离后的对象不再是menu2,只是一串存放着有效数据的地址(但仍被程序所知晓,能够通过GetMenu()重新获取)。menu2中原本存放该对象处已为空,因而在其被销毁时不会连累到对象。

执行Detach()前?:

执行Detach()后:

结果如图:

六、菜单的更新

通过下面方式,给a与b添加处理程序(类型不同)。

为Frame添加变量

记得初始化:

CMainFrame::CMainFrame() noexcept
{
	// TODO: 在此添加成员初始化代码
	m_bAutoMenuEnable = FALSE;
	m_isUpdate = false;
}

而后输入代码为:?

void CMainFrame::OnUpdateTestA(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	if (true == m_isUpdate) {
		pCmdUI->Enable(TRUE);
	}
	else {
		pCmdUI->Enable(FALSE);
	}

}


void CMainFrame::OnTestB()
{
	// TODO: 在此添加命令处理程序代码
	m_isUpdate = !m_isUpdate;
}

七、右键点击唤出菜单

为view准备事件鼠标右键按下。

void CMFC程序View::OnRButtonDown(UINT nFlags, CPoint point)//鼠标标志以及点击的坐标
{	//由于菜单是属于框架的,因而要单独为view创建一个
	CMenu menu;
	//载入需要的菜单
	menu.LoadMenuW(IDR_MENU1);
	CMenu* subMenu = menu.GetSubMenu(0);
	//将客户区域坐标转换为屏幕坐标(左上角原点)。因为弹窗坐标是以屏幕为单位
	ClientToScreen(&point);
	//标志位(设置鼠标在弹出菜单的位置,通过屏幕位置标志与鼠标键标志组合),
	//坐标x,坐标 y,属于哪一个窗口,对齐方式(TRUE,则菜单按从右到左的阅读顺序右对齐;FALSE,则菜单为从左到右的阅读顺序左对齐)
	//此处为鼠标在左侧,右键点击,去点击坐标,当前窗口,默认值FALSE
	subMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
	CView::OnRButtonDown(nFlags, point);
}

结果

八、动态图标

如图添加资源,导入ICON

笔者用的是256*256的ico图片。

由于菜单,标题属于框架,因此,为框架准备存储ICON的变量。

?

完成构造函数中的初始化。

通过AfxGetApp获得程序实例(因为构造函数初始化时,还没有创建窗口)

CMainFrame::CMainFrame() noexcept
{
	//AfxGetApp获得应用程序实例
	icon[0] = AfxGetApp()->LoadIconW(IDI_ICON1);
	icon[1] = AfxGetApp()->LoadIconW(IDI_ICON2);
}

?随后为其添加定时器。并在create事件中为其开始计时。


void CMainFrame::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//窗口句柄,修改什么,用什么修改
	//当前窗口的句柄,修改图标,图片
	//m_hWnd(自带)指明与这个CWnd对象相关联的句柄
	static int i = 0;
	i = i % 2;
	SetClassLong(m_hWnd, GCL_HICON,(LONG)icon[i]);
	i++;
	CFrameWnd::OnTimer(nIDEvent);
}

结果:

?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-26 09:58:18  更:2021-09-26 10:01:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 4:00:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计