一MFC菜单
1 MFC菜单相关类
CMenu类 -封装HMENU句柄,及相关的菜单的API函数.
2 菜单的用法
再来建一遍项目吧(还没到想吐的地步)
|
1.
| ||||
|
2.
| ||||
|
3.修改stdafx.h头文件,将#include <Windows.h> 改成#include <afxwin.h> | ||||
|
4.
| ||||
|
5.删掉MFCMenu.cpp文件中的WinMain()函数 | ||||
|
6.添加资源脚本文件
| ||||
|
7.在资源视图中,添加一个菜单资源IDR_MAINFRM
| ||||
|
8.设计菜单资源
| ||||
|
9.编译当前项目。会生成一个resource.h的文件。将它添加到项目中。 |
准备工作做好之后,开始进入程序编写。
转到MFCMenu.cpp文件中,按照之前的步骤,添加theApp之类的东西。注意引用resource.h头文件。
|
// MFCMenu.cpp : Defines the entry point for the application. //
#include "stdafx.h" #include "resource.h"
class CMenuFrame : public CFrameWnd { DECLARE_MESSAGE_MAP( ) public: afx_msg void OnExit( ); };
BEGIN_MESSAGE_MAP( CMenuFrame, CFrameWnd ) ON_COMMAND( ID_EXIT, OnExit ) END_MESSAGE_MAP( )
void CMenuFrame::OnExit( ) { PostQuitMessage( 0 ); }
class CMenuApp : public CWinApp { public: virtual BOOL InitInstance( ); };
CMenuApp theApp;
BOOL CMenuApp::InitInstance( ) { CMenuFrame * pWnd = new CMenuFrame( ); //创建一个带菜单的Frame窗口 pWnd->Create( NULL, "MenuApp", WS_OVERLAPPEDWINDOW, CFrameWnd::rectDefault, NULL, MAKEINTRESOURCE(IDR_MAINFRM) ); m_pMainWnd = pWnd; m_pMainWnd->ShowWindow( SW_SHOW ); m_pMainWnd->UpdateWindow( );
return TRUE; } |
3.其他
前面写的DECLARE_MESSAGE_MAP之类的宏都是写在CFrameWnd(继承自CWnd)中的,可不可以写在CMenuApp(继承自CWinApp)中呢?
答案是可以的。他们都继承自CCmdTarget这个类。这个类封装了消息映射的所有公共的东西,是“命令的终点”。
只要是继承CCmdTarget的子类,都可以添加消息映射机制.
这样的话,我们就可以修改一下代码,增加一个菜单项,用CMenuApp来响应
|
1.增加关于菜单项
| ||||
|
2.修改代码
|
二 工具栏
1 MFC工具栏相关的类
|
CToolBar - 父类是CControBar,提供了与框架窗口相关的支持。 |
|
CToolBarCtrl - 父类是CWnd,对Win32下的Toolbar控件进行封装。 |
在MFC程序当中,一般使用CToolBar创建工具栏,如果要进更多工具栏的操作,需要使用CToolBar的GetToolBarCtrl函数获取该工具栏的CToolBarCtrl类。
又来写MFC程序吧。之所以不直接创建一个MFC应用程序,是为了远离向导,这样可以更清楚地明白向导都干嘛了。
|
| ||||
|
| ||||
|
修改stdafx.h头文件,将#include <Windows.h> 改成#include <afxwin.h> | ||||
|
| ||||
|
删掉MFCToolBar.cpp文件中的WinMain()函数 | ||||
|
添加资源脚本文件
| ||||
|
在资源视图中,添加一个菜单资源IDR_MAINFRM
| ||||
|
设计菜单资源
| ||||
|
编译当前项目。会生成一个resource.h的文件。将它添加到项目中。 |
准备工作完毕。
接下来转到MFCToolBar.cpp文件中,按照之前的步骤,添加theApp之类的东西。注意引用resource.h头文件。
|
// MFCToolBar.cpp : Defines the entry point for the application. //
#include "stdafx.h" #include "resource.h"
class CToolBarFrame : public CFrameWnd { public: };
class CToolBarApp : public CWinApp { public: virtual BOOL InitInstance( ); };
CToolBarApp theApp;
BOOL CToolBarApp::InitInstance( ) { CToolBarFrame * pWnd = new CToolBarFrame( ); pWnd->Create( NULL, "ToolBarApp", WS_OVERLAPPEDWINDOW, CFrameWnd::rectDefault, NULL, MAKEINTRESOURCE(IDR_MAINFRM) ); m_pMainWnd = pWnd; m_pMainWnd->ShowWindow( SW_SHOW ); m_pMainWnd->UpdateWindow( ); return TRUE; } |
下一步,为CToolBarFrame类添加消息映射
|
// MFCToolBar.cpp : Defines the entry point for the application. //
#include "stdafx.h" #include "resource.h"
class CToolBarFrame : public CFrameWnd { DECLARE_MESSAGE_MAP( ) public: afx_msg void OnExit( ); };
BEGIN_MESSAGE_MAP( CToolBarFrame, CFrameWnd ) ON_COMMAND( ID_EXIT, OnExit ) END_MESSAGE_MAP( )
void CToolBarFrame::OnExit( ) { PostQuitMessage( 0 ); }
class CToolBarApp : public CWinApp { public: virtual BOOL InitInstance( ); };
CToolBarApp theApp;
BOOL CToolBarApp::InitInstance( ) { CToolBarFrame * pWnd = new CToolBarFrame( ); pWnd->Create( NULL, "ToolBarApp", WS_OVERLAPPEDWINDOW, CFrameWnd::rectDefault, NULL, MAKEINTRESOURCE(IDR_MAINFRM) ); m_pMainWnd = pWnd; m_pMainWnd->ShowWindow( SW_SHOW ); m_pMainWnd->UpdateWindow( ); return TRUE; } |
创建工具栏。在OnCreate函数中创建,因此,需要加WM_CREATE消息响应。
|
// MFCToolBar.cpp : Defines the entry point for the application. //
#include "stdafx.h" #include "resource.h"
class CToolBarFrame : public CFrameWnd { DECLARE_MESSAGE_MAP( ) public: afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct ); afx_msg void OnExit( ); };
BEGIN_MESSAGE_MAP( CToolBarFrame, CFrameWnd ) ON_WM_CREATE( ) ON_COMMAND( ID_EXIT, OnExit ) END_MESSAGE_MAP( )
int CToolBarFrame::OnCreate( LPCREATESTRUCT lpCreateStruct ) { CFrameWnd::OnCreate( lpCreateStruct );
return 1; }
void CToolBarFrame::OnExit( ) { PostQuitMessage( 0 ); }
class CToolBarApp : public CWinApp { public: virtual BOOL InitInstance( ); };
CToolBarApp theApp;
BOOL CToolBarApp::InitInstance( ) { CToolBarFrame * pWnd = new CToolBarFrame( ); pWnd->Create( NULL, "ToolBarApp", WS_OVERLAPPEDWINDOW, CFrameWnd::rectDefault, NULL, MAKEINTRESOURCE(IDR_MAINFRM) ); m_pMainWnd = pWnd; m_pMainWnd->ShowWindow( SW_SHOW ); m_pMainWnd->UpdateWindow( ); return TRUE; } |
下面在OnCreate中创建工具栏。
创建工具栏的步骤如下:
|
1 添加工具栏资源 在资源视图中,添加一个ToolBar资源,重命名为IDR_MAINFRM
然后在右边的编辑器上随便画一些什么
双击编辑器画面,修改按钮ID为ID_EXIT。和菜单项的ID一样。 | ||
|
2 添加CToolBar 创建工具栏 --Create或CreateEx创建工具栏 加载工具栏资源 --LoadToolBar加载工具栏资源.
CToolBar的头文件是afxext.h |
当前运行界面如下图

工具栏的停靠
|
1 工具栏本身支持停靠 CToolBar::EnableDocking |
|
2 框架窗口支持停靠 CFrameWnd::EnableDocking |
|
3 停靠工具栏 CFrameWnd::DockControlBar |
|
4 工具栏的显示和关闭 CFrameWnd::ShowControlBar |
编写代码如下:
|
int CToolBarFrame::OnCreate( LPCREATESTRUCT lpCreateStruct ) { CFrameWnd::OnCreate( lpCreateStruct );
//创建ToolBar if( FALSE == m_wndToolBar.Create( this ) { return 1; } //加载工具栏资源 m_wndToolBar.LoadToolBar( IDR_MAINFRM ); //工具栏支持停靠 m_wndToolBar.EnableDocking( CBRS_ALIGN_ANY ); //FrameWnd支持停靠 EnableDocking( CBRS_ALIGN_ANY ); //停靠工具栏 DockControlBar( &m_wndToolBar );
return 1; } |
从上面的运行界面图可以看到工具条上面有个黑边,不太好看。可以用PreCreateWindow()来修改窗口的属性,将框架窗口的客户区黑边去掉。
|
class CToolBarFrame : public CFrameWnd { public: virtual BOOL PreCreateWindow( CREATESTRUCT& cs );
DECLARE_MESSAGE_MAP( ) public: afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct ); afx_msg void OnExit( );
public: //工具栏成员变量 CToolBar m_wndToolBar; };
BEGIN_MESSAGE_MAP( CToolBarFrame, CFrameWnd ) ON_WM_CREATE( ) ON_COMMAND( ID_EXIT, OnExit ) ON_COMMAND( ID_ABOUT, OnAbout ) ON_COMMAND( ID_VIEW_STDBAR, OnViewStdBar ) END_MESSAGE_MAP( )
BOOL CToolBarFrame::PreCreateWindow( CREATESTRUCT& cs ) { CFrameWnd::PreCreateWindow( cs );
cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
return TRUE; } |
有的工具栏左边有一个突起的竖线,比较好看,这个可以用CToolBar的CreateEx()函数创建一个这样的风格
|
int CToolBarFrame::OnCreate( LPCREATESTRUCT lpCreateStruct ) { CFrameWnd::OnCreate( lpCreateStruct );
//创建ToolBar if( FALSE == m_wndToolBar.CreateEx( this, TBSTYLE_FLAT, WS_CHILD|WS_VISIBLE|CBRS_ALIGN_TOP|CBRS_GRIPPER ) ) { return 1; } //加载工具栏资源 m_wndToolBar.LoadToolBar( IDR_MAINFRM ); //工具栏支持停靠 m_wndToolBar.EnableDocking( CBRS_ALIGN_ANY ); //FrameWnd支持停靠 EnableDocking( CBRS_ALIGN_ANY ); //停靠工具栏 DockControlBar( &m_wndToolBar );
return 1; } |
工具栏的显示和关闭
ShowControlBar()
|
添加一个菜单项,用来显示和关闭工具栏
| ||
|
添加命令处理
|
菜单\工具栏按钮状态和提示信息
|
1 添加状态处理函数 afx_msg void XXXXX( CCmdUI * pCmdUI ); | |||
|
2 添加消息映射宏 ON_UPDATE_COMMAND_UI | |||
|
3 在状态处理函数设置菜单或工具栏按钮状态 使用CCmdUI提供的成员函数,可以修改状态
| |||
|
当前运行时,工具栏菜单项前面就会有一个勾了
| |||
|
接下来使工具栏图标按下去后出现按下的效果。 添加一个工具栏图标(黑色那只。中间的问号按钮我没用,它是教程里面拿来示例的,没有实际作用) 命名为ID_CHECK
| |||
|
菜单上也加一个菜单项 同样命名为ID_CHECK
| |||
|
添加他们的消息处理函数
| |||
|
运行效果如图
| |||
|
4 给工具栏显示Tooltip提示信息
|
三 状态栏
1 MFC状态栏相关类
|
CStatusBar - 父类是CControBar,提供了与框架窗口相关的支持. |
|
CStatusBarCtrl - 父类是CWnd,对Win32下的Statusbar控件进行封装。 |
在MFC程序中,通常使用CStatusBar.
2 状态栏的使用
|
1 创建状态栏 CStatusBar::Create/CreateEx |
|
2 设置指示器(每一个面版就是一个指示器) CStatusBar::SetIndicators |
|
3 设置和显示信息 CStatusBar::GetPaneText CStatusBar::SetPaneText |
|
4 可以使用自定义的字符串ID作为状态栏的指示器. 只需将字符串的资源ID添加到指示器 |
按照之前的步骤,重新创建一个Win32应用程序MFCStatusBar
环境改好之后,进入MFCStatusBar.cpp文件中,编写代码
|
// MFCStatusBar.cpp : Defines the entry point for the application. //
#include "stdafx.h"
UINT g_nIndicator[] = { ID_SEPARATOR, ID_SEPARATOR, ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_OVR };
class CStatusBarFrame : public CFrameWnd { DECLARE_MESSAGE_MAP() public: afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );
public: //状态栏成员变量 CStatusBar m_wndStatusBar; };
BEGIN_MESSAGE_MAP( CStatusBarFrame, CFrameWnd ) ON_WM_CREATE( ) END_MESSAGE_MAP( )
int CStatusBarFrame::OnCreate( LPCREATESTRUCT lpCreateStruct ) { CFrameWnd::OnCreate( lpCreateStruct );
//创建状态栏 m_wndStatusBar.Create( this ); //设置指示器 m_wndStatusBar.SetIndicators( g_nIndicator, sizeof(g_nIndicator)/sizeof(UINT)); //显示字符串 m_wndStatusBar.SetPaneText( 1, "我的状态栏", TRUE ); return 1; }
class CStatusBarApp : public CWinApp { public: virtual BOOL InitInstance( ); };
CStatusBarApp theApp;
BOOL CStatusBarApp::InitInstance( ) { CStatusBarFrame * pWnd = new CStatusBarFrame(); pWnd->Create( NULL, "StatusBar" ); m_pMainWnd = pWnd; m_pMainWnd->ShowWindow( SW_SHOW ); m_pMainWnd->UpdateWindow( );
return TRUE; } |
运行结果

PS:前面长长的空白就是第0个指示器。这个是被框架窗口占用了,用来显示工具栏的提示信息。
下面加个菜单项,再加一个显示时间的状态栏
|
添加资源脚本 | |
|
添加一个菜单资源 | |
|
编译一下,并将resource.h头文件包含进项目 | |
|
MFCStatusBar.cpp中写代码:
|
本文介绍了MFC中菜单和工具栏的实现方法,包括菜单和工具栏的创建、使用及自定义。详细讲解了如何通过CMenu和CToolBar类进行菜单项响应和工具栏的停靠操作。



![计算机生成了可选文字: 绝/,x一『l剑一.一拐为一,照尹口户华~’一”、.由口“'"'"'卜t.rt卜oJ.ct自哆日口11tG'oba'Sj电巳公,卜:ld1001,岌云nd,廿.lp吧国官叭…~ndP『ocBase日的下到阵:9.oba.memoe,:习今W1nMain习\,公日件即窗宝和冲嘎0参幽占!戴右叼Wol·ksp·孝C111dMs曰留MFCM(日口50111'固MF(固5tC日。I}ead正在共享FileSProjeds1Workspacesothe『DOCtlmentS!一阅ACtiveSe陇rPage习日ina甲rile川8itmapFIIe函CIC++HeadelFIIe函C++Sour二FIIe份CursorFIIe因HTMLPage一、IconFile口创dtoproiect:陌rCMen。FileResourceScr西pt不亏丽花厄了而下SOLScriptFIIeTeXtFi!eateLo'ation:D:、MFC、day02、codes、MFCMenu国5tJ}鲁日l+}砂困覃aReSC国Rea(]二ExteReg15W11dMS一一一一口…匡三三习一竺竺口l](https://i-blog.csdnimg.cn/blog_migrate/fc3266e73ce9d7cad2a39f103d79c12b.png)



















2802

被折叠的 条评论
为什么被折叠?



