VC最简版图片打印程序


自认为注释已经很详细了,没有什么可说的,以后再用的时候如果还有哪不明白的就当长教训了

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;
}



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号