【问题标题】:Process stays open after window is closed窗口关闭后进程保持打开状态
【发布时间】:2013-10-21 01:43:38
【问题描述】:

我在使用 winapi 时遇到了问题,或者我还是在猜测。当我关闭应用程序时,该过程仍然保持为“幽灵”。窗口像往常一样消失了,但是进程仍然存在,这阻止了我重新编译。我必须从任务管理器中手动杀死它。

我不知道代码的哪一部分是错误的,而且有点冗长,所以这里是完整代码的链接:http://pastebin.com/TmRiCeR4

不过我的猜测是,它可能与这个循环有关:

while(1) {
                if(PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) {
                        if(msg.message == WM_QUIT) {
                                break;
                        }

                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                } else
                        draw();

                Sleep(100);   //crappy way of stopping 10000000000000 loops a second

        }

我猜它没有正确地“转义”循环,所以它永远不会在它之后立即到达 closewindow() 函数,但我可能是错的。我从教程中部分复制了代码,尽管我确实更改了它,所以我看不出教程代码中的问题所在。这是我正在谈论的教程(可能已经过时?):http://bobobobo.wordpress.com/2008/02/11/opengl-in-a-proper-windows-app-no-glut/

Google 也没有给我答案。有什么想法吗?

【问题讨论】:

  • 您为什么不使用GetMessage() 和计时器?如果你只想每秒画 10 帧,SetTimer() 绰绰有余。
  • 我不一定只想每秒画 10 帧。我只是让它循环非常缓慢,因为它没有充分理由在 cpu 上使用 100% 的一个内核,所以我只是让它每秒循环 10 次,直到它真正起作用为止。

标签: c winapi opengl


【解决方案1】:

您尚未显示实际发布退出消息的代码,但如果它是一个简单的PostQuitMessage(0);,那么您的问题在于您的PeekMessage() 调用:

 if(PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE))

通过提供窗口过滤器 (hwnd),您可以防止 PeekMessage() 检索任何已发布的线程消息(即,消息不是发送到窗口,而是发送到线程)。由于PostQuitMessage() 发布了一条线程消息,因此您的循环将永远不会检索它,因此永远不会退出。

您应该更改您的调用以将NULL 传递给第二个参数。

【讨论】:

    【解决方案2】:

    当窗口关闭时,会生成WM_CLOSE 消息,您通常在窗口类的消息函数中处理该消息。通常的反应是调用PostQuitMessage,它将发送WM_QUIT 消息。在您的主应用程序循环中,您测试WM_QUIT,当该消息到达时,您执行所有必要的关闭并跳出循环或调用ExitProcess

    如果没有空闲处理要做,你应该使用GetMessage,而不是在PeekMessage之后休眠,它会在内部休眠直到下一条消息到达。但是,OpenGL 动画循环符合空闲处理的条件,因此您不能这样做。

    但是,如果您的绘图调用每秒迭代一百万次,您就会遇到另一个问题:即您的图形驱动程序中没有启用垂直回扫同步 (V-Sync)。 启用它!

    由于我们希望我们的程序具有健壮性,即如果它们在其他用户的计算机上运行,​​而 V-Sync 也被禁用,那么将迭代次数限制在某个合理的数字是有意义的。不过,这不应该使用硬 Sleep 来完成。相反,您应该测量draw() 迭代之间的时间dT,如果小于,例如 5 毫秒(即 200Hz),您应该在抽签后添加5 - dT - 1 的睡眠。

    【讨论】:

    • exitprocess 也不起作用。我开始认为它永远不会“过去” if msg.message == quit 事情。我尝试放置一个消息框而不是中断它,它永远不会弹出。也许这只是因为它在窗口弹出之前关闭了窗口?另外我注意到我发布的代码可能甚至没有编译,不知道为什么因为我没有编辑它并且它为我编译。循环外有 2 个中断,showwindow 的第二个参数应该是 10。不知道我是如何编译的,但是很好。
    【解决方案3】:

    改变它,而不是 while(1)

    int continue = 1;
    
    while(continue > 0) 
    

    if(msg.message == WM_QUIT) {
                               continue = 0;
                               break;
                               }
    

    我也会缩短睡眠时间。

    【讨论】:

    • 不幸的是,这没有做任何事情
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2013-11-14
    • 2023-04-11
    相关资源
    最近更新 更多