繁体   English   中英

透明度分层窗口白色

[英]transparency layered window white

我正在尝试使用c ++ win32制作一个分层的窗口,但是它的图形或“碰撞”存在问题

供参考,我试图显示的图片。

默认

这是窗口的基本创建

//window
DWORD exFlags = 0;
if(m_bTransparent)
    exFlags |= WS_EX_LAYERED;
Create(WS_POPUP, exFlags);

std::wstring sPic(L"power-disconnected.png");
m_pAlertPic = m_pPowerMon->GetGPPicMan()->LoadPicture(sPic.c_str());

// make the window layered when using transparency
if(m_bTransparent && m_pAlertPic != nullptr)
{
    HDC hdcScreen = GetDC(GetHandle());
    HDC hdc = CreateCompatibleDC(hdcScreen);
    HBITMAP hbmpold = (HBITMAP)SelectObject(hdc, m_pAlertPic->GetBuffer());

    POINT dcOffset = {0, 0};
    SIZE size = {ww, wh};

    BLENDFUNCTION bf = {AC_SRC_OVER, 0, (int) (2.55 * 100), AC_SRC_ALPHA}; // blend function combines opacity and pixel based transparency
    UpdateLayeredWindow(GetHandle(), hdcScreen, NULL, &size, hdc, &dcOffset, RGB(255, 255, 255), &bf, ULW_ALPHA);
    SelectObject(hdc, hbmpold);
    DeleteDC(hdc);
    ReleaseDC(GetHandle(), hdcScreen);
}

和消息循环

int WindowAlert::WndProc(Gnaq::WindowBase* pWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   switch(msg)
   {
   case WM_CLOSE:
       Hide();
       return 1;
   case WM_PAINT:
       // only draw when the widow is not transparent
       // layered window redraw them self
       if(!m_bTransparent)
           m_pCanvas->Draw(m_pGraphics);
       break;
   case WM_LBUTTONUP:
       pWnd->Hide();
       m_bDismised = true;
       break;
   }
   return DefWindowProcW(pWnd->GetHandle(), msg, wParam, lParam);

}

所以这就是我得到的结果 UpdateLayeredWindow结果 如您所见,使用这种方法时,我得到的白色边框实际上应该是完全透明的,但是半透明的部分却可以正常工作。

这是我尝试过的给我带来“有用”变化的方法。 首先,我只是尝试添加ULW_COLORKEY标志以隐藏白色

UpdateLayeredWindow(GetHandle(), hdcScreen, NULL, &size, hdc, &dcOffset, RGB(255, 255, 255), &bf, ULW_ALPHA | ULW_COLORKEY);

结果。 ULW_COLORKEY

因此,这将隐藏白色边框,但也隐藏图片中的所有白色。 我尝试过的下一件事是结合使用SetLayeredWindowAttributes和UpdateLayeredWindow,而没有ULW_COLORKEY标志

SetLayeredWindowAttributes(GetHandle(), 0xFFFFFF00, 255, LWA_COLORKEY);

同样在窗口proc中启用绘画,就像这样

case WM_PAINT:
    m_pCanvas->Draw(m_pGraphics);
    break;

这样,我从视觉上得到我想要的东西 SetLayeredWindowAttributes

但是他的方法的问题在于,整个窗口是可以单击的,而仅使用UpdateLayeredWindow,只有应该完全透明的部分才可以单击。 我对最后一种方法也有一种感觉,那就是它是一种“ hack”而不是一种体面的方法。

所以我希望有人能告诉我我在做什么错。

第一种方法是正确的。 错误出在位图中,它没有预乘alpha

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM