主程序中调用DLL的接口函数,DLL来调用硬件设备,设备提供有SDK,但是设备消息的回复是通过WINDOWS MESSAGE来实现响应的,所以用一个窗体的句柄来接收消息,访照他的例子,我也用一个窗体来接收消息(只创建,不显示),这个在单线程中是没有问题的,但是多线程就不行了,问了别人,说这样FORM无法收到消息,需要从消息队列里取,使用PeekMessage,从网上查了下用法BOOL PeekMessage(LPMSG IpMsg,HWND hWnd,UINT wMSGfilterMin,UINT wMsgFilterMax,UINT wRemoveMsg)
第二个参数hWnd如何设置,这个是DLL的句柄吗?是不是需要主程序传一个句柄过来?
第二个参数hWnd如何设置,这个是DLL的句柄吗?是不是需要主程序传一个句柄过来?
PeekMesssge只得到那些与参数hWnd标识的窗口相联系的消息或被lsChild确定为其子窗口相联系的消息,并且该消息要在由参数wMsgFiterMin和wMsgFiherMax确定的范围内。如果hWnd为NULL,则PeekMessage接收属于当前调用线程的窗口的消息(PeekMessage不接收属于其他线程的窗口的消息)。
PeekMessage若指定了hWnd,那么就是只取出发往hWnd的消息; 好像为0时,就取全部了比如消息队列中可能有上千条,但你只想要发往窗口A的消息,那么你就要事先知道窗口A的handle就行了
也可以利用wMsgFilterMin+wMsgFilterMax这2个参数,这是一个范围,可以过滤掉范围外消息
while true do
begin
if PeekMessage(Msg,0,0,0,PM_REMOVE) then
begin
if Msg.message = WM_QUITTHREAD then //WM_QUITTHREAD 自定义退出线程消息
begin
FQuitEvent.SetEvent;
Break;
end;
end;
....
....
end;还有,向线程传送消息,不一定非得在线程里创建一个FORM吧,可以PostThreadMessage(),只要知道线程的ID
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
很遗憾你没有真正理解SendMessage和PostMessage这2个函数的概念, 他们2个都是需要消息循环的, SendMessage 当调用者就是本窗口消息队列的创建线程则直接调用窗口处理过程, 如果调用者不在窗口消息队列创建线程里调用的, 则需要窗口消息队列创建的那个线程调用PeekMessage或者GetMessage否则 你可以试试SendMessage将会持续阻塞, 否则SendMessage又何谈线程安全?
很遗憾你没有真正理解SendMessage和PostMessage这2个函数的概念, 他们2个都是需要消息循环的, SendMessage 当调用者就是本窗口消息队列的创建线程则直接调用窗口处理过程, 如果调用者不在窗口消息队列创建线程里调用的, 则需要窗口消息队列创建的那个线程调用PeekMessage或者GetMessage否则 你可以试试SendMessage将会持续阻塞, 否则SendMessage又何谈线程安全?
好心被当成驴肝肺, 我是说他说的不正确而已, 不希望产生误导, 你的问题我开始也回答你了, 一个线程只有窗口队列, 别的线程不可以直接Peek, MSDN说的很清楚了, Peek的第2个参数是你要指定取哪个窗体的消息, 比如你在该线程里创建了3个窗体, 分别对应的句柄是ha hb hc, 那么第2个参数可以指定你只取某一个窗体的消息,相当一个过滤器, 当这个参数为0的时候, 就无视任何条件, 只要是消息就取出来, 其实按照你的说法你要实现的目前你自己都已经实现好了, 多线程在这个环境下不是这么用的, 不能用别的线程来取其他线程中的消息.