0

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

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

4

2 回答 2

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);
    };
}
于 2013-06-01T08:37:09.487 回答
0

要将消息发送到踏板,它必须有一个消息队列,在此链接的备注部分:http:
//msdn.microsoft.com/en-us/library/windows/desktop/ms644946(v=vs.85)。 aspx
你可以细化为线程创建消息队列所需的步骤。
顺便说一句,如果 PostThreadMessage 返回 0(FALSE),则有错误,您必须检查 GetLastError 返回的值。

于 2013-06-01T05:53:47.070 回答