调整大小时,WS_POPUP窗口的行为很奇怪

时间:2014-07-14 08:02:52

标签: c++ windows winapi

我有一个样式为WS_POPUP的窗口,可以通过NCHITTEST调整大小。我只返回角落结果(HTTOPLEFT等),以便无法拖动窗口。当调整窗口大小时,它会出现“摆动” - 也就是说,对于几帧,没有调整大小的角落会改变其位置,直到恢复到之前的位置。

这似乎是某种默认行为,因为无论我是否自己设置窗口位置都会发生这种情况 - IE,如果我只是在做NCHITTEST,就会发生这种情况。这不是什么大不了的事,因为窗口最终会稳定到正确的坐标,但它看起来有点不专业。我有什么办法可以改变这种行为吗?

这是我的代码:

#include <Windows.h>

LRESULT CALLBACK wnd_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam);

INT16 x = 0;
INT16 y = 0;
WORD width = 0;
WORD height = 0;
HWND handle = NULL;
bool run = true;
INT16 desktop_x = 0;
INT16 desktop_y = 0;
WORD desktop_width = 0;
WORD desktop_height = 0;

int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) {
        const WNDCLASSEXW wc = {
                sizeof(WNDCLASSEXW),
                CS_HREDRAW | CS_VREDRAW,
                wnd_proc,
                0, 0, GetModuleHandleW(NULL),
                NULL,
                LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_ARROW)),
                (HBRUSH)(COLOR_WINDOW + 2),
                NULL, L"DreamBeatWnd",
                NULL
        };

        RegisterClassExW(&wc);

        {
                RECT desktop = { 0 };

                GetWindowRect(GetDesktopWindow(), &desktop);

                desktop_x = desktop.left;
                desktop_y = desktop.top;
                desktop_width = desktop.right - desktop.left;
                desktop_height = desktop.bottom - desktop.top;
        }

        width = ((WORD)((desktop_width) * 0.80) / 16) * 16;
        height = (width / 16) * 9;
        x = desktop_x + ((desktop_width) / 2) - (width / 2);
        y = desktop_y + ((desktop_height) / 2) - (height / 2);

        handle = CreateWindowW(
                wc.lpszClassName,
                L"window",
                WS_POPUP,
                x, y,
                width, height,
                NULL, NULL, wc.hInstance, NULL
                );

        UpdateWindow(handle);
        ShowWindow(handle, SW_SHOW);

        MSG msg;

        while (true) {
                while (PeekMessageW(&msg, handle, 0, 0, PM_REMOVE) > 0) {
                        TranslateMessage(&msg);
                        DispatchMessageW(&msg);
                }

                if (!run) {
                        break;
                }
        }

        return 0;
}

LRESULT CALLBACK wnd_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) {
        switch (message) {
        case WM_CLOSE:
                run = false;
                return 0;

        case WM_NCHITTEST: {
                POINT p;
                p.x = LOWORD(lparam);
                p.y = HIWORD(lparam);
                ScreenToClient(window, &p);

                if (p.x < 3) {
                        if (p.y < 3) {
                                return HTTOPLEFT;
                        }
                        else if (p.y > height - 3) {
                                return HTBOTTOMLEFT;
                        }
                }
                else if (p.x > width - 3) {
                        if (p.y < 3) {
                                return HTTOPRIGHT;
                        }
                        else if (p.y > height - 3) {
                                return HTBOTTOMRIGHT;
                        }
                }

                return DefWindowProcW(window, message, wparam, lparam);
        }

        case WM_WINDOWPOSCHANGING: {
                WINDOWPOS* pos = (WINDOWPOS*)(lparam);

                pos->cx = (int)((double(pos->cy) / 9) * 16);
                pos->x = (int)((double(desktop_x + desktop_width) / 2) - (double(pos->cx) / 2));
                pos->y = (int)((double(desktop_y + desktop_height) / 2) - (double(pos->cy) / 2));

                x = pos->x;
                y = pos->y;
                width = pos->cx;
                height = pos->cy;

                return 0;
        }
        }

        return DefWindowProcW(window, message, wparam, lparam);
}

0 个答案:

没有答案