天天看點

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

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

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

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)

// 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);

// 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) +

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

繼續閱讀