平时在MFC里使用多线程时其实是很方面的,因为微软提供了一个API让我们很方面的去创建线程:下面是MSDN中关于CreateThread的函数原型:
1、函数原型声明:
- CreateThread
- The CreateThread function creates a thread to execute within the virtual address space of the calling process.
- To create a thread that runs in the virtual address space of another process, use the CreateRemoteThread function.
- HANDLE CreateThread(
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- SIZE_T dwStackSize,
- LPTHREAD_START_ROUTINE lpStartAddress,
- LPVOID lpParameter,
- DWORD dwCreationFlags,
- LPDWORD lpThreadId
- );
2、参数说明:
- lpThreadAttributes:指向SECURITY_ATTRIBUTES型态的结构的指针。在Windows 98中忽略该参数。在Windows NT中,它被设为NULL,表示使用缺省值。
- dwStackSize,线程堆栈大小,一般=0,在任何情况下,Windows根据需要动态延长堆栈的大小。
- lpStartAddress,指向线程函数的指针,形式:@函数名,函数名称没有限制,但是必须以下列形式声明:
- DWORD WINAPI ThreadProc (LPVOID pParam) ,格式不正确将无法调用成功。
- lpParameter:向线程函数传递的参数,是一个指向结构的指针,不需传递参数时,为Nil。
- dwCreationFlags :线程标志,可取值如下
- CREATE_SUSPENDED: 创建一个挂起的线程
- 0 :创建后立即激活。
- lpThreadId:保存新线程的id。
3、返回值:
函数成功,返回线程句柄;函数失败返回false。
4、实例代码:
A、新建一个对话框工程为MFC,在MFCDlg.h添加两个成员函数,注意一定要是静态的,代码如下:
- /////////////////////////////////////////////////////////////////////////////
- // CMFCDlg dialog
- class CMFCDlg : public CDialog
- {
- // Construction
- public:
- CMFCDlg(CWnd* pParent = NULL); // standard constructor
- // 线程B1、B2函数
- static DWORD WINAPI ThreadB1(LPVOID lpParam);
- static DWORD WINAPI ThreadB2(LPVOID lpParam);
- ......
- }
B、在cpp文件中实现函数,添加代码如下:
- DWORD WINAPI CMFCDlg::ThreadB1(LPVOID lpParam)
- {
- // 定义结构对象
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- BOOL bRet;
- // 申请空间
- ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
- ZeroMemory(&si,sizeof(STARTUPINFO));
- // 设置进程启动属性
- si.cb = sizeof(STARTUPINFO);
- si.lpReserved = NULL;
- si.lpDesktop = NULL;
- si.lpTitle = NULL;
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_SHOWNORMAL;
- si.cbReserved2 = NULL;
- si.lpReserved2 = NULL;
- bRet = CreateProcess(_T("C://Program Files//Internet Explorer//IEXPLORE.exe"),
- _T("http://www.coderfans.cn"),
- NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
- return 0;
- }
- DWORD WINAPI CMFCDlg::ThreadB2(LPVOID lpParam)
- {
- // 定义结构对象
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- BOOL bRet;
- // 申请空间
- ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
- ZeroMemory(&si,sizeof(STARTUPINFO));
- // 设置进程启动属性
- si.cb = sizeof(STARTUPINFO);
- si.lpReserved = NULL;
- si.lpDesktop = NULL;
- si.lpTitle = NULL;
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_SHOWNORMAL;
- si.cbReserved2 = NULL;
- si.lpReserved2 = NULL;
- bRet = CreateProcess(_T("C://Program Files//Internet Explorer//IEXPLORE.exe"),
- _T("http://blog.csdn.net/wangningyu"),
- NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
- return 0;
- }
C、然后在对话框初始化时创建进程即可,代码如下:
- BOOL CMFCDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- ......
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
- // TODO: Add extra initialization here
- DWORD dw1,dw2;
- CreateThread(NULL,0,ThreadB1,NULL,0,&dw1);
- Sleep(100);
- CreateThread(NULL,0,ThreadB2,NULL,0,&dw2);
- Sleep(100);
- return TRUE; // return TRUE unless you set the focus to a control
- }
5、MFC创建多线程完成,就这么简单咯!
平时在MFC里使用多线程时其实是很方面的,因为微软提供了一个API让我们很方面的去创建线程:下面是MSDN中关于CreateThread的函数原型:
1、函数原型声明:
- CreateThread
- The CreateThread function creates a thread to execute within the virtual address space of the calling process.
- To create a thread that runs in the virtual address space of another process, use the CreateRemoteThread function.
- HANDLE CreateThread(
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- SIZE_T dwStackSize,
- LPTHREAD_START_ROUTINE lpStartAddress,
- LPVOID lpParameter,
- DWORD dwCreationFlags,
- LPDWORD lpThreadId
- );
2、参数说明:
- lpThreadAttributes:指向SECURITY_ATTRIBUTES型态的结构的指针。在Windows 98中忽略该参数。在Windows NT中,它被设为NULL,表示使用缺省值。
- dwStackSize,线程堆栈大小,一般=0,在任何情况下,Windows根据需要动态延长堆栈的大小。
- lpStartAddress,指向线程函数的指针,形式:@函数名,函数名称没有限制,但是必须以下列形式声明:
- DWORD WINAPI ThreadProc (LPVOID pParam) ,格式不正确将无法调用成功。
- lpParameter:向线程函数传递的参数,是一个指向结构的指针,不需传递参数时,为Nil。
- dwCreationFlags :线程标志,可取值如下
- CREATE_SUSPENDED: 创建一个挂起的线程
- 0 :创建后立即激活。
- lpThreadId:保存新线程的id。
3、返回值:
函数成功,返回线程句柄;函数失败返回false。
4、实例代码:
A、新建一个对话框工程为MFC,在MFCDlg.h添加两个成员函数,注意一定要是静态的,代码如下:
- /////////////////////////////////////////////////////////////////////////////
- // CMFCDlg dialog
- class CMFCDlg : public CDialog
- {
- // Construction
- public:
- CMFCDlg(CWnd* pParent = NULL); // standard constructor
- // 线程B1、B2函数
- static DWORD WINAPI ThreadB1(LPVOID lpParam);
- static DWORD WINAPI ThreadB2(LPVOID lpParam);
- ......
- }
B、在cpp文件中实现函数,添加代码如下:
- DWORD WINAPI CMFCDlg::ThreadB1(LPVOID lpParam)
- {
- // 定义结构对象
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- BOOL bRet;
- // 申请空间
- ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
- ZeroMemory(&si,sizeof(STARTUPINFO));
- // 设置进程启动属性
- si.cb = sizeof(STARTUPINFO);
- si.lpReserved = NULL;
- si.lpDesktop = NULL;
- si.lpTitle = NULL;
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_SHOWNORMAL;
- si.cbReserved2 = NULL;
- si.lpReserved2 = NULL;
- bRet = CreateProcess(_T("C://Program Files//Internet Explorer//IEXPLORE.exe"),
- _T("http://www.coderfans.cn"),
- NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
- return 0;
- }
- DWORD WINAPI CMFCDlg::ThreadB2(LPVOID lpParam)
- {
- // 定义结构对象
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- BOOL bRet;
- // 申请空间
- ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
- ZeroMemory(&si,sizeof(STARTUPINFO));
- // 设置进程启动属性
- si.cb = sizeof(STARTUPINFO);
- si.lpReserved = NULL;
- si.lpDesktop = NULL;
- si.lpTitle = NULL;
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_SHOWNORMAL;
- si.cbReserved2 = NULL;
- si.lpReserved2 = NULL;
- bRet = CreateProcess(_T("C://Program Files//Internet Explorer//IEXPLORE.exe"),
- _T("http://blog.csdn.net/wangningyu"),
- NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
- return 0;
- }
C、然后在对话框初始化时创建进程即可,代码如下:
- BOOL CMFCDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- ......
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
- // TODO: Add extra initialization here
- DWORD dw1,dw2;
- CreateThread(NULL,0,ThreadB1,NULL,0,&dw1);
- Sleep(100);
- CreateThread(NULL,0,ThreadB2,NULL,0,&dw2);
- Sleep(100);
- return TRUE; // return TRUE unless you set the focus to a control
- }
5、MFC创建多线程完成,就这么简单咯!
===========================================================================================
实例:
DWORD WINAPI CTingDlg::ThreadB2(LPVOID lpParam)
{
Sleep(1500);
char buf[128];
//use mciSendCommand
MCI_OPEN_PARMS mciOpen;
MCIERROR mciError;
//mciOpen.lpstrDeviceType = "avivideo"; //*.avi
mciOpen.lpstrDeviceType = "mpegvideo";
mciOpen.lpstrElementName = "resource\\music.mp3";
mciError = mciSendCommand(3,MCI_OPEN,MCI_OPEN_TYPE | MCI_OPEN_ELEMENT ,(DWORD)&mciOpen);
if(mciError)
{
mciGetErrorString(mciError,buf,128);
// MessageBox("send MCI_PLAY command failed", "ERROR");
return 0;
}
UINT DeviceID = mciOpen.wDeviceID ;
MCI_PLAY_PARMS mciPlay;
mciError = mciSendCommand(DeviceID, MCI_PLAY, MCI_DGV_PLAY_REPEAT,
(DWORD) (LPMCI_PLAY_PARMS)&mciPlay); //MCI_DGV_PLAY_REPEAT, 要 #include "Digitalv.h"
if(mciError)
{
mciGetErrorString(mciError,buf,128);
return 0;
}
return 0;
}
=========================================================================================
创建线程时,线程函数如果要设置成类的成员函数,则必须是静态成员函数,在此函数中不能使用非静态成员变量,如果要使用非静态成员变量,则一种比较适合线程的方法是:建立线程的时候把this作为CreateThread的一个参数(即第4个参数,就是那个LPVOID型的),然后线程里就对应pParam,例如:
static UINT ThreadProc(LPVOID pParam)
{
Your_Class *p=(Your_Class *)pParam;
//然后用p间接使用成员变量。
}