使用 Windows 标准控件
一、Windows 标准控件
1、常用 Windows 控件
MFC 类a、使用 new 关键字在堆上创建控件对象,使用此种方式创建控件,需要在退出程序时,调用 delete 关键字销毁对象。
b、在对话框编辑器中创建控件对象,此种方式直观,所见即所得,并且在程序退出时系统会自动销毁 Windows 控件。具体步骤:
(1)打开对话框资源编辑器
(2)展开“工具箱”,单击要添加的控件,将鼠标移到对话框主窗体,单击鼠标添加控件;或是按下需要添加的控件,移动鼠标到对话框主窗体的合适位置,松开鼠标添加控件。
(3)单击要设置大小的控件,将鼠标移动到控制点进行拖动,直到控件大小符合需要。
(4)右击已经添加的控件,单击“属性”命令,弹出属性对话框,在 ID 组合框中指定控件 ID,在Caption 文本框中指定控件显示的文本。
(5)重复(2)~(4)步,依次添加所需的控件。例:添加月历控件:
CWnd 类是 MFC 中所有窗体类包括控件类的基类。
CWnd 对象由构造函数和析构函数创建和销毁。
Windows 对话框是 Windows 内部数据结构,由 Create() 成员函数创建并由 CWnd 的析构函数销毁。
CWnd 类和消息映射机制隐藏在 WndProctor() 函数中,当 Windows 通知消息到来时,会自动路由到相应的 CWnd 的 OnMessage() 函数中。
CWnd 类可以继承,创建派生自 CWnd 的子控件分为两步:
(1)调用 CWnd 的构造函数构造 CWnd 对象。
(2)调用 Create() 成员函数创建子对话框,并将其附加到 CWnd 对象中。
4、控件的消息以及处理
a、代码形式
要处理控件消息,则在父对话框中为每条消息条目增加以下代码:
ON_Notification(id,memberFunction) //消息映射
//此处 id 表示发送消息的控件 ID,memberFunction 是父类中处理此消息的成员函数,父类中的控件消息的处理函数如下:
afx_msg void memberFunction();
具体例子:
afx_msg void OnClickedButtonTest();
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON_TEST, &CAboutDlg::OnClickedButtonTest)
END_MESSAGE_MAP()
void CAboutDlg::OnClickedButtonTest()
// TODO: 在此添加控件通知处理程序代码
MessageBox(L"单击了按钮", L"提示");
b、使用可视化操作:
(1)在对话框资源编辑器中,右键正在编辑的对话框,在弹出的菜单中选择类向导。
(2)在对象 ID 列表框中选择要处理发送消息的控件 ID;在消息列表框中选择要处理的消息;然后单击添加处理程序或删除处理程序。
(3)单击编辑代码按钮跳转到代码编辑器,编辑消息处理函数中的代码。
(4)单击确定按钮退出类向导对话框。
5、创建控件对象
在程序代码中要操作控件,需要使用控件对应的控件对象进行操作。创建控件对象的步骤:
1)在 MFC 类向导对话框中,选择成员变量选项卡。
6.2、按钮类 CButton
VC 中使用 CButton 类对象表示按钮控件,继承自对话框类 CWnd;CButton 类的派生类 CBitmapButton 类支持图像按钮控件,其提供了一组独立的位图分别表示按钮按下、按钮抬起、按钮选中和按钮不可用 4 种状态。
6.3、按钮的属性与消息
按钮控件没有特殊的属性,常用的消息主要有:
ON_BN_CLICKED 消息:当用户单击按钮时,发送给父窗体此消息。
ON_BN_DOUBLECLICKED 消息:当用户双击按钮时,给父窗体发送此消息。
6.5、设定和获取按钮状态
对于单选按钮和复选框,有选择和未选择两个按钮状态;对于单选按钮,用黑色圆圈表示选择;对于复选框,在方框中有个对勾表示选择。按钮控件状态可通过 CButton 的 4 个函数使用。
1)GetState()函数:获取按钮控件的当前状态,函数返回值的意义:0-表示按钮没有选择,1-按钮被选择,2-中间状态,4-当前按钮被用户按下并高亮显示,8-按钮获得输入焦点。
2)SetState()函数:设置按钮控件是否高亮显示。
3)Getcheck()函数:返回按钮控件的当前状态。返回值:0-没有选择按钮控件,1-选择了按钮控件,2-中间状态。
4)SetCheck()函数:设置按钮控件的当前状态。返回值:0-没有选择按钮控件,1-选择了按钮控件,2-中间状态。
二、静态控件和编辑控件
静态控件是常用的信息提示控件,编辑控件是常用的用户输入控件。
1、创建与使用静态控件
创建静态控件的方法见“使用对话框编辑器创建控件”。
1.1、静态控件类 CStatic
CStatic 类提供 Windows 静态控件的功能。静态控件显示文本字符串、矩形、图标、光标、位图或增强型图元文件。可用作标记、分组或分隔其他控件。通常情况下,静态控件不接收输入也不提供输出。但是如果使用 SS_NOTIFY,则可以通知父窗口鼠标单击事件,在静态控件的属性对话框将 Notify 选项设置为 True。
常用静态类成员函数:
常用的编辑控件消息有以下几个:
1)ON_EN_CHANGE 消息:当用户修改编辑控件中的内容时,发送此消息。EN_UPDATE 通知消息则是当对话框更新时才发送此通知消息。
2)ON_EN_ERRSPACE 消息:当控件不能分配足够的内存处理特殊请求时发送此消息。
3)ON_EN_HSCROLL 消息:当用户单击编辑控件的水平滚动条时,在屏幕更新前,编辑控件向父对话框发送此消息。
4)ON_EN_KILLFOCUS 消息:当编辑控件失去输入焦点时发送此消息。
5)ON_EN_MAXTEXT 消息:当前输入框中的内容超过编辑控件指定的最大字符数时,触发此消息,并将多余的内容删除。当编辑控件没有水平滚动条,而当前输入的内容超过编辑控件的宽度时,也会发送此消息。当编辑控件没有垂直滚动条时,而当前编辑框中输入的内容超过编辑控件的高度时,也会发送此消息。
6)ON_EN_SETFOCUS 消息:当编辑控件接收到输入焦点时,发送此消息。
7)ON_EN_UPDATE 消息:编辑控件格式化完文本,但是还没有在屏幕上显示前,发送此消息。
8)ON_EN_VSCROLL 消息:当用户单击编辑控件的垂直滚动条时,在屏幕更新前,编辑控件向父对话框发送此消息。
4、编辑控件应用实例
//首先在菜单栏添加一个菜单命令用来弹出测试对话框
//接着在主程序的.h文件,增加一个菜单命令消息映射
afx_msg void OnTestDlg();
//其次在主程序的.cpp文件
ON_COMMAND(IDM_ABOUTBOX, OnTestDlg)
//接下来编写测试对话框的实现代码
//静态控件和编辑控件测试
class CStaticAndEditSampleDlg :public CDialog //对话框类声明
public:
void WriteLog(CString message, CString title);//记录日志函数声明
CStaticAndEditSampleDlg(CWnd* pParent = NULL);//标准构造函数
//{{AFX_DATA(CStaticAndEditSampleDlg)
IDD = IDD_STATICANDEDITSAMPLE_DIALOG
CEdit m_editTestScroll; //带滚动条的编辑控件对应的对象
CEdit m_editTest; //测试编辑控件对应的对象
CStatic m_staticLog; //日志静态框
//}}AFX_DATA
//{{AFX_VIRTUAL(CStaticAndEditSampleDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); //DDX/DDV 支持
//}}AFX_VIRTUAL
protected:
HICON m_hIcon; //图标变量
//{{AFX_MSG(CStaticAndEditSampleDlg)//消息映射
virtual BOOL OnTestInitDialog(); //初始化对话框函数声明
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);//系统命令函数声明
afx_msg void OnPaint(); //重绘函数声明
afx_msg HCURSOR OnQueryDragIcon(); //查询拖放图标函数声明
afx_msg void OnChangeEditTest(); //改变编辑框内容函数声明
afx_msg void OnErrspaceEditTest(); //擦除编辑框内容函数声明
afx_msg void OnKillfocusEditTest(); //编辑框失去焦点函数声明
afx_msg void OnMaxtextEditTest(); //编辑框内容达到最大值函数声明
afx_msg void OnSetfocusEditTest(); //设置编辑框检点函数声明
afx_msg void OnUpdateEditTest(); //更新编辑框函数声明
afx_msg void OnHscrollEditTestScroll(); //水平滚动条滚动事件函数声明
afx_msg void OnVscrollEditTestScroll(); //垂直滚动条滚动事件函数声明
afx_msg void OnButtonGetedittext(); //获取文本内容时间函数声明
afx_msg void OnButtonSetedittext(); //设置文本内容事件函数声明
afx_msg void OnButtonGetline(); //获取文本行内容事件函数声明
afx_msg void OnButtonGetsel(); //获取选择的文本内容事件函数声明
afx_msg void OnButtonSetsel(); //设置选择的文本内容事件函数声明
afx_msg void OnButtonReplacesel(); //替换选择的文本内容事件函数声明
afx_msg void OnStaticTest(); //静态控件测试事件函数声明
//}}AFX_MSG
DECLARE_MESSAGE_MAP() //结束消息映射
public:
/*DECLARE_MESSAGE_MAP()
afx_msg void OnEnChangeEditTest();
afx_msg void OnBnClickedButtonGetline();
afx_msg void OnEnChangeEditTestscroll();*/
/*afx_msg void OnAboutbox();
afx_msg void OnStnClickedStaticLog();*/
//对话框初始化函数
CStaticAndEditSampleDlg::CStaticAndEditSampleDlg(CWnd* pParent/*=NULL*/) :CDialog(CStaticAndEditSampleDlg::IDD, pParent)
//{{AFX_DATA_INIT(CStaticAndEditSampleDlg)
//}}AFX_DATA_INIT
m_hIcon = AfxGetApp()->LoadIconW(IDR_MAINFRAME); //装载应用程序图标
//数据交换函数
void CStaticAndEditSampleDlg::DoDataExchange(CDataExchange* pDX)
CDialog::DoDataExchange(pDX); //执行基类的数据交换函数
//{{AFX_DATA_MAP(CStaticAndEditSampleDlg) //控件和数据映射对应关系
DDX_Control(pDX, IDC_EDIT_TESTSCROLL, m_editTestScroll);
DDX_Control(pDX, IDC_EDIT1_TEST, m_editTest);
//日志静态框变量声明
DDX_Control(pDX, IDC_STATIC_LOG, m_staticLog);
//}}AFX_DATA_MAP
}BEGIN_MESSAGE_MAP(CStaticAndEditSampleDlg, CDialog) //消息映射表开始
//{{AFX_MSG_MAP(CStaticAndEditSampleDlg)
ON_WM_SYSCOMMAND() //系统命令消息
ON_WM_PAINT() //重绘消息
ON_WM_QUERYDRAGICON() //查询拖动图标消息
//编辑框内容改变消息映射
ON_EN_CHANGE(IDC_EDIT1_TEST, &CStaticAndEditSampleDlg::OnChangeEditTest)
//编辑框内容擦除消息映射
ON_EN_ERRSPACE(IDC_EDIT1_TEST, &CStaticAndEditSampleDlg::OnErrspaceEditTest)
//编辑框失去焦点消息映射
ON_EN_KILLFOCUS(IDC_EDIT1_TEST, &CStaticAndEditSampleDlg::OnKillfocusEditTest)
//编辑框内容改变消息映射
ON_EN_MAXTEXT(IDC_EDIT1_TEST, &CStaticAndEditSampleDlg::OnMaxtextEditTest)
//编辑框获得焦点消息映射
ON_EN_SETFOCUS(IDC_EDIT1_TEST, &CStaticAndEditSampleDlg::OnSetfocusEditTest)
//编辑框内容更新消息映射
ON_EN_UPDATE(IDC_EDIT1_TEST, &CStaticAndEditSampleDlg::OnUpdateEditTest)
//水平滚动消息映射
ON_EN_HSCROLL(IDC_EDIT_TEST_SCROLL, &CStaticAndEditSampleDlg::OnHscrollEditTestScroll)
//垂直滚动消息
ON_EN_VSCROLL(IDC_EDIT_TEST_VSCROLL, &CStaticAndEditSampleDlg::OnVscrollEditTestScroll)
//获取文本消息
ON_BN_CLICKED(IDC_BUTTON_GETEDITTEXT, &CStaticAndEditSampleDlg::OnButtonGetedittext)
//设置文本消息
ON_BN_CLICKED(IDC_BUTTON_SETEDITTEXT, &CStaticAndEditSampleDlg::OnButtonSetedittext)
ON_BN_CLICKED(IDC_BUTTON_GETLINE, &CStaticAndEditSampleDlg::OnButtonGetline) //获取行
//获取选择内容
ON_BN_CLICKED(IDC_BUTTON_GETSEL, &CStaticAndEditSampleDlg::OnButtonGetsel)
//设置选择内容
ON_BN_CLICKED(IDC_BUTTON_SETSEL, &CStaticAndEditSampleDlg::OnButtonSetsel)
//文本替换
ON_BN_CLICKED(IDC_BUTTON_REPLACESEL, &CStaticAndEditSampleDlg::OnButtonReplacesel)
ON_BN_CLICKED(IDC_STATIC_TEST, &CStaticAndEditSampleDlg::OnStaticTest)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CMFCApplication1App::OnTestDlg()
CStaticAndEditSampleDlg aboutDlg;
aboutDlg.DoModal();
//初始对话框
BOOL CStaticAndEditSampleDlg::OnTestInitDialog()
//调用基类对话框初始化函数
CDialog::OnInitDialog();
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); //判断是否关于命令
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
//定义存放菜单名称的字符串变量
CString strAboutMenu;
strAboutMenu.LoadStringW(IDD_STATICANDEDITSAMPLE_DIALOG); //装载对话框的菜单
if (!strAboutMenu.IsEmpty())
pSysMenu->AppendMenu(MF_SEPARATOR);//增加分隔符
//增加“关于”菜单命令
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
SetIcon(m_hIcon, TRUE); //设置大图标
SetIcon(m_hIcon, FALSE); //设置小图标
return TRUE;
void CStaticAndEditSampleDlg::OnSysCommand(UINT nID, LPARAM lParam)
if ((nID & 0xFFF0) == IDM_ABOUTBOX) //判断单击选择的命令是否为“关于”命令
CAboutDlg dlgAbout; //定义关于对话框
dlgAbout.DoModal(); //显示“关于”对话框
CDialog::OnSysCommand(nID, lParam); //如果不是“关于”命令,则处理命令消息
void CStaticAndEditSampleDlg::OnPaint() //对话框绘制函数
if (IsIconic()) //判断是否是图标状态
CPaintDC dc(this); //进行绘制的设备上下文
//发送图标背景绘制消息
SendMessage(WM_ICONERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0);
//将图标放置在客户端矩形中间
int cxIcon = GetSystemMetrics(SM_CXICON);//获取小图标的x长度
int cyIcon = GetSystemMetrics(SM_CYICON);//获取小图标的y高度
CRect rect; //定义矩形区域
GetClientRect(&rect); //获取客户区矩形
int x = (rect.Width() - cxIcon + 1) / 2; //计算客户区中心点的X值
int y = (rect.Height() - cyIcon + 1) / 2; //计算客户区中心点y值
dc.DrawIcon(x, y, m_hIcon); //绘制图标
CDialog::OnPaint();
//获取拖动图标消息处理函数
HCURSOR CStaticAndEditSampleDlg::OnQueryDragIcon()
return (HCURSOR)m_hIcon;
//文本内容改变消息处理函数
void CStaticAndEditSampleDlg::OnChangeEditTest()
// TODO: 如果该控件是 RICHEDIT 控件,它将不
// 发送此通知,除非重写 CDialog::OnInitDialog()
// 函数并调用 CRichEditCtrl().SetEventMask(),
// 同时将 ENM_CHANGE 标志“或”运算到掩码中。
WriteLog(L"接收到ON_EN_CHANGE消息", CString("左边的编辑控件"));
// TODO: 在此添加控件通知处理程序代码
//文本内容擦除消息处理函数
void CStaticAndEditSampleDlg::OnErrspaceEditTest()
WriteLog(L"接收到ON_EN_ERRSPACE消息", CString("左边的编辑控件"));
//失去焦点消息处理函数
void CStaticAndEditSampleDlg::OnKillfocusEditTest()
WriteLog(L"接收到ON_EN_KILLFOCUS消息", CString("左边的编辑控件"));
//达到最大文本数消息处理函数
void CStaticAndEditSampleDlg::OnMaxtextEditTest()
WriteLog(L"接收到ON_EN_MAXTEXT消息", CString("左边的编辑控件"));
//获取焦点 消息处理函数
void CStaticAndEditSampleDlg::OnSetfocusEditTest()
WriteLog(L"接收到ON_EN_SETFOCUS消息", CString("左边的编辑控件"));
//更新消息处理函数
void CStaticAndEditSampleDlg::OnUpdateEditTest()
WriteLog(L"接收到ON_EN_UPDATE消息", CString("左边的编辑控件"));
//水平滚动消息处理函数
void CStaticAndEditSampleDlg::OnHscrollEditTestScroll()
WriteLog(L"接收到ON_EN_HSCROLL消息", CString("右边的编辑控件"));
//垂直滚动消息处理函数
void CStaticAndEditSampleDlg::OnVscrollEditTestScroll()
WriteLog(L"接收到ON_EN_VSCROLL消息", CString("右边的编辑控件"));
//显示日志函数
void CStaticAndEditSampleDlg::WriteLog(CString message, CString title)
//获取当前日志静态框的文本内容
m_staticLog.SetWindowText(title + "--" + message);
//获取编辑框内容处理函数
void CStaticAndEditSampleDlg::OnButtonGetedittext()
CString content; //定义编辑框内容字符串
m_editTest.GetWindowText(content);
//在弹出对话框中显示获取的编辑内容
MessageBox(content, L"获取左边编辑框的内容");
//设置编辑框内容处理函数
void CStaticAndEditSampleDlg::OnButtonSetedittext()
m_editTest.SetWindowText(L"你好,这是在测试");
//获取编辑框指定行内容处理函数
void CStaticAndEditSampleDlg::OnButtonGetline()
TCHAR content[256]; //存放内容的字符串变量
memset(content, 0x00, sizeof(content));//初始化字符串数组
int iCount = m_editTest.GetLine(1, content, sizeof(content));//获取第二行的内容
if (iCount > 0)
MessageBox(content, L"GETLINE 获取第二行内容");
MessageBox(L"失败", L"GETLINE 获取第二行内容");
//获取选择的内容
void CStaticAndEditSampleDlg::OnButtonGetsel()
int iStart = 0, iEnd = 0; //定义开始位置和结束位置的变量
//获取选择的内容所在的开始位置和结束位置
m_editTest.GetSel(iStart, iEnd);
CString log; //日志字符串
log.Format(L"选择的内容从%d个字符到第%d个字符", iStart, iEnd);//格式化信息提示
MessageBox(log, L"GetSel");
//设置选择的内容
void CStaticAndEditSampleDlg::OnButtonSetsel()
m_editTest.SetSel(5, 10, TRUE);//设置选择第6~11个字符
MessageBox(L"选择第6个字符到第11个字符", L"SetSel");//显示提示信息
//文本替换命令
void CStaticAndEditSampleDlg::OnButtonReplacesel()
m_editTest.ReplaceSel(L"若道天涯无回路,漫漫黄沙掩枯骨");
//静态控件处理函数
void CStaticAndEditSampleDlg::OnStaticTest()
MessageBox(L"如果使用 SS_NOTIFY 创建静态控件, \n则可以接收单击事件,\n此处就是 例子。", L"静态控件");
5、单选按钮和复选框
单选框和复选框是特殊的按钮控件。单选按钮控件允许用户在一组选项中,选择其中的一项;复选按钮控件允许用户在一组选项中,选择其中多项。
5.1、单选按钮控件创建
1)在工具箱中选择 “Group Box” 添加分组框。
2)在工具箱中选择 “Radio Button” 向分组框中添加单选按钮。
3)将组合框里的第一个单选按钮的 Group 属性、Tab stop 属性和 Auto 属性都设置为 True;其余的单选按钮将 Tab stop 属性和 Auto 属性设置为 True 就可以了。
5.2 单选控件的消息
单选控件的消息主要有两个:
ON_BN_CLICKED 消息:当用单击单选按钮时,发送此消息给父窗体。
ON_BN_DOUBLECLICKED 消息:当用户双击单选按钮时,发送此消息给父窗体。
5.3 复选框的创建
1)在工具箱中选择 “Group Box” 添加分组框。
2)在工具箱中选择 “Chick Box” 向分组框添加复选框。
复选框的消息同单选按钮一样。
5.4 单选按钮和复选框示例
afx_msg void OnButtoGetstate();
ON_BN_CLICKED(IDC_BUTTON_CH, &CStaticAndEditSampleDlg::OnButtoGetstate)
//单选按钮和复选框测试
void CStaticAndEditSampleDlg::OnButtoGetstate()
//颜色选择
UINT iColor[] = { IDC_RADIO_RED,IDC_RADIO_GREEN,IDC_RADIO_BLUE };
CString sColor[] = { L"红色",L"绿色",L"蓝色" };
CString sResualtColor;
CButton *pBtn = NULL;
for (int i = 0; i < 3; i++)
pBtn = (CButton*)GetDlgItem(iColor[i]);
if (!pBtn)
continue;
if (pBtn->GetCheck() == 1)
sResualtColor = L"颜色选择:" + sColor[i];
//性别选择
UINT iSex[] = { IDC_RADIO_BOY,IDC_RADIO_GIRL };
CString sSex[] = { L"男",L"女" };
CString sResualtSex;
for (int i = 0; i < 2; i++)
pBtn = (CButton*)GetDlgItem(iSex[i]);
if (!pBtn)
continue;
if (pBtn->GetCheck() == 1)
sResualtSex = L"\n性别选择:" + sSex[i];
//喜好选择
UINT iLike[] = { IDC_CHECK_BOOK,IDC_CHECK_MUSIC,IDC_CHECK_SPORT,IDC_CHECK_DANCE };
CString sLike[] = { L"读书",L"听音乐",L"运动",L"跳舞" };
CString sResualtLike = L"\n爱好:";
for (int i = 0; i < 4; i++)
pBtn = (CButton*)GetDlgItem(iLike[i]);
if (!pBtn)
continue;
if (pBtn->GetCheck() == 1)
sResualtLike = sResualtLike + sLike[i] + L"、";
//总结输出
MessageBox(sResualtColor + sResualtSex + sResualtLike, L"选择结果");
列表框显示数据项的列表,如文件名等,用户可以选择和浏览数据项。创建列表框的步骤:
1)在工具箱中选择 “List Box” 向对话框中添加列表框。
2)使用类向导将控件与变量连接起来。
3)通过变量调用 CListBox 类的成员方法操作列表框
4)列表框类 CListBox 常用成员函数
列表框控件常用的消息有:
ON_LBN_DBLCLK 消息:当用户双击列表框控件中选项时,列表框向父对话框发送此消息;但只有具有 LBS_NOTIFY 属性的列表框控件才会发送此消息。
ON_LBN_ERRSPACE 消息:当列表框控件不能分配足够的内存处理特殊请求时发送此消息。
ON_LBN_KILLFOCUS 消息:当列表框控件失去输入焦点时发送此消息。
ON_LBN_SELCANCEL 消息:取消列表框的当前选择,只有具有 LBS_NOTIFY 属性的列表框控件才会发送此消息。
ON_LBN_SELCHANGE 消息:当列表框控件的选择发生变化时,发送此消息;只有具有 LBS_NOTIFY 属性的列表框控件才会发送此消息;当用户按下方向键,即使选择没有发生变化也会发送此消息。
ON_LBN_SETFOCUS 消息:当列表框获得输入焦点时发送此消息。
ON_WM_CHARTOITEM 消息:没有字符串的自绘列表框控件会接受 WM_CHAR 消息。
ON_WM_VKEYTOITEM 消息:具有 LBS_WANTKEYBOARDINPUT 属性的列表框控件会接收 WM_KEYDOWN 消息。
3、列表框示例
// MFCDiaLog 消息处理程序
BOOL MFCDiaLog::OnInitDialog()
CDialog::OnInitDialog();
CString items[5] = { L"地名",L"北京",L"上海",L"广州",L"肇庆" };
for (int i = 0; i < 5; i++)
m_listTest.AddString(items[i]);
return TRUE;
void MFCDiaLog::OnSelChangeTest()
int index = m_listTest.GetCurSel();
CString result;
m_listTest.GetText(index, result);
MessageBox(result, L"当前列表框选择的内容");
4、创建组合框
组合框是编辑控件与列表框的组合,组合框控件有三种样式:
何时显示列表框部分
静态控件还是编辑控件
1)打开要添加组合框的对话框,在对话框编辑器中的工具箱对话框中选择 ”Combo Box“。
2)在对话框的合适位置单击鼠标左键添加组合框
3)右键组合框控件打开属性对话框,设置控件 ID 与相关属性。
组合框类 CComboBox 类实现 Windows 组合框控件的功能,组合框控件具有 CListBox 类和 CEdit 类的部分函数,此外还有独有的成员函数:
组合框控件除了可以处理 CWnd 的消息,还能处理以下消息:
ON_CBN_CLOSEUP 消息:当组合框控件不是 CBS_SIMPLE 样式且组合框控件的列表框部分关闭时,发送此消息给父窗体。
ON_CBN_DBLCLK 消息:当用户双击选项时发送此消息,此消息仅对使用 CBS_SIMPLE 样式的组合框控件有效。
ON_CBN_DROPDOWN 消息:当用户要下拉组合框的列表框部分时发送此消息,此消息只对具有 CBS_DROPDOWN 和 CBS_DROPDOWNLIST 样式的组合框有效。
ON_CBN_EDITCHANGE 消息:当用户修改组合框的编辑控件的内容时发送此消息,并且是在 Windows 更新完屏幕后发送此消息;对 CBS_DROPDOWNLIST 的组合框无效。
ON_CBN_EDITUPDATE 消息:当组合框的编辑控件部分要显示修改的文本时,在控件格式化完文本内容但是显示文本前,发送此消息;对 CBS_DROPDOWNLIST 的组合框无效。
ON_CBN_ERRSPACE 消息:当组合框控件不能分配足够的内存处理特殊请求时发送此消息。
ON_CBN_SELENDCANCEL 消息:表示取消用户的选择。当用户单击某一项,然后单击其他窗体或控件隐藏的列表框部分,在发送 CBN_CLOSEUP 消息之前发送此消息,用于表示忽略用户的选择;当组合框是 CBS_SIMPLE 样式时,即使不发送 CBN_CLOSEUP 通知消息,也会发送 CBN_SELENDCANCEL 消息或 CBN_SELENDOK 通知消息。
ON_CBN_SELENDOK 消息:当用户选择其中一项,并且按下 Enter 键或单击下拉箭头隐藏列表框部分时,发送此消息。
ON_CBN_KILLFOCUS 消息:当组合框失去输入焦点时,发送此消息。
ON_CBN_SELCHANGE 消息:当组合框的选择发生变化时,触发此消息;在处理池消息时,如果要获取组合框中编辑控件的文本内容时,则 X 要通过 GetLBText() 函数获取,而不是 GetWindowText() 函数。
ON_CBN_SETFOCUS 消息:当组合框获得输入焦点时,发送此消息。
6、组合框示例
CComboBox m_combotest;
afx_msg void OnSelChangeCombotest();
BEGIN_MESSAGE_MAP(MFCDiaLog, CDialog)
ON_CBN_SELCHANGE(IDC_COMBO,OnSelChangeCombotest)
END_MESSAGE_MAP()
BOOL MFCDiaLog::OnInitDialog()
CDialog::OnInitDialog();
m_combotest.AddString(L"汉族");
m_combotest.AddString(L"回族");
m_combotest.AddString(L"满族");
m_combotest.AddString(L"白族");
m_combotest.AddString(L"其他");
return TRUE;
void MFCDiaLog::OnSelChangeCombotest()
CString result;
m_combotest.GetLBText(m_combotest.GetCurSel(),result);
MessageBox(result, L"当前组合框选择的内容");
四、微调控件、滑块控件和进度条控件
Windows 中提供了三种带有刻度功能的控件,分别是微调控件、滑块控件和进度条控件。
微调控件用于控制连续的整数值调整;滑块控件通过拖放滑块控件表示进度;进度条控件以动态滚动的方式显示当前程序的进度。
1、微调控件的创建和使用
微调控件也称上下文控件,提供一组箭头可以调整其值,此值称为当前位置。
创建步骤:
1)在工具箱中选择 “Spin Control” 添加微调控件。
2)将编辑控件的 Tab 顺序值与微调控件的顺序值相邻,且编辑控件的更大。
3)取消微调控件的 Tab属性。
4)将微调控件的 Auto Buddy 属性设为 True。
MFC 中使用 CSpinButtonCtrl 类实现微调控件的功能;微调控件的默认范围是0~100,按向上箭头时减少位置值,按下向下箭头时增加位置值;可使用 CSpinButtonCtrl::SetRange() 成员函数调整范围值。
2、创建和使用滑块控件
滑块又称为跟踪条,包含滑块和可选的标记线;当用户移动滑块时,发送改变取值的消息给父对话框。
滑块的创建与微调控件的创建相似,只不过在工具箱中选择 “slide control”。
滑块的 Orientation 用来设置滑块是水平还是滚动。
Point 属性设置滑块箭头的方向。
Tick marks 属性设置是否具有标记的滑块。
Auto ticks 属性设置是否在滑块上添加等分标记。
Enable selection 属性表示是否带有选择部分。
Border 属性设置滚动条是否有边框。
3、创建和使用进度条控件
创建方法同上面的类似,在工具箱中选择 “Progress Control”。
MFC 中使用 CProgressCtrl 类完成进度条功能,最重要的方法有下面4个:
SetRange() 函数:可以设置进度条控件的范围值。
SetStep() 函数:可以设置进度条控件的增量间隔值。
SetPOS() 函数:可以设置进度条当前的位置值。
GetPOS() 函数:获取进度条当前位置值。
// 微调控件测试
CSpinButtonCtrl m_spin;
// 滑块控件测试
CSliderCtrl m_slider;
// 进度条测试
CProgressCtrl m_progress;
afx_msg void OnReleasedcaptureSliderPercent(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnButtonTimer();
afx_msg void OnTimer(UINT nIDEvent);
// 微调控件所附的编辑控件
CEdit m_editPrecent;
void MFCDiaLog::DoDataExchange(CDataExchange* pDX)
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_SPIN1, m_spin);
DDX_Control(pDX, IDC_SLIDER1, m_slider);
DDX_Control(pDX, IDC_PROGRESS1, m_progress);
DDX_Control(pDX, IDC_EDIT2, m_editPrecent);
BEGIN_MESSAGE_MAP(MFCDiaLog, CDialog)
ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER1, OnReleasedcaptureSliderPercent)
ON_BN_CLICKED(IDC_BUTTON1,OnButtonTimer)
ON_WM_TIMER(IDC_PROGRESS1,OnTimer)
END_MESSAGE_MAP()
void MFCDiaLog::OnReleasedcaptureSliderPercent(NMHDR* pNMHDR, LRESULT* pResult)
CString text; //定义字符串变量
//获取滑块控件当前位置
text.Format(L"%d", m_slider.GetPos());
//在编辑控件中显示当前选择值
m_editPrecent.SetWindowText(text);
*pResult = 0;
//定时器按钮
void MFCDiaLog::OnButtonTimer()
m_progress.SetPos(0);
SetTimer(100, 100, NULL);
//定时器处理函数
void MFCDiaLog::OnTimer(UINT nIDEvent)
//如果定时器是滑块滑动定时器
if (nIDEvent == 100)
int pos = m_progress.GetPos();//获取进度条位置
if (pos < 100)
m_progress.SetPos(m_progress.GetPos() + 1);
KillTimer(100);//关闭计时器
CDialog::OnTimer(nIDEvent);
五、列表视图控件和树形视图控件
列表视图控件扩展了列表框控件的功能,用于显示并列级别的数据信息;树形视图控件用于显示层次结构的数据项。
1、创建列表视图控件
列表视图控件显示包含图标和标签的项的集合,每项在图标和标签的右边显示信息,最常见的列表视图控件是 Windows 系统的资源管理器。
列表视图控件支持以下四种显示方式(视图样式):
1)Icon 视图:图标视图,此种显示方式下,每个数据项显示时,在完整尺寸的图标下显示标签。用户可以拖动数据项到列表视图对话框的任意位置。
2)Small Icon 视图:(16 x 16)小图标视图,每个数据项以小视图的方式显示,并在右边显示标签,用户可以拖动数据项到列表视图对话框的任意位置。
3)List 视图:列表视图,每个数据项以小图标样式按列方式排列,标签显示在图标右边,不能任意拖动。
4)Report 视图:报表视图,每个数据项显示一行,除了名称外,其他信息在名称的右边列出,从左向右依次是图标列、标签列、其他信息列;此种样式内置了(CHeaderCtrl)来实现这些列。
2、CListCtrl 类
CListCtrl 类封装了列表视图控件的功能。
CListCtrl 类常用的成员方法有:
CListCtrl::GetItem() 方法:获取指定索引处的项的数据。
CListCtrl::InsertItem() 方法:在指定索引出添加新项。
CListCtrl::FindItem() 方法:查找指定项。
列表视图控件用 CImageList 类实现图像列表,每个控件有四个不同的图像列表:大图标、小图标、用户自定义状态和标题头项。
HDN:Header Notify
LVN:ListView control Notify
NM:Notify Message
TVN:TreeView control Notify
HDN_BEGINTRACK 开始拖动控件顶部的分割线
HDN_BEGINDRAG 开始拖动控件顶部的分栏(item)
HDN_BEGINFILTEREDIT 开始过滤器编辑(filter edit)
LVN_BEGINDRAG 鼠标左键正在被触发以便进行拖放操作(当鼠标左键开始拖拽列表视图控件中的项目时产生)
LVN_BEGINRDRAG 鼠标右键正在被触发以便进行拖放操作(当鼠标右键开始拖拽列表视图控件中的项目时产生)
LVN_BEGINLABELEDIT 开始编辑项的文本
LVN_BEGINSCROLL 开始滚动操作
LVN_COLUMNCLICK 单击列(当鼠标单击列表视图控件列标题时产生)
NM_CLICK 当鼠标单击列表视图控件时产生
NM_CUSTOMDRAW 自定义绘图操作
LVN_COLUMNCLICK 单击列
HDN_DIVIDERDBLCLICK 双击顶部的分割线
LVN_DELETEALLITEMS 删除所有项
LVN_DELETEITEM 删除某个项
NM_DBLCLK 当鼠标双击列表视图控件时产生
HDN_ENDTRACK 停止拖动顶部的分割线
HDN_ENDDRAG 停止拖动控件顶部的分栏(item)
HDN_ENDFILTEREDIT 结束过滤器的编辑
LVN_ENDLABELEDIT 结束对项文本的编辑
LVN_ENDSCROLL 结束滚动操作
HDN_FILTERBTNCLICK 单击过滤器按钮
HDN_FILTERCHANGE 顶部过滤器的属性正被改变/编辑
NM_FONTCHANGED 控件更换字体
HDN_GETDISPINFO 控件需要标题项的回调信息
LVN_GETDISPINFO 请求需要显示的信息
LVN_GETINFOTIP 请求显示在工具提示窗口内的附加的文本信息
LVN_GETEMPTYMARKUP 列表控件没有任何项(用于向父窗口请求标注文本markup text)
LVN_HOTTRACK 鼠标滑过某个项
NM_HOVER 鼠标悬停于某项(item)上
HDN_ITEMCLICK 鼠标单击标题项
HDN_ITEMCHANGED 标题项的属性被改变
HDN_ITEMCHANGING 标题项的属性将被改变
HDN_ITEMDBLCLICK 双击标题项
HDN_ITEMKEYDOWN 标题项被选中的同时按下某个按键
HDN_ITEMSTATEICONCLICK 用户点击标题项的状态图标
LVN_INSERTITEM 当向列表视图控件插入项目时产生
lVN_ITEMACTIVATE 激活某个项
LVN_ITEMCHANGED 某个项已经发生变化
LVN_ITEMCHANGING 某个项目正在发生变化
NM_KILLFOCUS 当视表列图控件失去焦点时产生
LVN_KEYDOWN 某个键被按下
LVN_LINKCLICK 单击一个链接
LVN_MARQUEEBEGIN 开始某个边框选择
NM_OUTOFMEMORY 当内存溢出时产生
LVN_ODCACHEHINT 虚拟列表控件的显示区域的内容发生了变化
LVN_ODSTATECHANGED 虚拟列表的控件的某个项或某个范围内的项已经发生变化
LVN_ODFINDITEM 需要拥有者查找一个特定的回调项
NM_RCLICK 当鼠标右键单击列表视图控件时产生
NM_RDBLCLK 当鼠标右键双击列表视图控件时产生
NM_RELEASEDCAPTURE 控件正在释放鼠标捕捉(releasing mouse capture)
NM_RETURN 控件获取输入焦点且用户按下return按键
NM_SETFOCUS 当列表视图控件获得焦点时产生
LVN_SETDISPINFO 父窗口必须更新控件为项所维护的信息
HDN_TRACK 用户正在拖动控件顶部的分割线
NM_THEMECHANGED 主题已经改变
3、CTreeCtrl 类
CTreeCtrl 类提供树形视图控件的功能,是实现层次项的窗口,如磁盘的文件项。每项包括一个标签和一个可选的位图图片,并且每项都可以包含与之相连的子项。通过单击每项可以展开和收缩与之相关的子项的列表。
CTreeCtrl 类成员函数
m_listview.InsertItem(0, L"张三", 0);
m_listview.InsertItem(1, L"李四", 1);
m_listview.InsertItem(2, L"王五", 2);
//树形视图
HTREEITEM hProvince = m_filectrl.InsertItem(L"广东省", 0, 0);
HTREEITEM hcity1 = m_filectrl.InsertItem(L"肇庆市", 1, 1, hProvince);
m_filectrl.InsertItem(L"端州区", 2, 2, hcity1);
m_filectrl.InsertItem(L"星湖区", 2, 2, hcity1);
m_filectrl.InsertItem(L"鼎湖区", 2, 2, hcity1);
m_filectrl.InsertItem(L"高要区", 2, 2, hcity1);
hcity1 = m_filectrl.InsertItem(L"汕尾市", 1, 1, hProvince);
HTREEITEM city2 = m_filectrl.InsertItem(L"陆丰市", 2, 2, hcity1);
m_filectrl.InsertItem(L"海丰县", 2, 2, hcity1);
m_filectrl.InsertItem(L"城区", 2, 2, hcity1);
m_filectrl.InsertItem(L"陆河县", 2, 2, hcity1);
m_filectrl.InsertItem(L"河西街道", 3, 3, city2);
return TRUE;
六、ActiveX 控件
ActiveX 控件,也称为 OLE 控件,是提供连接点和主机标准接口的 COM 组件。这些标准接口定义可以在包含器中处理控件的协议、交换信息和处理事件。
1、使用 ActiveX 控件
使用对话框编辑器可以往对话框中添加 ActiveX 控件,具体方法是:在对话框中右键,在弹出的右键菜单中选择“插入 ActiveX 控件”,然后在 ActiveX 控件添加对话框中选择要添加的 ActiveX 控件。控件可以在设计时设置控件属性,接着资源编辑器便会用相关的指定值初始化控件,但是这些属性值在编程时仍然可以修改。
2、ActiveX 控件的结构
作为 COM 服务器,ActiveX 控件的结构有以下几个方面:
属性:ActiveX 控件使用成员变量表示中间状态成员变量通过 Get() 和 Set() 访问函数实现后称为属性。idl 文件使用 progget 标识的每个访问方法都有对应的 Get() 函数,idl 文件中使用 propput 或 propputref 标识的每个访问方法都有对应的 Set() 函数。
方法:使用公共方法定义的控件行为。包装类提供了访问控件方法的途径。如果使用包装类,通过获取接口的指针访问控件的方法。
事件:空间可以使事件通知宿主程序“有事情发生”。如 Button 按钮控件的 OnClick 事件,当用户单击控件按钮时,按钮控件就会触发 OnClick 事件,然后调用相关的处理函数。
类型库:类型库告诉控件包含器,控件支持的属性、方法和事件。控件库可以放在单独的文件中,即扩展名为.tlb 的文件,或放在控件内部。控件库还可以包含控件的组件类信息。组件类是使用 GUID 定义的 COM 类,包含控件定义的一个或多个接口。