我最近初学Direct2D。这个窗口是支持透明的,这里我画了两个实心圆,它们有重合的部分
//ID2D1DCRenderTarget* pDCRT;
//ID2D1SolidColorBrush* pBrush;
pDCRT->Clear(D2D1::ColorF(D2D1::ColorF(0, 0, 1, 0.5f)));
D2D1_ELLIPSE pe1 = D2D1::Ellipse(D2D1::Point2F(200, 200), 150, 150);
D2D1_ELLIPSE pe2 = D2D1::Ellipse(D2D1::Point2F(350, 200), 150, 150);
pDCRT->CreateSolidColorBrush(D2D1::ColorF(1, 0, 0, 1), &pBrush);
pDCRT->FillEllipse(pe1, pBrush);
pDCRT->CreateSolidColorBrush(D2D1::ColorF(0, 1, 0, 0.5f), &pBrush);
pDCRT->FillEllipse(pe2, pBrush);
我想让重合的部分只有右边实心圆的颜色,就是让它透明的时候忽略掉左边圆和窗口背景色直接透到桌面,请问,怎么才能实现的效果。
【以下回答由 GPT 生成】
要实现让重叠的部分只显示右边实心圆的颜色,可以通过以下步骤进行:
WS_EX_LAYERED
,以支持透明度。可以使用以下代码片段将窗口的样式设置为WS_EX_LAYERED
:DWORD exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
exStyle |= WS_EX_LAYERED;
SetWindowLong(hWnd, GWL_EXSTYLE, exStyle);
D2D1::RenderTargetProperties
来创建一个具有透明背景的ID2D1HwndRenderTarget
对象。可以使用以下代码片段:D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
0,
0,
D2D1_RENDER_TARGET_USAGE_NONE,
D2D1_FEATURE_LEVEL_DEFAULT
);
HRESULT hr = pFactory->CreateHwndRenderTarget(
renderTargetProperties,
D2D1::HwndRenderTargetProperties(hWnd, size),
&pRenderTarget
);
ID2D1HwndRenderTarget
的透明度模式为D2D1_ALPHA_MODE_PREMULTIPLIED
。可以使用以下代码片段:pRenderTarget->SetDpi(dpiX, dpiY);
pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
pRenderTarget->BeginDraw();
pRenderTarget->Clear(D2D1::ColorF(0, 0, 0, 0));
pRenderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_ALIASED);
pRenderTarget->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
pRenderTarget->SetPixelSnappingPolicy(D2D1_PIXEL_SNAPPING_POLICY_DIPS);
pRenderTarget->SetTags(0, 0);
pRenderTarget->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_SOURCE_OVER);
pDCRT->CreateSolidColorBrush(D2D1::ColorF(1, 0, 0, 1), &pBrush);
pDCRT->FillEllipse(pe1, pBrush);
pDCRT->CreateSolidColorBrush(D2D1::ColorF(0, 1, 0, 1), &pBrush);
pDCRT->FillEllipse(pe2, pBrush);
其中,右边实心圆的颜色的透明度为1,这样重叠部分就会完全覆盖左边实心圆的颜色。
完整的代码示例可以参考以下内容:
#include <Windows.h>
#include <d2d1.h>
ID2D1Factory* pFactory = nullptr;
ID2D1HwndRenderTarget* pRenderTarget = nullptr;
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
// 创建窗口
HWND hWnd = CreateWindowExW(
WS_EX_LAYERED,
L"WindowClassName",
L"Transparent Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
nullptr, nullptr, hInstance, nullptr
);
if (hWnd == nullptr)
{
return 0;
}
// 创建Direct2D工厂
HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory);
if (FAILED(hr))
{
return 0;
}
// 设置窗口透明度样式
DWORD exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
exStyle |= WS_EX_LAYERED;
SetWindowLong(hWnd, GWL_EXSTYLE, exStyle);
// 创建透明窗口
RECT windowRect;
GetWindowRect(hWnd, &windowRect);
D2D1_SIZE_U size = D2D1::SizeU(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
0,
0,
D2D1_RENDER_TARGET_USAGE_NONE,
D2D1_FEATURE_LEVEL_DEFAULT
);
hr = pFactory->CreateHwndRenderTarget(
renderTargetProperties,
D2D1::HwndRenderTargetProperties(hWnd, size),
&pRenderTarget
);
if (FAILED(hr))
{
return 0;
}
ShowWindow(hWnd, nCmdShow);
// 消息循环
MSG msg = {};
while (GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// 释放资源
pRenderTarget->Release();
pFactory->Release();
return 0;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
if (pRenderTarget == nullptr)
{
break;
}
// 绘制透明窗口
pRenderTarget->BeginDraw();
pRenderTarget->Clear(D2D1::ColorF(0, 0, 0, 0));
pRenderTarget->EndDraw();
// 绘制实心圆
D2D1_ELLIPSE pe1 = D2D1::Ellipse(D2D1::Point2F(200, 200), 150, 150);
D2D1_ELLIPSE pe2 = D2D1::Ellipse(D2D1::Point2F(350, 200), 150, 150);
ID2D1SolidColorBrush* pBrush;
pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(1, 0, 0, 1), &pBrush);
pRenderTarget->FillEllipse(pe1, pBrush);
pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(0, 1, 0, 1), &pBrush);
pRenderTarget->FillEllipse(pe2, pBrush);
pBrush->Release();
ValidateRect(hWnd, NULL);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
【相关推荐】