目录
我们在工作中,经常需要在新线程里面创建对话框,要么是在工作线程里面创建对话框,
要么是再开一个独立的带对话框的UI线程,均可。
方式分别如下:
UI线程创建方式
CWinThread *pThread = AfxBeginThread(RUNTIME_CLASS(你的UI线程类),
THREAD_PRIORITY_NORMAL, 0, 0, NULL);
你的线程类必须派生自CWinThread,不能是其它基类,也不能没有基类。
头文件模板
这个类的形式必须如下:
class CYourUIThread :
public CWinThread
{
DECLARE_DYNCREATE(CYourUIThread) ///关键行
public:
CYourUIThread();
~CYourUIThread();
public:
virtual BOOL InitInstance();
protected:
DECLARE_MESSAGE_MAP(); ///关键行
};
实现代码模板
#include "stdafx.h"
#include "YourUIThread.h"
IMPLEMENT_DYNCREATE(CYourUIThread, CWinThread); ///关键行
CYourUIThread::CYourUIThread()
{
}
CYourUIThread::~CYourUIThread()
{
}
BEGIN_MESSAGE_MAP(CYourUIThread, CWinThread) ///关键行
END_MESSAGE_MAP()
BOOL CYourUIThread::InitInstance()
{
CWinThread::InitInstance(); ///关键行
//CXXXXXDlg为你的新的对话框
CXXXXXDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
return TRUE;
}
工作线程的创建方式
CWinThread *pThread = AfxBeginThread(工作线程名, this,
THREAD_PRIORITY_NORMAL, 0, 0, NULL);
工作线程的线程模板
UINT CXXXXX::ThreadXXXXX(LPVOID lParam)
{
CXXXDlg *pMsgDlg = new CXXXDlg();
if (NULL != pMsgDlg)
{
pMsgDlg->Create(CXXXDlg::IDD, NULL);
pMsgDlg->ShowWindow(SW_SHOW);
pMsgDlg->MsgLoop();//关键行
pMsgDlg->DestroyWindow();
delete pMsgDlg;
pMsgDlg = NULL;
}
return 0;
}
工作线程里的那个对话框就只能是非模态了,然后自己加个消息循环,举例如下:
对话框头文件模板
#pragma once
#include "resource.h"
class CXXXDlg : public CDialogEx
{
DECLARE_DYNAMIC(CXXXDlg)
public:
CXXXDlg(CWnd* pParent = NULL); // 标准构造函数
virtual ~CXXXDlg();
// 对话框数据
enum { IDD = IDD_DIALOG_xxxx };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
void MsgLoop();
virtual BOOL OnInitDialog();
};
对话框实现部分
#include "stdafx.h"
#include "XXXDlg.h"
#include "afxdialogex.h"
IMPLEMENT_DYNAMIC(CXXXDlg, CDialogEx)
CXXXDlg::CXXXDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CXXXDlg::IDD, pParent)
{
}
CXXXDlg::~CXXXDlg()
{
}
void CXXXDlg::MsgLoop()
{
MSG msg;
HWND hWnd = m_hWnd;
while (GetMessage(&msg, hWnd, 0, 0))
{
if (msg.message == WM_CLOSE)
break;
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
void CXXXDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CXXXDlg, CDialogEx)
END_MESSAGE_MAP()
BOOL CXXXDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
return TRUE;
}
记住:
- 一个进程也可以有N个UI线程(不推荐、但可以这样做)
- 一个进程可以有N个消息循环(不推荐、但可以这样做)
- 不要跨线程去UpdateData另一个线程类的对话框数据(禁止)
如有疑问,可以站内私信联系或评论留言。