MFC 一个dc复制到另一个dc怎么把网上复制过来的文件打印出来来为什么是黑的。

如何将屏幕dc拷贝到内存dc
[问题点数:100分,结帖人evi10r]
本版专家分:4633
结帖率 98.67%
CSDN今日推荐
本版专家分:358060
2013年 荣获名人称号
2011年 总版技术专家分年内排行榜第三2010年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第五
2012年1月 总版技术专家分月排行榜第一
本版专家分:358060
2013年 荣获名人称号
2011年 总版技术专家分年内排行榜第三2010年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第五
2012年1月 总版技术专家分月排行榜第一
本版专家分:4633
本版专家分:53949
2015年8月 硬件/嵌入开发大版内专家分月排行榜第一2015年7月 VC/MFC大版内专家分月排行榜第一2015年5月 VC/MFC大版内专家分月排行榜第一2015年4月 VC/MFC大版内专家分月排行榜第一2015年3月 VC/MFC大版内专家分月排行榜第一2015年1月 硬件/嵌入开发大版内专家分月排行榜第一2013年12月 VC/MFC大版内专家分月排行榜第一2013年11月 VC/MFC大版内专家分月排行榜第一2013年6月 VB大版内专家分月排行榜第一2013年5月 VB大版内专家分月排行榜第一2013年1月 VB大版内专家分月排行榜第一2012年12月 VB大版内专家分月排行榜第一
2015年9月 VC/MFC大版内专家分月排行榜第二2015年7月 硬件/嵌入开发大版内专家分月排行榜第二2014年5月 VC/MFC大版内专家分月排行榜第二2014年3月 VC/MFC大版内专家分月排行榜第二2013年10月 VB大版内专家分月排行榜第二2013年7月 VB大版内专家分月排行榜第二2012年5月 VB大版内专家分月排行榜第二2012年4月 VB大版内专家分月排行榜第二2012年2月 VB大版内专家分月排行榜第二2011年11月 VB大版内专家分月排行榜第二
2015年11月 VC/MFC大版内专家分月排行榜第三2015年6月 VC/MFC大版内专家分月排行榜第三2015年2月 VC/MFC大版内专家分月排行榜第三2014年1月 VC/MFC大版内专家分月排行榜第三2012年3月 VB大版内专家分月排行榜第三2011年12月 VB大版内专家分月排行榜第三2011年10月 VB大版内专家分月排行榜第三
本版专家分:2523
本版专家分:4633
本版专家分:4633
本版专家分:2523
本版专家分:4633
本版专家分:2523
本版专家分:4633
匿名用户不能发表回复!|
其他相关推荐一个DC拷贝到内存DC上。
1. 创建一个创建内存DC与HBitmap 对象
HDC hMemDC;
hBitmap, hOldB
// 位图句柄
HDC hdc = ::GetDC(m_hWnd); // 得到屏幕DC
hMemDC = ::CreateCompatibleDC(hdc); // 兼容内存区域
hBitmap = ::CreateCompatibleBitmap(hdc, rc.Width(), rc.Height()); // 建议兼容的HBitmap
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); //选择对象
2.将CGpsCtrl组件中的DC拷贝到这个hMemDC上
STDMETHODIMP CGpsCtrl::DrawToDC(long hDC)
// draw all cars
HBITMAP hOldImageBMP;
HBITMAP hImageBMP = CreateCompatibleBitmap((HDC)hDC,m_iMaxTileSize, m_iMaxTileSize); //创建兼容位图
HBITMAP hOldMaskBMP;
HBITMAP hMaskBMP = CreateBitmap(m_iMaxTileSize, m_iMaxTileSize,1,1,NULL); //创建单色掩码位图
HDC hImageDC = CreateCompatibleDC((HDC)hDC);
HDC hMaskDC = CreateCompatibleDC((HDC)hDC);
hOldImageBMP = (HBITMAP)SelectObject(hImageDC,hImageBMP);
hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC,hMaskBMP);
// 将源DC中的位图拷贝到临时DC中(因为可能会伸缩,所以用StretchBlt而不是BitBlt)
StretchBlt(hImageDC,0,0,m_iMaxTileSize,m_iMaxTileSize,m_hBackDC,0,0,m_iMaxTileSize, m_iMaxTileSize,SRCCOPY);
//设置透明色, 原来为
SetBkColor(hImageDC,GetPixel(m_hBackDC,0,0));
//生成透明区域为白色,其它区域为黑色的掩码位图
BitBlt(hMaskDC,0,0,m_iMaxTileSize, m_iMaxTileSize,hImageDC,0,0,SRCCOPY);
//生成透明区域为黑色,其它区域保持不变的位图
SetBkColor(hImageDC,RGB(0,0,0));
SetTextColor(hImageDC,RGB(255,255,255));
// 这里有两步,首先:单色位图转换成彩色位图:1-&BkC 0-&TextColor
其次:第一步转出来的彩色位图 AND hImageBMP
// 最终结果是:目标位图hImageBMP的透明区域为黑色(0),显示区域保持不变
BitBlt(hImageDC,0,0,m_iMaxTileSize, m_iMaxTileSize,hMaskDC,0,0,SRCAND);
//透明部分保持屏幕不变,其它部分变成黑色
SetBkColor((HDC)hDC,RGB(255,255,255));
SetTextColor((HDC)hDC,RGB(0,0,0));
// 也是两步,同上。
// 最终结果是:hdcDest上被打了个洞,洞的大小正是目标位图显示区域大小,洞里的颜色是黑色(0)
BitBlt((HDC)hDC,0,0,m_iMaxTileSize, m_iMaxTileSize,hMaskDC,0,0,SRCAND);
// OR运算,(hole in hdcDest) | (hImageBMP)
//"或"运算,生成最终效果
BitBlt((HDC)hDC,0,0,m_iMaxTileSize, m_iMaxTileSize,hImageDC,0,0,SRCPAINT);
//清理、恢复
SelectObject(hImageDC,hOldImageBMP);
DeleteDC(hImageDC);
SelectObject(hMaskDC,hOldMaskBMP);
DeleteDC(hMaskDC);
DeleteObject(hImageBMP);
DeleteObject(hMaskBMP);
return S_OK;
3.将动态GPS的DC输出来内存DC上,屏幕位图的句柄,保存到文件
m_pGPSView-&DrawToDC((long)hMemDC);
//得到屏幕位图的句柄,保存到文件
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);//得到屏幕位图的句柄
SaveBmp(hBitmap,strPathName);
SelectObject(hMemDC,hOldBitmap);
DeleteDC(hMemDC);
::ReleaseDC(m_hWnd, hdc);
在DC操作中SelectObject后要注意释放内存
WINAPI 拷贝指定的hDC的lpRect部分到文件Dstfile中(BMP文件格式)
没有更多推荐了,今天在学习用内存DC画图,终于有了初步了解。现将收集的关于内存DC介绍及其相关操作的资料贴出来共享一下。
我的图书馆
今天在学习用内存DC画图,终于有了初步了解。现将收集的关于内存DC介绍及其相关操作的资料贴出来共享一下。
DC&即Device&Context,是GDI内部的一个资料结构,一个DC会和某个特定的显示设备(如打印机、屏幕等)产生关联。我们如果能取得该DC的handle&那我们便可以在这显示设备上写字、画图。
在Form&或Picturebox中都有一个hdc的属性,指的便是这东西,但是,怎么又会有一个Memory&DC呢?这是一个存在记忆体内的&dc&,它除了不像form&picturebox能将图形、文字显示出来之外,其他的几乎都相同,它也可以用在所有的&GDI&API&呼叫之上,其实我们在VB中早就有使用上这&Memory&DC&了,只是没有自觉。当我们设&form&picturebox的AutoRedraw&=&True时,&hdc所指的便是Momoory&DC,这时我们在其上作绘图动作,都没有显示在form上,这便是先前说的,它只是在记忆体中,不会真的画出图。而我们下&refresh指令时,便是将这MemoryDC上的图,copy到&form/PictureBox上。
  另外我们也可以使用CreateCompatibleDC()&API&它传入一个&hDc&,代表产生的&Memory&DC和&hdc相容,若传0则是与屏幕相容的&Memory&DC&hMemDC&=&CreateCompatibleDC(0)
  这时候,该hMemDC所指的绘图区有多大呢?其实只有一个单色Pixel,直到我们使用SelectObject(&hMemDC,&hBitmap)
  那hMemDC显示区就会有和hBitmap一样的宽度、高度、颜色选择等。&而且我们在hMemDC上的任何绘图,也都会反映在&hBitMap上,也就是说,原本hBitMap所指的图,在SelectObject(hMemDC,&hBitMap)后,我们使用gdi函式在hMemDC上画一条线,那么该hBitmap所指的图也会有一条线了。
那么Memory&DC又有什么作用呢?
我们知道,&在使用VC开发图形相关的应用程序时,常常需要使用MFC的CDC类直接把图形画在窗口上。这通常是通过响应Windows的WM_PAINT消息实现的。如果要画的图形比较复杂,或者比较大,那么画图过程可能会造成窗口的闪烁。当窗口调整大小时,这种闪烁由为明显。
解决窗口闪烁问题的有效办法就是使用内存DC,也称为缓冲DC。在内存中准备一个和窗口DC相同属性的DC,在这个内存DC上执行画图操作。完成画图以后,把画图输出的内容整体复制到目标窗口DC上。因为画图操作不在窗口DC上进行,所以在画图的过程中窗口可以保持原来的内容。当画好的内容被复制到窗口DC时,因为复制操作执行的非常快,所以用户感觉窗口仿佛被立刻被画好,从而消除了从旧画面到白板再到新画面的闪烁现象。
生成内存DC主要用到以下四个函数:
CreateCompatibleDC(CDC*&pDC&)。CDC类的成员函数,用于创建一个和pDC指向的DC兼容的内存DC。
CreateDiscardableBitmap(&CDC*&pDC,&int&nWidth,&int&nHeight)。CBitmap类的成员函数,用于按指定尺寸创建一个和pDC指向的DC兼容的位图。&&&&
SelectObject(CBitmap&*&pBitmap)。CDC类的成员函数,执行以后,所有在该DC上的图像输出都将被画到pBitmap指向的位图上。
BOOL&BitBlt&(int&x,&int&y,&int&nWidth,&int&nHeight,&CDC*&pSrcDC,&int&xSrc,&int&ySrc,&DWORD&dwRop&)。CDC类的成员函数,用于从源DC(pSrcDC)复制一个矩形的图象到当前DC中。
&好了,目前我所能理解到的原理就是上面的样子,下面来看看具体应该怎样操作吧。
对于一个窗口,我们可以用下面的代码来创建内存DC,在内存DC上输出,并最终复制到窗口DC上。
C/C++ code12345678910111213141516171819202122void&PaintWnd(CWnd&*&pWnd){&&&&&CDC&*&pWndDC&=&pWnd-&GetWindowDC();&&&&&CRect&WndRect&=&pWnd-&GetWindowRect();&&&&&CDC&MemDC;&&&&&CBitMap&MemB&&&&&&MemDC.CreateCompatibleDC(pWndDC);&&//&创建内存DC&&&&&MemBitmap.CreateCompatibleBitmap(&&//&创建兼容的位图&&&&&&&&&pWndDC,&&&&&&&&&WndRect.Width(),&&&&&&&&&WndRect.Height());&&MemDC.SelectObject(MemBitmap);&&//&让内存DC输出到位图(我的理解就是选择画布)&&&&&//&使用MemDC画图&&&&&……&&&&pWndDC-&BitBlt(//&从内存DC复制到窗口DC&&&&&&&&&0,0,&&&&&&&&&WndRect.Width(),&&&&&&&&&WndRect.Height(),&&&&&&&&&&MemDC,&&&&&&&&&&0,0,&&&&&&&&&SRCCOPY);}
当然,实际的情况下,我们需要考虑的更多,因为内存DC、位图的创建都可能会失败。为了简化代码,此处定义了一个类CMemoryDC,包装了内存DC创建过程中的出错处理,内存DC的事后清理等操作,并自动复制内存DC的内容到目标DC上。
声明CMemoryDC类的头文件MemoryDC.h如下:
C/C++ code1234567891011121314151617181920#pragma&once&#include&"Afxwin.h"&&&&class&CMemoryDC&{&public:&&&&&&CMemoryDC(CDC&*dc,&RECT&*&rect,bool&autoRender&=&false);&&&&&&~CMemoryDC(void);&&&&&&&&&bool&IsOK();&&&&&&void&Render(CDC&*&p_objectDC&=&NULL);&&&&&&CDC*&GetMemoryDC();&&&&&&operator&CDC&*&();&private:&&&&&bool&m_bAutoR&&CRect&m_DCR&&&CDC*&m_pOriginalDC;&&&&&CDC&m_MemoryDC;&&&&&CBitmap&m_MemoryB};
类的实现文件CMemoryDC.cpp如下:
C/C++ code12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455&#include&".MemoryDC.h"&&&&CMemoryDC::CMemoryDC(CDC&*dc,&RECT&*&rect,&bool&autoRender)&&{&&&&&&&&&&m_bAutoRender&=&autoR&&&&&&m_pOriginalDC&=&&&&&&&if&(dc==NULL&||&rect==NULL)&&&&&&&&&&return;&&&&&&if&(!m_MemoryDC.CreateCompatibleDC(dc))&&&&&&&&&&return;&&&&&&m_DCRect.SetRect(rect-&left,&rect-&top,&rect-&right,&rect-&bottom);&&&&&&&&&if&(!m_MemoryBmp.CreateCompatibleBitmap(dc,&m_DCRect.Width(),&m_DCRect.Height()))&&&&&&&&&&return;&&&&&&m_MemoryDC.SelectObject(m_MemoryBmp);&}&&&&CMemoryDC::~CMemoryDC(void)&&{&&&&&&if&(m_bAutoRender)&&&&&&&&&&Render();&&&&&&if&(m_MemoryDC.m_hDC!=NULL)&&&&&&&&&&m_MemoryDC.DeleteDC();&&&&&&if&(m_MemoryBmp.m_hObject!=NULL)&&&&&&&&&&m_MemoryBmp.DeleteObject();&}&&&&bool&CMemoryDC::IsOK()&&{&&&&&&return&m_MemoryDC.m_hDC!=NULL&&&&m_MemoryBmp.m_hObject&!=&NULL;&&&&}&void&CMemoryDC::Render(CDC&*&p_objectDC)&&{&&&&&&if&(!IsOK())&&&&&&&&&&return;&&&&&&&&&CDC&*&pDC&=&(p_objectDC==NULL&?&m_pOriginalDC&:&p_objectDC);&&&&&&CSize&Size&=&m_MemoryDC.GetViewportExt()&;&&&&&&pDC-&BitBlt(&&&&&&&&&&m_DCRect.left,&&&&&&&&&&&m_DCRect.top,&&&&&&&&&&m_DCRect.Width(),&&&&&&&&&&m_DCRect.Height(),&&&&&&&&&&&m_MemoryDC,&&&&&&&&&&&0,0,&&&&&&&&&&SRCCOPY);&}&CDC*&CMemoryDC::GetMemoryDC()&&{&&&&&&return&&&m_MemoryDC;&}&CMemoryDC::operator&CDC&*&()&&{&&&&&&return&&&m_MemoryDC;}
使用这个类可以大大简化内存DC的创建操作。如果我们在窗口消息WM_PAINT的响应函数中使用内存DC,只要用如下这样简便的代码便可实现:
&C/C++ code123456789CRect&R&GetClientRect(Rect);&CPaintDC&dc(this);&//&device&context&for&painting&&&&&&CMemoryDC&MemDC(&dc,&Rect,&true);&&&&&&if&(MemDC.IsOK())&&&&&&&{&&&&&&&&&&//&使用MemDC画窗口&&&&&&&}&&&&&//&MemDC析构时会自动把图像复制到dc,无需其它操作使用CMemoryDC创建内存DC防止窗口闪烁,编程的代码和不使用内存DC时相比,数量和复杂性几乎没有增加。
另外,关于此文章的word文档我也上传了,需要的朋友可去下载。http://download.csdn.net/source/1381542
相关主题推荐:
相关帖子推荐:
喜欢该文的人也喜欢在线提问 问题标题: 问题描述:(简陋的描述会导致问题被最后回答、没有针对性回答甚至无法解答。请确保问题描述的足够清楚。)

我要回帖

更多关于 怎么复制图片然后打印出来 的文章

 

随机推荐