有人能解释一下如何在内存中的位图上绘制文本吗?我有下面的代码,但是我不知道怎么做。
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
HDC buffDC = CreateCompatibleDC(hdc);
SelectObject(buffDC, hFnt);
SetTextColor(buffDC, RGB(1, 1, 1));
SetBkColor(buffDC, RGB(0, 255, 0));
RECT rc;
GetClientRect(hWnd, &rc);
HBITMAP buffBitmap = CreateCompatibleBitmap(buffDC, rc.right, rc.bottom);
int savedDC = SaveDC(buffDC);
HBRUSH hBrush = CreateSolidBrush(RGB(0, 255, 0));
FillRect(buffDC, &rc, hBrush);
DeleteObject(hBrush);
//This is the part where I would like to draw to the bitmap
TextOutA(buffDC, 0, 0, "Hello", 6);
SelectObject(buffDC, buffBitmap);
BitBlt(hdc, 0, 0, rc.right, rc.bottom, buffDC, 0, 0, SRCCOPY);
RestoreDC(buffDC, savedDC);
DeleteObject(buffBitmap);
DeleteDC(buffDC);
EndPaint(hWnd, &ps);
break;
}
我已经看到了很多不同的解决方案,大多数使用MFC,但我想避免这种方法,如果可能的话。
编辑:我已经检查了其他已经提出的问题,但我找不到一个将涵盖这没有MFC。
我最初的问题是,我使用一个计时器调用RedrawWindow,更新文本的位置,并制作一种从右向左移动的滚动文本。
当我在测试过程中,我注意到,在一些机器上的应用程序运行高达25%的CPU使用率,而在其他一些它使用〈1%.我已经测试了应用程序的两台机器完全相同的规格运行Windows 7和应用程序运行在一个~10%和另一个0%.
(By我的计时器每33 ms调用一次,RedrawWindow使用RDW_UPDATENOW,我也没有处理WM_ERASEBKGND消息:P由于WM_TIMER(据我所知)是低优先级消息,我不担心计时器会导致CPU使用率问题。)
我开始想,也许我应该使用位图和BitBlt它到屏幕上,而不仅仅是简单地绘制到dc和更新x坐标,每次我重新绘制屏幕。
谢谢
2条答案
按热度按时间tv6aics11#
在位图上绘图之前,必须将其选择到内存设备上下文中。
在第一次调用绘图函数之前移动
SelectObject(buffDC, buffBitmap);
,但通常在创建位图之后尽快移动。在示例代码中,将其插入到
SaveDC()
调用之后似乎比较合适,这样当您调用RestoreDC()
时,原始位图将被恢复:正如评论者所指出的,
CreateCompatibleBitmap(buffDC, rc.right, rc.bottom)
应该改为CreateCompatibleBitmap(hdc, rc.right, rc.bottom)
。从CreateCompatibleBitmap()
的引用:当创建内存设备上下文时,它最初有一个1乘1的单色位图被选中。如果这个内存设备上下文在CreateCompatibleBitmap中使用,则创建的位图是单色位图。要创建彩色位图,请使用用于创建内存设备上下文的HDC
最后一个建议:如果你只需要一个 * 临时 * 位图(就像你的示例代码中那样),有一个自Windows Vista以来更有效的API可用。它被称为bufferedpaint API。MSDN似乎没有提供一个很好的概述,这里有一个tutorial和reference(所有函数的名称中都有“BufferedPaint”)。
klsxnrf12#
这是为我工作的窗口过程,它基于zett42的答案。这段代码只是为了测试purposes,因为我不能发布我正在工作的应用程序的原始源代码。