• 创建用户界面线程


    与工作者线程不同的是,用户界面线程通常用于处理用户的输入,响应用户产生的消息。为了建立一个用户界面线程,需要从CWinThread引出自定义的类,并将该类的运行时信息传给用户界面形式的AfxBeginThread函数,以便创建用户界面线程。
    
    一般来说,用户界面线程的创建过程需要先从基类CWinThread中派生出用户自定义的新类,再使用AfxBeginThread函数创建线程。
    【范例17-1】下面将通过一个实例来讲述如何创建一个用户界面线程。该实例实现创建一个独立于应用程序的窗口,其具体操作步骤如下所述。
      新建一个MFC单文档应用程序。单击【File】|【New】菜单项,打开新建对话框,选择建立【MFC AppWizard[exe]】工程,为工程命名为“创建线程”。在AppWizard的第一步中选中【Single document】,其他步骤按照默认设置,单击【Finish】按钮完成创建。
      添加菜单项。为了演示出该实例创建独立于应用程序的用户界面线程,在该工程中添加新的菜单项“用户界面线程”用于创建和启动线程。具体操作为:
    打开工作区的【ResourceView】选项卡,修改MFC应用程序向导自动生成的菜单资源。在原菜单基础上再添加一个弹出式菜单“线程”。在其下面添加菜单项“用户界面线程”,设置其ID为ID_THREAD_GUI,如图17-3所示。
      从CWinThread中派生新类。派生新类的方法很简单,在以前章节中也介绍过。可以使用ClassWizard工具单击【Add Class】|【New】命令,也可以通过打开工作区【ClassView】选项卡。右键单击最顶层类集,在弹出的快捷方式菜单中选择【New Class】菜单项来启动【New Class】对话框。在基类列表框中选择CWindThread类,然后在【Name】文本框中输入派生类名。该实例定义其派生类为MyThread。
    单击【OK】按钮后即创建了CWinThread类的派生类MyThread。此时读者在工作台的【FileView】标签中找到MyThread.h文件,打开后可看到如下的类定义。
    // MyThread thread
    class MyThread : public CWinThread
    {
        DECLARE_DYNCREATE(MyThread)
    protected:
        MyThread();           
        ……
        DECLARE_MESSAGE_MAP()
    };
    
    说明:代码中使用了DECLARE_DYNCREATE宏,使用该宏表明MyThread类具有动态创建的能力。使用DECLARE_MESSAGE_MAP宏表明具有消息映射,可以处理命令消息。
    再打开MyThread类的实现文件(MyThread.cpp)。下面列出其中一部分代码。
    // MyThread
    IMPLEMENT_DYNCREATE(MyThread, CWinThread)
    
    MyThread::MyThread()
    {
    }
    ……
    BEGIN_MESSAGE_MAP(MyThread, CWinThread)
    END_MESSAGE_MAP()
    
    提 示:代码中使用了IMPLEMENT_DYNCREATE宏是和头文件中DECLARE_ DYNCREATE宏相对应的,其保证新建的类具有动态创建的能力。而BEGIN_MESSA GE_MAP和END_MESSAGE_MAP宏是和头文件中DECLARE_MESSAGE_MAP宏相对应的,使类具有消息映射机制。
      重载CWinThread的虚函数。基类CWinThread有一些可以重载的虚函数。其中InitInstance函数必须要重载,该函数用于初始化实 例。ExitInstance函数一般情况下也应该重载,该函数用于清除实例。而Run函数,如果没有特殊需要,一般不去重载。该函数负责将消息分发出 去。重载InitInstance函数如示例代码17-1所示。
    示例代码17-1
    01    BOOL MyThread::InitInstance()
    02    {
    03        // TODO:  perform and per-thread initialization here
    04        CFrameWnd* pFrameWnd= new CFrameWnd();                    //定义框架对象
    05        pFrameWnd->CreateEx(0,AfxRegisterWndClass( CS_HREDRAW|CS_VREDRAW) ,
    06                "用户界面线程示例",    
    07                WS_OVERLAPPEDWINDOW|WS_VISIBLE,
    08                CRect(100,100,400,300),
    09                NULL,
    10                0);                                             //创建窗口
    11        m_pMainWnd=pFrameWnd;
    12        pFrameWnd->ShowWindow(SW_SHOW);                        //显示窗口
    13        pFrameWnd->UpdateWindow();
    14        return TRUE;
    15    }
      使用AfxBeginThread函数创建并启动线程对象。在CMyView类中,添加新建菜单项的COMMAND命令消息处理函数 OnThreadGui。添加方法为:右键单击CMyView类,选择【Add Windows Message Handle】菜单项,进入添加消息处理函数对话框。在【Class or Object IDS】下拉列表框中选择菜单项ID_Thread_Gui,事件则选择【COMMAND】并双击。
      单击【OK】按钮添加完成。单击【Edit Existing】按钮进入代码编辑器界面。在该消息处理函数中通过调用AfxBeginThread函数来启动用户界面线程,代码如下:
    void CMyView::OnThreadGui() 
    {
        // TODO: Add your command handler code here
        AfxBeginThread(RUNTIME_CLASS(MyThread));                //启动用户界面线程
    }
    代码中又用到了AfxBeginThread函数,但是创建工作者线程和创建用户界面线程的AfxBeginThread函数的形式是有一定区别的。在这段代码里,用的是创建用户界面线程的AfxBeginThread函数。
    

  • 相关阅读:
    electron中使用vue.js
    大三上学期学期总结
    小程序 弹窗的提示文字中添加链接
    03月14日总结
    03月16日总结
    03月10日总结
    03月11日总结
    03月19日总结
    03月17日总结
    03月15日总结
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318575.html
Copyright © 2020-2023  润新知