MFC 利用工作线程 刷新 界面

谁都会走 提交于 2020-03-12 10:37:01

(1)有时候需要在MFC中开启一个工作线程来处理数据,数据处理中可能需要刷新界面对应的显示,则可以通过在工作线程中发送消息来更新界面

下面给出了一个案例

#pragma once

#include <afxwin.h>

class Myapp : public CWinApp //WinApp应用类
{
public:
	//程序入口
	virtual BOOL InitInstance();
};

class MyFrame :public CFrameWnd //应用程序窗口框架类
{
public:
	MyFrame();

public:
	afx_msg void OnPaint();
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
	DECLARE_MESSAGE_MAP()
	// 重绘block
	void ReDrawBlock(CDC &DC);
	// 可控制的颜色块
	CPoint block = CPoint(300, 300);

public:
	CWinThread* pThread2;
};


UINT ThreadFunc2(LPVOID pParam);

#include "testworkThread.h"
#include <cstdlib>
#include <ctime>

Myapp app;//要实例化一个,有且仅有一个,全局的应用程序类对象!!

BOOL Myapp::InitInstance()
{
	//创建窗口
	MyFrame *frame = new MyFrame;

	//显示和更新
	frame->ShowWindow(SW_SHOWNORMAL);
	frame->UpdateWindow();

	//将自己创建的窗口的指针传递给 CWinThread类成员m_pMainWnd,用于取消息等操作
	m_pMainWnd = frame;  //保存指向应用程序主窗口的指针

	return TRUE;
}

BEGIN_MESSAGE_MAP(MyFrame, CFrameWnd)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_RBUTTONDOWN()
	ON_WM_KEYDOWN()
END_MESSAGE_MAP()


MyFrame::MyFrame()
{
	Create(NULL, TEXT("mfx"));

	pThread2 = AfxBeginThread(ThreadFunc2, m_hWnd);
}

void MyFrame::OnPaint()
{
	CPaintDC dc(this);

	CBrush brush(RGB(100, 100, 200));
	CRect rect(0, 0, 200, 200);//0-200区域是会被蓝色重新刷的200-500区域则不会被蓝色重刷
	dc.FillRect(&rect, &brush);

	int N = 50, step = 10;
	for (int i = 0; i < 50; ++i)
	{
		dc.MoveTo(i * step, 0);
		dc.LineTo(i * step, step*N);
		dc.MoveTo(0, i * step);
		dc.LineTo(step*N, i * step);
	}

	ReDrawBlock(dc);
	//MessageBox(TEXT("oo"));
}

void MyFrame::OnLButtonDown(UINT nFlags, CPoint point)
{
	CRect rect;
	int lt = 0, up = 0, rt = 0, dn = 0;
	CClientDC dc(this);

	CBrush brush(RGB(200, 100, 100));

	if (point.x > 0 && point.y > 0 && point.x < 500 && point.y < 500)
	{
		lt = point.x / 10 * 10;
		up = point.y / 10 * 10;
		rt = lt + 10;
		dn = up + 10;
		rect = CRect(lt, up, rt, dn);

		dc.FillRect(&rect, &brush);

	}
}

void MyFrame::OnRButtonDown(UINT nFlags, CPoint point)
{
	CRect rect;
	int lt = 0, up = 0, rt = 0, dn = 0;


	if (point.x >= 0 && point.y >= 0 && point.x < 500 && point.y < 500)
	{
		lt = point.x / 10 * 10;
		up = point.y / 10 * 10;
		rt = lt + 10;
		dn = up + 10;
		rect = CRect(lt, up, rt, dn);

		InvalidateRect(&rect, TRUE);//当为FALSE时,不会导致背景被刷新
		//Invalidate(TRUE);

	}
}

// 重绘block
void MyFrame::ReDrawBlock(CDC &DC)
{
	// TODO: 在此处添加实现代码.
	srand((unsigned)time(NULL));

	CPoint point = block;
	point.x = rand() % 100;
	point.y = rand() % 100;
	CRect rect;
	int lt = 0, up = 0, rt = 0, dn = 0;
	CClientDC dc(this);
	CBrush brush(RGB(200, 0, 0));

	if (point.x >= 0 && point.y >= 0 && point.x < 500 && point.y < 500)
	{
		lt = point.x / 10 * 10;
		up = point.y / 10 * 10;
		rt = lt + 10;
		dn = up + 10;
		rect = CRect(lt, up, rt, dn);

		dc.FillRect(&rect, &brush);

	}
}

void MyFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	CPoint block_old = block;//记录旧的位置

	switch (nChar)
	{
	case VK_LEFT:
		if (block.x >= 10)
		{
			block.x -= 10;
			OnRButtonDown(0, block_old); //使当前位置的块失效		
		}
		break;
	case VK_RIGHT:
		if (block.x < 400)
		{
			block.x += 10;
			OnRButtonDown(0, block_old); //使当前位置的块失效		
		}
		break;
	case VK_UP:
		if (block.y >= 10)
		{
			block.y -= 10;
			OnRButtonDown(0, block_old); //使当前位置的块失效		
		}
		break;
	case VK_DOWN:
		if (block.y < 400)
		{
			block.y += 10;
			OnRButtonDown(0, block_old); //使当前位置的块失效		
		}
		break;
	default:
		break;
	}
}

//工作者线程
UINT ThreadFunc2(LPVOID pParam)
{
	HWND hwnd = (HWND)pParam;

	
	CString str;
	str.Format(TEXT("%d"), hwnd);
	AfxMessageBox(str);

	while (true)
	{
		::SendMessage(hwnd, WM_PAINT, NULL, NULL);
		Sleep(1000);

	}

}

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!