【问题标题】:winapi: from HDC to an HBITMAPwinapi:从 HDC 到 HBITMAP
【发布时间】:2015-09-08 22:38:18
【问题描述】:

我想做一些我认为相当简单的事情,但是由于我是 winapi 的新手,所以我发现了很多问题。基本上我有一个 HDC(我是从加载的位图中 BitBlitting),我正在它上面绘制一个矩形。然后我想将那个 HDC BitBlt 到一个新的 HBITMAP 对象上,但可惜现在无济于事。

这是我已经尝试工作了几个小时的代码

BITMAPINFO info;
Bitmap *tempbmp = Bitmap::FromFile(L"C:\\Users\\abelajc\\Pictures\\BackgroundImage.png", false);
HBITMAP loadedbackground;
tempbmp->GetHBITMAP(NULL, &loadedbackground);

HBRUSH hRed = CreateSolidBrush(RGB(255, 0, 0));

HDC pDC = GetDC(0);
HDC TmpDC = CreateCompatibleDC(pDC); //main DC on which we will paint on

HDC dcBmp = CreateCompatibleDC(TmpDC); //DC for the loadedbackground HBitmap
HGDIOBJ TmpObj2 = SelectObject(dcBmp , tempbmp); //Selecting Bitmap in DC
BitBlt(TmpDC, 0, 0, 512, 512, dcBmp, 0, 0, SRCCOPY);
SelectObject(dcBmp, TmpObj2); //Deselecting Bitmap from DC
DeleteDC(dcBmp);

RECT rectangle;
SetRect(&rectangle, 5, 5, 20, 20);
FillRect(TmpDC, &rectangle, hRed);

HDC hCompDC = CreateCompatibleDC(TmpDC);
HBITMAP hBmp = CreateCompatibleBitmap(TmpDC, 512, 512);
HBITMAP hOld = (HBITMAP)SelectObject(hCompDC, hBmp);
BitBlt(hCompDC, 0, 0, 512, 512, TmpDC, 0, 0, SRCCOPY);
SelectObject(hCompDC, hOld);
DeleteDC(hCompDC);

Bitmap *image = new Bitmap(hBmp, NULL);

【问题讨论】:

  • 您似乎根本没有执行任何错误检查。也许您的一个 API 调用失败了。那是winapi 101。
  • 不要 CreateCompatibleDC() 使用内存 DC。我记得我在这样做时遇到了一些麻烦。

标签: c++ winapi bitmap gdi


【解决方案1】:

我认为您需要对 GDI 进行一些说明。
DC 正是它的名字所暗示的:设备上下文。这只是一个上下文,没有具体内容。一些 DC 是真实图形设备的上下文,另一些(内存 DC)是内存中虚拟图形表面的上下文。您使用CreateCompatibleDC 创建的 DC 是内存 DC,但创建 DC 仅创建上下文,而不是内存表面。正如 MSDN 文档所说:

在应用程序可以使用内存 DC 进行绘图操作之前,它必须在 DC 中选择正确宽度和高度的位图。

您需要将 HBITMAP 与 DC 关联。这样做之后,您可以认为绘制到 DC 本质上是绘制到位图。内存 DC 是位图的“窗口”。

一旦你明白这一点,你会发现你的程序可以大大缩短。如果您仍有问题,请随时发表评论。

【讨论】:

  • 非常感谢这个解释,我觉得有了它,我已经理解了使用 winapi 进行绘图的关键部分之一,而我一直在努力解决这个问题。我还设法使用从这个解释中学到的东西来修复我的代码:)
  • @JeanClaudeAbela 不客气 :) GDI 的这一部分确实有点晦涩难懂。过去我也很难弄清楚它是如何工作的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 2016-09-26
  • 2011-11-27
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
  • 2013-06-11
相关资源
最近更新 更多