内存绘图转换为位图对象,显示在clistctrl中的实现缩略图的问题,解决可加分

w327115047 2014-05-08 03:44:52
请教下 我是想 用clistctrl实现缩略图 ,显示我在内存绘图 (dc)中绘制的图形,我的思路是 先用兼容dc 绘图 然后将兼容dc里面的图形保存到一个位图对象比如 CBitmap bitmap; 然后m_ImgList.Add(pbitmap, RGB(100,100,100)); 应该可以显示了吧。
关机的一个问题:如何将兼容dc中的图形保存到那个位图对象中CBitmap bitmap;;新手对于位图和dc内部的机制不是很清楚
部分代码
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
CDC m_dcCompatible;
if(!m_dcCompatible.m_hDC)
{
m_dcCompatible.CreateCompatibleDC(&dc);
}

//CRect rect;
//GetClientRect(&rect);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc,30,30);
m_dcCompatible.SelectObject(&bitmap);
m_dcCompatible.BitBlt(0,0,30,30,&dc,0,0,SRCCOPY);
m_dcCompatible.SelectObject(pBrush);
SelectObject(m_dcCompatible, bitmap);

//CBitmap *pOldBit=dc.SelectObject(&bitmap);


m_dcCompatible.Rectangle(0,0,30,30);
m_dcCompatible.LineTo(5,15);
m_ImgList.Create(50,50,ILC_COLOR24,11,0);

m_ListCtl.SetImageList(&m_ImgList,LVSIL_NORMAL);
m_ImgList.Add(&bitmap, RGB(100,100,100));
...全文
194 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
傻X 2014-05-09
  • 打赏
  • 举报
回复
给个函数,自己看看吧。

void CMapXViewView::SaveHwndToBmpFile(HWND hWnd, LPCTSTR lpszPath)
{
	HDC hDC = ::GetDC(hWnd);
	if(hDC == NULL)
	{
		CString cstrError;
		cstrError.Format("%d",GetLastError());
		AfxMessageBox(_T("GetWindowDC is Error!")+cstrError);
	}

	HDC hMemDC = ::CreateCompatibleDC(hDC);
	if(hMemDC == NULL)
	{
		CString cstrError;
		cstrError.Format("%d",GetLastError());
		AfxMessageBox(_T("CreateCompatibleDC is Error!")+cstrError);
	}

	RECT rc;
	::GetWindowRect(hWnd, &rc);

	HBITMAP hBitmap = ::CreateCompatibleBitmap(hDC, rc.right - rc.left -5, rc.bottom - rc.top-5);
	if(hBitmap == NULL)
	{
		CString cstrError;
		cstrError.Format("%d",GetLastError());
		AfxMessageBox(_T("CreateCompatibleBitmap is Error!")+cstrError);
	}

	HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC, hBitmap);
	BOOL bPrintRes;
	bPrintRes = ::PrintWindow(hWnd, hMemDC, PW_CLIENTONLY);
	if(0 == bPrintRes)
	{
		CString cstrError;
		cstrError.Format("%d",GetLastError());
		AfxMessageBox(_T("PrintWindow is Error!")+cstrError);
	}
	//::StretchBlt()

	BITMAP bitmap = {0};
	::GetObject(hBitmap, sizeof(BITMAP), &bitmap);
	BITMAPINFOHEADER bi = {0};
	BITMAPFILEHEADER bf = {0};

	CONST int nBitCount = 24;	
	bi.biSize = sizeof(BITMAPINFOHEADER);
	bi.biWidth = bitmap.bmWidth;
	bi.biHeight = bitmap.bmHeight;
	bi.biPlanes = 1;
	bi.biBitCount = nBitCount;
	bi.biCompression = BI_RGB;
	DWORD dwSize = ((bitmap.bmWidth * nBitCount + 31) / 32) * 4 * bitmap.bmHeight;

	HANDLE hDib = GlobalAlloc(GHND, dwSize + sizeof(BITMAPINFOHEADER));
	LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
	*lpbi = bi;

	int iRes;
	iRes = ::GetDIBits(hMemDC, hBitmap, 0, bitmap.bmHeight, (BYTE*)lpbi + sizeof(BITMAPINFOHEADER), (BITMAPINFO*)lpbi, DIB_RGB_COLORS);
	if(iRes == NULL)
	{
		CString cstrError;
		cstrError.Format("%d",GetLastError());
		AfxMessageBox(_T("GetDIBits is Error!")+cstrError);
	}


	try
	{
		CFile file;
		file.Open(lpszPath, CFile::modeCreate | CFile::modeWrite);
		bf.bfType = 0x4d42;
		dwSize += sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
		bf.bfSize = dwSize;
		bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

		file.Write((BYTE*)&bf, sizeof(BITMAPFILEHEADER));
		file.Write((BYTE*)lpbi, dwSize);
		file.Close();
	}
	catch(CFileException* e)
	{
		e->ReportError();
		e->Delete();
	}

	GlobalUnlock(hDib);
	GlobalFree(hDib);

	::SelectObject(hMemDC, hOldBmp);
	BOOL bDO;
	bDO = ::DeleteObject(hBitmap);
	if(bDO == NULL)
	{
		CString cstrError;
		cstrError.Format("%d",GetLastError());
		AfxMessageBox(_T("DeleteObject(hBitmap) is Error!")+cstrError);
	}
	//::DeleteObject(hMemDC);
	bDO = ::DeleteDC(hMemDC);
	if(bDO == NULL)
	{
		CString cstrError;
		cstrError.Format("%d",GetLastError());
		AfxMessageBox(_T("DeleteDC(hMemDC) is Error!")+cstrError);
	}

	bDO =::ReleaseDC(hWnd, hDC);
	if(bDO == NULL)
	{
		CString cstrError;
		cstrError.Format("%d",GetLastError());
		AfxMessageBox(_T("::ReleaseDC(hWnd, hDC); is Error!")+cstrError);
	}
}
schlafenhamster 2014-05-09
  • 打赏
  • 举报
回复
CBrush *pBackBr=new CBrush; pBackBr->CreatePatternBrush(Bmp);// CBitmap Bmp; 装入 一个.bmp
schlafenhamster 2014-05-09
  • 打赏
  • 举报
回复
" 设置 dc背景" CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); 你创建一个PatternBrush 来代替它就可以;了.
w327115047 2014-05-09
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/390781643 讨论GDI 资源释放的问题 欢迎大家 来帮忙回答啊 谢谢
w327115047 2014-05-09
  • 打赏
  • 举报
回复
谢谢各位老大,现在可以结贴了 我将另开一个帖子讨论 GDI 资源释放的问题 内存管理很重要啊 不然软件运行不稳定 现在开了一个问题帖子 http://bbs.csdn.net/topics/390781643 讨论GDI 资源释放的问题 欢迎大家 来帮忙回答啊 谢谢
w327115047 2014-05-08
  • 打赏
  • 举报
回复
非常感谢 schlafenhamster 我的是在OnInitDialog()写的 确实 在OnPaint() 得到CPaintDC dc(this); 对话框的dc 直接用了 对话框的背景了 。但是还想问一下大家 上面的那个 如何 设置 dc背景,,和创建白色背景位图的问题 ? 解决后 马上就可以结贴了 兴奋啊
w327115047 2014-05-08
  • 打赏
  • 举报
回复
嗯 多谢了 明白了不少 看来我还得 多看看 这方面的基础知识,但是有个问题最后帮我看下 把那个背景去掉的话 应该创建一个白色背景的 位图 还是应该设置dc的背景SetBkColor这个好像不行
schlafenhamster 2014-05-08
  • 打赏
  • 举报
回复
我的是对话框,有背景图. Clouds.bmp CPaintDC dc(this); // device context for painting paint(dc);// 这个dc 就是对话框的
w327115047 2014-05-08
  • 打赏
  • 举报
回复
嗯 多谢 schlafenhamster 的帮助 你的 也是选择的电脑桌面的背景吧 或者是 当前 设备显示的图像的 我设置背景和画刷 怎么到这不管用了
schlafenhamster 2014-05-08
  • 打赏
  • 举报
回复

1k的不行大的到可以,csdn 怪吧?
w327115047 2014-05-08
  • 打赏
  • 举报
回复
是这样的 挺有意思 选择的背景是从 我 电脑桌面左上角开始的
w327115047 2014-05-08
  • 打赏
  • 举报
回复
谢谢 图是对的 这是 粘进 绘图 显示的 应该是背景颜色的 或者化刷的事儿吧
另外这是add进imagelist 显示的图 可以看出来也画出来了
[img=https://img-bbs.csdn.net/upload/201405/08/1399551428_784857.jpg][

这说明了被选进兼容dc里的 bitmap 也保存了兼容dc 绘图信息吧!?
schlafenhamster 2014-05-08
  • 打赏
  • 举报
回复
1k 的 结果.png 上传不了!!!!!
schlafenhamster 2014-05-08
  • 打赏
  • 举报
回复
else
{
CPaintDC dc(this); // device context for painting
paint(dc);
// CDialog::OnPaint();
}
schlafenhamster 2014-05-08
  • 打赏
  • 举报
回复
void paint(CDC &dc)
{
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(&dc);

CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc,30,30);
dcCompatible.SelectObject(&bitmap);
dcCompatible.BitBlt(0,0,30,30,&dc,0,0,SRCCOPY);
//
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
dcCompatible.SelectObject(pBrush);

dcCompatible.Rectangle(0,0,30,30);
dcCompatible.MoveTo(0,0);
dcCompatible.LineTo(30,30);

#if 1 //def TEST
OpenClipboard(0);
EmptyClipboard();
SetClipboardData(CF_BITMAP,bitmap.GetSafeHandle());
CloseClipboard();
#endif
//m_ImgList.Create(50,50,ILC_COLOR24,11,0);
//m_ListCtl.SetImageList(&m_ImgList,LVSIL_NORMAL);
//m_ImgList.Add(&bitmap, RGB(100,100,100));
}
w327115047 2014-05-08
  • 打赏
  • 举报
回复
运行后都是黑色的块
schlafenhamster 2014-05-08
  • 打赏
  • 举报
回复
先复制到 ClipBoard ,用 ”绘图“ paste 进来 看看 , 图 对不对。
w327115047 2014-05-08
  • 打赏
  • 举报
回复
或者其他的思路解决dc中自绘图形的 缩略图的显示 也可以

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧