Windows XP 上的真彩色 CImageList

Posted

技术标签:

【中文标题】Windows XP 上的真彩色 CImageList【英文标题】:True color CImageList on Windows XP 【发布时间】:2011-11-09 09:51:48 【问题描述】:

我在 CDialog 中有以下代码。此代码在 Windows 7 上完美运行,但在 Windows XP SP3 上其颜色始终为黑色。

UINT color_flags = CWindowDC(this).GetDeviceCaps(BITSPIXEL);

switch ( color_flags )

case 4 : color_flags = ILC_COLOR4; break;
case 8 : color_flags = ILC_COLOR8; break;
case 16 : color_flags = ILC_COLOR16; break;
case 24 : color_flags = ILC_COLOR24; break;
case 32 : color_flags = ILC_COLOR24; break;
default : color_flags = ILC_COLOR24;
;

CImageList imgage_list;
imgage_list.Create( 16, 16, color_flags, 0, 10 );
imgage_list.SetImageCount( number_of_bitmaps );

CDC * pDC = this->GetDC();
CDC memDC;
CRect memRect(0, 0, 16, 16);
CObject * pObj = 0;
COLORREF my_color = RGB(255,0,0);
CBitmap * bitmap = 0;
memDC.CreateCompatibleDC(pDC); 

for ( int i = 0; i < number_of_bitmaps; ++i )

  bitmap = new CBitmap;
  bitmap->CreateCompatibleBitmap( pDC, 16, 16 );
  pObj = memDC.SelectObject( bitmap );
  memDC.FillSolidRect( memRect, my_color );
  imgage_list.Replace( i, bitmap, 0 );
  memDC.SelectObject(pObj);
  delete bitmap;


memDC.DeleteDC();
this->ReleaseDC(pDC);

我启用了 MSDN 建议的视觉样式。我用这个CImageList对象作为CListCtrl::SetImageList成员函数的参数。

你有什么想法吗?

非常感谢您的帮助。

【问题讨论】:

只看代码看起来没问题,您可以验证 CImageList 替换成员:如果返回不正确,则返回零。这可能是调试的开始...... @Sunscreen:如果我用CImage写出CBitmap,颜色是正确的。如果我从资源中填充 CImageList,则列表是正确的。所以我完全糊涂了。 :( 在Windows XP中,你加载的是通用控件6还是5.0?您是否正确包含清单? @sarat:我使用公共控件 6。我使用来自MSDN 的清单 XML。 在控件销毁之前尽量不要删除图片列表。 【参考方案1】:

您还没有初始化您的memDC,所以它没有正确响应。在您使用SelectObject 将位图选择到其中之前,请执行以下操作:

memDC.CreateCompatibleDC(pDC);

【讨论】:

非常感谢您的帮助。对不起,我已经从这里的代码中忘记了这一点,但我并没有忘记真正的代码。我更新了帖子。【参考方案2】:

最终的、更正的和工作的代码:

CImageList imgage_list; // class member
imgage_list.Create( 16, 16, ILC_COLOR24, number_of_bitmaps, 0 );

CDC * pDC = this->GetDC();
CDC memDC;
COLORREF my_color = RGB(255,0,0);
memDC.CreateCompatibleDC(pDC);
CBitmap bitmap;

bitmap->CreateCompatibleBitmap( pDC, 16*number_of_bitmaps, 16 );
CObject * pObj = memDC.SelectObject( &bitmap );

int k = 0;
for ( int i = 0; i < number_of_bitmaps; ++i )

  // fill list control, so i is used
  // my_color is changing on every loop step

  memDC.FillSolidRect( k, 0, k+16, 16, my_color );
  k += 16;

memDC.SelectObject(pObj);
imgage_list.Add( &bitmap, RGB(0,0,0) );

memDC.DeleteDC();
this->ReleaseDC(pDC);

再次感谢您的帮助。

【讨论】:

如果您可以在此答案中发布更正的代码会很有用,这样我们就可以自己看到问题出在哪里。即使有这个解释,我也很难看到它。【参考方案3】:
    GdiObject * pObj 而不是 CObject

    我认为您需要在像这样调用 Replace() 之前从 mem DC 中选择位图:

    memDC.SelectObject(pObj);
    imgage_list.Replace( i, bitmap, 0 );
    

【讨论】:

【参考方案4】:

我了解到您的位图在 Windows XP 中无法正确显示。

虽然线程谈到位图在 Windows 7 中无法正确显示,这与您正在寻找的相反,但线索可能就在那里.. 不确定,只是想提供帮助。

Bitmaps dont show up properly in Windows 7.

【讨论】:

【参考方案5】:

我的位图在添加到图像列表时总是显示为黑色。

我终于自己弄明白了。这是我的代码的精简版。

// get device context
CDC* pDC = GetDC();

// create image list
imageList.Create( cx, cy, ILC_COLOR24, 1, 1 );

// Create offscreen device context
CDC memDC;
memDC.CreateCompatibleDC( pDC );

// Create new bitmap of size cx by cy
CBitmap newBmp;
newBmp.CreateCompatibleBitmap( pDC, cx, cy );

// Select new bitmap in memory for drawing
CBitmap* pOldBmp = memDC.SelectObject( &newBmp );

// do drawing here...
// e.g. memDC.FillSolidRect( 0, 0, cx, cy, RGB(255,0,0) );

/*
IMPORTANT:
Deselect new bitmap before adding to image list,
otherwise you'll potentially end up with a black icon
*/
memDC.SelectObject( pOldBmp );

// add bitmap to image list
imageList.Add( &bitmap, (CBitmap*)NULL );

// cleanup
memDC.DeleteDC();
ReleaseDC( pDC );

希望它对某人有所帮助。

【讨论】:

以上是关于Windows XP 上的真彩色 CImageList的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Perl 和 GD 创建透明的真彩色 PNG?

Windows Xp 上的 Microsoft.Windows.ActCtx

Windows XP 上的 IMAPI2 错误

Windows XP 与 Vista/7 上的 MS Crypto API 行为

Windows XP 上的 Java 最大内存

怎么安装windows XP?