MFC编程中不要在消息和事件处理中使用sleep

编者:李国帅

qq:9611153 微信lgs9611153

时间:2010-3-28 

背景:

有次在MFC消息里延迟实现一些功能,结果导致刷新失常。

下面的程序说明MFC编程的一些原则:

         不能在消息和事件处理中进行sleep,那样别指望paint操作能做什么,程序也会陷入假死状态,直到事件处理结束,也许事件处理必须是无阻塞处理。

         尽量通过postmessage而不要随便使用sendmessage,除非确认算法不耗时,并且无阻塞。

代码:

struct wParam_st
{
	CVc6Dlg* pThis;
	HANDLE hRead;
	CString strInfo;

};
HANDLE hRead,hWrite;
wParam_st wParamThrd;// = {this,hRead};


void CVc6Dlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;
		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);

	}
	else
	{
		CPaintDC dc(this); // device context for painting
		m_Edit1 = wParamThrd.strInfo;
		UpdateData(FALSE);//窗口只有无效的时候才会重绘,不能调用WM_PAINT消息,因为WM_LBUTTONDOWN事件没有完成。

		CDialog::OnPaint();
	}
}

DWORD WINAPI ShowInfoProc(WPARAM wParam)
{
	wParam_st* pwParam = (wParam_st*)wParam;
	CVc6Dlg* pThis = pwParam->pThis;
	HANDLE hRead = pwParam->hRead;
	//char buffer[4096] = {0};
	char buffer[32] = {0};
	DWORD bytesRead;
	while (true)
	{
		if (ReadFile(hRead,buffer,sizeof(buffer)-1,&bytesRead,NULL) == NULL)
			break;
		pwParam->strInfo += buffer;
		PostMessage(pThis->m_hWnd,WM_PAINT,0,0);

		Sleep(100);
	}

	return S_OK;
}
void CVc6Dlg::OnBnClickedButton1()
{
	SECURITY_ATTRIBUTES sa;

	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;
	if (!CreatePipe(&hRead,&hWrite,&sa,0))
	{
		AfxMessageBox("Error On CreatePipe()");
		return;
	}
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	si.cb = sizeof(STARTUPINFO);
	GetStartupInfo(&si);
	si.hStdError = hWrite;
	si.hStdOutput = hWrite;
	si.wShowWindow = SW_HIDE;
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	if (!CreateProcess(NULL,"c:\\windows\\system32\\cmd.exe /c dir /?",NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)) {
		AfxMessageBox("Error on CreateProcess()");
		return;
	}
	CloseHandle(hWrite);

	m_Edit1 = "NULL";
	wParamThrd.pThis = this;
	wParamThrd.hRead = hRead;
	wParamThrd.strInfo ="";
	HANDLE hGetCmdThrd = ::CreateThread(0,0,(LPTHREAD_START_ROUTINE)ShowInfoProc,&wParamThrd,0,0);

	//int i=0;
	//while (i++ < 50)
	//{
	//	if(m_Edit1.Compare(wParamThrd.strInfo)==0) break;
	//	//UpdateData();//异常,数据交换错误
	//	m_Edit1 = wParamThrd.strInfo;
	//	UpdateData(FALSE);//窗口只有无效的时候才会重绘,不能调用WM_PAINT消息,因为WM_LBUTTONDOWN事件没有完成。
	//
	//	CPaintDC dc(this); // device context for painting
	//	CDC *pDC = &dc;
	//	CRect   cClientRect;
	//	GetClientRect( cClientRect );
	//	//DrawText(pDC->m_hDC,m_Edit1, m_Edit1.GetLength(), &cClientRect,DT_CENTER);
	//	//CDialog::OnPaint();

	//	//InvalidateRect(NULL);
	//	//PostMessage(WM_PAINT,0,0);
	//	Sleep(200);
	//}

	//WaitForSingleObject(hGetCmdThrd,50000);
	//CloseHandle(hRead);
	//CDialog::OnPaint();

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微澜-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值