学习自猎豹网校
afx_msg宏表示声明的是一个消息响应函数。
afx_msg为消息响应标志,它向系统声明,有消息映射到函数实现体。而在map宏定义中,就有具体消息和此函数的映射定义。
MFC应用程序类型
单文档 SDI +-文档/视图结构 难
多文档 MDI +-文档/视图结构 难
对话框 无 简单
多顶级文档 文档/视图结构 难
该视频内容主要针对MFC对话框。参考教材Visual C++ 实例精通
对于单文档/多文档,参考MFC windows 程序设计(第2版),微软出品
统计按钮的代码button,这里是unicode模式。
CString strInput; //MFC的字符串格式
GetDlgItemText(IDC_EDIT_INPUT,strInput);//获得指定控件的句柄,且保存数据
int nLen = strInput.GetLength(); //获得字符串长度
CString strOutput;
strOutput.Format(_T("字符串长度:%d,字符个数:%d"),nLen,nLen);//设置格式
SetDlgItemText(IDC_STATIC_OUTPUT,strOutput); //设置静态文本框输出
还可以设置多行模式MultiLine为True,就可以添加竖直或者水平滚动条
你会发现enter被计算为输入字符,并且是2个字节
如果是多字节字符集,英文为一个,汉子为2个字节。
void Clb001Dlg::OnBnClickedButtonCount()
{
// TODO: 在此添加控件通知处理程序代码
CString strInput;
GetDlgItemText(IDC_EDIT_INPUT,strInput);
int nLen = strInput.GetLength();
int nCount = 0;
for(int i = 0; i if((BYTE)strInput[i]>0x7f) //转化成BYTE-单字节;WORD-2字节;DWORD-4字节
++i; //遇到汉字,自动加1掠过
nCount++;
}
CString strOutput;
strOutput.Format(_T("字符串长度:%d,字符个数:%d"),nLen,nCount);
SetDlgItemText(IDC_STATIC_OUTPUT,strOutput);
}
4.访问对话框控件的7种方法
1.GetDlgItem()->GetWindowText()
GetDlgItem()->SetWIndowText()
2.GetDlgItemText()
SetDlgItemText()
3.GetDlgItemInt()
SetDlgItemInt()
计算器示例——方法1
void Clb002Dlg::OnBnClickedButton1()
{
int num1,num2,num3; //在文本空间输入的都是字符串(重点,需要转换)
TCHAR ch1[12],ch2[12],ch3[12];//访问和获取文本框字符串,转换成num
GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,12);//第一个参数:保存位置;第二个参数:保存位数
GetDlgItem(IDC_EDIT2)->GetWindowText(ch2,12);
//字符串转化成数字
num1 = _ttoi(ch1); //字符串转数字,默认按照10进制
num2 = _ttoi(ch2); //
num3 = num1 + num2; //num3不能在控件中显示,需要转化成字符串
_itot(num3,ch3,10); //第3个参数,按照10进制转换
GetDlgItem(IDC_EDIT3)->SetWindowText(ch3);//结果显示
}
计算器示例——方法2:直接获取控件内文本字符
void Clb002Dlg::OnBnClickedButton2()
{
int num1,num2,num3; //在文本空间输入的都是字符串(重点,需要转换)
TCHAR ch1[12],ch2[12],ch3[12];//访问和获取文本框字符串,转换成num
GetDlgItemText(IDC_EDIT1,ch1,12);
GetDlgItemText(IDC_EDIT2,ch2,12);
//字符串转化成数字
num1 = _ttoi(ch1); //字符串转数字,默认按照10进制
num2 = _ttoi(ch2); //
num3 = num1 + num2; //num3不能在控件中显示,需要转化成字符串
_itot(num3,ch3,10); //第3个参数,按照10进制转换
SetDlgItemText(IDC_EDIT3,ch3);//结果显示
}
计算器示例——方法3:直接将文本转换成数字
void Clb002Dlg::OnBnClickedButton3()
{
int num1,num2,num3;
num1 = GetDlgItemInt(IDC_EDIT1);
num2 = GetDlgItemInt(IDC_EDIT2);
num3 = num1 + num2 ;
SetDlgItemInt(IDC_EDIT3,num3);//结果显示
}
计算机示例——方法4:把控件和变量值类型相关联。
点击第一个文本框的按钮,右击——添加变量——变量名“m_num1”,类别“value”,变量类型“int”,还可以限定最大值和最小值。
设置结束后在*Dlg.cpp 生成如下代码
void Clb002Dlg::DoDataExchange(CDataExchange* pDX) //关联的代码定义
{
CDialogEx::DoDataExchange(pDX); //pDX是关联指针
DDX_Text(pDX, IDC_EDIT1, m_num1); //将变量M_num1和IDC_EDIT1相关联
DDV_MinMaxInt(pDX, m_num1, -200, 200); //最大值和最小值限制
}
对创建的变量初始化
Clb002Dlg::Clb002Dlg(CWnd* pParent /*=NULL*/)
: CDialogEx(Clb002Dlg::IDD, pParent)
, m_num1(0) //默认初始化为0
, m_num2(0)
, m_num3(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
做关联后,button4的定义:
void Clb002Dlg::OnBnClickedButton4()
{
UpdateData(TRUE);//TRUE把控件里数据关联到变量
m_num3 = m_num1 + m_num2 ;
UpdateData(FALSE);//FAULSE把变量关联到空间内
}
计算器示例–方法5:把控件和变量控件类型
右击编辑框——添加变量——类别“control”,变量类型“CEdit”,变量名“m_edit1”
新建控件变量后,在dlg.h中自动生成代码
public:
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedCancel();
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedButton3();
afx_msg void OnBnClickedButton4();
afx_msg void OnBnClickedButton5();
int m_num1;
int m_num2;
int m_num3;
CEdit m_edit1;
CEdit m_edit2;
CEdit m_edit3;
编写方法5按钮代码
void Clb002Dlg::OnBnClickedButton5()
{
int num1,num2,num3;
TCHAR ch1[12],ch2[12],ch3[12];
m_edit1.GetWindowText(ch1,12);
m_edit2.GetWindowText(ch2,12);
num1 = _ttoi(ch1);
num2 = _ttoi(ch2);
num3 = num1 + num2 ;
_itot(num3,ch3,10); //第三个参数,按照十进制转换
m_edit3.SetWindowText(ch3);
}
刚才错把ch3[12]数组定义为3,导致报错“run-time failture #3,” Stack around the variable ‘?’ was corrupted. ? 栈溢出
计算机示例——方法6:发送消息(windows核心机制)SendMessage()
直接写按钮6的代码
void Clb002Dlg::OnBnClickedButton6()
{
int num1,num2,num3;
TCHAR ch1[12],ch2[12],ch3[12];
//::代表全局函数,属于windows
//第一个参数代表获取对话框的窗口句柄,第二个参数代表消息类型,第三个参数数组大小,最后参数代表该数组
::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,12,(LPARAM)ch1);
::SendMessage(GetDlgItem(IDC_EDIT2)->m_hWnd,WM_GETTEXT,12,(LPARAM)ch2);
num1 = _ttoi(ch1);
num2 = _ttoi(ch2);
num3 = num1 + num2 ;
_itot(num3,ch3,10);
//发送消息给第三个文本框:和。
::SendMessage(GetDlgItem(IDC_EDIT3)->m_hWnd,WM_SETTEXT,0,(LPARAM)ch3);
}
发送消息的机制是重点
::SendMessage()
WPARAM,LPARAM ??
消息类型?
计算机示例——方法7:SendDlgItemMessage(),方法6的合成简化版
按钮7代码
void Clb002Dlg::OnBnClickedButton7()
{
int num1,num2,num3;
TCHAR ch1[12],ch2[12],ch3[12];
SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,12,(LPARAM)ch1);
SendDlgItemMessage(IDC_EDIT2,WM_GETTEXT,12,(LPARAM)ch2);
num1 = _ttoi(ch1);
num2 = _ttoi(ch2);
num3 = num2 + num2;
_itot(num3,ch3,10);
SendDlgItemMessage(IDC_EDIT3,WM_SETTEXT,0,(LPARAM)ch3);
}
方法1/2/3 MFC的基本方法。
方法4和5 和控件变量有关,最简单。
方法6和7 windows例的基本方法
Dlg,cpp 对话框的源码完整为:
// lb002Dlg.cpp : 实现文件
//
#include "stdafx.h"
#include "lb002.h"
#include "lb002Dlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// Clb002Dlg 对话框
Clb002Dlg::Clb002Dlg(CWnd* pParent /*=NULL*/)
: CDialogEx(Clb002Dlg::IDD, pParent)
, m_num1(0)
, m_num2(0)
, m_num3(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void Clb002Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_num1);
DDV_MinMaxInt(pDX, m_num1, -200, 200);
DDX_Text(pDX, IDC_EDIT2, m_num2);
DDX_Text(pDX, IDC_EDIT3, m_num3);
DDX_Control(pDX, IDC_EDIT1, m_edit1);
DDX_Control(pDX, IDC_EDIT2, m_edit2);
DDX_Control(pDX, IDC_EDIT3, m_edit3);
}
//控件和消息映射的定义。
BEGIN_MESSAGE_MAP(Clb002Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, &Clb002Dlg::OnBnClickedOk)
ON_BN_CLICKED(IDCANCEL, &Clb002Dlg::OnBnClickedCancel)
ON_BN_CLICKED(IDC_BUTTON1, &Clb002Dlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &Clb002Dlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, &Clb002Dlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON4, &Clb002Dlg::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON5, &Clb002Dlg::OnBnClickedButton5)
ON_BN_CLICKED(IDC_BUTTON6, &Clb002Dlg::OnBnClickedButton6)
ON_BN_CLICKED(IDC_BUTTON7, &Clb002Dlg::OnBnClickedButton7)
END_MESSAGE_MAP()
// Clb002Dlg 消息处理程序
BOOL Clb002Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void Clb002Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void Clb002Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR Clb002Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void Clb002Dlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
CDialogEx::OnOK();
}
void Clb002Dlg::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码
CDialogEx::OnCancel();
}
void Clb002Dlg::OnBnClickedButton1()
{
int num1,num2,num3; //在文本空间输入的都是字符串(重点,需要转换)
TCHAR ch1[12],ch2[12],ch3[12];//访问和获取文本框字符串,转换成num
GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,12);//第一个参数:保存位置;第二个参数:保存位数
GetDlgItem(IDC_EDIT2)->GetWindowText(ch2,12);
//字符串转化成数字
num1 = _ttoi(ch1); //字符串转数字,默认按照10进制
num2 = _ttoi(ch2); //
num3 = num1 + num2; //num3不能在控件中显示,需要转化成字符串
_itot(num3,ch3,10); //第3个参数,按照10进制转换
GetDlgItem(IDC_EDIT3)->SetWindowText(ch3);//结果显示
}
void Clb002Dlg::OnBnClickedButton2()
{
int num1,num2,num3; //在文本空间输入的都是字符串(重点,需要转换)
TCHAR ch1[12],ch2[12],ch3[12];//访问和获取文本框字符串,转换成num
GetDlgItemText(IDC_EDIT1,ch1,12);
GetDlgItemText(IDC_EDIT2,ch2,12);
//字符串转化成数字
num1 = _ttoi(ch1); //字符串转数字,默认按照10进制
num2 = _ttoi(ch2); //
num3 = num1 + num2; //num3不能在控件中显示,需要转化成字符串
_itot(num3,ch3,10); //第3个参数,按照10进制转换
SetDlgItemText(IDC_EDIT3,ch3);//结果显示
}
void Clb002Dlg::OnBnClickedButton3()
{
int num1,num2,num3;
num1 = GetDlgItemInt(IDC_EDIT1);
num2 = GetDlgItemInt(IDC_EDIT2);
num3 = num1 + num2 ;
SetDlgItemInt(IDC_EDIT3,num3);//结果显示
}
void Clb002Dlg::OnBnClickedButton4()
{
UpdateData(TRUE);//TRUE把控件里数据关联到变量
m_num3 = m_num1 + m_num2 ;
UpdateData(FALSE);//FAULSE把变量关联到空间内
}
void Clb002Dlg::OnBnClickedButton5()
{
int num1,num2,num3;
TCHAR ch1[12],ch2[12],ch3[12];
m_edit1.GetWindowText(ch1,12);
m_edit2.GetWindowText(ch2,12);
num1 = _ttoi(ch1);
num2 = _ttoi(ch2);
num3 = num1 + num2 ;
_itot(num3,ch3,10); //第三个参数,按照十进制转换
m_edit3.SetWindowText(ch3);
}
void Clb002Dlg::OnBnClickedButton6()
{
int num1,num2,num3;
TCHAR ch1[12],ch2[12],ch3[12];
//::代表全局函数,属于windows
//第一个参数代表获取对话框的窗口句柄,第二个参数代表消息类型,第三个参数数组大小,最后参数代表该数组
::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,12,(LPARAM)ch1);
::SendMessage(GetDlgItem(IDC_EDIT2)->m_hWnd,WM_GETTEXT,12,(LPARAM)ch2);
num1 = _ttoi(ch1);
num2 = _ttoi(ch2);
num3 = num1 + num2 ;
_itot(num3,ch3,10);
//发送消息给第三个文本框:和。
::SendMessage(GetDlgItem(IDC_EDIT3)->m_hWnd,WM_SETTEXT,0,(LPARAM)ch3);
}
void Clb002Dlg::OnBnClickedButton7()
{
int num1,num2,num3;
TCHAR ch1[12],ch2[12],ch3[12];
SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,12,(LPARAM)ch1);
SendDlgItemMessage(IDC_EDIT2,WM_GETTEXT,12,(LPARAM)ch2);
num1 = _ttoi(ch1);
num2 = _ttoi(ch2);
num3 = num2 + num2;
_itot(num3,ch3,10);
SendDlgItemMessage(IDC_EDIT3,WM_SETTEXT,0,(LPARAM)ch3);
}