0

我正在尝试将一些 HBITMAP 保存到一个数组中,并在以后显示它们。从 DC 创建 HBITMAP 是可行的,但是当我尝试显示保存的 HBITMAP 时,我似乎弄错了。这让我觉得我还没有真正理解 HTBIMAP 是如何存储在内存中的。我假设数据类型 HBITMAP 本质上是指向内存中对象的指针,这就是我所需要的,但也许还有更多?

这是一个示例代码:

HBITMAP aBitMaps[NUM_BITMAPS];
int iNumBitMaps;

void SaveScreen(CDC *dc)
{
  if (iNumBitMaps>0)
  {
    if (iNumBitMaps>=NUM_BITMAPS)
    {
      iNumBitMaps=NUM_BITMAPS-1;
      DeleteObject(aBitMaps[iNumBitMaps]);
    }
    for (int i=iNumBitMaps;i>0;i--)
    {
      aBitMaps[i] = aBitMaps[i-1];
    }
  }
  iNumBitMaps++;
  aBitMaps[0] = CreateCompatibleBitmap(dc->m_hDC, 800, 800);
  HDC hdcMem = CreateCompatibleDC(dc->m_hDC);
  SelectObject(hdcMem, aBitMaps[0]);
  BitBlt(hdcMem, 0, 0, 800, 800, dc->m_hDC, 0, 0, SRCCOPY);
  ReleaseDC(hdcMem);
}

void RestoreScreen(CDC *dc, int i)
{
  if (i>=NUM_BITMAPS) i = NUM_BITMAPS-1;
  if (i<0) i = 0;
  HDC hdcMem = CreateCompatibleDC(dc->m_hDC);
  SelectObject(hdcMem, aBitMaps[i]);
  BitBlt(dc->m_hDC, 0, 0, 800, 800, hdcMem, 0, 0, SRCCOPY);
  ReleaseDC(hdcMem);
}

因此,这个想法本质上是将 HBITMAP 指针推送到一个数组,然后通过将任何存储的图像选择到内存 DC 中然后将其复制到实际 DC 来显示任何存储的图像。这有什么问题?

我使用的是 VC++、Visual Studio 2010,没有 MFC。

编辑:

我又做了一些测试。为了调试,我尝试通过添加以下for循环来显示所有存储的位图(位置偏移)SaveScreen

...
BitBlt(hdcMem, 0, 0, 800, 800, dc->m_hDC, 0, 0, SRCCOPY);
for (int j=0; j<iNumBitMaps;j++)
{
  SelectObject(hdcMem, aBitMaps[j]);
  BitBlt(dc->m_hDC, 20*(j+1), 100*(j+1), 800+20*(j+1), 800+100*(j+1), hdcMem, 0, 0, SRCCOPY);
}
ReleaseDC(hdcMem);

然后它会显示iNumBitMaps图像的时间,但它始终是相同的图像(即我存储在 中的图像aBitMaps[0])。我确实在调试器中进行了验证,它aBitMaps包含所有不同的指针。所以,不知何故,我认为我没有正确地将位图加载到内存 DC 中。

4

1 回答 1

0

我想到了。在我上面的代码中有两个错误(我知道)。首先,内存DC使用后必须删除,所以ReleaseDC必须更换为DeleteDC

其次,必须知道被选入 DC 的对象不能被选入另一个 DC。因此重要的是,在对内存 DC 中的对象进行操作后,必须通过选择 DC 的前一个对象来卸载该对象。因此,正确的构造本质上是

HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, aBitMaps[0]);
BitBlt(...);
HBITMAP hbmNew = (HBITMAP)SelectObject(hdcMem, hbmOld);

where nowhbmNew指向与 相同的对象aBitMaps[0]

于 2014-10-31T14:53:05.363 回答