图形能在窗口显示,但是用打印机的句柄printDC.BitBlt画到打印机设备上就不能显示图片了 注:printDC.TextOut可以打印出字符
解决方案 »
- 无法获得媒体长度,请大家帮帮忙
- 一个多线线程的问题,求解释
- MFC同时改变窗口背景和控件背景的颜色
- 节日快乐
- VassistX 无提示,感觉不是VassistX 的问题,别的都可以,写DerectX程序就不行,怎么办
- 问题
- 我用Wise Installation System做安装程序,涉及数据库路径,WIN2000和WIN98的系统目录不同,我该如何安排一个数据库的路径等问题,请各位
- 请问“成都电子科大”今年研究生的分数线是多少?在那里查啊?
- 由Description()输出的error是"表的ID无效",这是什么错误?
- 如何取得一个域名对应的多个IP?
- 调用delphi写的DLL抛出异常访问异常,怎么解决?
- >>> 怎么样打印数据库的记录
关键字 打印 位图
关于位图的打印,很多人对此很困惑,在这方面产生的问题也很多,主要包括以下几点。 1:打印的图片太小; 2:根本打印不出来位图 3:打印预览可见、但打印不出来; 产生这些问题的根本原因,在于对位图的理解不够深刻。 一个CBitmap对象,可能是DDB位图(设备相关位图),或者DIB位图(设备无关位图),其中,一个设备兼容的内存DC中,只能选择该设备兼容的DDB位图或者单色的位图。注意,位图只能被选择进入到设备兼容的内存DC中,并不能选择进入到真实的dc中,这就是有时候根本打印不出来图片的原因。 至于打印图片太小的问题,主要是因为衡量位图大小的单位是横向和纵向的像素数,而不是确切的长度,所以如果把一个图片映射到屏幕上,会出现一个比较大的图像,但是打印机的分辨率比屏幕高很多(屏幕一般是96dpi,而打印机最少一般也有300dpi),如果把位图不缩放地映射到打印机上,则必然要小很多。解决该类问题的方法是使用StretchBlt拉伸显示图像。 另外LoadImage函数中使用LR_CREATEDIBSECTION选项产生的DIB位图可以被选择进入任何设备兼容的内存DC中。因此可以使用LoadImage函数加载一个位图文件或者资源,直接把位图通过StretchBlt打印出来。下面是把一个位图文件进行打印的相关代码:/*//打印或者在屏幕左上角上画位图文件//pDC 打印机或者屏幕dc指针iLogPixelXiLogPixelY屏幕DC的GetDeviceCaps(LOGPIXELSX)值,其中iLogPixelX=DC.GetDeviceCaps(LOGPIXELSX);iLogPixelY=DC.GetDeviceCaps(LOGPIXELSY);const char *strFileName BMP图片文件名称*/void DrawBMP(CDC* pDC,int iLogPixelX,int iLogPixelY,const char *strFileName){ CDC MemDC; // 内存设备环境指针,在视的整个存在过程都将存在 CBitmap Bitmap,*pOldBmp; CRect Source, Dest; // 记录源位图尺寸和最终显示尺寸 BITMAP bm; if(MemDC.GetSafeHdc() == NULL) { HBITMAP hbitmap=(HBITMAP)LoadImage(0,strFileName,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE); Bitmap.Attach(hbitmap); MemDC.CreateCompatibleDC(pDC); Bitmap.GetObject(sizeof(bm),&bm); pOldBmp=MemDC.SelectObject(&Bitmap); Source.top=0; Source.left=0; Source.right= bm.bmWidth; Source.bottom = bm.bmHeight; Dest = Source; } pDC->DPtoLP(&Dest); if(pDC->IsPrinting()) { Dest.left=(int)(Dest.left*((double)pDC->GetDeviceCaps(LOGPIXELSX))/iLogPixelX); Dest.right=(int)(Dest.right*((double)pDC->GetDeviceCaps(LOGPIXELSX))/iLogPixelX); Dest.top=(int)(Dest.top*((double)pDC->GetDeviceCaps(LOGPIXELSY))/iLogPixelY); Dest.bottom=(int)(Dest.bottom*((double)pDC->GetDeviceCaps(LOGPIXELSY))/iLogPixelY); } pDC->StretchBlt(Dest.left, Dest.top, Dest.right, Dest.bottom, &MemDC, Source.left, Source.top, Source.right,Source.bottom, SRCCOPY); MemDC.SelectObject(pOldBmp); Bitmap.DeleteObject(); MemDC.DeleteDC(); return;} 但是对于显示设备兼容的DDB位图的打印则不是那么简单,比如屏幕截图,这种位图不能选择进入打印设备兼容的内存DC中,对于这种问题的处理,一般是通过转化成DIB位图,然后使用StretchDIBits函数把位图显示在DC上,下面是一个可以打印任何位图的函数代码。
关键字 打印 位图
/*
HDC hDC, 打印机dcHBITMAP hBmp, 待打印位图int iX, 位图的左上角点x坐标int iY, 位图的左上角点y坐标double dScaleX, 打印机分辨率和屏幕分辨率x方向的比值,在没有指定位图显示高度和宽度的时候用的上double dScaleY, 打印机分辨率和屏幕分辨率y方向的比值,在没有指定位图显示高度和宽度的时候用的上int iWidth=0, 位图的显示宽度int iLength=0 位图的显示高度*/void Draw(HDC hDC,HBITMAP hBmp,int iX,int iY,double dScaleX=1.0,double dScaleY=1.0,int iWidth=0,int iLength=0){ HPALETTE hPal; BITMAP bm; BITMAPINFOHEADER bi; LPBITMAPINFOHEADER lpbi; DWORD dwLen; HANDLE hDIB; HANDLE handle; HDC hDC1; if(GetDeviceCaps(hDC,RASTERCAPS) & RC_PALETTE ) { UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256); LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300; pLP->palNumEntries =GetSystemPaletteEntries( hDC, 0, 255, pLP->palPalEntry ); hPal=CreatePalette(pLP ); delete[] pLP; } if (hPal==NULL) hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); ::GetObject(hBmp,sizeof(bm),(LPSTR)&bm); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bm.bmWidth; bi.biHeight = bm.bmHeight; bi.biPlanes = 1; bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; int nColors = (1 << bi.biBitCount); if( nColors > 256 ) nColors = 0; dwLen = bi.biSize + nColors * sizeof(RGBQUAD); hDC1 = ::GetDC(NULL); hPal = SelectPalette(hDC1,hPal,FALSE); RealizePalette(hDC1); hDIB = GlobalAlloc(GMEM_FIXED,dwLen); if (!hDIB) { SelectPalette(hDC1,hPal,FALSE); ::ReleaseDC(NULL,hDC1); DeleteObject(hPal); return ; } lpbi = (LPBITMAPINFOHEADER)hDIB; *lpbi = bi; ::GetDIBits(hDC1, hBmp, 0L, (DWORD)bi.biHeight, (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS); bi = *lpbi; if (bi.biSizeImage == 0) bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)* bi.biHeight; dwLen += bi.biSizeImage; if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE)) hDIB = handle; else { GlobalFree(hDIB); SelectPalette(hDC1,hPal,FALSE); ::ReleaseDC(NULL,hDC1); DeleteObject(hPal); return ; } lpbi = (LPBITMAPINFOHEADER)hDIB; BOOL bGotBits = GetDIBits( hDC1, hBmp,0L,(DWORD)bi.biHeight,(LPBYTE)lpbi+ (bi.biSize + nColors * sizeof(RGBQUAD)), (LPBITMAPINFO)lpbi,(DWORD)DIB_RGB_COLORS); if( !bGotBits ) { GlobalFree(hDIB); SelectPalette(hDC1,hPal,FALSE); ::ReleaseDC(NULL,hDC1); DeleteObject(hPal); return; } if(iWidth==0||iLength==0) { iWidth=lpbi->biWidth; iLength=lpbi->biHeight; iWidth=(int)(dScaleX*iWidth); iLength=(int)(iLength*dScaleY); } StretchDIBits(hDC,iX,iY,iWidth,iLength,0,0,lpbi->biWidth,lpbi->biHeight,(LPBYTE)lpbi // address for bitmap bits + (bi.biSize + nColors * sizeof(RGBQUAD)),(LPBITMAPINFO)lpbi,DIB_RGB_COLORS,SRCCOPY); SelectPalette(hDC1,hPal,FALSE); ::ReleaseDC(NULL,hDC1); DeleteObject(hDIB); DeleteObject(hPal);}// 附:得到一个DC位图的代码HBITMAP GetSrcBit(HDC hDC,DWORD BitWidth, DWORD BitHeight){ HDC hBufDC; HBITMAP hBitmap, hBitTemp; hBufDC = CreateCompatibleDC(hDC); hBitmap = CreateCompatibleBitmap(hDC, BitWidth, BitHeight); hBitTemp = (HBITMAP) SelectObject(hBufDC, hBitmap); StretchBlt(hBufDC, 0, 0, BitWidth, BitHeight, hDC, 0, 0, BitWidth, BitHeight, SRCCOPY); hBitmap = (HBITMAP) SelectObject(hBufDC, hBitTemp); ::DeleteDC(hBufDC); return hBitmap;}
{
CDC printDC;
CPrintDialog printDlg(FALSE);
CDC dcMemory;
DOCINFO docInfo; bitmap.LoadBitmap(IDB_BITMAP2); dcMemory.CreateCompatibleDC(&printDC);
pOldBmp=dcMemory.SelectObject(&bitmap); if(printDlg.DoModal()==IDOK)
{
HDC hDC;
hDC=printDlg.GetPrinterDC();
if(!printDC.Attach(hDC))
return;
}
else
{
printDC.Detach();
return;
}
memset(&docInfo,0,sizeof(docInfo));
docInfo.cbSize=sizeof(DOCINFO);
docInfo.lpszDocName="Print Window";
if(printDC.StartDoc(&docInfo)<=0)
{
#ifdef _DEBUG
AfxMessageBox("Start Doc Failed");
#endif
printDC.Detach();
return;
}
dcMemory.SelectObject(&bitmap);
printDC.StartPage();
printDC.SetMapMode(MM_HIENGLISH);
printDC.BitBlt(0,0,1000,1000,&dcMemory,0,0,SRCCOPY);
printDC.EndPage();
printDC.EndDoc(); printDC.Detach();}
这个函数怎么改一下能把资源IDB_BITMAP2打印出来啊
你的错误是LoadBitmap是显示设备兼容的,而不是打印设备兼容的,所以我不用调试就知道你在打印的时候创建的打印设备兼容DC在SelectObject的时会报错误(打印预览不会报错,因为这也是显示设备)不信你查返回值。打印位图的话必须使用StretchDIBits才可以,上面的代码也是把显示设备兼容的位图转化成DIB位图然后打印到打印机的