什么是正确的方式来使用GDI对象
Win32 - What is the proper way to use GDI objects?
我在Win32做一个简单的游戏。目前,我在主文件中声明了大部分的绘图对象,这样我就不必删除它们或重新加载位图。所以基本上我所有的位图都加载在WM_CREATE中,然后没有任何东西需要被删除——有人告诉我,我可以依靠系统在项目终止时清理我的资源。在WM_PAINT(每秒调用大约10次)中,我有很多BitBlt()调用,以及相当多的SelectObject()调用。运行大约10 - 15分钟后,选择对象()。什么会导致SelectObject()失败,我是否错误地使用了GDI对象?
的例子:
// Top of the file
HDC hdc;
HDC hdcmem;
HDC hbcmem;
HBITMAP colorsprites, blackwhitesprites, nums;
HBITMAP hdcold, hdcbmold, hdcbm;
// Some functions to get the window ready
// More variables used for drawing:
HBITMAP bg, side, mainCont, tmpbm, tmpold, bm_left, bm_right, sidebg, win_bm;
PAINTSTRUCT ps;
RECT rc;
HDC tmphdc;
HDC tmp;
HFONT font;
HBRUSH hbr;
HPEN pen;
BITMAP structBitmapHeader;
HGDIOBJ hBitmap;
HCURSOR crosshairs = LoadCursorW(hInst, IDC_CROSS);
HCURSOR normal = LoadCursorW(hInst, IDC_ARROW);
POINT cursor;
bool addPass = false, ignorePass;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
hdc = GetDC(hWnd);
hdcmem = CreateCompatibleDC(hdc);
GetClientRect(hWnd, &rc);
hdcbm = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
hbcmem = CreateCompatibleDC(hdcmem);
hdcbmold = (HBITMAP)SelectObject(hdcmem, hdcbm);
// Load bitmaps
bg = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BACKGROUND));
mainCont = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_GAME_CONT));
side = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SIDEINFO));
colorsprites = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_COLOR_SPRITES));
blackwhitesprites = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BLACKWHITE_SPRITES));
sidebg = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SIDEBG));
nums = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_NUMBERS));
bm_left = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_LEFT));
bm_right = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_RIGHT));
win_bm = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_VICTORY));
if(bg == NULL || mainCont == NULL || side == NULL || colorsprites == NULL
|| blackwhitesprites == NULL || sidebg == NULL || nums == NULL || bm_left == NULL
|| bm_right == NULL)
ThrowError("A bitmap failed to load.");
break;
case WM_PAINT:
BeginPaint(hWnd, &ps);
// SelectObject() and BitBlt() are called a lot in here
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
// System will clean up all GDI stuff - no need to delete anything
PostQuitMessage(0);
break;
}
}
确保当您销毁DC时,您已将原始位图选择回其中。当位图仍然处于选中状态时,永远不要销毁DC。
通过在BeginPaint之后调用SaveDC,在EndPaint之前调用RestoreDC,可以使生活变得容易得多。这将把DC恢复到它被释放之前的原始状态。
http://msdn.microsoft.com/en-us/library/windows/desktop/dd162945 (v = vs.85) . aspx
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 如何从依赖于设备的 HBITMAP 构造 GDI+ 位图对象
- 如何从 GDI+ 图元文件对象获取原始图元文件字节
- 使用GDI+删除位图和CLSID对象时,C++内存管理失败
- 在将图像对象保存到文件 (GDI+) 时获取 Win32Error
- 删除GDI对象不会减少其数量
- 如何使用窗口的C++图形(GDI+)库移动对象?
- 如何将SVG文件转换为等效的GDI+对象
- 什么是正确的方式来使用GDI对象
- 从gdiplus (GDI+)中的设备上下文或图形对象中获取图像/位图
- GDI+图形对象-当用GDI直接绘制到DC时,抗混叠丢失
- 非托管C++的GDI对象的调试器可视化工具
- std::make_unique用于GDI+对象