前言

类向导是非常好用的工具,学会了他,我们可以减少很多不必要的麻烦,我就结合着按钮和编辑框控件的使用来说了。我们为啥要知道类向导在帮我们做什么,因为我们在这里出问题了,这样按照这个思路找到对应的解决办法。或者我们要删除类向导给我们添加的东西我们知道在哪里删除!

按钮类 CButton

官方说明文档
详细见官方说明文档,我这里说一下常用的,按钮有好多种的啦,我们这里说最基础的类CButton

简单属性

按钮上显示的字

在属性栏里修改这caption就可修改按钮上的字啦
image.png

给按钮起一个合适的名字

写程序的时候,名字乱了就很讨厌,我们起名字的基本要求就是一眼可以看出他是哪个控件作用是啥,我个人的习惯是 IDC_控件的简写_用途
image.png
image.png

给按钮添加事件

右键添加事件

image.png
重命名的啥我就不用说了

类向导此时帮你做了什么?

类向导就是帮你免去了添加一些消息映射的宏处理之类的

  1. 声明DECLARE_MESSAGE_MAP()
    DECLARE_MESSAGE_MAP()是个宏定义,是说明这个类支持消息映射,这种宏处理我们还会遇到很多,比如说支持序列化技术之类的。
  2. 声明消息处理函数(在对于的头文件里)
    image.png
    其中 afx_msg为消息标志,它向系统声明:有消息映射到函数实现体,这是写MFC的大牛写上去的。
  3. 添加消息映射(在对于的cpp文件里面)
    image.png
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
//消息
END_MESSAGE_MAP()

这个也是一个宏处理,其实这短短的三行,是这么多行代码

const AFX_MSGMAP* theClass::GetMessageMap() const 
{ 
	return &theClass::messageMap; 
} 
const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() 
{ 
	return &baseClass::messageMap; 
}
AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = 
{ 
	&baseClass::messageMap,				//基类路由信息指针
        &theClass::_messageEntries[0]		       //路由表数组地址
}; 
 
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = 
{ 
	{WM_COMMAND,N_COMMAND,(WORD)id,(WORD)id,AfxSig_vv,(AFX_PMSG)&memberFxn },
	{0, 0, 0, AfxSig_end, (AFX_PMSG)0 } 
};

看不同吧,没关系我也看不懂,知道这里是消息映射就好啦,这种底层知识得深入了解才可以明白,为哈要这个样子。不得不佩服大牛在那个年代已经有那么先进的设计思想!!!

我们只需在对于位置上写上消息处理的语句就好了

void CTest1Dlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	MessageBox(L"MFC真有趣");
}

image.png

编辑框

说明文档

一些属性

你只想让他输入数字就可以修个这个属性为true

image.png

如何获取文本框里的文字

简答的方法(高级一点的方法在后续一节补充)

添加与他关联的值
这样的好处就是,1.简单 2.假如这个对话框关闭了我可以用这个变量继续获取它里面存的值

  1. 打开类向导 添加值变量
    image.png
    image.png

配合UpdateData(),可以做到在修改编辑框的时候其实也在修改与之关联的变量,updateData建立一个我们的对于CExchange对象,然后调用DoDataExchange()函数交换数据。

  • UpdateData(true)
    把控件里的数据交换到我们关联的变量里面
  • UpdateData(false)
    将关联的变量的数据交换到控件里面

类向导在帮我们做什么

  1. 在类的声明里面声明该变量image.png
  2. 声明一个MFC交换数据的虚函数 DoDataExchange image.png
  3. 在dotataExchange里面加入交换数据的语句
    image.png

至于何时交换数据,这个编译器可帮你想不到,根据自己的需求调用UpdateData吧

如何处理鼠标单击的消息

  1. 打开类向导
    注意一定要在对应的类里面添加别添加到别的窗口里面了 image.png
  2. 添加对于消息函数
    image.png
void CTest1Dlg::OnLButtonDblClk(UINT nFlags, CPoint point)

着重介绍一下参数

  • nFlags 表示控制键状态(包括 ctrl,shift,鼠标左、中、右 共5个键的状态)我们可以通过和这个来判断同时我们按下了那些按键
    MK_CONTROL CTRL键被按下
    MK_LBUTTON 鼠标左键bai被按下
    MK_MBUTTON 鼠标中键被按下
    MK_RBUTTON 鼠标右du键被按下
    MK_SHIFT shift键被按下
  • point表示鼠标坐标。(相对于当前窗口而言的坐标)
  1. 写一些处理函数

类向导在帮我们干什么

  1. 声明消息处理函数
    afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
  2. 在前面的BEGIN_MESSAGE_MAP宏处理里面添加消息处理函数
    image.png
  3. 帮我们写一下定义的框架

自定义消息

image.png
我在写简单计算器的时候就需要自定义一个消息处理函数,刚好我放在这里说一下,加深一下印象。

处理特别的消息---连续消息的事件

我在写计算器的时候想写一个能够对我按下那个按钮的来做处理的函数(如果我每个按钮来都写一个函数来处理,是不是就太烦锁了),所以我可以写一个消息映射函数 afx_msg Onnumberkey(UINT nID);

当然在前面加是上afx_msg是远远不够的,我们还需要在这个宏处理上加入这一段

BEGIN_MESSAGE_MAP(CCalculatorDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
//上面的是系统帮我们添加的
	ON_COMMAND_RANGE(IDC_BUTTON1, IDC_BUTTON10, OnNumberKey)
	ON_COMMAND_RANGE(IDC_BUTTON11, IDC_BUTTON20, OnOperationKey)
END_MESSAGE_MAP()

ON_COMMAND_RANGE

ON_COMMAND_RANGE( id1, id2, memberFxn )
使用这个宏把一个连续范围的命令ID映射到单个命令处理函数。ID的范围从id1开始,到id2结束。
ON_COMMAND_RANGE把一个范围的命令ID映射到一个成员函数。用ON_COMMAND把单个命令ID映射到成员函数。每个给定的命令ID只能有一个消息映射入口。这就是说,不能把命令映射到多于一个的处理函数。关于映射消息范围的更多信息参见Visual C++程序员指南”中的“消息映射范围的处理函数
当然这里我们需要消息的id是连续的,那消息的id是多少呢,咋看?在Resource.h里面!
image.png
值得强调的是你需要你设置的按钮id 连续,这个id 的先后是根据你新建按的顺序的先后决定的。
没事干就不要定义消息id<1000的消息了,因为已经被windows自己用了!!!

结语

好辛苦哇,大家可以评论支持一下吗?
微信小程序

努力成长的程序员