繁体   English   中英

如何正确移动带有区域的窗口?

[英]How do I properly move a window with a region?

我刚刚开始研究窗口区域,我正在尝试创建一个椭圆窗口,我可以通过拖动客户区来移动它。 不幸的是,当我拖动窗口时,窗口从椭圆到正常窗口来回闪烁(好像我从未调用过SetWindowRgn ),然后反复快速地返回。

我在MSDN上读到我必须调用SetWindowRgn(nullptr); ,然后移动窗口,然后重置我已经在我的代码中完成的区域。 我通过调用带有SWP_NOZORDERSWP_NOSIZESWP_NOREDRAW SetWindowPos移动窗口,并且我尝试添加所有SWP_NOSENDCHANGINGSWP_DEFERERASESWP_NOCOPYBITS ,但无济于事。

这是我的窗口过程,重点是WM_MOUSEMOVE 我知道如果我释放窗外的按钮,它将无法工作; 我计划在这个工作之后解决这个问题。 我也遗漏了错误检查。 很明显,调用确实有效,因为窗口在我拖动时会移动。

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    static bool moving{};

    switch (msg) {
        case WM_DESTROY: {
            PostQuitMessage(0);
            return 0;
        }

        case WM_LBUTTONDOWN: {
            moving = true;
            return 0;
        }

        case WM_LBUTTONUP: {
            moving = false;
            return 0;
        }

        case WM_MOUSEMOVE: {
            static POINT old{0, 0};

            if (moving) {
                RECT r;
                GetWindowRect(hwnd, &r);

                int x = GET_X_LPARAM(lParam);
                int y = GET_Y_LPARAM(lParam);

                RECT newPos;
                newPos.left = r.left + x - old.x;
                newPos.top = r.top + y - old.y;

                SetWindowRgn(hwnd, nullptr, FALSE);

                SetWindowPos(hwnd, nullptr, newPos.left, newPos.top, 0, 0,
                    SWP_NOZORDER | SWP_NOSIZE | SWP_NOREDRAW
                );

                SetWindowRgn(hwnd, CreateEllipticRgn(200, 200, 600, 400), FALSE);
            }

            old.x = GET_X_LPARAM(lParam);
            old.y = GET_Y_LPARAM(lParam);

            return 0;
        }
    }

    return DefWindowProc(hwnd, msg, wParam, lParam);
}

我也试过调用ValidateRgn(hwnd, nullptr); WM_MOUSEMOVE结束时,它不会改变任何东西。 同样,我已经尝试在一个条件下包装DefWindowProc调用,如果设置了moving就返回0,以便查看是否只是发送的其他消息正在弄乱它,但是这导致窗口什么都不做拖累。 然后我将该条件应用于WM_PAINTWM_ERASEBKGND处理程序,但是在拖动时会导致相同的闪烁问题。

为了更容易地测试它,这里是完整的代码 (只是基本的窗口创建等)。 我要以正确的方式移动窗户吗? 是否有一些我应该处理的消息或事情,但不是吗? 这种情况发生在Window 7 Ultimate N.

处理移动逻辑的一种更简单的方法是处理WM_NCHITTEST消息,返回HTCAPTION 这使得Windows可以为您处理所有移动逻辑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM