我正在使用Borland C ++(Delphi Forms)编写一个多线程应用程序。我最近了解到,当我调用PostThreadMessage()函数时,我可以在这些类中使用Windows的消息传递服务:
System = new STSystem(SystemName,1000,1,NULL);
while (PostThreadMessage(System->ThreadID,ST_MSG_SYSTEM_INIT,0,0) == 0)
{
Sleep(0);
};
以上似乎工作得很好。问题在于线程执行函数内部此进程的检索结束:
void __fastcall STSystem::Execute()
{
ST_Message STMSG;
while(FStatus != Destroyed)
{
FHeartBeat++;
if(GetMessage(MSG,NULL,ST_MSG_SYSTEM_START,ST_MSG_SYSTEM_END))
{
STMSG.Value = MSG->wParam;
if((STMSG.dSYS + (8*STMSG.dSEC) + (64*STMSG.dDEP)) == FSystemID)
{
RXMessages[RxQueueIn++] = STMSG.MSG; // Message
RXMessages[RxQueueIn++] = MSG->lParam; // Data
}
}
if(TaskList->Count>0)
ProcessTask();
if(RxQueueIn!=RxQueueOut)
ProcessRxMessage();
if(TxQueueIn!=TxQueueOut)
ProcessTxMessage();
Sleep(0);
};
}
以上工作大约两个线程循环然后停止;线程停止,而不是程序。我已尝试在FHeartbeat ++计数器后面的IF子句中使用PeekMessage()函数而不是GetMessage()函数。这可以防止线程停止,但是仍然找不到第一个代码块中发送的INIT消息。
我希望这个例子不太具体。我试图留下任何相关的东西。基本上,这是一个没有窗口的类的消息泵。
答案 0 :(得分:1)
GetMessage()
会阻止调用线程。就像Luis所说,在开始向其发送消息之前,您需要确保该线程有一个消息队列,并且您需要检查PostThreadMessage()
的返回值是否有失败。在线程中首次调用任何user32.dll函数之前,不会在线程中创建消息队列。例如:
System = new STSystem(SystemName,1000,1,NULL);
while (!System->Ready)
Sleep(100);
if (!PostThreadMessage(System->ThreadID,ST_MSG_SYSTEM_INIT,0,0))
{
DWORD err = GetLastError();
//...
}
void __fastcall STSystem::Execute()
{
// create a message queue
PeekMessage(MSG, NULL, 0, 0, PM_NOREMOVE);
Ready = true;
ST_Message STMSG;
while(FStatus != Destroyed)
{
FHeartBeat++;
if(GetMessage(MSG,NULL,ST_MSG_SYSTEM_START,ST_MSG_SYSTEM_END)) // or PeekMessage()
{
STMSG.Value = MSG->wParam;
if((STMSG.dSYS + (8*STMSG.dSEC) + (64*STMSG.dDEP)) == FSystemID)
{
RXMessages[RxQueueIn++] = STMSG.MSG; // Message
RXMessages[RxQueueIn++] = MSG->lParam; // Data
}
}
if(TaskList->Count>0)
ProcessTask();
if(RxQueueIn!=RxQueueOut)
ProcessRxMessage();
if(TxQueueIn!=TxQueueOut)
ProcessTxMessage();
Sleep(0);
};
}
答案 1 :(得分:0)
要发送消息,必须在此链接的备注部分中有一个消息队列:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644946(v=vs.85).aspx
您可以完善为线程创建消息队列所需的步骤
顺便说一下,如果PostThreadMessage返回0(FALSE),则会出现错误,您必须检查GetLastError返回的值。