是否可以创建一个只有边框的 winapi window
Is it possible to create a winapi window with only borders
所以我正在尝试创建一个 window 只显示其边界并让主体的其余部分透明。
我已经创建了一个我脑海中的模型:
我尝试在具有透明像素的缓冲区中进行 blitting,但没有达到预期的效果。
有什么想法吗?
这可以通过传递 WS_EX_NOREDIRECTIONBITMAP1 extended window style to a call to CreateWindowEx 来实现。这可以防止系统为 window 的客户区分配渲染表面,使客户区完全透明。
请注意,这不会使 window 对鼠标点击透明。命中测试仍然由 window 管理,即使它没有可见的客户区。
以下代码提供了一个展示其用法的最小代码示例:
#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;
}
这会产生类似于以下屏幕截图的输出:
有关内部结构以及常见用例的更多信息,请参阅 Kenny Kerr 2014 年 6 月在 MSDN 杂志上发表的优秀文章 Windows with C++ : High-Performance Window Layering Using the Windows Composition Engine。
1 这需要启用桌面组合。桌面组合在 Windows 的所有受支持版本中都可用,但可以在 Windows 8.
之前由 user/system 管理员禁用
所以我正在尝试创建一个 window 只显示其边界并让主体的其余部分透明。 我已经创建了一个我脑海中的模型:
我尝试在具有透明像素的缓冲区中进行 blitting,但没有达到预期的效果。
有什么想法吗?
这可以通过传递 WS_EX_NOREDIRECTIONBITMAP1 extended window style to a call to CreateWindowEx 来实现。这可以防止系统为 window 的客户区分配渲染表面,使客户区完全透明。
请注意,这不会使 window 对鼠标点击透明。命中测试仍然由 window 管理,即使它没有可见的客户区。
以下代码提供了一个展示其用法的最小代码示例:
#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;
}
这会产生类似于以下屏幕截图的输出:
有关内部结构以及常见用例的更多信息,请参阅 Kenny Kerr 2014 年 6 月在 MSDN 杂志上发表的优秀文章 Windows with C++ : High-Performance Window Layering Using the Windows Composition Engine。
1 这需要启用桌面组合。桌面组合在 Windows 的所有受支持版本中都可用,但可以在 Windows 8.
之前由 user/system 管理员禁用