[toc]
基础控件的使用
- 创建和初始化
- 消息的响应
- 控制函数
按钮
- 使用
CButton
来绑定按钮控件,一般不需初始化 - 消息响应:只有按钮被单击的消息
- 控制函数:
SetWindowText
设置按钮的标题
单选框
单选框也是按钮的一种,也有被点击的消息,响应方式和按钮一样
- 使用
CButton
绑定单选框控件 - 初始化:
- 单选框一般都是分组,同一组单选框的选中状态是互斥的
- 需要将每一组单选框第一个按钮的
Group
属性设置为True
- 操作函数:
- 若单选框控件绑定
CButton
类的变量,可以使用GetCheck
和SetCheck
来获取和设置单选框的选中状态 - 若单选框控件绑定
int
类型的变量,int
变量的值是一个分组中的单选框的序号,使用UpdateData
时,int
型变量的值是几,分组中的第几个单选框就会被选中 - 只需将分组中第一个单选框添加
int
变量即可,修改int
型变量的值在UpdateData
时,MFC 会自动操作同一分组内其他的单选框
- 若单选框控件绑定
添加好单选框,设置好 Group
属性和添加变量后,再添加一个按钮1,双击按钮,自动生成 OnBnClickedButton1()
函数,就可以在其中编程
1 | void CMFCApplication2Dlg::OnBnClickedButton1() |
复选框
- 初始化
- 消息:和按钮一样
- 操作函数:
- 绑定
CButton
类型的变量,可以使用GetCheck
和SetCheck
- 绑定值类型的变量,可以使用
UpdateData
来获取和修改选中状态
- 绑定
同上,添加按钮2,双击,在函数内编程
1 | void CMFCApplication2Dlg::OnBnClickedButton2() |
编辑框
初始化:在资源编辑视图的属性栏中设置
消息:编辑框文本被修改:
EN_CHANGE
操作函数:可以在
OnInitDialog
函数中添加设置函数,也可在编辑框的属性中修改,初始化编辑框1
2
3
4
5
6
7
8
9
10
11
12
13//设置编辑框的最大文本个数
m_edit.SetLimitText(10000);
//设置是否是只读
m_edit.SetReadOnly(0);
//密码风格,显示的字符默认是"*"
m_edit.SetPasswordChar('@');
//获取文本
CString buff;
m_edit.GetWindowText(buff);
//获取一共有几行
DWORD dwLineCount = m_edit.GetLineCount();
//滚动到指定行
m_edit.LineScroll(dwLineCount);按钮3设置编辑框文本
1
2
3
4
5
6
7
8
9
10
11
12void CMFCApplication2Dlg::OnBnClickedButton3()
{
//获取文本
UpdateData(FALSE);
CString buff;
m_edit.GetWindowText(buff);
MessageBox(buff);
//获取行数
DWORD dwLineCount = m_edit.GetLineCount();
buff.Format(L"%d", dwLineCount);
MessageBox(buff);
}
列表框
初始化
消息:
SEL_CHANGE
:当前选中项被修改操作函数:控件类型绑定(
CListBox
)AddString
:将一行字符串添加到列表框ResetContent
:清空所有项GetCurSel
:获取当前选中项的下标GetText
:获取指定下标的文本- 更多函数可以 F1
CListBox
类查看帮助文档
在 OnInitDialog()
函数中初始化
1 | BOOL CMFCApplication2Dlg::OnInitDialog() |
在类向导的命令中,根据控件类型找到函数进行编程实现功能
1 | void CMFCApplication2Dlg::OnSelchangeList1() |
下拉框
下拉框也称组合框,是编辑框和列表框的组合
初始化:有一个列表是否排序的属性
消息:
ON_CBN_SELENDCANCEL
当前选中项改变操作函数:
AddString
:向类表框添加文本GetCurSel
:获取列表框的当前选中项GetLBText
:获取列表框指定行的文本ResetContent
:清空列表框的所有节点SetCurSel
:设置列表框的当前选项SetEditSel
:设置编辑框的文本
初始化
1
2
3
4
5
6
7
8
9
10
11
12BOOL CMFCApplication2Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_ComBox1.AddString(L"河西");
m_ComBox1.AddString(L"河北");
m_ComBox1.AddString(L"河南");
m_ComBox1.AddString(L"河东");
m_ComBox1.SetCurSel(0);
return TRUE;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36void CMFCApplication2Dlg::OnSelchangeCombo1()
{
int nIndex = m_ComBox1.GetCurSel();
if (nIndex == -1)
return;
CString buff;
m_ComBox1.GetLBText(nIndex, buff);
switch (nIndex) {
case 0:
m_ComBox2.ResetContent();
m_ComBox2.AddString(L"111");
m_ComBox2.AddString(L"112");
m_ComBox2.AddString(L"113");
break;
case 1:
m_ComBox2.ResetContent();
m_ComBox2.AddString(L"211");
m_ComBox2.AddString(L"212");
m_ComBox2.AddString(L"213");
break;
case 2:
m_ComBox2.ResetContent();
m_ComBox2.AddString(L"311");
m_ComBox2.AddString(L"312");
m_ComBox2.AddString(L"313");
break;
case 3:
m_ComBox2.ResetContent();
m_ComBox2.AddString(L"411");
m_ComBox2.AddString(L"412");
m_ComBox2.AddString(L"413");
break;
default: break;
}
m_ComBox2.SetCurSel(0);
}
静态文本
标签
一般不需要绑定变量,不需响应消息,只是文本提示。若想动态修改标签的文本,可以得到标签控件的窗口句柄,使用 SetWindowText
来修改
图片控件
初始化:
- 修改资源 ID(类向导不会自动修改静态文本类的控件资源 ID)
- 将
type
属性修改成bitmap
- 将
center image
改为TRUE
,图片控件不能缩放要显示的图片。若图比控件大,控件会自动将大小修改成和图片一样大,该属性设为TRUE
之后,控件大小就不会自动跟随图片大小,而是固定大小并只显示图片的部分内容
消息:不需处理
操作函数:
绑定控件类型(
CStatic
)给图片控件设置图片
使用资源
将一张位图添加到资源中,在图片控件的
Image
属性中填写位图的资源 ID,调用CStatic.SetBitmap
函数将位图资源句柄设置进去调用
CStatic.SetBitmap
函数,将位图的资源句柄设置进去1
2
3
4
5
6
7void CMFCApplication2Dlg::OnBnClickedButton4()
{
static int index = 0;
m_Pic.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),
(TCHAR*)(index % 2 ? IDB_BITMAP1 : IDB_BITMAP2)));
++index;
}另设一个按钮修改图片,从磁盘中获取图片
1
2
3
4
5
6
7
8
9
10
11
12void CMFCApplication2Dlg::OnBnClickedButton5()
{
CFileDialog dlg(TRUE);
dlg.DoModal();
CString path = dlg.GetPathName();
if (path.IsEmpty())
return;
CImage img;// 使用CImage类加载图片
img.Load(path);
// 将CImage类对象作为图片对象设置到图片控件中
m_Pic.SetBitmap(img);
}
加载 GIF 动图
默认的
CStatic
类不支持这个功能,需要自定义,网上有CPictureEx
类。添加图片控件添加变量时变量的类型使用CPicturEx
类,在对话框初始化函数中,使用CPicturEx.Load
函数加载 GIF 图片,使用CPicturEx.Draw
函数来绘制 GIF 图片在
OnInitDialog()
函数内添加1
2//初始化gif动图,直接传图片的路径
m_Gif.Load(L"123.gif");1
2
3
4
5
6
7
8void CMFCApplication2Dlg::OnBnClickedButton6()
{
m_Gif.Draw();
}
void CMFCApplication2Dlg::OnBnClickedButton7()
{
m_Gif.Stop();
}
滑块
初始化
设置水平或垂直风格
设置滑块取指范围:
SetRange()
消息:
- 若滑块是水平风格,向父窗口发送
WM_HSCROLL
消息 - 若滑块是垂直风格,向父窗口发送
WM_VSCROLL
消息
- 若滑块是水平风格,向父窗口发送
操作函数:控件类型绑定(
CSliderCtrl
)获取当前位置:
GetPos
设置当前位置:
SetPos
进度条
- 进度条实际就是一个在界面上修改位置的滑块,通过
SetPos
来修改进度条的进度 - 进度条和滑块外观不一样,但也有水平和垂直
- 进度条和滑块一模一样
- 通过
SetRange
设置范围 - 通过
SetPos
来设置位置 - 通过
GetPos
来获取当前的位置
- 通过
代码和滑块的写在同一个函数里,水平和垂直函数是在类向导的消息中
1 | void CMFCApplication2Dlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) |
菜单栏
- 添加一个菜单资源
- 使用
CMenu
来加载菜单 - 在
OnInitDialog
函数中使用SetMen
函数来设置程序的菜单栏
1 | //加载菜单栏 |
菜单栏的响应消息:
1 | void CMenuDlg::OnFileOpen32771() |
每一个菜单都这样操作
弹出菜单
不能弹出根菜单
状态栏
在 OnInitDialog
函数中初始化
1 | //创建状态栏 |
还需在 WM_SIZE
的消息回调函数中来自动修改状态栏的位置
1 | void CMenuDlg::OnSize(UINT nType, int cx, int cy) |
工具栏
自己画工具图
在
OnInitDialog
函数中加载1
2
3//加载资源
m_ToolBar.Create(this);
m_ToolBar.LoadToolBar(IDR_TOOLBAR1);响应点击消息
先得到工具栏按钮 ID
响应虚函数
WM_COMMAND
消息在
wParam
保存的就是按钮 ID
1 | BOOL CAboutDlg::OnCommand(WPARAM wParam, LPARAM lParam) |
外部传入图片,在 OnInitDialog
函数中
1 | //第二个工具栏 |
通用控件
列表控件
列表框应该先添加列,再添加行,然后设置每一个单元格显示的内容。属性调为 report
模式
初始化:设置窗口风格
消息:
NM_CLICK
:左键单击NM_DBCLICK
:左键双击NM_RCLICK
:右键单击NM_RDBCLICK
:右键双击NM_RETURN
:回车
操作函数:
函数 说明 InsertColumn 插入一列 DeleteColumn 删除一列 InsertItem 插入一行 DeleteItem 删掉一行 GetItemText 获取某一个单元格的文本 SetItemText 设置某一个单元格的文本 GetItemData 获取单元格中的值 SetItemData 用int型数据设置单元格文本 GetItemCount 获取行数 获取被点击的节点:
初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25m_List.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES);
//插入列
m_List.InsertColumn(0,//列号
L"进程名",//列标题
0,//对齐风格
120//列宽
);
m_List.InsertColumn(1, L"PID", 0, 120);
m_List.InsertColumn(2, L"路径", 0, 120);
//插入节点(插入时, 只能设置这行节点的第0列的文本)
// 想要设置其它列需要通过SetItemText
m_List.InsertItem(0, L"QQ.exe");
//设置第0行第1列的文本
m_List.SetItemText(0, 1, L"1122");
m_List.SetItemText(0, 2, L"D:\\QQ.exe");
m_List.SetItemData(0, (DWORD)L"aaaaaaaaaa");
m_List.InsertItem(1, L"wechat.exe");
m_List.SetItemText(1, 1, L"1133");
m_List.SetItemText(1, 2, L"D:\\wechat.exe");
m_List.SetItemData(1, (DWORD)L"bbbbbbbbbbb");
//获取ID信息
ProcessInfo* procInfo = new ProcessInfo;
m_List.SetItemData(1, (DWORD_PTR)procInfo);
基本使用:
1 | void CMFCApplication2Dlg::OnBnClickedButton1() |
列表框的封装:
先创建一个 MFC 程序,在对话框资源中拖一个列表框,为其添加一个 MFC 类,基类是 CListCtrl
,此类名是 CMyListCtrl
,然后再添加变量,变量类型是 CMyListCtrl
。在 CMyListCtrl
类中添加结构体和函数
1 |
|
1 | //初始化列数据 |
在主对话框中添加和显示数据
1 | void CMFCApplication1Dlg::OnBnClickedButton1()//添加列数据按钮 |
通过右键菜单获取每一列的信息,用到函数 OnRangeCmds(UINT nId)
,需添加消息映射 ON_COMMAND_RANGE(ID_32771, ID_32774, &CMFCApplication1Dlg::OnRangeCmds)
,菜单 ID 编号
1 | void CMFCApplication1Dlg::OnRangeCmds(UINT nId) { |
将磁盘信息显示在列表框里
1 | //初始化列表控件 |
1 | //右击列表产生菜单,先要创建菜单资源 |
树控件
初始化
消息:和列表控件一样
操作函数
InsertItem 插入一项 DeleteAllItems 删除所有项 DeleteItem 删除某一项 SelectItem 选择某一项 GetItemText 获取某个节点的文本 GetNextSiblingItem 获取下个兄弟节点 GetPrevSiblingItem 获取上个兄弟节点 GetParentItem 获取父节点 GetRootItem 获取根节点 GetSelectedItem 获取被选择的项
1 | BOOL CTreeViewDlg::OnInitDialog() |
1 | void CTreeViewDlg::OnClickTree1(NMHDR *pNMHDR, LRESULT *pResult) |
并将消息映射 ON_NOTIFY(NM_CLICK, IDC_TREE1, &CTreeViewDlg::OnClickTree1)
中的 NM_CLICK
改为 NM_RCLICK
选项卡控件
选项卡依托于父窗口,选项卡控件是一个窗口,选项卡中的页面也是独立窗口,是选项卡的子窗口
消息反射机制:MFC 独有的机制,让控件能够处理控件发给父窗口的消息
子类化 Tab
控件
继承
CTabCtr
类添加成员函数:
addTab
添加一个选项卡选项卡标题,选项卡子窗口
处理
TCN_SELCHANG
发射消息- 将所有选项卡的子窗口的大小设置成
Tab
控件的客户区大小 - 将所有选项卡的子窗口的坐标移动到
Tab
控件的客户区 - 将所有的选项卡的子窗口隐藏
- 将当前选项卡对应的子窗口显示
- 将所有选项卡的子窗口的大小设置成
先创建一个 MFC 程序,在主对话框资源上拖一个 Table Ctrl,类向导中点击添加 MFC 类,基类选择 CTabCtrl,自己类名为 CMyTabCtrl。为主对话框中的 Table 控件添加控件变量,将变量类型修改为自己定义的 CMyTabCtrl,然后变量名为 m_MyTable。之后在资源视图中添加两个对话框资源,分别设置对话框属性,将 style
设为 child
,将 border
设为 NONE
,然后为这两个对话框添加类,基类为 CDialogEx,类名分别为 CDiaA 和 CDiaB。
在自己建的类 CMyTableCtrl 中添加函数和变量
1 | //在.h文件中添加头文件 #include<vector> 和私有变量 std::vector<CWnd*>m_subWnd; |
使用变参函数
1 | void CMyTableCtrl::InitTab(DWORD nCount, ...) { |
在主对话框中初始化
1 | BOOL CTabCtrlDlg::OnInitDialog() |