+ -
当前位置:首页 → 问答吧 → 本线程或线程间传递消息出错,求解!

本线程或线程间传递消息出错,求解!

时间:2011-12-19

来源:互联网

我的目的是想从别的线程发消息到主线程。在主线程中,我写了下面的一个函数,此为主界面创建完成的消息函数
int CSmsDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here

BOOL bRet = PostMessage(WM_COMMSGRX, 1, 2);
LPMSG lpMsg;
HWND hWnd = AfxGetMainWnd()->m_hWnd;

BOOL ibt = GetMessage(lpMsg, hWnd, 0, WM_COMMSGRX+1);
.....
}
我想先测试下消息发送的情况,但程序会出现“指令引用的内存不能为“read””的错误。debug发现是由GetMessage引起的。


注释掉前面出错的语句,然后在另一个线程中,我写了以下的语句:
pWnd = AfxGetApp()->GetMainWnd();
hWnd = pWnd->m_hWnd;

BOOL bRet = PostMessage(hWnd,WM_COMMSGRX, (unsigned int)str, wCount);
bRet的值为TRUE,但主线程却收不到;

若将上面的那句话改为
idThreadMain = GetWindowThreadProcessId(hWnd,lpdwsProcessId);
PostThreadMessage(idThreadMain, WM_COMMSGRX, (unsigned int)str, wCount);
则GetWindowThreadProcessId()函数将导致出现unhandled exception ...USER32.dll...,程序运行出错中止。

在网上搜了下,别人的想法是指针访问出错了,是不是这还是在窗口创建阶段导致的,但是获得主窗口的句柄不为NULL啊。求解!

作者: jamiedame   发布时间: 2011-12-19

同一个进程吗?得到主窗口的HWND,然后SendMessage/PostMessage即可

作者: VisualEleven   发布时间: 2011-12-19

是同一个进程。但是同一线程跟不同线程都出错了。是不是窗口刚创建时时没创建消息队列之类的原因啊?我不是干这行的,这是课程设计,现学现用,遇到问题太痛苦了。

作者: jamiedame   发布时间: 2011-12-19

放到OnCreate()也是可以的,这个时候HWND窗口应该不会NULL的,你这里的BOOL bRet = PostMessage(WM_COMMSGRX, 1, 2);
 应该是没有问题的。
你下面的BOOL ibt = GetMessage(lpMsg, hWnd, 0, WM_COMMSGRX+1);
这句是干嘛????

作者: VisualEleven   发布时间: 2011-12-19

我只是想现场测试下能不能获取刚刚上面pose的消息而已,貌似GetMessage()应该能获得消息而不会导致整个程序出错中止啊?

作者: jamiedame   发布时间: 2011-12-19

PostMessage(WM_COMMSGRX, 0, 0);

MSG msg;
BOOL bRet = GetMessage(&msg, NULL, 0, 0);
if(bRet)
{
AfxMessageBox(_T("OLL"));
}

作者: VisualEleven   发布时间: 2011-12-19

我试了下,发现假如用lpMsg换成&msg就没问题,LPMSG是MSG far*,是不是这里只能用MSG Near*?

作者: jamiedame   发布时间: 2011-12-19

还有在另一个线程中,我写了以下的语句:
pWnd = AfxGetApp()->GetMainWnd();
hWnd = pWnd->m_hWnd;

BOOL bRet = PostMessage(hWnd,WM_COMMSGRX, (unsigned int)str, wCount);
bRet的值为TRUE,但主线程却收不到;

若将上面的那句话改为
idThreadMain = GetWindowThreadProcessId(hWnd,lpdwsProcessId);
PostThreadMessage(idThreadMain, WM_COMMSGRX, (unsigned int)str, wCount);
则GetWindowThreadProcessId()函数将导致出现unhandled exception ...USER32.dll...,程序运行出错中止。

这又是什么原因呢?

作者: jamiedame   发布时间: 2011-12-19

楼主你好,你要注意了,GetMessage函数的第一个参数是让你传结构体对象的地址,而不是指针变量。这个亏很多人都吃过。这次记住了,下次就不会再犯了。^_^

作者: feizhuangxuan   发布时间: 2011-12-20

BOOL GetMessage(
  LPMSG lpMsg, // address of structure with message
  HWND hWnd, // handle of window
  UINT wMsgFilterMin, // first message
  UINT wMsgFilterMax // last message
);
 
Parameters
lpMsg 
Pointer to an MSG structure that receives message information from the thread's message queue. 
我是照着MSDN里的解释打的,难道官方文档也有错?

作者: jamiedame   发布时间: 2011-12-20