MFC知识点总结

一:消息
1.什么是消息?消息是驱动windows系统运行的基础。从计算机的角度来看,消息就是一个整数。
    (1)一个无符号整数,是消息值;
    (2)消息附带的WPARAM和LPARAM类型的参数;
    (3)其实我们一般所说的消息是狭义上的消息值,也就是一个无符号整数,经常被定义为宏。

2.消息映射机制: MFC使用消息映射机制来处理消息,在程序框架中的表现就是,在程序中有一个消息与消息处理函数组成的消息硬设备,每条消息都有与之相对应的消息处理函数。当窗口接收到消息时,会到消息映射表中查找该消息对应的消息处理函数,然后由消息处理函数进行相应的处理。SDK编程时需要在窗口过程中一一判断消息值进行相应的处理,相比之下MFC的消息映射机制要方便好用的多。

3.消息分类:分为两大类,系统消息和自定义消息。其中系统消息又分为三种。
    (1)标准Windows消息。除WM_COMMAND外以WM_开头的消息是标准消息
    (2)命令消息。消息名为WM_COMMAND,消息中附带了产生消息的控件ID,即在消息参数中有相关的按钮等控件ID。
    (3)通知消息。通知消息一般由列表框等子窗口发送给父窗口,消息名也是WM_COMMAND,其中在消息中附带了控件通知码来区分控件

4.CWnd的派生类都可以接收到标准Windows消息、通知消息和命令消息。命令消息还可以由文档类等接收。

5.用户自定义消息实际上就是用户定义一个宏作为消息,此宏的值应该大于等于WM_USER,然后此宏就可以跟系统消息一样使用,窗口类中可以定义它的处理函数。

6.WM_NOTIFY消息: 在操作列表框等控件时往往会给父窗口发送WM_NOTIFY通知消息。WM_NOTIFY消息的wParam参数为发送通知消息的控件的ID,lParam参数指向一个结构体,可能是NMHDR结构体,也可能是第一个元素为NMHDR结构体变量的其他结构体。NMHDR结构体的定义如下(仅作了解):
       Typedef sturct tagNMHDR{
                HWND hwndFrom;
                UINT idFrom;
                UINT code;
       } NMHDR;
       hwndFrom为发送通知消息控件的句柄,idFrom为控件ID,code为要处理的通知消息的通知码,例如NM_CLICK。

7.通知消息:  通知消息的消息映射入口项形式如:ON_NOTIFY(wNotifyCode,id,memberFxn)
    wNotifyCode为要处理的通知消息通知码,例如:NM_CLICK。id为控件标识ID。MemberFxn为此消息的处理函数。
    通知消息的处理函数的原型为:afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * result);

8.用户自定义消息:
    (1)首先要定义消息宏,如:#define WM_UPDATE_WND (WM_USER+1)
    (2)再到消息映射表中添加消息映射入口项:ON_MESSAGE(WM_UPDATE_WND, &CMainFrame::OnUpdateWnd)
    (3)然后在MainFrm.h中添加消息处理函数的函数声明:afx_msg LRESULT OnUpdateWnd(WPARAM wParam, LPARAM lParam);
    (4)最后在MainFrm.cpp中实现此函数。


9.我们自定义的类要想响应自定义消息就只能从CWnd中派生

10.自定义类相应自定义消息:
    (1)自定义类要继承与CWnd类
    (2)在处理消息之前要确保m_hWnd关联到一个窗体,即便这个窗体是不可见的。
    那么有人说,在自定义类的构造函数中调用Create函数就行了,不错,当然也可以在别处调用,只要确保在消息发送之前。但是,Create的调用很有说法,要注意两个地方,第一个参数是类的名称,我建议最好设为NULL;第五个参数是父窗体对象的指针,这个函数指定的对象一定要存在,我建议最好为整个程序的主窗体。。如下是我的自定义类的构造函数:
    CMyTestObject::CMyTestObject()
    {
    CWnd::Create(NULL,"MyTestObject",WS_CHILD,CRect(0,0,0,0),::AfxGetMainWnd(),1234);
    }   //一定要在生成主窗体后使用,在主窗体完成OnCreate消息的处理后
    CMyTestObject::CMyTestObject(CWnd*pParent)
    {
    CWnd::Create(NULL,"MyTestObject",WS_CHILD,CRect(0,0,0,0),pParent,1234);
    }




二:属性页
1.属性页对话框主要用到两个类:CPropertyPage类和CPropertySheet类

2.CPropertyPage三个构造函数:
    CPropertyPage( );//无参构造函数
    explicit CPropertyPage(
                UINT nIDTemplate,//属性页ID
                UINT nIDCaption = 0,//数nIDCaption是属性页对话框选项卡的标题所用字符串资源的ID,若设为0,则选项卡标题就使用                 该属性页的对话框资源的标题
                DWORD dwSize = sizeof(PROPSHEETPAGE)
            );
    explicit CPropertyPage(
                LPCTSTR lpszTemplateName,//属性页的对话框资源的名称字符串,不能为NULL(?)
                UINT nIDCaption = 0,
                DWORD dwSize = sizeof(PROPSHEETPAGE)
        );

3.CancelToClose()函数:在模态属性页对话框的属性页进行了某不可恢复的操作后,使用CancelToClose()函数将“OK”按钮改为“Close”按钮,并禁用“Cancel”按钮。函数原型为:void CancelToClose( );(?)

4.SetModified()函数:调用此函数可激活或禁用“Apply”按钮,函数原型为:void SetModified(BOOL bChanged = TRUE);

5.可重载函数:CPropertyPage类提供了一些消息处理函数,来响应属性页对话框的各种消息。我们重载这些消息处理函数,就可以自定义对属性页对话框操作的处理。
    OnApply:处理属性页的“Apply”按钮被单击的消息
    OnCancel:处理属性页的“Cancel”按钮被单击的消息
    OnKillActive:处理属性页当前活动状态被切换的消息,常用于数据验证
    OnOK:处理属性页的“OK”按钮、“Apply”按钮或者“Close”按钮被单击的消息
    OnQueryCancel:处理属性页的“Cancel”按钮被单击前发出的消息
    OnReset:处理属性页的“Reset”按钮被单击的消息
    OnSetActive:处理属性页被切换为当前活动页的消息
    OnWizardBack:处理属性页的“Back”按钮被单击的消息,仅在向导对话框中有效
    OnWizardFinish:处理属性页的“Finish”按钮被单击的消息,仅在向导对话框中有效
    OnWizardNext:处理属性页的“Next”按钮被单击的消息,仅在向导对话框中有效

6.CPropertySheet属性表类:继承于Cwnd类。有模态和非模态两种。负责属性特的加载,打开,删除以及切换。

7.CPropertySheert类的三个构造函数:
    (1)CPropertySheet( );
    (2)explicit CPropertySheet(
               UINT nIDCaption,//标题字符串资源id
               CWnd* pParentWnd = NULL,//属性页对话框的父窗口,若为null,则为应用程序主窗口
               UINT iSelectPage = 0//初始状态时,活动属性页的索引
       );
    (3)explicit CPropertySheet(
               LPCTSTR pszCaption,//标题字符串
               CWnd* pParentWnd = NULL,
               UINT iSelectPage = 0
       );

8.GetActiveIndex()函数:获取当前活动属性页的索引。函数原型为:int GetActiveIndex( ) const;返回值:当前活动属性页的索引

9.GetActivePage()函数:获取当前活动属性页对象。函数原型为:CPropertyPage* GetActivePage( ) const;返回值:当前活动属性页对象的指针。

10.GetPage()函数:获取某个属性页对象。函数原型为:CPropertyPage* GetPage(int nPage) const;参数nPage:目标属性页的索引。返回值:目标属性页对象的指针。

10.GetPageCount()函数:获取属性页的数量。函数原型为:int GetPageCount( ) const;返回值:属性页的数量。

11.GetPageIndex()函数:获取某属性页在属性页对话框中的索引。函数原型为:int GetPageIndex(CPropertyPage* pPage);参数pPage:要获取索引的属性页对象的指针。返回值:属性页对象在属性页对话框中的索引。

12.SetActivePage()函数:设置某个属性页为活动属性页。函数原型为:   
    BOOL SetActivePage(int nPage);//要设置为活动属性页的索引。
    BOOL SetActivePage(CPropertyPage* pPage);//要设置为活动属性页的对象指针。

13.SetWizardButtons()函数:在向导对话框上启用或禁用Back、Next或Finish按钮,应在调用DoModal之前调用此函数。函数原型为:
    void SetWizardButtons(DWORD dwFlags);
    参数dwFlags:设置向导按钮的外观和功能属性。可以是以下值的组合:
       PSWIZB_BACK                    启用“Back”按钮,如果不包含此值则禁用“Back”按钮。
       PSWIZB_NEXT                    启用“Next”按钮,如果不包含此值则禁用“Next”按钮。
       PSWIZB_FINISH                  启用“Finish”按钮。
       PSWIZB_DISABLEDFINISH          显示禁用的“Finish”按钮。

14.SetWizardMode()函数:设置属性页对话框为向导对话框模式,应在调用DoModal之前调用此函数。函数原型为:void SetWizardMode( );

15.SetTitle()函数:设置属性对话框的标题。函数原型为:void SetTitle(LPCTSTR lpszText,UINT nStyle = 0);
    参数lpszText:标题字符串。
    参数nStyle:指定属性表标题的风格。应当为0或PSH_PROPTITLE。如果设为PSH_PROPTITLE,则单词“Properties”会出现在指定标题之后。例如,SetTitle("Simple",PSH_PROPTITLE)这种调用会使得属性表标题为“Simple Properties”。

15.AddPage()函数:为属性对话框添加新的属性页。函数原型为:void AddPage(CPropertyPage *pPage);参数pPage:要添加的新的属性页的对象指针。

16.PressButton()函数:模拟按下某指定的按钮。函数原型为:void PressButton(int nButton);
    参数nButton:要模拟按下的按钮,它可以是下列值之一:
       PSBTN_BACK   选择“Back”按钮。
       PSBTN_NEXT   选择“Next”按钮。
       PSBTN_FINISH   选择“Finish”按钮。
       PSBTN_OK   选择“OK”按钮。
       PSBTN_APPLYNOW   选择“Apply”按钮。
       PSBTN_CANCEL   选择“Cancel”按钮。
       PSBTN_HELP   选择“帮助”按钮。

17.RemovePage()函数:删除某属性页。函数原型为:
    void RemovePage(CPropertyPage *pPage);
    void RemovePage(int nPage);

18._T实际上是一个宏,工程的字符集选择为Unicode时字符串就转为Unicode字符串,选择为Muli-Byte时就转为ASCII字符串。

19.获得父窗口,即属性表CPropertySheet类(在属性页类中进行调用)   CPropertySheet* psheet = (CPropertySheet*) GetParent();   
     
20.在属性表中应该注意属性页的添加顺序

21. SetFinishText(_T("完成")); //设置属性表只有“完成”按钮

22.属性页对话框和想到对话框的区别在于: 一般属性页对话框和向导对话框的创建和显示的不同包括,是否需要OnSetActive和OnWizardFinish等重载函数,是否需要调用属性表类的SetWizardMode函数设置为向导对话框模式。还有向导对话框使用next,back切换属性页,属性页对话框使用不同的标签和切换属性页




三:消息对话框
1.两个函数:CWnd::MessageBox函数和全局的AfxMessageBox函数

2.CWnd::MessageBox()函数:
    原型如下:
    int MessageBox(
    LPCTSTR lpszText,//显示的文本
        LPCTSTR lpszCaption = NULL,//标题文本
        UINT nType = MB_OK//风格
    );
    nType的取值在对话框类型的图标类型的nType中任选其一,或者两者同时选择
    (1)对话框类型
        nType取值                 参数说明
    MB_ABORTRETRY     有“终止”、“重试”和“忽略”按钮
    MB_OK             有“确定”按钮
    MB_OKCANCEL            有“确定”和“取消”按钮
    MB_RETRYCANCEL     有“重试”和“取消”按钮
    MB_YESNO             有“是”和“否”按钮
    MB_YESNOCANCEL     有“是”、“否”和“取消”按钮
    (2)图标类型
    nType取值:
        MB_ICONEXCLAMTION,MB_ICONWARNING (警告)    
        MB_ICONASTERISK,MB_ICONINFORMATION(i)
    MB_ICONQUESTION(?)    
    MB_ICONHAND,MB_ICONSTOP,MB_ICONERROR(X)

3.AfxMessageBox()函数:
    int AfxMessageBox(
           LPCTSTR lpszText,
           UINT nType = MB_OK,
           UINT nIDHelp = 0//此消息的帮助的上下文ID。默认值为0,取0时表示要使用应用程序的默认帮助上下文
       );//参数以及类型取值如上

4.两个函数的返回值:
    DABORT:单击“终止”按钮。
    IDCANCEL:单击“取消”按钮。
    IDIGNORE:单击“忽略”按钮。
    IDNO:单击“否”按钮。
    IDOK:单击“确定”按钮。
    IDRETRY:单击“重试”按钮。
    IDYES:单击“是”按钮。

5.模态对话框:弹出后必须要关闭了才可以操作其他窗口。非模态对话框,弹出后即使不关闭,但是任然可以操作其他窗口




四.文件对话框:
1.CFileDialog类:文件对话框的所有操作都封装在这个类里面.

2.构造函数:
    CFileDialog(
    BOOL bOpenFileDialog,//要创建的文件对话框类型,TRUE为打开文件对话框,FALSE为保存文件对话框
    LPCTSTR lpszDefExt = NULL,//文件扩展名
    LPCTSTR lpszFileName = NULL,//文件对话框中显示的初始文件名
    DWORD dwFlags = OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,//文件对话框属性,此处第一个意思是隐藏文件对话框                                 的"Read Only"复选框,第二个参数意思是在保存文件对                                 话中,如果你选择的文件存在了就弹出一个消息对话框                                 ,要求确定是否要覆盖此文件
    LPCTSTR lpszFilter = NULL,//文件过滤器,这个很重要
    CWnd* pParentWnd = NULL,//文件对话框的父窗口指针
    DWORD dwSize = 0,//默认为0
    BOOL bVistaStyle = TRUE//默认为TRUE
    );

3.文件过滤器:static TCHAR BASED_CODE szFilter[] = _T("Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|*.xlc; *.xls|All Files (*.*)|*.*||");

4.文件对话框属于莫泰对话框,因此,他的显示需要调用domodal函数

5.文件对话框的相关函数:
    GetFileExt():获得选定文件的后缀名。
    GetFileName():获得选定文件的名称,包括后缀名。
    GetFileTitle():获得选定文件的标题,即不包括后缀名。
    GetFolderPath():获得选定文件的目录。
    GetNextPathName():获得下一个选定的文件的路径全名。
    GetPathName():获得选定文件的路径全名。
    GetReadOnlyPref():获得是否“以只读方式打开”。
    GetStartPosition():获得文件名列表中的第一个元素的位置。
 
 6.文件对话框中选中多个文件:OFN_ALLOWMULTISELECT(多选属性)




五.字体对话框
1.MFC使用CFontDialog类封装了字体对话框的所有操作。字体对话框是一种模态对话框。

2.常用构造函数原型如下:
    CFontDialog(
        LPLOGFONT lplfInitial = NULL,//指向LOGFONT结构体数据的指针,可以通过它设置字体的一些特征
        DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS,//指定选择字体的一个或多个属性
        CDC* pdcPrinter = NULL,//指向一个打印设备上下文的指针。
        CWnd* pParentWnd = NULL//指向字体对话框父窗口的指针
    );

3.LOGFONT结构体:
    typedef struct tagLOGFONT {
        LONG lfHeight;//
        LONG lfWidth;
        LONG lfEscapement;
        LONG lfOrientation;
        LONG lfWeight;
        BYTE lfItalic;
        BYTE lfUnderline;
        BYTE lfStrikeOut;
        BYTE lfCharSet;
        BYTE lfOutPrecision;
        BYTE lfClipPrecision;
        BYTE lfQuality;
        BYTE lfPitchAndFamily;
        TCHAR lfFaceName[LF_FACESIZE];
        } LOGFONT;

4.获取字体对话框中所选字体:在字体对话框中选择了字体后,可以通过CFontDialog类的成员变量m_c GFONT结构体,然后在调用CreateFontIndirect函数就可以获得CFont对象。

5.CFont::CReateFontOInDirect函数:函数原型如下:
    BOOL CreateFontIndirect(const LOGFONT* lpLogFont );参数是LOGFONT指针类型,我们可以传入CFontDialog类成员变量m_cf的lpLogFont成员,就可以得到所选字体的CFont对象了。




六.颜色对话框
1.MFC中提供了CColorDialog类封装了颜色对话框的所有操作,颜色对话框是一种模态对话框

2.构造函数:
    CColorDialog(
    COLORREF clrInit = 0,//默认选择颜色的颜色值,类型为COLORREF,实际上就是unsigned long类型。如果没有设置                   它的值,则默认为RGB(0,0,0)。
    DWORD dwFlags = 0,//自定义颜色对话框功能和外观的属性值
    CWnd* pParentWnd = NULL//颜色对话框的父窗口的指针
        );

3.获取颜色对话框中所选颜色值:CColorDialog::GetColor函数, COLORREF GetColor( ) const;

4. 如果想获得R、G、B各分量的值,可以根据GetColor得到的COLORREF颜色值,通过使用GetRValue、GetGValue和GetBValue三个宏获得。GetRValue的语法形式为:
       BYTE GetRValue(DWORD rgb);
       参数rgb就是COLORREF颜色值,返回值即是R分量值。其他两个宏的形式与之类似。例如,GetColor()函数返回的COLORREF为10000,则R分量值就是GetRValue(10000)。




 七.静态文本框
 1.当控件有事件发生时,会向父窗口发送通知WM_COMMAND消息。最常发生的事件就是鼠标单击了,此时控件会向父窗口发送BN_CLICKED消息,实际上也就是给父窗口发送WM_COMMAND消息,在wParam参数中包含有通知消息码(鼠标单击时的通知消息码就是BN_CLICKED)和控件ID,lParam参数中包含了控件的句柄

 2.控件的消息映射宏的格式大致是:
       ON_通知消息码(nID, memberFun):nID是控件ID,memberFun是消息处理函数,例如ON_BN_CLICKED(IDC_BUTTON1, &CDlg::OnBnClickedButton1)。此消息映射宏应添加到BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间。
       消息处理函数声明的语法形式为:afx_msg void memberFun();

3.动态创建静态文本框,CStatic::Create函数:Create函数的原型如下:
    virtual BOOL Create(
        LPCTSTR lpszText,//指定要在控件中显示的文字。如果为NULL则不会显示任何文字。
        DWORD dwStyle,//dwStyle:指定静态控件的风格。静态文本框一般都是对话框或其他窗口的子窗口,而且是可见的            ,所以应该包含WS_CHILD 和WS_VISIBLE风格,
        const RECT& rect,//指定静态控件的位置和大小,它可以是RECT结构体类型,也可以是CRect类的对象
        CWnd* pParentWnd,//定静态控件的父窗口,通常是一个CDialog对象,不能是NULL
        UINT nID = 0xffff//指定静态控件的ID
    );
    静态文本控件风格dwStyle:
    SS_BITMAP     一个位图将显示在静态控件中,Create函数的lpszText参数字符串是资源文件中定义的位图名。此            风格忽略宽度和高度参数,静态控件自动调整它的尺寸来适应位图
    SS_BLACKFRAME     指定一个具有与窗口边界同色的框,默认为黑色
    SS_BLACKRECT     指定一个具有与窗口边界同色的实矩形,默认为黑色
    SS_CENTER     使显示的正文居中对齐,正文可以换行
    SS_GRAYFRAME     指定一个具有与屏幕背景同色的边框
    SS_GRAYRECT     指定一个具有与屏幕背景同色的实矩形
    SS_ICON     使控件显示一个在资源中定义的图标,图标的名字由Create 函数的lpszText 参数指定,图标自动            调整它的尺寸
    SS_LEFT     左对齐正文,正文能回绕
    SS_LEFTNOWORDWRAP     左对齐正文,正文不能回绕
    SS_NOTIFY     使控件能向父窗口发送鼠标事件消息
    SS_RIGHT     右对齐正文,可以回绕
    SS_SIMPLE     使静态正文在运行时不能被改变并使正文显示在单行中
    SS_WHITEFRAME     指定一个具有与窗口背景同色的框,默认为白色
    SS_WHITERECT     指定一个具有与窗口背景同色的实心矩形,默认为白色

4.成员函数:
    GetBitmap         获取由SetBitmap函数设置的位图的句柄
    GetCursor          获取由SetCurSor设置的光标的句柄
    GetEnhMetaFile     获取由SetEnhMetaFile设置的增强图元文件的句柄
    GetIcon         获取由SetIcon设置的图标的句柄
    SetBitmap         设置要在静态控件中显示的位图
    SetCursor         设置要在静态控件中显示的光标图片
    SetEnhMetaFile     设置要在静态控件中显示的增强图元文件
    SetIcon         设置要在静态控件中显示的图标
    除了上述成员函数外,由于CStatic是CWnd的派生类,CWnd的很多成员函数也可以使用,例如,GetWindowText、GetWindowRect、SetWindowText等。

5.若想改变静态文本控件的颜色,可以通过MFC消息WM_CTLCOLOR并重载其消息处理函数OnCtlColor来实现(后面在消息处理模块会专门介绍这些消息)




八.编辑框
1.MFC为编辑框提供了CEdit类。编辑框的所有操作都封装到了CEdit类中。

2.常用通知消息:
    EN_CHANGE:        编辑框的内容被用户改变了,与EN_UPDATE 不同,该消息是在编辑框显示的正文被刷新后才发出的
    EN_ERRSPACE:    编辑框控件无法申请足够的动态内存来满足需要
    EN_HSCROLL:    用户在水平滚动条上单击鼠标
    EN_KILLFOCUS:    编辑框失去输入焦点
    EN_MAXTEXT:    输入的字符超过了规定的最大字符数。在没有ES_AUTOHSCROLL 或ES_AUTOVSCROLL编辑框中,当正                文超出了编辑框的边框时也会发出该消息
    EN_SETFOCUS:    编辑框获得输入焦点
    EN_UPDATE:        在编辑框准备显示改变了的正文时发送该消息
    EN_VSCROLL:    用户在垂直滚动条上单击鼠标

3.编辑框的动态创建:CEdit::Create函数
    virtual BOOL Create(
        DWORD dwStyle,//编辑框的风格
        const RECT& rect,//
        CWnd* pParentWnd,//
        UINT nID//
    );

4.编辑框风格:
    ES_AUTOHSCROLL:横向滚动条    
    ES_AUTOVSCROLL:纵向滚动条
    ES_CENTER: 在多行编辑框中使正文居中
    ES_LEFT :左对齐正文
    ES_LOWERCASE: 把用户输入的字母统统转换成小写字母
    ES_MULTILINE:指定一个多行编辑器。若多行编辑器不指定ES_AUTOHSCROLL 风格,则会自动换行,若不指定              ES_AUTOVSCROLL,则多行编辑器会在窗口中正文装满时发出警告声响
    ES_NOHIDESEL:默认时,当编辑框失去输入焦点后会隐藏所选的正文,当获得输入焦点时又显示出来。设置该风格可禁止              这种默认行为
    ES_NUMBER :编辑框中只允许输入数字
    ES_OEMCONVERT:使编辑框中的正文可以在ANSI字符集和OEM 字符集之间相互转换。这在编辑框中包含文件名时是很有用               的
    ES_PASSWORD: 使所有键入的字符都用“*”来显示
    ES_READONLY: 将编辑框设置成只读的
    ES_RIGHT :   右对齐正文
    ES_UPPERCASE: 把用户输入的字母统统转换成大写字母
    ES_WANTRETURN:使多行编辑器接收回车键输入并换行。如果不指定该风格,按回车键会选择默认的命令按钮,这往往会导致对话框的关闭

    除了上面的风格外,编辑款一般还会设置WS_CHILD、WS_VISIBLE、WS_BORDER等窗口风格。另外,编辑框可以是多行的,也就是在编辑框中显示多行文字,这就需要设置ES_MULTILINE风格,如果想要多行编辑框支持回车键,则还要设置ES_WANTRETURN。对于在对话框模板中创建的编辑框,它的属性中包含了上述的风格,例如,Multiline属性对应的就是ES_MULTILINE风格,WantReturn属性对应ES_WANTRETURN风格。

5.经常使用的成员函数:
(1)GetWindowText:获取编辑框中的正文
(2)SetWindowText:设置编辑框中的正文
(3)GetWindowTextLength:获取编辑框中正文的长度。
(4)int LineFromChar(int nIndex = –1) const;返回多行编辑框中指定索引的字符所在行的行号(从零开始),只适用于多行编辑框。nIndex等于-1则返回所选择正文的第一个字符所在行的索引。如果没有选择正文,则返回当前行的行号。
(5) int LineIndex(int nLine = –1) const;返回由nLine指定行的起始字符在编辑框的整个字符串中的索引,只适用于多行编辑框。如果指定行超过编辑框的最大行数,则返回-1,而如果nLine为-1,则返回当前插入符所在行的起始字符的索引。
(6) void GetSel(int& nStartChar,int& nEndChar) const;获取选择正文的索引范围。nStartChar返回被选择正文的起始索引,nEndChar返回被选择正文的终止索引(不包括在选择范围内)。如果没有选择正文,则两者均为当前插入符的索引
(7)void SetSel(int nStartChar,int nEndChar,BOOL bNoScroll=FALSE);选择编辑框中的正文。nStartChar为选择开始处的索引,nEndChar为选择结束处的索引。如果nStartChar为0并且nEndChar为-1,则选择所有正文,而如果nStartChar为-1则取消所有选择。bNoScroll为FALSE时滚动插入符并使之可见,为TRUE时不滚动。
(8)void ReplaceSel(LPCTSTR lpszNewText,BOOL bCanUndo = FALSE);用lpszNewText指向的字符串来替换选择的正文。如果bCanUndo为TRUE则替换可以被撤销。
(9)int GetLineCount() const;获取正文的行数,只适用于多行编辑框。如果编辑框没有正文则返回1。
(10)int LineLength( int nLine = –1 ) const;获取指定字符索引所在行的字节长度(行尾的回车和换行符不计算在内),如果nLine 的值为-1,则函数返回当前行的长度(假如没有正文被选择),或选择正文占据的行的字符总数减去选择正文的字符数(假如有正文被选择)。若用于单行编辑框,则函数返回整个正文的长度。
(11)int GetLine( int nIndex, LPTSTR lpszBuffer ) const;
    int GetLine( int nIndex, LPTSTR lpszBuffer, int nMaxLength ) const;
    用来获得指定行的正文(不包括行尾的回车和换行符),只适用于多行编辑框。参数nIndex 是行号,lpszBuffer 指向存放正文的缓冲区,nMaxLength 规定了拷贝的最大字节数。若指定的行号小于编辑框的实际行数,函数返回实际拷贝的字节数,若指定的行号大于编辑框的实际行数,则函数返回0。需要注意的是,GetLine 函数不会在缓冲区中字符串的末尾添加字符串结束符(NULL)。    
(12)UINT GetLimitText( ) const;获取编辑框能够接受的正文的最大字节数。
(13)void LimitText(int nChars = 0);设置用户在编辑框中可以输入的正文的最大长度(字节数)。如果nChars为0,则最大长度为UINT_MAX个字节。


 

 九 按钮控件
1.最常用的按钮控件有三种:命令按钮(Button),单选按钮(Radio Button),复选框(Check Box)。单选按钮一般是多个组成一组,同组的单选按钮只能有一个被选中。

2.要是复选框具有三态(选中,未选中,不确定),则必须对复选框选中BS_3STATE风格,不确定状态时复选框内出现一个灰色“√”。

3.按钮控件会向父窗口发送通知消息。

4.按钮控件的创建:
BOOL Create(
LPCTSTR lpszCaption,//指定按钮控件显示的文本
    DWORD dwStyle,   //指定按钮控件的风格
    const RECT& rect,//
    CWnd* pParentWnd,//
    UINT nID         //
    );

5.按钮风格dwStyle取值:
BS_AUTOCHECKBOX :同BS_CHECKBOX,不过单击鼠标时按钮会自动反转
BS_AUTORADIOBUTTON: 同BS_RADIOBUTTON,不过单击鼠标时按钮会自动反转
BS_AUTO3STATE :同BS_3STATE,不过单击按钮时会改变状态
BS_CHECKBOX:指定在矩形按钮右侧带有标题的选择框
BS_DEFPUSHBUTTON:指定默认的命令按钮,这种按钮的周围有一个黑框,用户可以按回车键来快速选择该按钮
BS_GROUPBOX:指定一个组框
BS_LEFTTEXT:使控件的标题显示在按钮的左边
BS_OWNERDRAW:指定一个自绘式按钮
BS_PUSHBUTTON:指定一个命令按钮
BS_RADIOBUTTON:指定一个单选按钮,在圆按钮的右边显示正文
BS_3STATE:同BS_CHECKBOX,不过控件有3 种状态—选择、未选择和变灰
对于一般的子类控件,一般还会设置WS_CHILD、WS_VISIBLE和WS_TABSTOP等风格,WS_TABSTOP风格使按钮控件具有tab停止属性,即按tab键切换焦点控件时能够将焦点停在按钮控件上

6.注意:在调用create函数动态创建一个窗口控件时,首先需要判断m_hWnd句柄是否为空,若为空,则创建控件,不为空,调用destroywindow函数销毁控件串口。否不进行此操作的话,则第二次创建窗口控件时会出现异常

7.CButton类的主要成员函数:
(1)HBITMAP SetBitmap(HBITMAP hBitmap);设置要在按钮中显示的位图。参数hBitmap为位图的句柄。返回值为按钮原来位图的句柄
(2) HBITMAP GetBitmap( ) const;获取之前由SetBitmap函数设置的按钮位图的句柄
(3) void SetButtonStyle(UINT nStyle,BOOL bRedraw = TRUE);设置按钮风格。nStyle指定按钮的风格,bRedraw指定按钮是否重绘,为TRUE则重绘,否则不重绘,默认为重绘。
(4) UINT GetButtonStyle( ) const;获取按钮控件的风格。
(5)void SetCheck(int nCheck);设置按钮的状态。nCheck为0表示未选中状态,1表示选中状态,2表示不确定状态(仅用于复选框)。
(6)int GetCheck( ) const;获取按钮的选择状态。返回值的意义同SetCheck函数的nCheck参数
(7)HCURSOR SetCursor(HCURSOR hCursor);设置按钮上的光标图。参数hCursor指定了光标的句柄。返回值为按钮原来光标的句柄。
(8)HCURSOR GetCursor( );获取之前由SetCursor设置的光标的句柄。
(9)HICON SetIcon(HICON hIcon);设置要在按钮上显示的图标。参数hIcon指定了图标的句柄。返回值为按钮原来图标的句柄
(10) HICON GetIcon( ) const;获取之前由SetIcon设置的图标的句柄。
(11)void SetState(BOOL bHighlight);设置按钮的高亮状态。参数bHighlight指定按钮是否高亮显示
(12)UINT GetState( ) const;获取按钮控件的选择状态、高亮状态和焦点状态。我们可以通过将返回值与各个掩码相与来获得各种状态值,掩码与对应的相与结果说明如下:
    掩码0x0003:用来获取单选按钮或复选框的状态。相与结果为0表示未选中,1表示被选中,2表示不确定状态(仅用于复选框)。
    掩码0x0004:用来判断按钮是否是高亮显示。相与结果为非0值表示按钮是高亮显示的。
    掩码0x0008:相与结果为非零值表示按钮拥有输入焦点。
(13)CWnd::void CheckDlgButton(int nIDButton,UINT nCheck);用来设置按钮的选择状态。参数nIDButton指定了按钮的ID。
(14)UINT CWND::IsDlgButtonChecked(int nIDButton) const;返回复选框或单选按钮的选择状态。
(15)void CWnd::CheckRadioButton(int nIDFirstButton,int nIDLastButton,int nIDCheckButton);用来选择组中的一个单选按钮。参数nIDFirstButton指定了组中第一个按钮的ID,nIDLastButton指定了组中最后一个按钮的ID,nIDCheckButton指定要选择的按钮的ID。
(16) int CWnd::GetCheckedRadioButton(int nIDFirstButton, int nIDLastButton);用来获得一组单选按钮中被选中按钮的ID。参数nIDFirstButton 说明了组中第一个按钮的ID,nIDLastButton 说明了组中最后一个按钮的ID。
(17)另外,CWnd类的成员函数GetWindowText()、SetWindowText()等也可以用来获取或设置按钮中显示的文本。




十 列表框
1.列表框给出了一个选项清单,允许用户从中进行单项或多项选择,被选中的项会高亮显示。列表框可分为单选列表框和多选列表框

2.列表框也会向父窗口发送通知消息。这些通知消息及含义如下:
LBN_DBLCLK :用户用鼠标双击了一列表项,只有具有LBS_NOTIFY 的列表框才能发送该消息
LBN_ERRSPACE :列表框不能申请足够的动态内存来满足需要
LBN_KILLFOCUS :列表框失去输入焦点
LBN_SELCANCEL:当前的选择被取消,只有具有LBS_NOTIFY 的列表框才能发送该消息
LBN_SELCHANGE:单击鼠标选择了一列表项,只有具有LBS_NOTIFY 的列表框才能发送该消息
LBN_SETFOCUS:列表框获得输入焦点
WM_CHARTOITEM:收到WM_CHAR 消息后,向父窗口发送该消息, 只有具有LBS_WANTKEYBOARDINPUT 风格的列表框才会发送该消息
WM_VKEYTOITEM:收到WM_KEYDOWN消息后,向父窗口发送该消息,只有具有LBS_WANTKEYBOARDINPUT 风格的列表框才会发送该消息

3.列表框控件的创建:MFC将列表框控件的所有操作都封装到了CListBox类中。

4.动态创建,需要调用Create函数:
virtual BOOL Create(
   DWORD dwStyle,//
   const RECT& rect,//
   CWnd* pParentWnd,//
   UINT nID
);

5.列表框控件的风格参数dwStyle:
LBS_EXTENDEDSEL:支持多重选择,在点击列表项时按住Shift 键或Ctrl 键即可选择多个项
LBS_HASSTRINGS:指定一个含有字符串的自绘式列表框
LBS_MULTICOLUMN:指定一个水平滚动的多列列表框, 通过调用CListBox::SetColumnWidth 来设置每列的宽度
LBS_MULTIPLESEL:支持多重选择。列表项的选择状态随着用户对该项单击或双击鼠标而翻转
LBS_NOINTEGRALHEIGHT:列表框的尺寸由应用程序而不是Windows 指定。通常,Windows指定尺寸会使列表项的某些部分隐藏起来
LBS_NOREDRAW:当选择发生变化时防止列表框被更新,可发送消息改变该风格
LBS_NOTIFY:当用户单击或双击鼠标时通知父窗口
LBS_OWNERDRAWFIXED:指定自绘式列表框,即由父窗口负责绘制列表框的内容,并且列表项有相同的高度
LBS_OWNERDRAWVARIABLE:指定自绘式列表框,并且列表项有不同的高度
LBS_SORT:使插入列表框中的项按升序排列
LBS_STANDARD:相当于指定了WS_BORDER|WS_VSCROLL|LBS_SORT
LBS_USETABSTOPS:使列表框在显示列表项时识别并扩展制表符(‘ ’),默认的制表宽度是32 个对话框单位
LBS_WANTKEYBOARDINPUT:允许列表框的父窗口接收WM_VKEYTOITEM 和WM_CHARTOITEM 消息,以响应键盘输入
LBS_DISABLENOSCROLL:使列表框在不需要滚动时显示一个禁止的垂直滚动条

6.主要成员函数:
(1)int GetCount( ) const;
    返回值:返回列表框中列表项的数目,如果发生错误则返回LB_ERR。
(2)int GetSel(int nIndex) const;
    参数:nIndex指定某个列表项的索引。返回值:返回nIndex指定列表项的状态。如果此列表项被选择了则返回一个正值,否则返回0,若发生错误则返回LB_ERR。
(3)int SetSel(int nIndex,BOOL bSelect = TRUE);
    此函数只用于多选列表框,使用它可以选择或取消选择指定的列表项。
    参数:nIndex指定某个列表项的索引,若为-1则相当于指定了所有列表项。bSelect为TRUE时选择指定列表项,否则取消选择指定列表项。
    返回值:如果发生错误则返回LB_ERR
(4)  int AddString(LPCTSTR lpszItem);
    此函数用来向列表框中添加字符串。如果列表框指定了LBS_SORT风格,字符串就被以排序顺序插入到列表框中,如果没有指定LBS_SORT风格,字符串就被添加到列表框的结尾。
    参数:lpszItem指定了要添加的字符串。
    返回值:返回字符串在列表框中添加的位置。如果发生错误则返回LB_ERR,内存不够则返回LB_ERRSPACE。
(5) int InsertString(int nIndex, LPCTSTR lpszItem);
    该函数用来在列表框中的指定位置插入字符串。与AddString函数不同的是,InsertString函数不会导致LBS_SORT风格的列表框重新排序。不要在具有LBS_SORT风格的列表框中使用InsertString函数,以免破坏列表项的次序。
    参数:。参数nIndex 给出了插入位置(索引),如果值为-1,则字符串将被添加到列表的末尾。参数lpszItem 指定了要插入的字符串。
    返回值:返回实际的插入位置,若发生错误,会返回LB_ERR 或LB_ERRSPACE。
(6) int DeleteString(UINT nIndex);
    该函数用于删除指定的列表项。
    参数:nIndex 指定了要删除项的索引。
    返回值:函数的返回值为剩下的列表项数目,如果nIndex 超过了实际的表项总数,则返回LB_ERR。
(7)void ResetContent();该函数用于清除所有列表项。
(8)int GetText(int nIndex,LPTSTR lpszBuffer) const;
    void GetText(int nIndex,CString& rString) const;
    这两个成员函数用于获取指定列表项的字符串。参数nIndex 指定了列表项的索引。参数lpszBuffer 指向一个接收字符串的缓冲区。引用参数rString 则指定了接收字符串的CString对象。第一个版本的函数会返回获得的字符串的长度,若出错,则返回LB_ERR;第二个版本的函数则不会。
(9) int GetTextLen(int nIndex) const;
    该函数返回指定列表项的字符串的字节长度。
    参数:nIndex 指定了列表项的索引。
    返回值:若出错则返回LB_ERR。
(10)int GetCurSel() const;
    该函数仅适用于单选列表框,用来返回当前被选择项的索引,如果没有列表项被选择或有错误发生,则函数返回LB_ERR。
(11)int SetCurSel(int nIndex);
    该函数仅适用于单选列表框,用来选择指定的列表项。该函数会滚动列表框以使选择项可见。参数nIndex 指定了列表项的索引,若为-1,那么将清除列表框中的选择。若出错函数返回LB_ERR。
(12)int GetSelCount() const;
    该函数仅用于多重选择列表框,它返回选择项的数目,若出错函数返回LB_ERR
(13)int FindString(int nStartAfter,LPCTSTR lpszItem) const;
    该函数用于对列表项进行与大小写无关的搜索。参数nStartAfter 指定了开始搜索的位置,合理指定nStartAfter 可以加快搜索速度,若nStartAfter 为-1,则从头开始搜索整个列表。参数lpszItem 指定了要搜索的字符串。函数返回与lpszItem 指定的字符串相匹配的列表项的索引,若没有找到匹配项或发生了错误,则会返回LB_ERR。FindString 函数先从nStartAfter指定的位置开始搜索,若没有找到匹配项,则会从头开始搜索列表。只有找到匹配项,或对整个列表搜索完一遍后,搜索过程才会停止,所以不必担心会漏掉要搜索的列表项。
(14) int SelectString(int nStartAfter,LPCTSTR lpszItem);
    该函数仅适用于单选列表框,用来选择与指定字符串相匹配的列表项。该函数会滚动列表框以使选择项可见。参数的意义及搜索的方法与函数FindString 类似。如果找到匹配的项,函数返回该项的索引,如果没有匹配的项,函数返回LB_ERR 并且当前的选择不被改变。