Winapi 是否可以使用Direct2d和Win7创建透明窗口?

Winapi 是否可以使用Direct2d和Win7创建透明窗口?,winapi,alpha,direct2d,alpha-transparency,Winapi,Alpha,Direct2d,Alpha Transparency,我的系统是Windows 7,我想将Direct2D用于工具包项目 我想在窗口的某些部分创建一个每像素透明/半透明的窗口(我们可以透明或半透明地看到我窗口下方的窗口) 我已经看过了(见本网页最底部的图片),这似乎是可能的,但只有使用扩展窗口样式的WS_EX_NoreditionBitmap,它在Win7上不可用(仅在win8之后) 我曾尝试使用一个渲染目标,它是带有预乘alpha的bgra和一个扩展窗口样式WS_EX_COMPOSITED | WS_EX_TRANSPARENT,没有运气 以下是

我的系统是Windows 7,我想将Direct2D用于工具包项目

我想在窗口的某些部分创建一个每像素透明/半透明的窗口(我们可以透明或半透明地看到我窗口下方的窗口)

我已经看过了(见本网页最底部的图片),这似乎是可能的,但只有使用扩展窗口样式的WS_EX_NoreditionBitmap,它在Win7上不可用(仅在win8之后)

我曾尝试使用一个渲染目标,它是带有预乘alpha的bgra和一个扩展窗口样式WS_EX_COMPOSITED | WS_EX_TRANSPARENT,没有运气

以下是我的代码(相关代码,即创建渲染目标和布局,位于render()函数中):

#包括
#ifdef_WIN32_WINNT
#undef\u WIN32\u WINNT
#恩迪夫
#定义_WIN32_WINNT 0x602
#包括
静态HINSTANCE实例=NULL;
静态HWND win=NULL;
静态ID2D1Factory*工厂=NULL;
静态ID2D1HwndRenderTarget*rt=NULL;
LRESULT回调\u窗口\u过程(HWND窗口,
UINT消息,
WPARAM窗口参数,
lpram数据参数);
静态空隙
render()
{
矩形r;
HRESULT res;
/*渲染目标*/
GetClientRect(win,&r);
D2D1_SIZE_SIZE=D2D1::SizeU(右,右下);
浮动dpix;
浮动dpiy;
工厂->GetDesktopDpi(&dpix和&dpiy);
D2D1_渲染_目标_属性rtp;
rtp.type=D2D1_RENDER_TARGET_type_DEFAULT;
rtp.pixelFormat.format=DXGI_format_B8G8R8A8_UNORM;
rtp.pixelFormat.alphaMode=D2D1_ALPHA_MODE_预乘;
rtp.dpiX=dpiX;
rtp.dpiY=dpiY;
rtp.usage=D2D1_RENDER_TARGET_usage_NONE;
rtp.minLevel=D2D1_特征_等级_10;
D2D1_HWND_RENDER_TARGET_PROPERTIES wrtp;
wrtp.hwnd=win;
wrtp.pixelSize=大小;
wrtp.presentOptions=D2D1\u立即显示\u选项;
res=工厂->创建HwnRenderTarget(rtp、wrtp和rt);
如果(失败(res))
{
标准::cout Clear(D2D1::ColorF(D2D1::ColorF::天蓝色,0.5f));
rt->填充椭圆(椭圆,画笔);
rt->EndDraw();
}
LRESULT回调
_窗口程序(HWND窗口,
UINT消息,
WPARAM窗口参数,
LPRAM数据(参数)
{
开关(信息)
{
案例WM_结束:
PostQuitMessage(0);
返回0;
案例WM_KEYUP:
如果(窗口参数=='Q')
{
PostQuitMessage(0);
}
返回0;
/*GDI通知*/
案例WM_油漆:
{
RECT-RECT;

std::cout在Win7上可以有一个透明的窗口,而不使用
WS\u EX\u LAYERED
样式,但它有一些缺点:

  • 窗口必须有
    WS\u弹出窗口
    样式,否则如果窗口样式有玻璃,窗口背景将模糊

  • 必须打开windows上的DWM(桌面窗口管理器),否则windows将不透明

  • 虽然窗口在视觉上是透明的,但鼠标点击并没有穿过100%透明的区域。也许有解决办法,但我不知道有什么办法

     // Transparent window setup
     #include <dwmapi.h>
     #pragma comment(lib, "Dwmapi")
     // ....
    
     MARGINS margins = { -1 };
     DwmExtendFrameIntoClientArea(m_hwnd, &margins);
     if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory)))
     {
         return -1;
     }
    
     // ...
    
     hr = pFactory->CreateHwndRenderTarget(
         D2D1::RenderTargetProperties(
             D2D1_RENDER_TARGET_TYPE_DEFAULT
             , D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED)
         )
         , D2D1::HwndRenderTargetProperties(m_hwnd, size)
         , &pRenderTarget
     );
    
    //透明窗口设置
    #包括
    #pragma注释(lib,“Dwmapi”)
    // ....
    边距边距={1};
    DwmExtendFrameIntoClientArea(m_hwnd和margins);
    如果(失败(D2D1CreateFactory(D2D1工厂类型单线程和PFFactory)))
    {
    返回-1;
    }
    // ...
    hr=pFactory->CreateHwndRenderTarget(
    D2D1::RenderTargetProperties(
    D2D1_渲染_目标_类型_默认值
    ,D2D1::像素格式(DXGI格式未知,D2D1阿尔法模式预乘)
    )
    ,D2D1::HwndRenderTargetProperties(m_hwnd,大小)
    ,&pRenderTarget
    );
    
如果窗口不透明,则可能已关闭DWM或窗口未设置areo样式


Kenny Kerr在这方面发表了一篇很好的文章:@JonathanPotter在这篇文章中,使用了分层窗口,正如我在帖子中所说,这是我不想要的。如果你主动拒绝解决方案,那么你的问题就没有解决方案。我不会拒绝解决方案,因为它不是解决方案:有人提出了我不想要的东西。你不能这将是一个解决方案。如果有人告诉我我想要的真的不可能,那么,我同意。在Windows 7上使用分层窗口是解决方案。你不希望它成为解决方案这一事实不会改变这一点。或者使用分层窗口,不支持Windows 7,或者干脆放弃半透明窗口的用途一个好的用户界面。
 // Transparent window setup
 #include <dwmapi.h>
 #pragma comment(lib, "Dwmapi")
 // ....

 MARGINS margins = { -1 };
 DwmExtendFrameIntoClientArea(m_hwnd, &margins);
 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory)))
 {
     return -1;
 }

 // ...

 hr = pFactory->CreateHwndRenderTarget(
     D2D1::RenderTargetProperties(
         D2D1_RENDER_TARGET_TYPE_DEFAULT
         , D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED)
     )
     , D2D1::HwndRenderTargetProperties(m_hwnd, size)
     , &pRenderTarget
 );