[GDI]如何将N个位图对象画到一个内存DC上? 本帖最后由 weiwuyuan 于 2011-11-10 23:53:00 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 // hMemoryDC 没有创建画布HBITMAP hMemoryBMP = ::CreateCompatibleBitmap(hMemoryDC, 200, 200);SelectObject(hMemoryDC, hMemoryBMP);// 具体要创建怎么样的画布,你可以自己定。 一个个SelectObjec(),到memory DC,然后BitBlt/StretchBlt()到目的DC的指定位置。和你贴一个图是一样的 加了这两句这后,图像还是画不出来,只能看到黑色画布 HDC hMainDC = ::GetDC(hWnd); HDC hMemoryDC = ::CreateCompatibleDC(hMainDC); HDC hMemoryDC2 = ::CreateCompatibleDC(hMainDC); HBITMAP hMemoryBMP = ::CreateCompatibleBitmap(hMemoryDC, WND_WIDTH, WND_HEIGHT); HBITMAP hBitmap = (HBITMAP)LoadImageA(NULL, "test.bmp", IMAGE_BITMAP, 64, 64, LR_LOADFROMFILE); HBITMAP hBitmap2 = (HBITMAP)LoadImageA(NULL, "test.bmp", IMAGE_BITMAP, 64, 64, LR_LOADFROMFILE); while (TRUE) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } { SelectObject(hMemoryDC, hMemoryBMP); ::SelectObject(hMemoryDC2, hBitmap); ::BitBlt(hMemoryDC, 100, 100, 64, 64, hMemoryDC2, 0, 0, SRCCOPY); ::SelectObject(hMemoryDC2, hBitmap2); ::BitBlt(hMemoryDC, 200, 100, 64, 64, hMemoryDC2, 0, 0, SRCCOPY); ::BitBlt(hMainDC, 0, 0, WND_WIDTH, WND_HEIGHT, hMemoryDC, 0, 0, SRCCOPY); } Sleep(1); } ::DeleteObject(hBitmap2); ::DeleteObject(hBitmap); ::DeleteDC(hMemoryDC2); ::DeleteDC(hMemoryDC); ::ReleaseDC(hWnd, hMainDC); HDC hMainDC = ::GetDC(this->m_hWnd); // Step 1:为屏幕DC创建兼容的内存. HDC hMemoryDC = ::CreateCompatibleDC(hMainDC); HDC hMemoryDC2 = ::CreateCompatibleDC(hMainDC); // Step 2:创建位图. //HBITMAP hMemoryBMP = ::CreateCompatibleBitmap(hMemoryDC, 128, 128); HBITMAP hBitmap = (HBITMAP)LoadImageA(NULL, "0000.bmp", IMAGE_BITMAP, 64, 64, LR_LOADFROMFILE); HBITMAP hBitmap2 = (HBITMAP)LoadImageA(NULL, "0001.bmp", IMAGE_BITMAP, 64, 64, LR_LOADFROMFILE); // Step 3:把位图选入设备环境:SelectObject(),可以理解为选择画布dcMem.SelectObject(&bm) SelectObject(hMemoryDC, hBitmap); SelectObject(hMemoryDC2, hBitmap2); while (TRUE) { MSG msg; if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } // Step 4:把绘制好的图形“拷贝“到屏幕上 { //::BitBlt(hMemoryDC, 100, 100, 64, 64, hMemoryDC2, 0, 0, SRCCOPY); //::BitBlt(hMemoryDC, 200, 100, 64, 64, hMemoryDC2, 0, 0, SRCCOPY); static BOOL bShowFlag = TRUE; if (bShowFlag) ::BitBlt(hMainDC, 0, 0, 128, 128, hMemoryDC, 0, 0, SRCCOPY); else ::BitBlt(hMainDC, 0, 0, 128, 128, hMemoryDC2, 0, 0, SRCCOPY); bShowFlag = !bShowFlag; } Sleep(500); } ::DeleteObject(hBitmap2); ::DeleteObject(hBitmap); ::DeleteDC(hMemoryDC2); ::DeleteDC(hMemoryDC); ::ReleaseDC(this->m_hWnd, hMainDC); 感激不尽。。可以显示了。另外问一下,一定得为每个位图对象都提供一份内存DC么??不可以共用一个内存DC么?(我之所以这么问是因为,如果游戏里有100个位图对象,就要提供100份内存DC,我怕这会影响性能……) 就是说,贴一个图和贴多个图是一样的,你要改变的只是否BitBlt中贴到目标DC的坐标就行了。 还有个问题,就是,为什么还是直接往窗口DC上画?而不是往内存DC里画呢?这样的话,内存DC还有意义么? 楼主的代码hMemoryDC 缺少个画布,思路是正确的另外贴多个图到一个DC上,一定现在内存DC画完,最后再一次性画到目标DC。 HDC hMainDC = ::GetDC(hWnd); HDC hMemoryDC = ::CreateCompatibleDC(hMainDC); HDC hMemoryDC2 = ::CreateCompatibleDC(hMainDC);//以源dc建立画布 HBITMAP hMemoryBMP = ::CreateCompatibleBitmap(hMemoryDC2, 200, 200);//大小自己指定 SelectObject(hMemoryDC, hMemoryBMP); HBITMAP hBitmap = (HBITMAP)LoadImageA(NULL, "test.bmp", IMAGE_BITMAP, 64, 64, LR_LOADFROMFILE); HBITMAP hBitmap2 = (HBITMAP)LoadImageA(NULL, "test.bmp", IMAGE_BITMAP, 64, 64, LR_LOADFROMFILE); while (TRUE) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } { ::SelectObject(hMemoryDC2, hBitmap); ::BitBlt(hMemoryDC, 100, 100, 64, 64, hMemoryDC2, 0, 0, SRCCOPY); ::SelectObject(hMemoryDC2, hBitmap2); ::BitBlt(hMemoryDC, 200, 100, 64, 64, hMemoryDC2, 0, 0, SRCCOPY); ::BitBlt(hMainDC, 0, 0, WND_WIDTH, WND_HEIGHT, hMemoryDC, 0, 0, SRCCOPY); } Sleep(1); } ::DeleteObject(hBitmap2); ::DeleteObject(hBitmap); ::DeleteDC(hMemoryDC2); ::DeleteDC(hMemoryDC); ::ReleaseDC(hWnd, hMainDC); void CXXXDlg::OnPaint() { CPaintDC dc(this); CDC memDC; memDC.CreateCompatibleDC(&dc); ASSERT(memDC.GetSafeHdc()); CBitmap bitmap; BITMAP bmp; int y = 0; for(int i=IDB_BITMAP1; i<=IDB_BITMAP3; i++) { bitmap.LoadBitmap(i); ASSERT(bitmap.GetSafeHandle()); bitmap.GetBitmap(&bmp); CBitmap* pBitmap = memDC.SelectObject(&bitmap); dc.BitBlt(0, y, bmp.bmWidth, bmp.bmHeight, &memDC, 0, 0, SRCCOPY); memDC.SelectObject(pBitmap); bitmap.DeleteObject(); y += bmp.bmHeight; } memDC.DeleteDC();} lync 2010二次开发 更换logo 实在看不惯一些伪专家了,发个牢骚帖,顺便散点分。 MCI错误 无法在指定的MCI设备上播放指定的文件,文件可能已损坏或格式不对,或没有次格式的文件处理程序可用。 20分求,有人做过VC下三汇卡的下的IVR开发吗. 调用自己封装的OCX控件时出现的错误 怎样用自己的登陆对话框取代win2000的登陆画面? 用Cdatabase类删除数据库记录,为什么会出现异常! NLC格式的电子书用什么阅览器看 如何调用自定义函数? 怎样建立自己程序的发布版本 重新排序后怎么在ListControl中显示出来 求解
HBITMAP hMemoryBMP = ::CreateCompatibleBitmap(hMemoryDC, 200, 200);
SelectObject(hMemoryDC, hMemoryBMP);// 具体要创建怎么样的画布,你可以自己定。
加了这两句这后,图像还是画不出来,只能看到黑色画布
HDC hMainDC = ::GetDC(hWnd);
HDC hMemoryDC = ::CreateCompatibleDC(hMainDC);
HDC hMemoryDC2 = ::CreateCompatibleDC(hMainDC); HBITMAP hMemoryBMP = ::CreateCompatibleBitmap(hMemoryDC, WND_WIDTH, WND_HEIGHT);
HBITMAP hBitmap = (HBITMAP)LoadImageA(NULL, "test.bmp", IMAGE_BITMAP, 64, 64, LR_LOADFROMFILE);
HBITMAP hBitmap2 = (HBITMAP)LoadImageA(NULL, "test.bmp", IMAGE_BITMAP, 64, 64, LR_LOADFROMFILE); while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break; TranslateMessage(&msg);
DispatchMessage(&msg);
} {
SelectObject(hMemoryDC, hMemoryBMP); ::SelectObject(hMemoryDC2, hBitmap);
::BitBlt(hMemoryDC, 100, 100, 64, 64, hMemoryDC2, 0, 0, SRCCOPY); ::SelectObject(hMemoryDC2, hBitmap2);
::BitBlt(hMemoryDC, 200, 100, 64, 64, hMemoryDC2, 0, 0, SRCCOPY); ::BitBlt(hMainDC, 0, 0, WND_WIDTH, WND_HEIGHT, hMemoryDC, 0, 0, SRCCOPY);
} Sleep(1);
} ::DeleteObject(hBitmap2);
::DeleteObject(hBitmap);
::DeleteDC(hMemoryDC2);
::DeleteDC(hMemoryDC);
::ReleaseDC(hWnd, hMainDC);
HDC hMainDC = ::GetDC(this->m_hWnd); // Step 1:为屏幕DC创建兼容的内存.
HDC hMemoryDC = ::CreateCompatibleDC(hMainDC);
HDC hMemoryDC2 = ::CreateCompatibleDC(hMainDC); // Step 2:创建位图.
//HBITMAP hMemoryBMP = ::CreateCompatibleBitmap(hMemoryDC, 128, 128);
HBITMAP hBitmap = (HBITMAP)LoadImageA(NULL, "0000.bmp", IMAGE_BITMAP, 64, 64, LR_LOADFROMFILE);
HBITMAP hBitmap2 = (HBITMAP)LoadImageA(NULL, "0001.bmp", IMAGE_BITMAP, 64, 64, LR_LOADFROMFILE); // Step 3:把位图选入设备环境:SelectObject(),可以理解为选择画布dcMem.SelectObject(&bm)
SelectObject(hMemoryDC, hBitmap);
SelectObject(hMemoryDC2, hBitmap2); while (TRUE)
{
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break; TranslateMessage(&msg);
DispatchMessage(&msg);
} // Step 4:把绘制好的图形“拷贝“到屏幕上
{
//::BitBlt(hMemoryDC, 100, 100, 64, 64, hMemoryDC2, 0, 0, SRCCOPY);
//::BitBlt(hMemoryDC, 200, 100, 64, 64, hMemoryDC2, 0, 0, SRCCOPY);
static BOOL bShowFlag = TRUE;
if (bShowFlag)
::BitBlt(hMainDC, 0, 0, 128, 128, hMemoryDC, 0, 0, SRCCOPY);
else
::BitBlt(hMainDC, 0, 0, 128, 128, hMemoryDC2, 0, 0, SRCCOPY);
bShowFlag = !bShowFlag;
} Sleep(500);
} ::DeleteObject(hBitmap2);
::DeleteObject(hBitmap);
::DeleteDC(hMemoryDC2);
::DeleteDC(hMemoryDC);
::ReleaseDC(this->m_hWnd, hMainDC);
感激不尽。。
可以显示了。另外问一下,一定得为每个位图对象都提供一份内存DC么??不可以共用一个内存DC么?(我之所以这么问是因为,如果游戏里有100个位图对象,就要提供100份内存DC,我怕这会影响性能……)
还有个问题,就是,为什么还是直接往窗口DC上画?而不是往内存DC里画呢?这样的话,内存DC还有意义么?
另外贴多个图到一个DC上,一定现在内存DC画完,最后再一次性画到目标DC。 HDC hMainDC = ::GetDC(hWnd);
HDC hMemoryDC = ::CreateCompatibleDC(hMainDC);
HDC hMemoryDC2 = ::CreateCompatibleDC(hMainDC);//以源dc建立画布
HBITMAP hMemoryBMP = ::CreateCompatibleBitmap(hMemoryDC2, 200, 200);//大小自己指定
SelectObject(hMemoryDC, hMemoryBMP);
HBITMAP hBitmap = (HBITMAP)LoadImageA(NULL, "test.bmp", IMAGE_BITMAP, 64, 64, LR_LOADFROMFILE);
HBITMAP hBitmap2 = (HBITMAP)LoadImageA(NULL, "test.bmp", IMAGE_BITMAP, 64, 64, LR_LOADFROMFILE); while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break; TranslateMessage(&msg);
DispatchMessage(&msg);
} {
::SelectObject(hMemoryDC2, hBitmap);
::BitBlt(hMemoryDC, 100, 100, 64, 64, hMemoryDC2, 0, 0, SRCCOPY); ::SelectObject(hMemoryDC2, hBitmap2);
::BitBlt(hMemoryDC, 200, 100, 64, 64, hMemoryDC2, 0, 0, SRCCOPY); ::BitBlt(hMainDC, 0, 0, WND_WIDTH, WND_HEIGHT, hMemoryDC, 0, 0, SRCCOPY);
} Sleep(1);
} ::DeleteObject(hBitmap2);
::DeleteObject(hBitmap);
::DeleteDC(hMemoryDC2);
::DeleteDC(hMemoryDC);
::ReleaseDC(hWnd, hMainDC);
{
CPaintDC dc(this); CDC memDC;
memDC.CreateCompatibleDC(&dc);
ASSERT(memDC.GetSafeHdc()); CBitmap bitmap;
BITMAP bmp;
int y = 0;
for(int i=IDB_BITMAP1; i<=IDB_BITMAP3; i++)
{
bitmap.LoadBitmap(i);
ASSERT(bitmap.GetSafeHandle());
bitmap.GetBitmap(&bmp); CBitmap* pBitmap = memDC.SelectObject(&bitmap);
dc.BitBlt(0, y, bmp.bmWidth, bmp.bmHeight, &memDC, 0, 0, SRCCOPY);
memDC.SelectObject(pBitmap);
bitmap.DeleteObject(); y += bmp.bmHeight; }
memDC.DeleteDC();
}