首先是建立一个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指针指的是同一块内存。
好了,到这里,消息传递已经测试过了,那么,接下来就是整个框架的设计了。