MFC之使用 Windows 标准控件

使用 Windows 标准控件

  • 为了提高常用代码的复用性,VC 使用控件将常用的诸如用户输入、操作数据等功能封装起来。控件通常放在对话框或工具栏中,分为 3 种:Windows 标准控件、ActiveX 控件和 MFC 支持的其他控件类。
  • 一、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 类,包含控件定义的一个或多个接口。