友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
喜书网 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

C语言实例教程(PDF格式)-第48章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!



Control,两种选择的不同将在后面的内容中讲述),在Variable  

type下拉列表中选择CString        (还有其它很多数据类型可供选择,但 

由于这里编辑框中的内容为一字符串,因此CString是最恰当的选 

择)。单击OK关闭对话框。  


…………………………………………………………Page 296……………………………………………………………

                                                 



                     图6。 6 为控件映射添加成员变量  



5。    检查一下现在的ClassWizard对话框 (图6。7)与图6。5相比有何不 

同。在图6。7所示的对话框中下方的Maximum   characters文本框中输 

入50。由字面意思可以很容易猜出其含义,即将编辑框IDC_EDIT中可 

能的最长字符串的大小限制为50。单击OK关闭对话框。  



                                                           



                  图6。 7 使用ClassWizard设置数据验证方案  



6。          从Workspace窗口的ClassView中双击类CDialogDemoDlg的 

OnInitDialog成员函数,使用下面的代码来代替位于语句  



return TRUE;  



前的// TODO注释:  



m_strEdit=〃您好! 请在这里输入一些字符串。〃;  



UpdateData(FALSE);  


…………………………………………………………Page 297……………………………………………………………

7。  在ClassView中双击类CDialogDemoApp的InitInstance成员函数, 

使用下面的代码来找替位于选择支  



if (nResponse == IDOK)  



下的//TODO注释:  



AfxMessageBox(dlg。m_strEdit);  



然后将同一成员函数中的下面的代码行删掉 (或注释掉):  



m_pMainWnd = &dlg;  



8。 编译并运行该应用程序。显示如图6。8所示的对话框。  



                                     



                图6。 8 示例程序DialogDemo的运行结果  



在图6。8所示的文本框中输入一些字符,单击 “确定”。随即弹出如 

图6。9所示的消息框。该消息框复述了用户在图6。8所示的对话框中的 

输入。我们还发现,在图6。8所示的对话框中,当输入字符串达到一 

定的长度之后,我们不可以再输入更多的字符,这是我们在前面设置 

了Maximum characters为50的结果。  



                                       



               图6。 9 以消息框的形式反馈输入的字符串  



下面我们来看在上面的步骤中都完成了什么。首先我们使用资源编辑 

器向对话框模板中添加这些标准控件,这一步的概念很清晰,因此并 

不难理解。  



然后,我们打开了所绘制的编辑框的Properties               (属性)对话框。先 

将其控件ID设置为IDC_EDIT。这时如果打开头文件Resource。h,就会 

发现宏IDC_EDIT被定义为常量1001。不过,事实上在很多情况下我们 

并不需要关心每一控件的ID的具体值,而只需要记住相应的助记符。 

对于这里的编辑框控件,我们只需要记住IDC_EDIT即可,而不需要关 


…………………………………………………………Page 298……………………………………………………………

心它等于1001。接着,我们在Styles选项卡中设置了Multiline属 

性,同时清除了Auto        HScroll属性,两者共同作用使用得编辑框 

IDC_EDIT支持多行文本,并且如文本行的长度超过编辑框宽度时自动 

回行。  



下面的步骤是最重要的一步,我们动用了功能强大的工具 

ClassWizard。首先,我们将编辑框与一个CString对象相关联,这使 

用了一种被称为Dialog  Data  Exchange  (DDX)的机制。在这种机制 

中,我们先在处理函数OnInitDialog或对话框类的构造函数中对对话 

框对象的成员变量进行初始化,在对话框显示之前,框架的DDX机制 

将成员变量的值传递给对话框中的控件。这个过程在成员函数 

DoModal或Create被调用的过程中发生。类CDialog中对OnInitDialog 

成员函数的默认实现调用了类CWnd成员函数UpdateData来初始化对话 

框中的控件。这时我们就可以看到前面的第6步还可在具有下面的几 

种变通方案:  



1。 将代码行  



m_strEdit=〃您好! 请在这里输入一些字符串。〃;  



移到对基类的OnInitDialog成员函数的调用之前,即位于下面的代码 

之前:  



CDialog::OnInitDialog();  



2。 将代码  



m_strEdit=〃您好! 请在这里输入一些字符串。〃;  



移到类CDialogDemoDlg的构造函数中。  



对于上面的两种方法,与前面第6步中使用的方法相比,我们没有必 

要调用类CWnd的成员函数UpdateData。因为该函数在类CDialog的成 

员函数OnInitDialog中将被调用。  



这三种方法之间并没有明确的优劣之分,在很多情况下,它们分别适 

用于不同的场合。  



这里我们说一下成员函数UpdateData。该函数带有一个布尔类型的参 

数,如果该参数为FALSE,函数UpdateData将成员变量的值传递给对 

话框的变量;而如果该参数为TRUE,函数UpdateData将进行相反的过 

程。  


…………………………………………………………Page 299……………………………………………………………

如果用户单击了对话框中ID为IDOK的按钮,或者以TRUE为参数调用函 

数UpdateData,DDX机制从控件中将值传递到成员变量,同时对话框 

数据验证 (dialog  data  validation,DDV)机制根据设定的验证规则 

验证所有数据项。  



在数据交换的过程中,成员函数UpdateData先创建一个 

CDataExchange对象,然后调用对话框对类CDialog成员函数 

DoDataExchange的重载版本。该CDataExchange对象将作为成员函数 

DoDataExchange的一个参数,该参数定义了数据交换的上下文。  



在DoDataExchange中,我们为每一个数据成员指定了一个对DDX函数 

的调用。每一个函数定义了基于由成员函数UpdateData所提供的 

CDataExchange参数所确定的上下文而进行的双向数据交换。  



下面的代码摘自实现文件DialogDemo。cpp 中对函数DoDataExchange的 

定义:  



void CDialogDemoDlg::DoDataExchange(CDataExchange* pDX)  



{  



CDialog::DoDataExchange(pDX);  



//{{AFX_DATA_MAP(CDialogDemoDlg)  



DDX_Text(pDX; IDC_EDIT; m_strEdit);  



DDV_MaxChars(pDX; m_strEdit; 50);  



//}}AFX_DATA_MAP  



}  



在两行注释//{{AFX_DATA_MAP和//}}AFX_DATA_MAP之间的代码部分称 

作数据映射。函数DDX_Text使用CString对象m_strEdit与ID为 

IDC_EDIT的编辑框控件相关联。函数DDV_MaxChars设置与编辑框控件 

IDC_EDIT相关联CString对象m_strEdit的最大长度为50。  



需要注意的是,如果用户在模式对话框中单击了 “取消”(Cancel)按 

钮,DoModal函数将返回值IDCANCEL,在这种情况下,在对话框和对 

话框对象之前的数据交换不会发生。  



由于这个原因,如果DoModal函数返回了值IDOK,我们可以使用下面 

的代码来复述用户在对话框中所输入的值:  


…………………………………………………………Page 300……………………………………………………………

AfxMessageBox(dlg。m_strEdit);  



  l 注意:  



  l 在前面的第7步中有一个乍看起来有一些费解的过程,这就是我们 

   为什么要将下面的代码从函数OnInitDialog中删除:  



  l m_pMainWnd = &dlg;  



      这基于下面的一个事实:  



      类CWinThread的数据成 员m_pMainWnd有一个有用的特征,如 

      果由该成员所引用的窗口被关闭的话,MFC库将 自动的终止 

      CWinThread对象所代表的线程。这样,如果我们将指向dlg的 

      指针赋予了成员变量m_pMainWnd,那么,无论我们单击 了 

       “确认”还是 “取消”,应用程序的主线程都将被自动终 

      止,之后的代码 当然不会得到执行。而在本示例中,我们希 

      望在对话框被关闭后程序继续运行 (即弹出一个消息重述用户 

      所输入的内容),因此不应该将dlg对象的指针赋予成员变量 

      m_pMainWnd,从而需要将前面的代码从函数OnInitDialog中 

      删除。  



          



           第二节 所有窗口类的基类:CWnd  



在MFC中类CWnd是一个很重要的类,它封装了Windows窗口句柄HWND。 

在Windows编程中,窗口句柄唯一的标识了一个窗口。然而,尽管类 

CWnd的对象和窗口句柄之间有着如此紧密的联系,但两者并不是等同 

的概念。CWnd对象通过类CWnd的构造函数和析构函数创建和消毁,而 

Windows窗口是Windows内部的一种数据结构,在类CWnd中,它通过 

Create成员函数创建,通过其析构函数消毁。除此之外,成员函数 

DestroyWindow可以消毁Windows窗口,而不需要消毁CWnd对象。  



传统的Windows应用程序中,消息是通过一个称作窗口过程 (window  

procedure,通常具有WndProc之类的函数名)的回调函数来处理的。 

这种方式在MFC中仍然使用,但为CWnd类及其消息映射所隐藏。在类 

CWnd中,Windows通知消息会被自动的通过消息映射传递到类CWnd中 

合适的OnMessage成员函数 (这里OnMessage是指这些函数具有的以On 

为前缀的函数名,如OnPaint和前面接触到的OnInitDialog等)进行处 

理。通常我们都在类CWnd的派生类中重载需要处理的特定消息所对应 

的OnMessage成员函数。除了直接从CWnd派生新的窗口类以外,我们 


…………………………………………………………Page 301……………………………………………………………

更倾向于从MFC中定义的其它类,如CFrameWnd、CMIDFrameWnd、 

CMDIChileWnd、CView和CDialog以及CButton之类的控件类派生新的 

窗口类。在MFC中定义的这些类本身也是从CWnd派生的。  



通常我们使用两个步骤来创建一个窗口:首先,调用类CWnd的构造函 

数来构造一个CWnd对象,然后调用其成员函数Create来创建窗口并将 

该窗口与所创建的CWnd对象相关联。  



当用户终止该窗口时,消毁与之相关联的CWnd对象,或者调用CWnd对 

象的成员函数DestroyWindow删除窗口并消毁其数据结构。  



大多数以HWND为参数的Win32   API函数都已作为类CWnd的成员函数进 

行了封装,事实上,很多时候我们通过类Wnd的派生类调用的成员
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!