1. Button 按钮控件
1.1、按钮控件的基本使用
新建对话框工程,拖拽按钮控件,添加点击事件响应函数!
a、双击模版进行添加;
b、事件方式进行添加;
button的常见事件类型
void CMFCTestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
MessageBox(_T("1111"));
}
void CMFCTestDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
MessageBox(_T("1111"));
}
两种方式本质是一样的
按钮的消息类型
1.2、删除按钮的点击响应函数
一共要删除3个地方:
a、h头文件中的函数声明
public:
afx_msg void OnBnClickedButton2();
b、cpp文件中的函数定义;
void CMFCTestDlg::OnBnClickedButton2()
{
MessageBox(_T("1111"));
}
c、cpp文件中的ON_BN_CLICKED宏绑定代码。
ON_BN_CLICKED(IDC_BUTTON2, &CMFCTestDlg::OnBnClickedButton2)
1.3、按钮控件属性
属性 | 含义 |
---|---|
Default Button | True,按下回车键,相应该按钮的处理函数 |
Visable | False ,在资源对话框存在,但是不能显示 |
Caption | 标题 |
Flat | 平滑 |
Disabled | false 启用 true 禁用 |
ID | 按钮的ID,可以通过ID得到该按钮 |
1.4、控件的启用与禁用
void CMFCTestDlg::OnBnClickedButton3()
{
// 启用和禁用登录按钮
//1.获取按钮句柄
HWND hBtn = ::GetDlgItem(m_hWnd, IDC_BUTTON2);
//2.获取当前按钮的指针
CWnd*login = GetDlgItem(IDC_BUTTON2);
if (hBtn == NULL)
{
return;
}
// 2.判断该按钮是否启用
if (GetDlgItem(IDC_BUTTON2)->IsWindowEnabled())
{
::EnableWindow(hBtn, FALSE);
}
else
{
login->EnableWindow(TRUE);
}
//GetDlgItem 是MFC中的函数
//::GetDlgItem SDK 全局的API
}
1.5、绑定控件类型变量
刚刚我们想对按钮控件启用或者禁用之前必须先获得按钮控件的窗口句柄,也就是说如果以后要对这个按钮控件进行任何操作,都得先获取他的窗口句柄,之后才能操作,也就是都得调用这句话:HWND hBtn = ::GetDlgItem(m_hWnd, IDC_BTN_1); 比较麻烦
简单的方式:就是绑定控件类型变量
MFCTestDlg.h
public:
CButton m_loginBtn;
------------------------------------------------------------------------------------------ void CMFCTestDlg::OnBnClickedButton3()
{
// 判断该按钮是否启用
if (m_loginBtn.IsWindowEnabled())
{
//禁用
m_loginBtn.EnableWindow(FALSE);
}
else
{
//启用
m_loginBtn.EnableWindow(TRUE);
}
}
1.6、控件的美化
微软也提供给我们控件的美化接口,那就是自绘,就是自己完全重新绘制控件的样子。其实控件的重绘是件非常麻烦的事情,类似按钮的倒还好,如果是类似列表控件那就更麻烦了。
我们可以在 codeproject 上面找开源的控件类,一般这些开源的控件类都是基于MFC中已有的各种控件的类,比如按钮的就是 CButton 的派生类,美化后的按钮效果如图:
下载源码:
1》.h文件和.cpp文件,导入工程 CCoolButton
2》右键添加 现有项
3》stdafx.h 可以手动添加,也可以在某个文件,修改预编译头
4》CButton m_loginBtn ==》改为CCoolButton m_loginBtn
2. 单选框与复选框控件
2.1、单选框控件的基本使用:
a、要求一组内的单选框按钮控件ID必须由小到大排列,中间不能夹杂其他组的单选框按钮;
b、若有多组,则组内第一个单选框按钮的Group属性为True,其他为False;
c、选中组内某个单选框按钮:CheckRadioButton(IDC_RADIO1, IDC_RADIO3, IDC_RADIO2);
d、获得当前当前选中的单选框按钮控件:int nCheckId = GetCheckedRadioButton(IDC_RADIO1, IDC_RADIO3);
1. 选中按钮
//选中方式一
CButton*radio1 = (CButton*)GetDlgItem(IDC_RADIO1);
radio1->SetCheck(BST_CHECKED);
//选中方式二,选中某一组内某个按钮
CheckRadioButton(IDC_RADIO1, IDC_RADIO3, IDC_RADIO2);
2. 获得当前当前选中的单选框按钮控件
int nCheckId = GetCheckedRadioButton(IDC_RADIO1, IDC_RADIO3);
CString t;
t.Format(_T("%d"), nCheckId);
MessageBox(t); //整数转换为LPCTSTR
备注:Resouce.h定义的宏可以随便该,只有不重复就行
#define IDM_ABOUTBOX 0x0010
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define IDD_MFCTEST_DIALOG 102
#define IDR_MAINFRAME 128
#define IDC_BUTTON1 1000
#define IDC_BUTTON2 1001
#define IDC_BUTTON3 1002
#define IDC_RADIO1 1003
#define IDC_RADIO2 1004
#define IDC_RADIO3 1005
#define IDC_RADIO4 1006
#define IDC_RADIO5 1007
2.2、复选框控件的基本使用
a、勾选复选框控件:
1)::SendMessage(::GetDlgItem(m_hWnd, IDC_CHECK1), BM_SETCHECK, BST_CHECKED, 0);
2)GetDlgItem(IDC_CHECK1)->SendMessage(BM_SETCHECK, BST_CHECKED, 0);
3)m_Check.SetCheck(BST_CHECKED);
三种方法任意一种都可以!
备注:取消勾选的话只需要把 BST_CHECKED 改成 BST_UNCHECKED 就可以了!
b、获取复选框的勾选状态:
1)UINT nCheckState = ::SendMessage(::GetDlgItem(m_hWnd, IDC_CHECK1), BM_GETCHECK, 0, 0);
2)nCheckState = GetDlgItem(IDC_CHECK1)->SendMessage(BM_GETCHECK, 0, 0);
3)nCheckState = m_Check.GetCheck();
三种方法任意一种都可以!
如果返回值 nCheckState 的值为 BST_CHECKED,那么就是勾选状态。如果值为 BST_UNCHECKED,那么就是非勾选状态。
3.文本框
3.1 设置text
1)SetDlgItemText(IDC_EDIT1, _T("姓名:张三"));
2)m_Edit1.SetWindowText(_T("姓名:李四"));
3)HWND hEdit = ::GetDlgItem(GetSafeHwnd(), IDC_EDIT1);
::SetWindowText(hEdit, _T("姓名:王五"))
//三种方式均可以
3.2获取编辑框文本内容
//方式一
CString str;
GetDlgItemText(IDC_EDIT1, str);
MessageBox(str);
//方式2 成员变量
m_Edit1.GetWindowText(str);
MessageBox(str);
//方式3全局变量,其实要判断文本框的内容
TCHAR szMsg[256] = { 0 };
HWND hEdit = ::GetDlgItem(GetSafeHwnd(), IDC_EDIT1);
::GetWindowText(hEdit, szMsg, 256);
MessageBox(szMsg);
3.3、编辑框控件的属性介绍
a、让编辑框文本为只读模式;
readonly
b、让编辑框文本为密码模式;
password
d、让编辑框支持多行显示,即:自动换行;
mutiline 设置为 true
e、让编辑框显示滚动条;
vetical scroll 设置为true
f、让编辑框只能接受数字输入;
g、让编辑框长度控制
UINT nLimitLen = m_Edit.GetLimitText();
m_Edit.SetLimitText(0);
g、让编辑框结尾增加数据;
int iLen;
strMsg += "
";
iLen = m_editLogInfo.GetWindowTextLength();
m_editLogInfo.SetSel(iLen,iLen,TRUE);
m_editLogInfo.ReplaceSel(strMsg, FALSE);
3.3、事件通知
void CMFCTestDlg::OnEnChangeEdit2()
{
CString str;
GetDlgItemText(IDC_EDIT2, str);
for (size_t i = 0; i < str.GetLength(); i++)
{
if (str[i]!='A'&&str[i] != 'B'str[i] != 'C')
{
str.SetAt(i, '#');
}
}
str.Replace(_T("#"), _T(""));
SetDlgItemText(IDC_EDIT2, str);
}
4.ComboBox 下拉框
4.1、初始化下拉框
a、通过Data属性添加,以分号间隔;
b、向下拉框的结尾添加数据
- 调整下控件的 Sort 自动排序属性
- 调整下拉控件的类型 Dropdown:可以从下拉列表中选择一项,也可以自己输入;Drop List:只能从下拉列表中选择一项,不能修改。
- 控制下拉列表的高度:No Integral Height :默认的FALSE,即表示最大高度不是设计的高度,而是根据实际内容的高度来决定
4.2、从下拉框删除数据:
m_ComboBox.DeleteString(0); //删除指定索引的数据
m_ComboBox.ResetContent(); //删除全部数据
4.3、设置下拉框选中某条数据:
m_ComboBox.SetCurSel(1);
//参数传递要设置的索引序号,如果不想选中任何一条,那么就传递 -1.
4.4、获得下拉框当前选中的是哪条数据:
int idx = m_ComboBox.GetCurSel();
//返回以0开始的选中的数据索引,如果没选中任何一条数据,则返回 -1.
4.5、添加内容
m_Combox2.AddString(_T("兰博基尼"));
m_Combox2.AddString(_T("法拉利"));
m_Combox2.AddString(_T("斯特拉"));
4.6、获得指定数据的字符串内容
//获取选中
int idx = m_Combox2.GetCurSel();
TCHAR szText[100] = { 0 };
m_Combox2.GetLBText(idx, szText);
4.7、下拉框选择改变事件
响应 CBN_SELCHANGE 事件,在其响应函数中判断当前选中的是哪个!
void CMFCTestDlg::OnCbnSelchangeCombo2()
{
//获取选中
int idx = m_Combox2.GetCurSel();
TCHAR szText[100] = { 0 };
m_Combox2.GetLBText(idx, szText);
MessageBox(szText);
}
5. ListBox 列表控件
5.1、初始化
- 调整Section Single:单选模式 Mutipal :多选模式
5.2 插入和删除
void CMFCListBoxDlg::OnBnClickedButton1()
{
m_listbox.AddString(_T("兰博基尼"));
m_listbox.InsertString(3, _T("斯特拉"));
}
void CMFCListBoxDlg::OnBnClickedButton2()
{
//删除
m_listbox.DeleteString(0);
//清空
m_listbox.ResetContent();
}
5.3 选中与获取
单选选中
Single:单选模式
//清空选中
m_listbox.SetCurSel(-1);
//选中
m_listbox.SetCurSel(1);
//获取当前选中索引
int index= m_listbox.GetCurSel();
TCHAR szText[100] = { 0 };
m_listbox.GetText(index, szText);
MessageBox(szText);
多选选中
Mutipal 多选模式
void CMFCListBoxDlg::OnBnClickedButton3()
{
//多选:选中
m_listbox.SetSel(0);
m_listbox.SetSel(1);
CString cur_sel_str;
//获取当前选中的行数
int sel_count = m_listbox.GetSelCount();
if (sel_count>0)
{
int *p_arr_int = new int[sel_count];
//获取的是选中的索引
m_listbox.GetSelItems(sel_count, p_arr_int);
for (size_t i = 0; i < sel_count; i++)
{
int cur_sel = p_arr_int[i];
cur_sel_str.AppendFormat(_T("%d "), cur_sel);
}
}
MessageBox(cur_sel_str);
}
6. GroupBox
本身默认的控件ID就是 IDC_STATIC,所以没什么过多的属性可设置
利用搜索引擎,找网上相关的group box
7. StaicText静态文本
跟 GroupBox 控件类似,静态文本框控件的ID也是 IDC_STATIC,所以默认的情况下他也是没有什么属性可修改的,拖拽到对话框上面之后,只是作为默认的显示提示文本信息的作用了。
关于扩展
其实关于这个控件还是有点需求的,比如在界面上显示一个类似URL的网址链接,点击就启动默认的浏览器访问网页的,或者默认的字体,默认的颜色发生变化的,等等吧,还是有不少自定义的需求的
主要还是利用 第三方的开源控件类
8.Picture 图片控件
8.1、Picture控件加载静态BMP图片资源:
a、向工程中插入一个BMP类型的图片资源,例如,ID为:IDC_BITMAP1
b、在Picture控件的Type属性下拉框中选择Bitmap;
c、在Picture控件的Image属性下拉框中选择BMP资源ID为IDC_BITMAP1即可。
Type属性下拉列表中有8种类型,下面分别介绍下:
Frame:显示一个无填充的矩形框,边框颜色可以通过Color属性的下拉列表设定
Etched Horz:显示一条横分割线
Etched Vert:显示一条竖分割线
Rectangle:显示一个填充的矩形框,矩形颜色可通过Color属性的下拉列表设定
Icon:显示一个图标(Icon),图标通过Image下拉列表来设置图标资源ID
Bitmap:显示一个位图(Bitmap),位图通过Image下拉列表来设置位图资源ID
Enhanced Metafile:显示一个加强的元数据文件(Metafile)
Owner Draw:自绘
8.2 图片控件动态加载图片
以上讲的是静态加载图片的方法,下面接着讲动态加载图片的方法。程序依然沿用上面的工程。步骤如下:
(1)将上面添加的图片控件的Image属性IDB_BITMAP1清空,Type属性不变。
(2)修改图片控件的ID为IDC_PIC_STATIC,然后为其添加CStatic类型空间变量m_pictureControl。(若不修改ID则无法为其添加控件变量)
(3)在对话框下方添加一按钮控件,Caption属性改为“加载图片”,添加点击消息的处理函数OnBnClickedButton6()
void CMFCListBoxDlg::OnBnClickedButton6()
{
CBitmap bitmap; // CBitmap对象,用于加载位图
HBITMAP hBmp; // 保存CBitmap加载的位图的句柄
bitmap.LoadBitmapW(IDB_BITMAP1); // 将位图IDB_BITMAP1加载到bitmap
hBmp = (HBITMAP)bitmap.GetSafeHandle(); // 获取bitmap加载位图的句柄
m_pictureControl.SetBitmap(hBmp); // 设置图片空间m_pictureControl的位图为IDB_BITMAP
}
8.3、Picture控件加载 png、jpg 等常用格式图片
默认情况下,Picture控件只能显示BMP类型的图像,因为BMP文件格式是微软自家的。但是bmp这个确实不是很常用,或者说针对 png、jpg、gif 等文件类型来说 bmp 不常用。那么Picture控件如何来显示我们常用的 png、jpg 等图像格式呢?这里要借助微软的ATL中的一个类:CImage(VC6用不了,VC6可以考虑使用开源的 CxImage)
8.4、开源控件类:
图片开源控件
An MFC picture control to dynamically show pictures in a dialog
9. Spin Control
9.1 添加数值调节控件
向GUI界面添加一个MFC 提供的Spin数值调节控件
9.2 设置其"伙伴“
设置伙伴并设置数值调节的范围
9.3 绑定变量
绑定变量 m_edt_DelayValue 到文本框 IDC_EDT_DELAYVAL
BOOL CNbtscanDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//-------略去一段代码-----------------------------
// 定义“数值调节按钮(spin)”控件对象
CSpinButtonCtrl *pSpinBtn = (CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_DELAY);
// 设置伙伴按钮
pSpinBtn->SetBuddy(GetDlgItem(IDC_EDT_DELAYVAL)); // IDC_EDT_DELAYVAL 与显示界面的一个文本框控件绑定,设置的是值类型
// 最大设置为10000毫秒(10秒)
pSpinBtn->SetRange(1, 10000);
// 设置延迟扫描时间默认为500毫秒
UpdateData(TRUE);
m_edt_DelayValue = 500;
UpdateData(FALSE);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
9.4 响应函数“OnDeltaposSpinDelay”
//当用户单击上、下调值按钮时,改变文本框的数值
void CNbtscanDlg::OnDeltaposSpinDelay(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
if (pNMUpDown->iDelta == -1)
{
// 用户按下了spin控件的向下箭头
m_edt_DelayValue -= 100;
if (m_edt_DelayValue < 100)
{
m_edt_DelayValue = 100;
}
}
else if (pNMUpDown->iDelta == 1)
{
// 用户按下了spin控件的向上箭头
m_edt_DelayValue += 100;
if (m_edt_DelayValue > 10000)
{
m_edt_DelayValue = 10000;
}
}
UpdateData(FALSE);
*pResult = 0;
}
10 slider control控件
10.1silder初始化
m_slider.SetRange(0, 100);
m_slider.SetPos(50);
//设置步长
m_slider.SetLineSize(10);
10.2 silder事件
void CMFCListBoxDlg::OnNMCustomdrawSlider1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
int pos = m_slider.GetPos();
CString strText;
strText.Format(_T("%d"), pos);
SetDlgItemText(IDC_STATIC15, strText);
*pResult = 0;
}
11 Progress Control控件
Slider滑块控件用于控制数值的多少,而Progress进度条控件一般用于显示当前进度的多少,用来展示用的。跟Slider滑块控件相比一个用于输出,一个用于输入
//a、设置滑动范围:
m_ProgressCtrl.SetRange32(0, 100);
//b、设置每次步进的长度:
m_ProgressCtrl.SetStep(1);
//c、设置当前位置:
m_ProgressCtrl.SetPos(50);
在OnInitDialog函数中 设置定时器
//设置定时器,200毫秒,事件Id为1
SetTimer(1,200,NULL);
在主对话框的类 【右键】》【属性】》【增加响应TIMER的事件消息的函数】
没200毫米步进1,到100% 停下来
void CMFCListBoxDlg::OnTimer(UINT_PTR nIDEvent)
{
CDialog::OnTimer(nIDEvent);
//d、获取当前位置:
int pos = m_ProgressCtrl.GetPos();
//e、让进度条控件步进一次:
m_ProgressCtrl.StepIt();
if (pos == 100)
{
KillTimer(1);
m_ProgressCtrl.SetPos(100);
MessageBox(_T("已完成"));
}
}