首页 > 解决方案 > WinAPI 不妥协的无边框窗口,下方有阴影

问题描述

我想达到什么目标:

我想创建一个行为类似于 a 的窗口WS_OVERLAPPEDWINDOW | WS_SIZEBOX(可以从系统上下文菜单中最小化、最大化、关闭Alt+Space,支持Window Snapping,如果它在系统中启用则有阴影Performance Options -> [x] Enable shadow under window等等)。它也应该是无边界的(没有标题栏、图标、标题栏中的应用程序名称等),只有客户区域,没有其他内容。

所以主要目标是:

不要说这是不可能的。这种窗口最简单的例子是 Telegram Desktop。他们使用 Qt 库。不要说我应该使用它。我想了解他们是如何做到这一点的。他们的窗口是无边界的,没有错误(如下所述)。我知道 Qt 在其窗口中使用 OpenGL。但我也知道应该可以只在没有 OpenGL 的情况下使用 GDI+ 进行绘制。

我已经尝试过的:

    LRESULT wmPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
        PAINTSTRUCT ps = {};
        HDC hdc = BeginPaint(hWnd, &ps);

        auto [width, height] = dimensions.normal;

        HDC memHdc = CreateCompatibleDC(hdc);
        HBITMAP hBitmap = CreateCompatibleBitmap(hdc, width, height);
        SelectObject(memHdc, hBitmap);

        // Children perform their drawings on "back buffer" - memDc
        handleChildrenDraw(memDc);


        // Copy top line as transparent and other as always to paint over non-client area as it was client

        BLENDFUNCTION bf = {};
        bf.BlendOp = AC_SRC_OVER;
        bf.SourceConstantAlpha = 254;
        bf.AlphaFormat = AC_SRC_ALPHA;
        auto alphaSuccess = AlphaBlend(hdc, 0, 0, width, 1, memHdc, 0, 0, width, 1, bf);
        expect(alphaSuccess == TRUE);
        auto copySuccess = BitBlt(hdc, 1, 0, width, height, memHdc, 1, 0, SRCCOPY);
        expect(copySuccess == TRUE);

        EndPaint(hWnd, &ps);

        DeleteObject(memHdc);
        DeleteObject(hBitmap);

        return 0;
    }

截图:顶部有白色条纹的窗口(由于某些原因已经渲染了边框)

问题:

你能告诉我如何修复这个顶部边框绘制错误或任何更好的解决方案来使用 WinAPI 绘制无边框窗口吗?提前致谢。

标签: c++winapigdi+gdiborderless

解决方案


推荐阅读