自认为注释已经很详细了,没有什么可说的,以后再用的时候如果还有哪不明白的就当长教训了
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;
}
posted on 2009-06-08 09:58
似水之心 阅读(8127)
评论(0) 编辑 收藏 引用