急求对话框中打印位图文件的可用代码(包括获取默认打印机)? 以前没用vc做过打印,才发现对话框下实现起来不很方便,时间急先求代码,各位帮忙啊! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 没做过,不过知道可以通过读写注册表获取当前打印机,然后用类似于ShellExecute(this->m_hWnd,"print","c:\\abc.txt","","", SW_HIDE)的办法来打印 关于位图的打印,很多人对此很困惑,在这方面产生的问题也很多,主要包括以下几点。 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);} 获取默认打印机的例子void PrintTest(){ CPrintDialog pd(FALSE, PD_ALLPAGES | PD_COLLATE | PD_NOPAGENUMS | PD_HIDEPRINTTOFILE); if(pd.GetDefaults()) { DOCINFO di; memset( &di, 0, sizeof(DOCINFO) ); di.cbSize = sizeof(DOCINFO); di.lpszDocName = "Printing Test"; di.lpszOutput = (LPTSTR) NULL; di.fwType = 0; HDC hDC=pd.CreatePrinterDC(); CDC dc; dc.Attach(hDC); dc.StartDoc(&di); dc.StartPage(); dc.MoveTo(0,0); dc.LineTo(1000,1000); dc.EndPage(); dc.EndDoc(); dc.DeleteDC(); }} 在线等数据库addnew出错 【求教】关于在按钮上加一个位图的问题 【串口】如何检测串口设备意外断开的事件? 求CoolFox源码 请问设置特定对话框背景颜色怎么设置? TreeCtrl图标显示的问题 再发一帖,请遇到这个问题的人来帮帮我啊!!“服务器无法通过系统非页面共享区来进行分配,因为共享区当前是空的。”这是系统日志中出现 正态分布曲线怎么拟合呀? 一个简单的问题 我想在WIN2000下编写一个读写硬件端口的程序,哪位高手能给点建议? 如何获取菜单条的屏幕坐标? 想问大家一个小问题!希望各位DX不吝赐教!
ShellExecute(this->m_hWnd,"print","c:\\abc.txt","","", SW_HIDE)的办法来打印
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);}
void PrintTest()
{
CPrintDialog pd(FALSE, PD_ALLPAGES | PD_COLLATE | PD_NOPAGENUMS | PD_HIDEPRINTTOFILE);
if(pd.GetDefaults())
{
DOCINFO di;
memset( &di, 0, sizeof(DOCINFO) );
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = "Printing Test";
di.lpszOutput = (LPTSTR) NULL;
di.fwType = 0;
HDC hDC=pd.CreatePrinterDC();
CDC dc;
dc.Attach(hDC);
dc.StartDoc(&di);
dc.StartPage();
dc.MoveTo(0,0);
dc.LineTo(1000,1000);
dc.EndPage();
dc.EndDoc();
dc.DeleteDC();
}
}