利用MFC尝试事件驱动

首先是建立一个MFC程序,基于对话框的(最简单的,About对话框也不要了,只留下一个窗口)。把原来的窗口上的控件全部删除,然后添加一个按钮,在按键上添加事件处理响应函数用于测试。
新建一个对话框资源,在对话框中添加一个类,类名随便起,在主窗口中的按钮事件处理响应函数中,以非模态方式创建子窗口,因为不需要显示,所以代码如下:

void CSendMsgDlg::OnBnClickedButton1()
{
    
    
	// TODO: 在此添加控件通知处理程序代码
	if (ChildDialog == NULL)
	{
    
    
		ChildDialog = new CChild();
		ChildDialog->Create(IDD_Child);
		//ChildDialog->ShowWindow(SW_SHOWNORMAL);
	}

}

在stdafx.h中自定义一个消息:
#define WM_UPDATEDATA (WM_USER + 100)
在子窗口完成数据初始化后,起一个子线程,为了测试,线程中不断向父窗口发送消息。

UINT proc1(LPVOID lpParameter)
{
    
    
	CChild* child = (CChild*)lpParameter;
	if (child == NULL)
	{
    
    
		return 0;
	}
	while (true)
	{
    
    
		//WPARAM实际的定义是unsigned int
		WPARAM a = 8;
		//LPARAM实际的定义是long
		LPARAM b = 9;

		//SendMessage需要等待回调返回才会继续走,阻塞的
		//child->GetParent()->SendMessage(WM_UPDATEDATA, a, b);

		//PostMessage则不需要等待回调返回,非阻塞的
		child->GetParent()->PostMessage(WM_UPDATEDATA, a, b);

		Sleep(50000);
	}
	return 0;
}

// CChild 对话框
IMPLEMENT_DYNAMIC(CChild, CDialogEx)
CChild::CChild(CWnd* pParent /*=NULL*/)
	: CDialogEx(IDD_Child, pParent)
{
    
    }

CChild::~CChild()
{
    
    
}

void CChild::DoDataExchange(CDataExchange* pDX)
{
    
    
	CDialogEx::DoDataExchange(pDX);
	AfxBeginThread(proc1, this);
}

在主窗口中添加一个消息响应映射:

BEGIN_MESSAGE_MAP(CSendMsgDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, &CSendMsgDlg::OnBnClickedButton1)	//按钮的消息响应

	ON_MESSAGE(WM_UPDATEDATA, &CSendMsgDlg::Onadd_event_ok)		//收到自定义消息的响应

END_MESSAGE_MAP()

实现自定义消息响应函数,加个断点可以看到消息发送时传来的参数值,表示本次尝试成功了一半。

我们可以看到发送消息时,能传来两个参数,WPARAM 和LPARAM ,这两个参数值可能对不同的消息响应函数来说意义不同,那么查看它们的定义,可以看出来,这两个宏定义的都是数值型的。
/* Types use for passing & returning polymorphic values */ typedef UINT_PTR WPARAM; typedef LONG_PTR LPARAM; typedef LONG_PTR LRESULT;

#else  // midl64
// old midl and C++ compiler

#if defined(_WIN64)
    typedef __int64 INT_PTR, *PINT_PTR;
    typedef unsigned __int64 UINT_PTR, *PUINT_PTR;

    typedef __int64 LONG_PTR, *PLONG_PTR;
    typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;

    #define __int3264   __int64

#else
    typedef _W64 int INT_PTR, *PINT_PTR;
    typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;

    typedef _W64 long LONG_PTR, *PLONG_PTR;
    typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;

    #define __int3264   __int32

#endif
#endif // midl64

其实也说得过去,对于计算机而言,所有东西都是0 和1,完全没有区别,那么,我们是不是能把这两个参数看成是万能的呢,假如把一个数据结构的地址(还是一串数值)赋值给它们是否可行呢?带着这个问题,我们自定义一个数据结构,在发送消息的时候,把它传出去。子窗口中,线程函数改为这样:

UINT proc1(LPVOID lpParameter)
{
    
    
	CChild* child = (CChild*)lpParameter;
	if (child == NULL)
	{
    
    
		return 0;
	}
	while (true)
	{
    
    
		Data* data = (Data*)malloc(sizeof(Data));
		data->abc[0] = 111;
		data->abc[1] = 222;
		data->abc[2] = 333;
		data->bbb = 123.456;
		data->c = 'A';

		//SendMessage需要等待回调返回才会继续走,阻塞的
		//child->GetParent()->SendMessage(WM_UPDATEDATA, (WPARAM)data, b);

		//PostMessage则不需要等待回调返回,非阻塞的
		child->GetParent()->PostMessage(WM_UPDATEDATA, (WPARAM)data, b);

		Sleep(50000);
	}
	return 0;
}

验证时,主窗口的消息响应函数改为这样:

LRESULT CSendMsgDlg::Onadd_event_ok(WPARAM wParam, LPARAM lParam)
{
    
    
	Data* data = (Data*)wParam;
	return 0;

}

通过加断点,可以看到,强转后的data指针指的是同一块内存。
在这里插入图片描述
在这里插入图片描述
好了,到这里,消息传递已经测试过了,那么,接下来就是整个框架的设计了。

猜你喜欢

转载自blog.csdn.net/griffin041702/article/details/111033798