网站配色分析,中企动力属于什么企业,手机网站素材,遵义在线论坛本专栏上几篇文章讲解了MFC几大机制#xff0c;今天带领大家学习MFC自定义消息以及常用控件#xff0c;最常用的控件请查看本专栏第一二篇文章#xff0c;今天这篇文章介绍工具栏#xff0c;菜单和状态栏#xff0c;以及菜单创建大总结。 文章目录 MFC消息分类#xff1…本专栏上几篇文章讲解了MFC几大机制今天带领大家学习MFC自定义消息以及常用控件最常用的控件请查看本专栏第一二篇文章今天这篇文章介绍工具栏菜单和状态栏以及菜单创建大总结。 文章目录 MFC消息分类菜单创建方法总结1.对话框上直接添加菜单资源2. 在WM_CREATE消息处理中加载菜单设置菜单3.框架类Create方法中创建4.使用CMenu对象创建 MFC范围宏工具栏控件状态栏控件右键消息处理总结 MFC消息分类 Windows下的常用消息标准消息 win32 WM_CREATE WM_PAINT 在Win32消息前添加ON_ WM_COMMAND 菜单按钮加速键是单独处理的 用户自定义消息 #define MY_MSG WM_USERN
用户自定义消息我们在MFC中使用通配ON_MESSAGE(ID,PFUN)也就是说
在消息映射中
BEGIN_MESSAGE_MAP(CMyFrameWdn,CFreamWnd)ON_WM_CREATE()
END_MESSAGE_MAP()而这个消息MFC早就帮我们写好了我们可以自己去看一看由于这是一个虚函数我们也可以重写
在类中
int OnCreate(LPCRATESTRUCT cs){AfxMessageBox(LWM_CREATE);return 0;
}
我们运行发现这时候WM_CREATE消息处理的时候就是我们自己写的函数了用户自定义消息 首先我们需要去定义宏我们自定义消息 #define MY_MSG WM_USER1 用户自定义消息MFC已经帮我们写好了统配消息映射ON_MESSAGE() 接下来我们来看看官方定义
#define ON_MESSAGE(message, memberFxn) \{ message, 0, 0, 0, AfxSig_lwl, \(AFX_PMSG)(AFX_PMSGW) \(static_cast LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM) \(memberFxn)) },那么我们就可以自己定义函数
首先设置签名 afx_msg LRESULT onMyMsg(WPARAM,LPARAM);实现
LRESULT CMenuToolBarDlg::onMyMsg(WPARAM W,LPARAM L)
{AfxMessageBox(LMy_Msg);return 0;
}
这里就弹一个消息框 3. 我们发送消息看看
int CMenuToolBarDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{if (CDialogEx::OnCreate(lpCreateStruct) -1)return -1;// TODO: 在此添加您专用的创建代码AfxMessageBox(LonCreate);SendMessage(MY_MSG, 0, 0);return 0;
}这里是重写了Create函数发送了我们自定义的消息
菜单创建方法总结
之前几篇文章中我们已经讲解过了好几种加载菜单的方法今天我们来总结一下
1.对话框上直接添加菜单资源
这种方法可谓是非常简单了直接在对话框属性上添加菜单MFC会自动帮我们生成代码 首先我们创建菜单资源 然后到对话框属性中设置就可以了 这样就算设置好了我们运行 我们发现对话框已经创建好了
2. 在WM_CREATE消息处理中加载菜单设置菜单
int CMenuToolBarDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{if (CDialogEx::OnCreate(lpCreateStruct) -1)return -1;// TODO: 在此添加您专用的创建代码HMENU hMenu LoadMenu((HINSTANCE)GetWindowLongPtr(m_hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDR_MENU1));::SetMenu(m_hWnd, hMenu);return 0;
}这样运行之后我们发现菜单也创建出来了
3.框架类Create方法中创建
我们前面在介绍MFC几大机制的时候介绍了框架类我们使用框架类的Create方法也可以创建菜单 基本使用方法就是CFRame::Create(…);
4.使用CMenu对象创建
int CMenuToolBarDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{if (CDialogEx::OnCreate(lpCreateStruct) -1)return -1;// TODO: 在此添加您专用的创建代码CMenu menu;menu.LoadMenuW(IDR_MENU1);this-SetMenu(menu);return 0;
}使用CMenu这种方法也可以创建菜单但是创建了菜单之后点击之后会崩溃 这里我创建的MFC是基于对话框的之前在基于单文档架构的时候会崩溃 这是应为CMenu对象被析构 解决方法在类中声明CMenu成员new出来这样就不会被析构 我们首先声明成员CMenu* menu new CMenu; 这样时候我们函数这样写
int CMenuToolBarDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{if (CDialogEx::OnCreate(lpCreateStruct) -1)return -1;// TODO: 在此添加您专用的创建代码menu-LoadMenuW(IDR_MENU2);this-SetMenu(menu);return 0;
}这样创建就没有问题了。
MFC范围宏
我们在处理按钮或者菜单消息等的时候我们有时候有这种需求连续几个按钮都有着相同的回调方法这时候我们就可以使用范围宏
首先我们来创建这样一个菜单 我们将这三个菜单ID设置为连续我这里是322733227432275 我们到消息映射中使用范围宏来处理 我们首先来看一下范围宏的定义
#define ON_COMMAND_RANGE(id, idLast, memberFxn) \{ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)idLast, AfxSigCmd_RANGE, \(AFX_PMSG) \(static_cast void (AFX_MSG_CALL CCmdTarget::*)(UINT) \(memberFxn)) },我们到消息映射中添加
ON_COMMAND_RANGE(ID_32773,ID_32775,onRangle)然后我们定义回调函数
void CMenuToolBarDlg::onRangle(UINT id)
{CString str;str.Format(L按钮id %d, id);AfxMessageBox(str);
}
这样我们就可以统一处理这三个按钮了
工具栏控件
我们到资源中创建工具栏对象 然后我们加载工具栏 首先我们要在类中声明CToolBar成员 CToolBar toolBar 然后到Create函数中加载工具栏 if (!toolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS) || !toolBar.LoadToolBar(IDR_TOOLBAR1)){ AfxMessageBox(TEXT(Failed to create toolbar!), NULL, NULL);return FALSE;}m_toolBar.EnableDocking(CBRS_ALIGN_ANY);this-EnableDocking(CBRS_ALIGN_ANY);this-DockControlBar(m_toolBar,AFX|IDW_DOCKBAR_TOP);很多软件的提示栏我们鼠标移动到上面的时候都有提示信息我们也可以到工具栏的按钮上面添加提示信息 比如紫色\n按钮 \n之前的信息会出现在状态栏上之后的信息我们鼠标移动到上面的时候会直接显示.
状态栏控件
状态栏控件我们不需要添加资源直接在创建窗口的时候加载就可以了
类中添加成员
SCtatusBar statusBar;onCreate消息中
statusBar.CreateEx(this);我们发现状态栏只有一项如果我们想添加就要定义一个全局数组 UNIT g_arr[] {0,ID_TIME,2,}; 我们再来设置
指示器
statusBar.SetIndicators(g_arr,3);
//ID---表示字符串
statusBar.SetPaneInfo(1,ID_TIMESBPS_NORMAL,100);这时候就发现可以分项了。 我们来处理一下状态栏 我们设置系统时间到状态栏上 消息映射
ON_WM_TIMER()void CMenuToolBarDlg::OnTimer(UINT_PTR id)
{SYSTEMTIME time;::GetLocalTime(time);CString str;str.Format(L%d-%d-%d %d:%d:%d, time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);staubar.SetPaneText(1, str);
}右键消息处理
以前我们处理右键单击消息都是通过消息来处理的今天我来带领大家使用MFC的另一种方式 消息映射
N_WM_CONTEXTMENU()处理
void onContextMenu(CWnd*,CPoint pt){CMenu menu;menu.LoadMenu(IDR_MENU1);CMenu* pPopMenu menu.GetSubMenu(0);::tRACKpOPUPmENU(PpOPmENU-m_hMenu,TPM_CENTERALIGN,pt.x,pt.y,0,this-hWnd,NULL);;
}
我们通常使用右键来弹出右键菜单这里介绍一种方式弹出右键菜单的时候可以初始化
void onInitMenuPopup(CMenu* pMenu,UINT,BOOL){::CheckMenuItem(pMenu-m_hMenu,ID_DEL,MF_CHECKED);
}总结
最后总结一下容易出现的误区
我们使用MFC消息映射的时候很多时候都需要我们自己写函数但是很多时候我们会写错不知道参数该些什么返回值该写什么实际上我们查看宏定义就是消息映射上的宏就可以看到函数名称返回值参数等或者我们再定义宏的时候可以在括号里写上消息ID和回调函数就可以解决上述问题 好了今天的分享就到这里大家如果发现有什么错误还请及时指出来我们大家共同进步