【问题标题】:C++ Winapi while-loop workaround?C ++ Winapi while-loop解决方法?
【发布时间】:2023-03-14 12:05:01
【问题描述】:

所以,我有这个普通的 while 循环(如图所示),当我的程序在 while 循环内运行很长时间时,窗口变得没有响应,说“等等等等没有响应”。嗯...我知道在 WinAPI 中我应该使用 SetTimer() 函数和 WM_TIMER,但你猜怎么着!这次我是为了好玩而编程,我想知道是否有解决方法……比如在我的 while 循环中放一些东西,让它保持“响应式”。我不想破坏。

代码如下:

while (battleupdate == 1)
{
    RECT wrect;
    wrect.left   = 0;
    wrect.right  = 570;
    wrect.top    = 0;
    wrect.bottom = 432;

    if (FILLRECT == 0){
    FillRect(hdc, &wrect, (HBRUSH) GetStockObject (WHITE_BRUSH));
    cout << "battleupdated" << endl; FILLRECT = 1; }


    /*OPPONENT STATS*/        
    if (1 == 1) {   stringstream stream; stream << opname << "            ";        
        TextOut (hdc, 20, 50, stream.str().c_str(), 12); }
    //if (1 == 1) {   stringstream stream; stream << itemslot4name << "        ";        
        //TextOut (hdc, 465, 188, stream.str().c_str(), 12); }
    //if (1 == 1) {   stringstream stream; stream << itemslot4effect << "   ";        
        //TextOut (hdc, 465, 204, stream.str().c_str(), 4); }

        battleupdate = 1; 

        //I DON'T CARE IF MY DELAY CODE IS LAME YES I KNOW ABOUT SLEEP().
        while (delay > 0)
        {
            delay -= 1;
        }
        if (delay == 0)
        {
            delay = resetdelay;
        }
    }

我问的可能吗?

我很感激任何答案,即使是“不,不能那样做,你最好使用 WM_TIMER!” 所以提前感谢您的回答!

  • 操作系统:windows 7 Ultimate

  • 编译器:Dev-C++

  • 其他:使用winapi

【问题讨论】:

  • 实际上,这是需要的!谢谢sayem。
  • 如果你是一个 UI 线程,你需要处理消息。 WM_TIMER 不是问题,您需要在循环中调用 GetMessage()PeekMessage() 并发送消息。
  • 正如我所说,我不太了解,甚至不知道这意味着什么。 .请告诉我!!!
  • 没有变通方法,(甚至 WM_TIMER 也没有),要么您需要处理消息,要么您需要在单独的线程上完成这项工作。
  • 约翰我不是说这个循环里面有 wmtimer,我的意思是我可以用 wmtimer 循环。

标签: c++ winapi


【解决方案1】:

如您所知,您应该使用计时器来处理您的逻辑...

但如果你真的不想这样做,你可以使用“DoEvents”来保持窗口“响应”...

void DoEvents()
{
  MSG msg;
  BOOL result;

  while ( ::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE ) )
  {
    result = ::GetMessage(&msg, NULL, 0, 0);
    if (result == 0) // WM_QUIT
    {                
      ::PostQuitMessage(msg.wParam);
      break;
    }
    else if (result == -1)
    {
       // Handle errors/exit application, etc.
    }
    else 
    {
      ::TranslateMessage(&msg);
      ::DispatchMessage(&msg);
    }
  }
}

而在您的 while 循环中,您只需要定期调用“DoEvents”...

【讨论】:

  • 为什么用PM_NOREMOVE 后跟GetMessage() 调用PeekMessage()
  • 因为Getmessage如果没有消息就会阻塞!
  • 如果您使用PM_REMOVE 标志,则会删除该消息。
  • 但是你如何区分 WM_QUIT 和没有消息?签入消息?对我来说,这个解决方案有效并且更好......
  • PeekMessage() 检索 WM_QUIT 就像任何其他消息一样。 if (msg.message == WM_QUIT) { }
猜你喜欢
  • 2020-10-30
  • 1970-01-01
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多