【问题标题】:Direct2D: Opaque child windows over a transparent parent windowDirect2D:透明父窗口上的不透明子窗口
【发布时间】:2013-02-21 09:34:25
【问题描述】:

我想创建一个 Direct2D 应用程序,它具有透明背景,上面放置了一些不透明的复杂控件。 问题可以分解成几个子问题:

架构:是否应该将控件实现为子窗口?我认为这是正确的方法,而不是创建实现子窗口功能的 Direct2D 多边形。

我尝试通过初始化父窗口来实现这一点:

SetWindowLong(m_hwnd, GWL_EXSTYLE, GetWindowLong(m_hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(m_hwnd, 0, (255 * 50) / 100, LWA_ALPHA);

并将子窗口创建为 WS_CHILD。这导致了一个孩子,包括背景在内的所有 D2D 溺水都是透明的。我找不到让孩子变得不透明的方法。 当我将子窗口创建为 WS_POPUPWS_OVERLAPPED 时,不透明度问题得到解决,但子窗口位于与父窗口无关的桌面上。

分层窗口? 我选择使用分层 Windows,但由于我的目标是 VistaSP2 及更高版本,因此可能会有更好的解决方案。 我尝试了here 提供的解决方案,但我也未能实施。

【问题讨论】:

    标签: c++ transparency direct2d layered-windows


    【解决方案1】:

    您的意思是创建一个每像素 32 位的窗口吗? (抱歉无法评论,这里没有足够的代表)

    在这种情况下,无论如何,每次完成场景绘制后,您都必须使用 UpdateLayeredWindow(以及在初始化时调用 CreateDIBSection),例如:

    // Draw to your D2D1 RenderTarget here
    RECT rcWin = {0};
    GetWindowRect(hWnd,&rcWin);
    POINT ptw = {rcWin.left,rcWin.top};
    SIZE pts = {rcWin.right-rcWin.left,rcWin.bottom-rcWin.top};
    POINT ptsrc = {0};
    HDC ScreenDC = GetDC(0);
    UpdateLayeredWindow( hWnd, ScreenDC, &ptw, &pts, MemDC, &ptsrc, 0, &bf, ULW_ALPHA);
    ReleaseDC(0,ScreenDC);
    

    关于初始化:

    RECT r = {0};
    GetWindowRect(hWnd,&r);
    HDC scrDC = GetDC(0);
    MemDC = CreateCompatibleDC(scrDC);
    ReleaseDC(0,scrDC);
    if(!MemDC)
        { FailInit(); }
    BITMAPINFO bmi = {0};
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biWidth = r.right-r.left;
    bmi.bmiHeader.biHeight = r.bottom-r.top;
    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
    DIBSectionBitmap = CreateDIBSection(MemDC,&bmi,DIB_RGB_COLORS,0,0,0);
    if(!DIBSectionBitmap)
        return 0;
    OldBmp = (HBITMAP)SelectObject(MemDC,DIBSectionBitmap);
    // Now create the HWND D2D1 RenderTarget.
    

    关于资源的释放:

    // Free the D2D1 RenderTarget here
    if(MemDC && OldBmp)
        SelectObject(MemDC,OldBmp);
    if(DIBSectionBitmap)
        DeleteObject(DIBSectionBitmap);
    if(MemDC)
        DeleteDC(MemDC);
    MemDC = 0;
    OldBmp = 0;
    DIBSectionBitmap = 0;
    

    编辑:MemDC、OldBmp 和 DIBSectionBitmap 是每个窗口的。 MemDC 是一个 HDC。 OldBmp 是一个 HBITMAP。 DIBSectionBitmap 是一个 HBITMAP。 此时,您可以绘制您的子窗口,就好像它们是您自己的主窗口的一部分一样,具有每像素 alpha 精度,但您需要自己处理焦点和消息传递。

    【讨论】:

      猜你喜欢
      • 2019-04-24
      • 2012-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-21
      • 2012-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多