友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
第三电子书 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

VC语言6.0程序设计从入门到精通-第44部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


图 8…6 所示。  



                                                                          



                               图 8…6    为对话框模板添加控件  



    注意,在图 8…6  中可以看到,新添加包含“删除”按钮的对话框模板是放在文件对话框 

的底部。因此需要将对话框的模板设置为子窗口而且无边框,更重要的是要复选“Clip  

siblings ”和“Clip children ”两个属性,使得文件对话框的原始控件可以得到恰当的重绘。  



    2 .重载 CFileDialog 类  



    在 ClassWizard 中创建一个CFileDialog 的派生类CMyFileDialog 。然后修改CMyFileDialog 

的构造函数,代码如下:  



    //构造函数创建一个新的打开文件对话框,没有后缀名过滤器和默认的后缀名  



    //参数中设置 OFN_ENABLETEMPLATE 用于从自定义模板中添加新的控件  



    CMyFileDialog::CMyFileDialog() :  



             CFileDialog(TRUE; NULL; NULL;    



                      OFN_FILEMUSTEXIST|OFN_ENABLETEMPLATE; NULL; NULL)  



     {  



         //设置文件对话框的模板为 IDD_MYFILEDIALOG  



         //这里有两个参数分别对应于老版本和新版本的文件对话框  



         //这里将两类版本的文件对话框模板都进行设置  



                                                                                 ·205 ·  


…………………………………………………………Page 217……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



         SetTemplate(IDD_MYFILEDIALOG;IDD_MYFILEDIALOG);  



     }  



     然后在 ClassWizard  中为 CMyFileDialog 添加 IDC_DEL 控件的 BN_CLICKED 处理函数 

OnDel(),代码如下:  



     void CMyFileDialog::OnDel()    



     {  



         // TODO: Add your control notification handler code here  



         //  提示用户是否删除文件  



         if (MessageBox(〃确定删除文件?〃;〃提示〃;MB_OKCANCEL)!=IDOK)  



         {  



              //不删除文件则退出  



              return;  



         }  



         CFile::Remove(GetPathName());    //删除选定的文件  



     }  



     3 .使用重载的文件对话框  



     创建好 CMyFileDialog 就可以在程序中使用重载后的对话框,使用方法跟普通的文件对 

话框类似,代码如下:  



     CMyFileDialog dlg;     //创建 CMyFileDialog 对象  



     if (dlg。DoModal()==IDOK)   //打开对话框  



     {  



          ……                     //进行用户选定文件后的处理  



     }  



     这样就能打开如图 8…4 所示的对话框,在选择文件打开的同时还可以通过单击“删除” 

按钮删除一个选定的文件,为文件对话框提供了附加的功能。  

     本小节给出的例子稍加修改就可以添加更多更复杂的功能 。同时 CFileDialog 还提供了一 

些虚函数用于自定义处理文件对话框原有控件产生的消息,重载这些函数就可以为 

CFileDialog 原有的功能进行重新设计,从而大大提高文件对话框的灵活性。  



8。4    本章小结  



     本章主要介绍了在  MFC            中如何对文件进行读写操作和一些管理操作,主要内容包括以 

下几个方面:  

     o  在文档视图结构中对文档进行串行化;  

     o  用 CFile 类和相关类对磁盘文件进行读写和管理;  

     o  文件对话框 CFileDialog 的一些高级使用方法。  

     总之,文件操作是应用程序保存和使用数据的基本方法 。只有熟练使用本章中介绍的各 

种文件操作的类和函数才能在程序中体现出更大的灵活性。  



 ·206 ·  


…………………………………………………………Page 218……………………………………………………………

                 第 9 章    多线程  

                 第 9 章    多线程  



   本章主要介绍 Windows 操作系统下多线程的基本概念、创建管理线程的方法,以及线程 

的同步问题。Windows 提供了大量的线程同步技术,这些技术可以应用于不同的实际情况。 

同时,MFC 对线程操作进行了封装,提供了支持线程操作的类库。本章主要讨论这些技术, 

并且给出相应的实例。主要包括以下几个方面的内容:  

   o  Windows 下多线程的基本概念;  

   o  用户界面线程和工作者线程;  

   o  线程的管理操作;  

   o  线程的同步;  

   o  多线程编程实例。  



9。1    多线程的基本概念  



   在 Win32 下,一个应用程序由一个或多个进程组成。一个进程由一个或多个线程以及代 

码、数据和其他内存中的程序资源组成。典型的程序资源包括打开的文件、信号量、动态分 

配的内存等。线程在进程空间中执行。  

   线程是操作系统分配处理器时间的最小单位 。每个线程有自己的堆栈,CPU 寄存器,以 

及程序入口。每个线程共享所有处理器的资源。  

   进程中的每个线程都独立执行,不会影响该进程中的其他线程。所有线程共享公共的资 

源。因此必须采用信号量或者其他进程间通信方法来调整线程的工作。  



9。2    两种重要的线程  



   Windows 提供了两种线程,用户界面线程和工作者线程。用户界面线程通常用来处理消 

息循环、与用户交互,工作者线程用来处理后台的计算。下面分别介绍这两种线程。  



9。2。1    用户界面线程  



   每一个 Windows 应用程序都有一个主线程 。这里的用户界面线程是指用来和用户进行交 

互的线程。接收用户传送的数据,并且做出响应。用户界面线程通常包含自己的窗口,有自 

己的消息循环,独立于应用程序的其他部分。  

   创建一个用户界面线程需要首先继承线程类 CWinThread,重载它的成员函数,如表 9…1 

所示。最后调用 AfxBeginThread 创建线程对象。  


…………………………………………………………Page 219……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



    表 9…1                  需要重载的 CWinThread 的成员函数  



                 函数名称                                     作用  

 InitInstance                            线程的初始化,通常需要重载  

 ExitInstance                            释放线程占用的资源,通常需要重载  

 OnIdle                                  空闲时间的处理,不一定重载  

 PreTranslateMessage                     过滤消息,不一定重载  

 ProcessWndProcException                 处理线程抛出的意外  

 Run                                     线程控制函数,通常不重载  



9。2。2    工作者线程  



    工作者线程通常用来处理后台运行的任务 。在后台任务运行的同时,用户可进行其他操 

作,不必等待后台任务的结束 。例如一个三维模型编辑软件,用户要对两个模型做布尔运算。 

在进行计算的同时,用户希望可以观察两个模型,对模型进行旋转,缩放的操作。再如文本 

浏览软件的打印功能,在打印文本的工程中,用户仍然会继续浏览文本内容。这些都属于工 

作者线程。  

    创建一个工作者线程只需要两个步骤 。首先实现工作者线程的功能函数,然后启动线程 

即可。可以调用 Win32 提供的 API 函数 CreateThread 创建一个线程,MFC 对 Win32  的线程 

操作做了封装,也可以通过调用 AfxBeginThread 创建一个线程对象 。这些函数及其调用方法 

将在下一节详细介绍。  



9。3    线程的操作  



    本小节介绍 Windows 线程的操作方法,包括线程的创建、线程的管理、线程的同步、线 

程的终止等。  



9。3。1    线程的创建  



    线程的创建方法有 3 种,分别介绍如下:  



    1.调用 Win32API 函数 CreateThread 和 CreateRemoteThread  



    (1)CreateThread  

    函数 CreateThread 用来创建线程。如果调用成功则返回非 0,否则返回 0 。它的函数原型 

如下:  



    HANDLE CreateThread(  



        LPSECURITY_ATTRIBUTES lpThreadAttributes;    



        SIZE_T dwStackSize;               



        LPTHREAD_START_ROUTINE lpStartAddress;   



        LPVOID lpParameter;                                              



        DWORD dwCreationFlags;                                      



 ·208 ·  


…………………………………………………………Page 220……………………………………………………………

                                                                               第 9 章    多线程  



         LPDWORD lpThreadId                                            



     );  



     函数中主要参数的意义如下:  

     o  lpThreadAttributes :指向SECURITY_ATTRIBUTES结构的指针,决定返回的句柄是否 

       可以被继承。  

     o  dwStackSize :设定堆栈的大小。  

     o  lpStartAddress :线程函数的名称,它的参数是第 4 个参数。  

     o  lpParameter :线程函数的参数。    

     o  dwCreationFlags :线程创建标志。如果是 CREATE_SUSPENDED,则线程的初始状态 

       为挂起,直到调用了 ResumeThread 才开始执行,如果为 0,线程创建后即开始执行。    

     o  lpThreadId :存放线程标志的变量指针。  



     (2 )CreateRemoteThread  

     函数 CreateRemoteThread 用来创建在另外一个进程的虚拟空间中执行的线程,它的函数 

原型如下:  



     HANDLE CreateRemoteThread(  



         HANDLE hProcess;    



         LPSECURITY_ATTRIBUTES lpThreadAttributes;    



         SIZE_T dwStackSize;    



         LPTHREAD_START_ROUTINE lpStartAddress;    



         LPVOID lpParameter;    



         DWORD dwCreationFlags;    



         LPDWORD lpThreadId    



     );  



     函数中主要参数的意义如下。  

     o  hProcess :进程的句柄。  

     o  lpThreadAttributes :指向SECURITY_ATTRIBUTES结构的指针,决定返回的句柄是否 

       可以被继承。  

     o  dwStackSize :设定堆栈的大小。  

     o  lpStartAddress :线程函数的名称,它的参数是第四个参数。  

     o  lpParameter :线程函数的参数。    

     o  dwCreationFlags :线程创建标志。如果是 CREATE_SUSPENDED,则线程的初始状态 

       为挂起,直到调用了ResumeThread才开始执行。如果为 0,线程创建后即开始执行。    

     o  lpThreadId :存放线程标志的变量指针。  



     2 .C 运行库函数_beginthreadex  



     _beginthreadex 和 Win32API 函数 CreateThread 非常类似。如果调用成功,返回新创建线 

程的句柄,否则返回…1 。它们的参数几乎完全相同。函数原型如下:  



     unsigned long _beginthread(  



       void( __cdecl *start_address )( void * );    



                                                                                       ·209 ·  


…………………………………………………………Page 221……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



        unsigned stack_size;    



        void *arglist    



      );  



      unsigned long _beginthreadex(    



        void *security; unsigned stack_size;    



        unsigned ( __stdcall *start_address )( void * );    



        void *arglist;    



        unsigned initflag;    



        unsigned *thrdaddr    



      );  



      函数中主要参数的意义如下。  

      o  start_address:线程的入口地址。  

      o  stack_size:初始堆栈大小。  

      o  arglist :传给线程的参数。  

      o  security:安全属性。  

      o  initflag :线程创建标志。  

      o  thrdaddr :存放线程标志的变量指针。  



      3 .调用函数 AfxBeginThread  



      MFC 对 Win32 的线程操作做了封装,可以通过调用 AfxBeginThread 创建一个线程对象, 

函数 AfxBeginThread 有两种调用方式,函数原型如下:  



      CWinThread* AfxBeginThread(    



        AFX_THREADPROC pfnThreadProc ;    



        LPVOID pParam ; int nPriority = THREAD_PRIORITY_NORMAL;    



        UINT nStackSize = 0;    



        DWORD dwCreateFlags = 0;    



        LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL    



      );  



      CWinThread* AfxBeginThread(    



        CRuntimeClass* pThreadClass ;    



        int nPriority = THREAD_PRIORITY_NORMAL;    



        UINT nStackSize = 0;    



        DWORD dwCreateFlags = 0;    



        LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL    



      );  



      函数中主要参数的意义如下。  

      o  pfnThreadProc :指向工作者线程的控制函数指针,该参数不能为空,这个函数必须按 

         如下方式声明:  



      UINT MyControllingFunction( LPVOID pParam )  



      o  PThreadClass :继承自 CWinThread 的RUNTIME_CLASS对象。  



 ·210 ·  
返回目录 上一页 下一页 回到顶部 1 2
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!