是否可以创建仅带边框的winapi窗口

jus*_*erg 4 c++ winapi dxgi

所以我正在尝试创建一个只显示其边框并让身体其他部分透视的窗口.我已经创建了一个模拟我头脑中的样子:

透明窗口,仅显示边框并显示其下方的内容

我尝试在具有透明像素的缓冲区中进行blitting但是没有达到预期的效果.

有任何想法吗 ?

IIn*_*ble 10

这可以通过将WS_EX_NOREDIRECTIONBITMAP 1扩展窗口样式传递给对CreateWindowEx的调用来实现.这可以防止系统为窗口的客户区分配渲染表面,使客户区完全透明.

请注意,这不会使窗口对鼠标单击透明.命中测试仍受窗口控制,即使它没有可见的客户区域.

以下代码提供了一个展示使用情况的最小代码示例:

#define UNICODE
#include <Windows.h>
#pragma comment(lib, "user32.lib")

int CALLBACK wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int) {

    WNDCLASSW wc{};
    wc.hCursor = ::LoadCursorW(nullptr, IDC_ARROW);
    wc.hInstance = hInstance;
    wc.lpszClassName = L"TransparentWindow";
    wc.lpfnWndProc = [](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -> LRESULT
    {
        switch (message) {
        case WM_DESTROY:
            ::PostQuitMessage(0);
            return 0;
        default:
            return ::DefWindowProcW(hWnd, message, wParam, lParam);
        }
    };
    ::RegisterClassW(&wc);

    ::CreateWindowExW(WS_EX_NOREDIRECTIONBITMAP, wc.lpszClassName, L"Transparent window",
                      WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                      CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                      nullptr, nullptr, hInstance, nullptr);

    MSG msg{};
    while (::GetMessageW(&msg, nullptr, 0, 0) > 0) {
        ::DispatchMessageW(&msg);
    }

    return msg.wParam;
}
Run Code Online (Sandbox Code Playgroud)

这会产生类似于以下屏幕截图的输出:

示例应用程序的截图


有关内部的更多信息以及常见的用例可以在Kenny Kerr的2014年6月MSDN杂志文章Windows with C++:使用Windows组合引擎的高性能窗口分层中找到.


1 这需要启用桌面合成.桌面组合在Windows的所有受支持版本中均可用,但在Windows 8之前可由用户/系统管理员禁用.

  • 如果禁用DWM,可能无法正常工作? (3认同)