防止窗户移动

Prevent window movement

本文关键字:移动 窗户      更新时间:2023-10-16

我目前有一个在win32窗口运行的小游戏。我刚刚注意到,当我按住窗口的顶部(有关闭按钮的栏)时,它会冻结我的应用程序。我想禁用这个,因为它设法完全破坏我的应用程序(计时器继续计数)。

看起来,即使是最简约的创建窗口的设置,它仍然有这个功能。如何禁用此功能?我现在有:

 HWND hWnd = CreateWindowW( L"Game",L"Game",
                          0x00000000L | 0x00080000L,
                          wr.left,
                          wr.top,
                          wr.right-wr.left,
                          wr.bottom-wr.top,
                          NULL,
                          NULL,
                          wc.hInstance,
                          NULL );

我读到我的线程在拖拽时被忽略,如果我被迫使用2个线程,有人可以提供一个使用的小例子吗?

或者我应该停止计时器?(我应该捕获什么消息,它甚至会被捕获吗?)

我正在使用我的time类的实例来处理时间,它看起来像:

Timer::Timer() {
    __int64 frequency;
    QueryPerformanceFrequency( (LARGE_INTEGER*)&frequency );
    invFreqMilli = 1.0f / (float)((double)frequency / 1000.0);
    StartWatch();
}
void Timer::StartWatch() {
    startCount = 0;
    currentCount = 0;
    watchStopped = false;
    QueryPerformanceCounter( (LARGE_INTEGER*)&startCount );
}

我的Win32消息循环包含:mousemove, keyup和keydown

当DefWindowProc在wParam中使用SC_MOVE或SC_SIZE处理WM_SYSCOMMAND时,它进入一个循环,直到用户通过释放鼠标按钮或按enter或escape来停止它。这样做是因为它允许程序通过处理WM_PAINT和WM_NCPAINT消息来渲染客户端区域(你的小部件或游戏或任何绘制的地方)和边框和标题区域(你应该仍然在你的窗口过程中接收这些事件)。

对于普通的Windows应用程序来说,它工作得很好,因为它们的大部分处理都是在接收消息的窗口过程中进行的。它只影响那些在窗口程序之外进行处理的程序,比如游戏(通常是全屏的,不受影响)。

但是,有一种方法可以绕过它:自己处理WM_SYSCOMMAND,调整大小或移动自己。这需要大量的努力,但可能证明是值得的。或者,当发送WM_SIZING时,您可以使用setjmp/longjmp从窗口过程中转义,或者沿着相同的线路运行Windows纤维;

我在上周末解决了它(使用第一种方法),如果你感兴趣的话,我已经在sourceforge上将代码发布到公共领域。一定要阅读README,尤其是注意事项部分。网址:https://sourceforge.net/projects/win32loopl/

既然标题栏向用户表示他/她可以移动窗口,那么就可以将标题栏和边框一并删除。参见"使用win32打开没有标题栏的窗口"的示例。

当游戏启动或暂停时,你可以显示你自己的UI元素,允许用户在这些特定情况下移动游戏窗口,但只有在这种情况下。

您可以使用WM_ENTERSIZEMOVEWM_EXITSIZEMOVE消息检查size/move循环