自认为注释已经很详细了,没有什么可说的,以后再用的时候如果还有哪不明白的就当长教训了 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 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()); // 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;iRotateFlip(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; } 注: 加载头文件winspool.h