本文共 6025 字,大约阅读时间需要 20 分钟。
自认为注释已经很详细了,没有什么可说的,以后再用的时候如果还有哪不明白的就当长教训了
BOOL CMYDlg::PrintPic(CString strFileName/*打印的图片文件名,带路径*/,int iCopies/*打印次数*/,CString strPrintName/*指定打印机名,如果只有一台打印机可忽略,相应的注释下面的一些代码*/) { CDC dc; CPrintDialog printDlg(FALSE); HGLOBAL hDevMode; HGLOBAL hDevNames; //以下为判断纸型,m_strPrintSize为类的成员变量short paperWidth = 0;
short paperHeight = 0; if(0==m_strPrintSize.CompareNoCase("a3")) { paperWidth = 2970; paperHeight = 4200; } if(0==m_strPrintSize.CompareNoCase("a4")) { paperWidth = 2100; paperHeight = 2970; } if(0==m_strPrintSize.CompareNoCase("a5")) { paperWidth=1480; paperHeight=2100; } if(0==m_strPrintSize.CompareNoCase("a6")) { paperWidth = 1050; paperHeight = 1480; }BSTR bstr=strFileName.AllocSysString();
Bitmap* pPicture = new Bitmap(bstr); HBITMAP hBitmap;//创建bmp的句柄 pPicture->GetHBITMAP(NULL,&hBitmap);//获取句柄 BITMAP bitmap; ::GetObject(hBitmap,sizeof(BITMAP),&bitmap); printDlg.GetDefaults(); DEVMODE FAR *pDevMode=(DEVMODE FAR *)::GlobalLock(printDlg.m_pd.hDevMode); pDevMode->dmFields = pDevMode->dmFields | DM_PAPERSIZE; pDevMode->dmPaperSize = DMPAPER_USER; //将打印纸设置为自定义DMDO_90/* if (bitmap.bmHeight<bitmap.bmWidth)
{ pDevMode->dmPaperWidth = paperHeight; pDevMode->dmPaperLength = paperWidth; } else {*/ pDevMode->dmPaperWidth = paperWidth; pDevMode->dmPaperLength = paperHeight; // }::GlobalUnlock(printDlg.m_pd.hDevMode);
::DeleteObject(hBitmap);
CPrintInfo Info;//
if(GetPrinterDevice(strPrintName.GetBuffer(0), &hDevNames, &hDevMode)) { printDlg.m_pd.hDevMode=hDevMode; printDlg.m_pd.hDevNames = hDevNames; }dc.Attach(printDlg.CreatePrinterDC()/*这里很重要,一定要CreatePrinterDC,要不然还是打印机默认的纸型*/); // Attach a printer DC 让HANDLE连接到dc上
dc.m_bPrinting = TRUE; CString strTitle; // Get the application title ? strTitle.LoadString(AFX_IDS_APP_TITLE); DOCINFO di; // Initialise print document details DOCINFO中有相关的打印信息 ::ZeroMemory (&di, sizeof (DOCINFO)); di.cbSize = sizeof (DOCINFO); di.lpszDocName = strFileName;//设置标题for (int i=0;i<iCopies;i++)
{ BOOL bPrintingOK = dc.StartDoc(&di); // Begin a new print job 开始打印 // Get the printing extents and store in the m_rectDraw field of a // CPrintInfo object Info.m_rectDraw.SetRect(0,0,dc.GetDeviceCaps(HORZRES),dc.GetDeviceCaps(VERTRES));//设置范围Info.SetMaxPage (1);
OnPrint(&dc, &Info,strFileName); // 往DC上画图片,具体实现在下面给出 //OnEndPrinting(&dc, &Info); // 结束打印 if (bPrintingOK) dc.EndDoc(); // end a print job else dc.AbortDoc(); // abort job. } dc.Detach(); // detach the printer DC delete pPicture; pPicture=NULL; return TRUE; } 相关函数: void OnPrint(CDC* pdc,CPrintInfo * lParam,CString strFileName1) { CDC* pDC = pdc; CPrintInfo* pInfo = (CPrintInfo *)lParam; CFont DataFont; DataFont.CreatePointFont(120,"宋体",pDC); CString strFileName=strFileName1; BSTR bstr=strFileName.AllocSysString(); Bitmap* pPicture = new Bitmap(bstr); pPicture->RotateFlip(Gdiplus::Rotate90FlipNone); HBITMAP hBitmap;//创建bmp的句柄 pPicture->GetHBITMAP(NULL,&hBitmap);//获取句柄 BITMAP bitmap; ::GetObject(hBitmap,sizeof(BITMAP),&bitmap); double dScale=(double)pInfo->m_rectDraw.Width()/bitmap.bmWidth; //int nScaledWidth=m_cxWidth; int nScaledHeight=(int)(bitmap.bmHeight*dScale); HDC dcMem; dcMem=::CreateCompatibleDC(pDC->m_hDC); HBITMAP hOldBmp=(HBITMAP)::SelectObject(dcMem,hBitmap); CRect r = pInfo->m_rectDraw; SizeToPlace(STP_FIX, r, CRect(0,0,bitmap.bmWidth, bitmap.bmHeight));//这个函数没有给出,可以自己写一下,注释掉也行,功能就是调整尺寸的 int nVertCenterPos = pDC->GetDeviceCaps (VERTRES) / 2; ::StretchBlt(pDC->m_hDC, r.left, r.top, r.Width(), r.Height(), dcMem,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY); ::SelectObject(dcMem,hOldBmp); ::DeleteDC(dcMem); ::DeleteObject(hBitmap); delete pPicture; pPicture=NULL;}
BOOL GetPrinterDevice(LPTSTR pszPrinterName, HGLOBAL* phDevNames, HGLOBAL* phDevMode)//从MSDN复制来的,获取打印机设备 { // if NULL is passed, then assume we are setting app object's // devmode and devnames if (phDevMode == NULL || phDevNames == NULL) return FALSE; // Open printer HANDLE hPrinter; if (OpenPrinter(pszPrinterName, &hPrinter, NULL) == FALSE) return FALSE; // obtain PRINTER_INFO_2 structure and close printer DWORD dwBytesReturned, dwBytesNeeded; GetPrinter(hPrinter, 2, NULL, 0, &dwBytesNeeded); PRINTER_INFO_2* p2 = (PRINTER_INFO_2*)GlobalAlloc(GPTR, dwBytesNeeded); if (GetPrinter(hPrinter, 2, (LPBYTE)p2, dwBytesNeeded, &dwBytesReturned) == 0) { GlobalFree(p2); ClosePrinter(hPrinter); return FALSE; } ClosePrinter(hPrinter); // Allocate a global handle for DEVMODE HGLOBAL hDevMode = GlobalAlloc(GHND, sizeof(*p2->pDevMode) + p2->pDevMode->dmDriverExtra); ASSERT(hDevMode); DEVMODE* pDevMode = (DEVMODE*)GlobalLock(hDevMode); ASSERT(pDevMode); // copy DEVMODE data from PRINTER_INFO_2::pDevMode memcpy(pDevMode, p2->pDevMode, sizeof(*p2->pDevMode) + p2->pDevMode->dmDriverExtra); GlobalUnlock(hDevMode); // Compute size of DEVNAMES structure from PRINTER_INFO_2's data DWORD drvNameLen = lstrlen(p2->pDriverName)+1; // driver name DWORD ptrNameLen = lstrlen(p2->pPrinterName)+1; // printer name DWORD porNameLen = lstrlen(p2->pPortName)+1; // port name // Allocate a global handle big enough to hold DEVNAMES. HGLOBAL hDevNames = GlobalAlloc(GHND, sizeof(DEVNAMES) + (drvNameLen + ptrNameLen + porNameLen)*sizeof(TCHAR)); ASSERT(hDevNames); DEVNAMES* pDevNames = (DEVNAMES*)GlobalLock(hDevNames); ASSERT(pDevNames); // Copy the DEVNAMES information from PRINTER_INFO_2 // tcOffset = TCHAR Offset into structure int tcOffset = sizeof(DEVNAMES)/sizeof(TCHAR); ASSERT(sizeof(DEVNAMES) == tcOffset*sizeof(TCHAR)); pDevNames->wDriverOffset = tcOffset; memcpy((LPTSTR)pDevNames + tcOffset, p2->pDriverName, drvNameLen*sizeof(TCHAR)); tcOffset += drvNameLen; pDevNames->wDeviceOffset = tcOffset; memcpy((LPTSTR)pDevNames + tcOffset, p2->pPrinterName, ptrNameLen*sizeof(TCHAR)); tcOffset += ptrNameLen; pDevNames->wOutputOffset = tcOffset; memcpy((LPTSTR)pDevNames + tcOffset, p2->pPortName, porNameLen*sizeof(TCHAR)); pDevNames->wDefault = 0; GlobalUnlock(hDevNames); GlobalFree(p2); // free PRINTER_INFO_2 // set the new hDevMode and hDevNames *phDevMode = hDevMode; *phDevNames = hDevNames; return TRUE; }转载地址:http://ncuab.baihongyu.com/