为什么要用MFC?
不是专业开发,只是做个工具。
MFC的主界面是在界面线程运行的,如果在Button的响应函数中写了一个用时很长的函数,那么就要考虑运用工作线程,否则MFC程序主界面就会卡住不动,直到函数运行完才会响应消息。
开启工作线程的正确姿势
那就是用MFC封装好的线程函数AfxBeginThread。
CString strFolderPath = L"C:\\";
CWinThread* pThread = NULL;
pThread = AfxBeginThread((AFX_THREADPROC)BeginScan, szFolderPath, THREAD_PRIORITY_IDLE);//szFolderPath是参数,路径
DoEvent();
if(pThread)
{
do
{
dwRet = ::MsgWaitForMultipleObjects(1, &pThread->m_hThread, FALSE, INFINITE, QS_ALLINPUT);
if (dwRet != WAIT_OBJECT_0)
{
DoEvent();
}
} while ((dwRet != WAIT_OBJECT_0) && (dwRet != WAIT_FAILED));
}
if (pThread)
{
CloseHandle(pThread);
}
其中DoEvent
void CMyDlg::DoEvent()
{
MSG msg;
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) //取消息,检索应用程序的消息队列,PM_REMOVE取过之后从消息队列中移除
{
//发消息
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
如此方式开启工作线程,不会影响界面的操作响应。而且工作线程的权限为THREAD_PRIORITY_IDLE,不容易消耗过高CPU造成卡死。
参考链接:
https://blog.csdn.net/xl19900502/article/details/50342021
工作线程中控制控件
由于我们写的函数是运行在工作线程之下的,所以不能直接调用界面线程的主对话框类对象中的方法,否则会引起崩溃。
这时解决方法有以下几种:
一、把需要更改的控件变量或控件句柄,当作参数传到AfxBeginThread创建的函数中。
这样的缺点是如果需要更改的控件比较多时,需要传很多参数。要更改的控件比较少时可以这样搞。
二、向界面线程发送消息更改控件状态。
在工作线程中不能使用UpdateData来更新主线程中的数据,只能在主线程中使用。界面的东西,最好就是用主线程(界面线程)去执行相应的操作。要想在子线程(工作线程)里执行界面线程的操作,最好是向主线程发送消息。当然创建消息需要遵循固定的四步骤。
参考链接:https://blog.csdn.net/u011499425/article/details/52515216
三、在工作线程中重新获取一遍控件的句柄。
CWnd* edit = AfxGetApp()->GetMainWnd()->GetDlgItem(IDC_EDIT1);//获取主窗口编辑框控件的句柄