我正在更新一个带有多个按钮的MFC对话框。
目前,该对话框有一个Picture控件,覆盖整个对话框,提供带图案的背景。最重要的是,每个按钮都是CBitmapButton,使用(不透明)图像精心生成,以匹配它们所覆盖的背景区域。
如果图像可以创建为大部分透明,显然会更容易,因此背景会自动显示。但是,在这种情况下,我无法弄清楚如何让MFC正确渲染透明图像。
据我所知,我可能想要一个与CBitmapButton不同的类,或者需要编写一个自定义子类;那没关系,但我不知道从哪里开始。支持带有alpha通道的32位BMP或PNG会很不错,但我会选择“指定的颜色应该是透明的”类型。
答案 0 :(得分:1)
这可能不是最好的方法,但我要做的是创建一个自定义的CButton派生类(假设您实际上正在使用其余的CButton功能),然后重写DrawItem函数以放置您的自定义绘图代码。
对于图像本身,我使用Bitmap GDI +对象(允许您加载带有alpha通道的BMP或PNG),然后使用常规DrawImage函数绘制位图。
如果您要将PNG放入资源文件中,则需要将它们作为“PNG”类型放入。确保在查看条目的资源文件代码时
IDB_PNG1 PNG“C:\ temp \ test.png”
并且不会尝试将其视为BITMAP资源,否则您将无法加载它们。
修改强>
将我的回复放在这里,以便我可以发布代码。是的,我的意思是从CButton派生一个自定义类,然后添加一个Gdiplus :: 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);
}