【问题标题】:How to create a DIB, set the bits and attach to a CImageList如何创建 DIB、设置位并附加到 CImageList
【发布时间】:2020-09-29 22:44:03
【问题描述】:

我正在尝试创建一个与设备无关的位图,以编程方式设置像素(而不是从资源或磁盘加载)并将 DIB 附加到 CImageList 以在 CComboBoxEx 控件中使用。我相信 DIB 已成功创建并且位设置正确,但组合框中显示的图像都是黑色的。

我创建 CImageList,绘制位图并将列表附加到此处的控件:

m_Images.Create(m_nImageWidth, m_nImageHeight, ILC_COLOR32, 0, 1);

// Draw bitmaps
size_t szIndex;
for (szIndex = 0; szIndex < m_aColourMaps.size(); ++szIndex) {
    DrawImage(szIndex);
}

// Attach image list to combo box
m_ctrlColourMapCombo.SetImageList(m_Images.GetSafeHandle());

绘制位图(DrawImage)的函数在这里(这里简化为只是将所有像素设置为红色):

CDC* pDC;
pDC = GetDC();

HDC hDC;
hDC = *pDC;

HDC hDCMem;
hDCMem = CreateCompatibleDC(hDC);

BYTE* lpBitmapBits;
lpBitmapBits = nullptr;

BITMAPINFO bi;
ZeroMemory(&bi, sizeof(BITMAPINFO));

bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = m_nImageWidth;
bi.bmiHeader.biHeight = -m_nImageHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;

HBITMAP hBitmap = ::CreateDIBSection(hDCMem, &bi, DIB_RGB_COLORS, (LPVOID*)&lpBitmapBits, nullptr, 0);
HGDIOBJ oldbmp = ::SelectObject(hDCMem, hBitmap);

size_t szImageIndex, szIndexX, szIndexY;
float nIndex;
UINT32* pColourData;
pColourData = reinterpret_cast<UINT32*>(lpBitmapBits);
UINT32 nColour;

for (szIndexX = 0; szIndexX < m_nImageWidth; ++szIndexX) {
    szImageIndex = szIndexX;

    for (szIndexY = 0; szIndexY < m_nImageHeight; ++szIndexY) {
        pColourData[szImageIndex] = 0xff0000ff;

        szImageIndex += m_nImageWidth;
    }
}

CBitmap bitmap;
bitmap.Attach(hBitmap);
m_Images.Add(&bitmap, nullptr);
bitmap.Detach();

SelectObject(hDCMem, oldbmp);
DeleteDC(hDCMem);
DeleteObject(hBitmap);

我猜问题出在将 DIB 附加到 CBitmap 然后将其插入 CImageList 的代码中的某个地方,但我一直无法找到任何示例代码来执行此操作,尽管从表面上看代码看起来很合理大部头书。不幸的是,CBitmap 和 CImageList 都在 afxwin.h 中定义,因此很难/不可能调试该部分代码中实际发生的情况,但 CBitmap.Attach 和 CImage.Add 不会返回错误。

【问题讨论】:

  • 您能尝试延长您的CBitmap bitmap; 的使用寿命吗? CImageList 有一个指向它的指针,我不确定它是否会复制。
  • ImageList_Add 复制一份,这并不奇怪。转移所有权的 API 调用不超过几个。当他们这样做时,会明确说明。不转移所有权是默认设置。

标签: c++ mfc dib


【解决方案1】:

我发现了问题 - 位图已被选入 DC 中:

HGDIOBJ oldbmp = ::SelectObject(hDCMem, hBitmap);

这阻止了 CImageList 添加位图。删除这个(以及最后相应的 SelectObject 调用)后,代码可以正常工作。

【讨论】:

    猜你喜欢
    • 2013-10-16
    • 2019-02-20
    • 2019-08-22
    • 2017-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多