winapi – Win32 – 什么可能导致不正确的绘图?
副标题[/!--empirenews.page--]
我正在创建一个游戏,其中在WM_PAINT消息期间完成了大量绘图.窗口失效有几个不同的地方,迫使它重绘.我把所有东西画到了一个屏幕外的DC,然后把它绘制到窗口 – 创建非闪烁的“帧”. 然而,每隔一段时间,一切都突然开始被错误地绘制.在我使用的五个位图中,前三个正在或多或少(但不完全)正确绘制.同样,所有颜色信息对于这三个都是正确的.在这三个之后绘制的另外两个是用错误的颜色绘制的 – 我认为白色仍然是白色的,但其他一切都被绘制为灰色.我不是说灰度,我的意思是除了白色之外的所有东西都是相同的颜色 – 灰色. 此外,当这种情况开始发生时,通常情况下所有内容都被绘制得太高 – 大约20到30个像素.此外,字体和消息框停止工作 – 所有文本都以默认字体绘制(但奇怪的是,正确的颜色),消息框只出现短暂,没有文字,然后消失 – 但必须像常规一样被解雇(你必须按回车键,否则如果你点击主窗口,它会按照正常情况执行,当有一个消息框打开时输入 – 闪烁并拨打错误音.所以一切都被皇家搞砸了. 我一直在研究这个项目已经有一段时间了,我最近才开始看到这个错误 – 尽管我根本没有修改下面的代码片段.很难测试可能会做什么,因为它似乎偶尔会发生. 这是WndProc中WM_CREATE和WM_PAINT中的代码: case WM_CREATE: { hdc = GetDC(hWnd); hdcmem = CreateCompatibleDC(hdc); RECT rc; 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)); if(bg == NULL || mainCont == NULL) ThrowError("A bitmap failed to load."); } break; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(hWnd,&ps); // Background hdcold = (HBITMAP)SelectObject(hbcmem,bg); BitBlt(hdcmem,237,196,hbcmem,SRCCOPY); BitBlt(hdcmem,237 * 2,SRCCOPY); // Main Game Container hdcold = (HBITMAP)SelectObject(hbcmem,mainCont); BitBlt(hdcmem,26,300,SRCCOPY); // Side Info HBITMAP side = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_SIDEINFO)); hdcold = (HBITMAP)SelectObject(hbcmem,side); BitBlt(hdcmem,339,154,SRCCOPY); DrawLevelNumber(game.map.levelnumber); if (color) sprites = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_COLOR_SPRITES)); else sprites = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BLACKWHITE_SPRITES)); hdcold = (HBITMAP)SelectObject(hbcmem,sprites); // Find x and y coordinate for the top left of the visible screen int x = game.player.x,y = game.player.y,ypos = 0; if (x < 4) x = 4; if (x > 27) x = 27; if (y < 4) y = 4; if (y > 27) y = 27; x -= 4; y -= 4; // Draw lower layer for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (game.map.Layer_Two[x + i][y + j] != 0) { int xpos = game.get_pos(game.map.Layer_Two[x + i][y + j].get(),ypos,false); BitBlt(hdcmem,(i * 32) + 32,(j * 32) + 32,32,xpos,SRCCOPY); } } } // Draw upper layer for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if ((game.map.Layer_Two[x + i][y + j] != 0 && game.map.Layer_One[x + i][y + j] >= 64 && game.map.Layer_One[x + i][y + j] <= 111)) { int xpos = game.get_pos(game.map.Layer_One[x + i][y + j].get(),true); BitBlt(hdcmem,xpos + 96,SRCPAINT); BitBlt(hdcmem,SRCAND); } else { int xpos = game.get_pos(game.map.Layer_One[x + i][y + j].get(),SRCCOPY); } } } // If it isn't started,show title if (!game.started) { HDC tmphdc = CreateCompatibleDC(hdcmem); HDC tmp = CreateCompatibleDC(tmphdc); RECT rc; GetClientRect(hWnd,&rc); string str = game.map.leveltitle.substr(0,game.map.leveltitle.length() - 1); TCHAR* tch = new TCHAR[str.length()]; mbstowcs_s(NULL,tch,_tcslen(tch),str.c_str(),str.length()); HFONT font = CreateFont(25,FW_BOLD,false,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FF_DONTCARE,NULL); SelectObject(tmp,font); DrawText(tmp,str.length(),&rc,DT_CALCRECT); rc.right += 16; HBITMAP tmpbm = CreateCompatibleBitmap(hdcmem,rc.bottom); HBITMAP tmpold = (HBITMAP)SelectObject(tmphdc,tmpbm); HBRUSH hbr = CreateSolidBrush(RGB(255,255,255)); HPEN pen = CreatePen(PS_SOLID,1,RGB(255,255)); SelectObject(hdcmem,pen); SelectObject(hdcmem,hbr); Rectangle(hdcmem,176 - (rc.right / 2),243,177 + (rc.right / 2),248); hbr = CreateSolidBrush(RGB(128,128,128)); pen = CreatePen(PS_SOLID,RGB(128,128)); SelectObject(hdcmem,294,299); HBITMAP left = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_LEFT)); hdcold = (HBITMAP)SelectObject(hbcmem,left); BitBlt(hdcmem,176 - (rc.right / 2) - 4,4,56,SRCCOPY); HBITMAP right = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_RIGHT)); hdcold = (HBITMAP)SelectObject(hbcmem,right); BitBlt(hdcmem,176 + (rc.right / 2) + ((rc.right % 2) != 0),SRCCOPY); SelectObject(tmphdc,font); SetTextColor(tmphdc,0)); SetBkColor(tmphdc,RGB(0,0)); DrawText(tmphdc,DT_CENTER); BITMAP structBitmapHeader; memset( &structBitmapHeader,sizeof(BITMAP) ); HGDIOBJ hBitmap = GetCurrentObject(tmphdc,OBJ_BITMAP); GetObject(hBitmap,sizeof(BITMAP),&structBitmapHeader); BitBlt(hdcmem,247,structBitmapHeader.bmWidth,structBitmapHeader.bmHeight,tmphdc,SRCCOPY); DeleteDC(tmphdc); DeleteDC(tmp); } // If paused if (game.paused) { RECT rc; rc.top = 32; rc.left = 32; rc.bottom = 330; rc.right = 330; BitBlt(hdcmem,288,NULL,BLACKNESS); HFONT font = CreateFont(50,FW_NORMAL,NULL); SelectObject(hdcmem,font); SetTextColor(hdcmem,0)); SetBkColor(hdcmem,0)); DrawText(hdcmem,L"PAUSED",6,(DT_CENTER + DT_SINGLELINE + DT_VCENTER)); } nums = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_NUMBERS)); hdcold = (HBITMAP)SelectObject(hbcmem,nums); for (int i = 100; i > 0; i /= 10) // coins and time left { int tmp; if (i == 100) tmp = game.coinsleft / 100; if (i == 10) tmp = ((game.coinsleft % 100) - (game.coinsleft % 10)) / 10; if (i == 1) tmp = game.coinsleft % 10; if (game.coinsleft < i && i > 1) tmp = 10; int ypos = game.get_num_pos(tmp,(game.coinsleft == 0)); BitBlt(hdcmem,417 + ((3 - (int)floor(log10((double)i)) * 17)),215,17,23,SRCCOPY); if (i == 100) tmp = game.timeleft / 100; if (i == 10) tmp = ((game.timeleft % 100) - (game.timeleft % 10)) / 10; if (i == 1) tmp = game.timeleft % 10; if (game.timeleft < i && i > 1) tmp = 10; if (game.map.timelimit == 0) tmp = 11; ypos = game.get_num_pos(tmp,(game.timeleft < 16 || game.map.timelimit == 0)); BitBlt(hdcmem,369 + ((3 - (int)floor(log10((double)i))) * 17),125,SRCCOPY); } if (game.onhint) { HBITMAP sidebg = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_SIDEBG)); hdcold = (HBITMAP)SelectObject(hbcmem,sidebg); BitBlt(hdcmem,353,165,127,146,SRCCOPY); HFONT font = CreateFont(18,true,255)); SetBkColor(hdcmem,0)); RECT rc; rc.top = 168; rc.left = 356; rc.bottom = 308; rc.right = 477; string str = "Hint: " + game.map.hint; TCHAR* tch = new TCHAR[str.length()]; mbstowcs_s(NULL,str.length()); DrawText(hdcmem,DT_CENTER + DT_WORDBREAK); } else { hdcold = (HBITMAP)SelectObject(hbcmem,sprites); // LOWER SIDE INFO if (game.player.key1 > 0) BitBlt(hdcmem,352,192,160,SRCCOPY); else BitBlt(hdcmem,SRCCOPY); if (game.player.key2 > 0) BitBlt(hdcmem,384,SRCCOPY); if (game.player.key3 > 0) BitBlt(hdcmem,416,224,SRCCOPY); if (game.player.key4) BitBlt(hdcmem,448,SRCCOPY); if (game.player.mod1) BitBlt(hdcmem,279,256,SRCCOPY); if (game.player.mod2) BitBlt(hdcmem,SRCCOPY); if (game.player.mod3) BitBlt(hdcmem,320,SRCCOPY); if (game.player.mod4) BitBlt(hdcmem,SRCCOPY); } BitBlt(hdc,518,401,hdcmem,SRCCOPY); EndPaint(hWnd,&ps); } break; case WM_DESTROY: SelectObject(hdc,hdcold); DeleteDC(hdcmem); DeleteDC(hbcmem); ReleaseDC(hWnd,hdc); DeleteObject(bg); PostQuitMessage(0); break; 我也非常感谢任何人可以提供的关于语法,效率和/或更好的代码处理方式的建议/批评.我是Win32的新手. 解决方法您正在泄漏GDI对象.(编辑:青岛站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |