具有透明度的MFC图像按钮

MFC Image Button with transparency

本文关键字:图像 按钮 MFC 透明度      更新时间:2023-10-16

我正在更新一个MFC对话框,上面有很多按钮。

目前,该对话框有一个图片控件,覆盖整个对话框,提供图案背景。除此之外,每个按钮都是一个CBitmapButton,使用精心生成的(不透明)图像来匹配它们覆盖的背景区域。

如果图像可以被创建为基本透明,这样背景就会自动显示出来,这显然会容易得多。然而,在这种情况下,我无法弄清楚如何让MFC正确地渲染透明图像。

我知道我可能想要一个不同于CBitmapButton的类,或者需要编写一个自定义子类;那很好,但我不知道从哪里开始。支持带有alpha通道的32位BMP或PNG会很好,但我会选择"指定的颜色应该是透明的"类型。

这可能不是最好的方法,但我要做的是创建一个自定义的CButton派生类(假设您实际上正在使用CButton的其余功能),然后覆盖DrawItem函数以将您的自定义绘图代码放入。

对于图像本身,我会使用位图GDI+对象(这将允许您使用alpha通道加载BMP或PNG),然后使用常规DrawImage函数绘制位图。

如果要将PNG放入资源文件中,则需要将其作为"PNG"类型放入。确保在查看资源文件代码时,条目看起来像

IDB_PNG1 PNG"C:\temp\test.PNG"

并且不要试图将其视为BITMAP资源,否则加载它们时会遇到问题。

编辑

把我的回复放在这里,这样我就可以发布代码了。是的,我想从CButton派生一个自定义类,然后添加一个Gdipls:Bitmap成员变量。以下是让它工作所需的大致操作,尽管我还没有检查代码是否真的编译和工作,但希望你能明白。这不是最有效的方法,但如果你以前没有做过很多自定义绘图,那么它确实有简单的优点!

void CMyButton::LoadImage(const int resourceID)
{
    m_pBitmap = Gdiplus::Bitmap::FromResource(NULL, MAKEINTRESOURCE(resourceID));
    ASSERT(m_pBitmap);
}
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
    ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON);
    CRect rcClient;
    GetClientRect(&rcClient);
    if (lpDrawItemStruct->itemState & ODS_SELECTED)
    {
        // If you want to do anything special when the button is pressed, do it here
        // Maybe offset the rect to give the impression of the button being pressed?
        rcClient.OffsetRect(1,1);
    }
    Graphics gr(lpDrawItemStruct->hDC);
    gr.DrawImage(m_pBitmap, rcClient.left, rcClient.top);
}