CMFCStatusBar::SetPaneIcon是否支持alpha图标?
Does CMFCStatusBar::SetPaneIcon supports alpha icon?
我的应用程序设置图标窗格的状态栏(类CMFCStatusBar)。这个任务只有一个方法——CMFCStatusBar::SetPaneIcon()。但是如果图标有alpha通道,这个方法会加载错误的图像(黑色背景)。我查看了源代码,发现CMFCStatusBar对每个窗格使用内部HIMAGELISTs。所有这些HIMAGELIST创建标志ILC_MASK | ILC_COLORDDB,而不是ILC_COLOR32或ILC_COLOR24。
这是一个bug!
那么,是否有一种方法可以在CMFCStatusBar窗格中使用带有alpha通道的图标?
的例子:
HICON hIcon = ::LoadImage(hModule, MAKEINTRESOURCE(nIconID), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
m_StatusBar.SetPaneIcon(m_StatusBar.CommandToIndex(ID_INDICATOR_1), hIcon);
Microsoft从BCG工具包中开发了CMFC类(Feature Pack)。如果将CMFCStatusBar::SetPaneIcon()
方法与来自同一类的BCG方法进行比较,您会注意到一些细微的差异。
BCG用alpha blend标志定义了它的方法。方法如下:
void CBCGPStatusBar::SetPaneIcon (int nIndex, HBITMAP hBmp,
COLORREF clrTransparent, BOOL bUpdate, BOOL bAlphaBlend/* = FALSE*/)
CMFC等效删除' bAlphaBlend '标志。比较方法代码,您将看到BCG使用了以下从CMFC版本中删除的代码:
DWORD dwFlags = ILC_MASK | ILC_COLORDDB;
if (bAlphaBlend)
{
dwFlags = ILC_COLOR32;
}
pSBP->hImage = ::ImageList_Create (pSBP->cxIcon, pSBP->cyIcon, dwFlags, 1, 0);
我不确定为什么CMFC版本差异如此之大(微软可能有一个合理的理由),但是,我在下面包含了BCG版本。我将研究BCG版本,并可能从该代码创建您自己的' SetPaneIcon '方法(风险由您自己承担)。
void CBCGPStatusBar::SetPaneIcon (int nIndex, HBITMAP hBmp,
COLORREF clrTransparent, BOOL bUpdate, BOOL bAlphaBlend/* = FALSE*/)
{
ASSERT_VALID(this);
CBCGStatusBarPaneInfo* pSBP = _GetPanePtr(nIndex);
if (pSBP == NULL)
{
ASSERT (FALSE);
return;
}
// Disable animation (if exist):
SetPaneAnimation (nIndex, NULL, 0, FALSE);
if (hBmp == NULL)
{
if (pSBP->hImage != NULL)
{
::ImageList_Destroy (pSBP->hImage);
}
pSBP->hImage = NULL;
if (bUpdate)
{
InvalidatePaneContent (nIndex);
}
return;
}
BITMAP bitmap;
::GetObject (hBmp, sizeof (BITMAP), &bitmap);
if (pSBP->hImage == NULL)
{
pSBP->cxIcon = bitmap.bmWidth;
pSBP->cyIcon = bitmap.bmHeight;
DWORD dwFlags = ILC_MASK | ILC_COLORDDB;
if (bAlphaBlend)
{
dwFlags = ILC_COLOR32;
}
pSBP->hImage = ::ImageList_Create (pSBP->cxIcon, pSBP->cyIcon, dwFlags, 1, 0);
RecalcLayout ();
}
else
{
ASSERT (pSBP->cxIcon == bitmap.bmWidth);
ASSERT (pSBP->cyIcon == bitmap.bmHeight);
::ImageList_Remove (pSBP->hImage, 0);
}
//---------------------------------------------------------
// Because ImageList_AddMasked changes the original bitmap,
// we need to create a copy:
//---------------------------------------------------------
HBITMAP hbmpCopy = (HBITMAP) ::CopyImage (hBmp, IMAGE_BITMAP, 0, 0, 0);
if (bAlphaBlend)
{
::ImageList_Add (pSBP->hImage, hbmpCopy, NULL);
}
else
{
::ImageList_AddMasked (pSBP->hImage, hbmpCopy, clrTransparent);
}
::DeleteObject (hbmpCopy);
if (bUpdate)
{
InvalidatePaneContent (nIndex);
}
}
我的解决方案,基于rrirower代码。
CMFCStatusBarPaneInfo* CMyStatusBar::GetPane(int nIndex) const {
if (nIndex == 255 && m_nCount < 255) {
// Special case for the simple pane
for (int i = 0; i < m_nCount; i++)
{
CMFCStatusBarPaneInfo* pSBP = GetPane(i);
ENSURE(pSBP != NULL);
if (pSBP->nStyle & SBPS_STRETCH) {
return pSBP;
}
}
}
if (nIndex < 0 || nIndex >= m_nCount) {
return NULL;
}
if (m_pData == NULL) {
ASSERT(FALSE);
return NULL;
}
return((CMFCStatusBarPaneInfo*)m_pData) + nIndex;
}
void CMyStatusBar::SetPaneIcon(int nIndex, HICON hIcon, BOOL bUpdate /*= TRUE*/)
{
ASSERT_VALID(this);
CMFCStatusBarPaneInfo* pSBP = GetPane(nIndex);
if (pSBP == NULL)
{
ASSERT(FALSE);
return;
}
// Disable animation(if exist):
SetPaneAnimation(nIndex, NULL, 0, FALSE);
if (hIcon == NULL)
{
if (pSBP->hImage != NULL)
{
::ImageList_Destroy(pSBP->hImage);
}
pSBP->hImage = NULL;
if (bUpdate)
{
InvalidatePaneContent(nIndex);
}
return;
}
ICONINFO iconInfo;
::GetIconInfo(hIcon, &iconInfo);
BITMAP bitmap;
::GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bitmap);
::DeleteObject(iconInfo.hbmColor);
::DeleteObject(iconInfo.hbmMask);
if (pSBP->hImage == NULL)
{
pSBP->cxIcon = bitmap.bmWidth;
pSBP->cyIcon = bitmap.bmHeight;
pSBP->hImage = ::ImageList_Create(pSBP->cxIcon, pSBP->cyIcon, ILC_COLOR32 | ILC_MASK, 1, 0);
::ImageList_AddIcon(pSBP->hImage, hIcon);
RecalcLayout();
}
else
{
ASSERT(pSBP->cxIcon == bitmap.bmWidth);
ASSERT(pSBP->cyIcon == bitmap.bmHeight);
::ImageList_ReplaceIcon(pSBP->hImage, 0, hIcon);
}
if (bUpdate)
{
InvalidatePaneContent(nIndex);
}
}
相关文章:
- 如何为 C++ Visual Studio 2019 指定应用程序图标?
- 从 wxWidgets 中的.DLL加载图标
- 如何修复加载图标()函数不显示图标?
- QT Framewrok 和 Visual Studio - 图标冲突
- 如何在 c++ 中将图标放在按钮上?
- Windows 资源管理器中的图标在使用 resource.rc 时显示 2 个不同的图标
- 为什么从文件获取图标时应用程序有时会崩溃?
- 如何在MFC中的静态文本控件上插入图标?
- wxWidgets 3.1.3 图标在 mac 下加载 - ICNS 文件不可读?
- 如何检查流中文件的下一个单词是否为 alpha?
- 关于 Direct3D9 中的 alpha 混合的问题
- OpenCV java alpha Blending
- 如何使用IExecuteCommand和动词在上下文菜单外壳扩展中显示本地化文本和自定义图标?
- 在 C# 中更改鼠标光标图标
- Gtk::带有set_icon_name的窗口图标集在 wayland 上不起作用
- 为什么图标主题资源路径没有列在get_search_path
- 如何在 VC6 中的对话框中将图标设置为按钮
- GTK 3 C++按钮中带有标签的图标
- CMFCStatusBar::SetPaneIcon是否支持alpha图标?
- 在WinXP安装中,带有alpha混合图标的工具栏不能正确显示