拖动时保持窗口处于活动状态(Win32上的SDL) [英] Keep window active while being dragged (SDL on Win32)

查看:229
本文介绍了拖动时保持窗口处于活动状态(Win32上的SDL)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我的代码设置了SDL环境,并继续更新了OpenGL上下文,而不执行任何SDL_Event处理.只要窗口一直处于打开状态,这就会使Windows显得无响应.窗口闪烁了一下.标题栏将被附加(不响应)",并且在窗口内部单击时,该窗口将变为灰色,因为Windows默认在无响应窗口上执行此操作.但是,在这种状态下(甚至在变灰之后),OpenGL显示仍将继续更新和设置动画,这是踢球者,甚至在拖动窗口时也会这样做.显然,在这种情况下,应用程序无法正确处理Windows中的事件,导致Windows认为它处于挂起状态.但是有明确的证据表明opengl仍在继续渲染.

At first my code set up the SDL environment, and proceeded to update the OpenGL context, without performing any SDL_Event processing whatsoever. This causes the window, as long as it was open, to appear to Windows to be unresponsive. The window flickers a bit. The titlebar would get "(Not Responding)" appended to it, and upon clicking inside the window it becomes grayed out, as Windows does this by default on non responsive windows. However in this state (even as and after it becomes grayed out), the OpenGL display continues to update and animate, and here's the kicker, it even does so while the window is being dragged. Clearly in this case the application isn't handling events from windows correctly, causing windows to think that it is in a hanged state. But there is clear evidence that the opengl continues to render.

现在,我对代码进行一次修改,即将这三行代码放置在循环内的适当位置(这也进行OpenGL绘制):

Now I make one single modification to the code, which is these three lines placed in an appropriate spot inside the loop (which also does the OpenGL draw):

SDL_Event event;
if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
    break;

这一切都是使用SDL刷新消息队列.

All this is doing is flushing the message queue using SDL.

现在的行为是Windows不再认为它是无响应",并且不会变灰.没有闪烁.一切似乎都如鱼得水.但是,一旦我单击并拖动标题栏以拖动窗口,渲染就会被阻塞.我不确定是否进行调试,但是我怀疑SDL_PollEvent在窗口拖动期间会阻塞.

Now the behavior is that Windows no longer thinks it is "Not Responding" and it does not get grayed out. No flicker. Everything seems to run swimmingly. But once I click and drag the title bar to drag the window, rendering gets blocked. I haven't debugged it to be sure, but I suspect that SDL_PollEvent blocks for the duration of the window drag.

有没有解决的办法?这很有趣,因为未能处理事件表现出的部分行为证明了我想要的理论上是可能的.

Is there a way around this? This is interesting because part of the behavior exhibited by failing to handle events is proof that what I want is possible in theory.

更新:我发现了这个线程: http://www.gamedev.net/topic/488074-win32-message-pump-and-opengl---rendering-pauses-while-draggingresizing/

Update: I found this thread: http://www.gamedev.net/topic/488074-win32-message-pump-and-opengl---rendering-pauses-while-draggingresizing/

判决似乎归结于Microsoft为我们做出的某些选择...它基本上会卡在DefWindowProc()中,直到释放鼠标为止.破解此修复程序将变得非常混乱,我也许可以通过在另一个线程中进行渲染来解决此问题.但是我什至不想开始考虑从多个线程来处理OpenGL上下文,如果有可能的话.

The verdict seems to be that it comes down to certain choices that Microsoft made for us... It basically gets stuck in DefWindowProc() till the mouse is released. It would get very messy to hack a fix for this and I might be able to do a work around by rendering in another thread. But I don't even want to begin to think about juggling an OpenGL context from multiple threads, if that's even something that's possible.

推荐答案

一些适用于我的解决方法-为SDL_WINDOWEVENT_SIZE_CHANGED事件添加事件过滤器,并执行其他SetViewport并绘制框架.

Some workaround that works for me - add event filter for SDL_WINDOWEVENT_SIZE_CHANGED event and do additional SetViewport and draw frame.

int SDLApp::eventFilter(void* pthis, const SDL_Event *event)
{
    if (event->type == SDL_WINDOWEVENT &&
        event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
    {
        SDLApp* app = (SDLApp*)pthis;
        // Note: NULL rectangle is the entire window
        SDL_RenderSetViewport(app->renderer_, NULL);
        app->DrawFrame();
    }
    return 1;
}

...
SDL_SetEventFilter((SDL_EventFilter)SDLApp::eventFilter, this);

这篇关于拖动时保持窗口处于活动状态(Win32上的SDL)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆