(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);
}
}
来源:CSDN
作者:xiyangxiaoguo
链接:https://blog.csdn.net/xiyangxiaoguo/article/details/104791577