文章目录
前言
今天在使用MFC消息传递函数时遇到一个问题,困了了半天,最终终于还是找到了原因。
函数信息
先看看两个函数原型:
LRESULT SendMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
BOOL PostMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
两者的四个参数含义是一样的。
参数含义:hWnd
:其窗口程序将接收消息的窗口的句柄。Msg
:指定被发送的消息。wParam
:指定附加的消息指定信息。IParam
:指定附加的消息指定信息。
目的
我使用这个消息的目的是,在消息发送过程中,第三个参数wParam
需要带上我需要的消息,就是一串字符串。
出现问题
我首先用的是PostMessage
,毕竟它不堵塞线程,不至于引起程序卡死,在使用过程中,我发现一个问题,在我接收消息时,发现解析出来的参数始终是乱码,起初我一直以为之强转导致的问题,但其实在我使用PostMessage
函数的函数中强转又是正常的。过程如下:
使用方式
//发送消息
void NotifyRequstQuery(const std::string& body)
{
const char *cBody = body.c_str();
PostMessage(WM_MYMESSAGE_ONQUREY, (WPARAM)cBody, 0);
}
//接收消息
afx_msg LRESULT OnMyMessageOnqurey(WPARAM wParam, LPARAM lParam)
{
char *strBody = (char *)wParam;
.....
return 0;
}
测试
在接收消息函数中解析不到我想要的消息时,以为强转除了问题,所以我进行了如下测试:
void NotifyRequstQuery(const std::string& body)
{
const char *cBody = body.c_str();
WPARAM wParm = (WPARAM)cBody;
const char *cResult = (const char *)wParm;
z_pFrame->PostMessage(WM_MYMESSAGE_ONQUREY, (WPARAM)cBody, 0);
}
这时发现其实强转回来,是没问题的。
更换消息函数
这时我将PostMessage
函数更换为SendMessage
,这时发现接收消息函数接收到的参数正常。
本着思考的目的,查了很多两者间的区别,总结出来就是:前者不需要相应,直接返回;而后者必须要消息处理后才返回,否则处于线程等待。
那么究竟是什么原因导致这两者出现不同的参数情况呢。
这时候想起会不会是变量使用周期引起的。
然后我又进行了如下测试:
void NotifyRequstQuery(const std::string& body)
{
//const char *cBody = body.c_str();
const char *cBody = "This is a Test."
z_pFrame->PostMessage(WM_MYMESSAGE_ONQUREY, (WPARAM)cBody, 0);
}
这是发现也能正常接收。很奇怪。但我现在不确定这种使用方式 const 常指针变量会不会生命周期不一样?
说实话,形参、常引用形参、常指针变量等等,这一些列烧脑玩意,很多人还真不一定不会出错,于是进行了如下测试:
#include <iostream>
std::string g_strTemp;
//返回指向常变量的常指针
const char *TestStr1()
{
const char *cTemp = "This is TestStr1.";
return cTemp;
}
//返回常引用形参赋值常指针
const char *TestStr2(const std::string &strTemp)
{
const char *cTemp = strTemp.c_str();
return cTemp;
}
//返回一般形参赋值常指针
const char *TestStr3(std::string strTmpe)
{
const char *cTemp = strTmpe.c_str();
return cTemp;
}
//局部变量传常变量实参
const char *TestStr4()
{
const char *cTemp = "********5555********";
return TestStr2(cTemp);
}
//全局变量传实参
const char *TestStr5()
{
g_strTemp = "********6666********";
return TestStr2(g_strTemp);
}
int main()
{
const char *cReturn1 = TestStr1();
std::cout << cReturn1 << std::endl;
g_strTemp = "********1111********";
const char *cReturn2 = TestStr2(g_strTemp);
std::cout << cReturn2 << std::endl;
g_strTemp = "********2222********";
cReturn2 = TestStr3(g_strTemp);
std::cout << "MAIN:" << cReturn2 << std::endl;
std::string strBody = "********3333********";
const char *cReturn3 = TestStr2(strBody);
std::cout << cReturn3 << std::endl;
strBody = "********4444********";
cReturn3 = TestStr3(strBody);
std::cout << cReturn3 << std::endl;
const char *cReturn4 = TestStr4();
std::cout << cReturn4 << std::endl;
const char *cReturn5 = TestStr5();
std::cout << cReturn5 << std::endl;
system("pause");
return 0;
}
运行结果如图:
通过结果我们得出如下结论:
- 将常变量赋值给常指针变量作为成员变量,成员变量的生命周期直到程序结束。
- 通过常引用参数赋值返回的变量周期跟传入的实参有关,实参改变,周期结束。
出错原因
由此说明,问题出在调用NotifyRequstQuery
的地方,说明传入的实参有所改变,因为发消息
和接收消息
处于不同的线程,所以说这完全是可能存在的情况,因为PostMessage
不阻塞。
解决办法
1、在调用NotifyRequstQuery
时传入的实参,定义为全局变量,但个人不推荐;
2、使用SendMessage
代替PostMessage
,但具体情况要根据实际而定。