对GetMessage的调用会导致线程停止

时间:2013-06-01 05:24:48

标签: c++builder

我正在使用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消息。

我希望这个例子不太具体。我试图留下任何相关的东西。基本上,这是一个没有窗口的类的消息泵。

2 个答案:

答案 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返回的值。