Printing using GDI
-
Hello, We would like to print some simple drawing output using GDI. We have used the PrintDlgEx function to obtain a device context handle to a printer, but are unsure of how to proceed. We have not been able to find much example code and are a little stuck. Basically, we have the DC handle. Presumably we then call Rectangle(x,x,x,x) etc to do the painting. What must be done then to initiate the actual printing? Any help would be appreciated. Thanks, Steve
-
Hello, We would like to print some simple drawing output using GDI. We have used the PrintDlgEx function to obtain a device context handle to a printer, but are unsure of how to proceed. We have not been able to find much example code and are a little stuck. Basically, we have the DC handle. Presumably we then call Rectangle(x,x,x,x) etc to do the painting. What must be done then to initiate the actual printing? Any help would be appreciated. Thanks, Steve
-
-
Hello, We would like to print some simple drawing output using GDI. We have used the PrintDlgEx function to obtain a device context handle to a printer, but are unsure of how to proceed. We have not been able to find much example code and are a little stuck. Basically, we have the DC handle. Presumably we then call Rectangle(x,x,x,x) etc to do the painting. What must be done then to initiate the actual printing? Any help would be appreciated. Thanks, Steve
char devstring[256]; // array for WIN.INI data HANDLE printer; LPDEVMODE devMode = NULL; DWORD structSize, returnCode; GetProfileString("Devices", printerName, "", devstring, sizeof(devstring)); char *driver = strtok (devstring, (const char *) ","); char *port = strtok((char *) NULL, (const char *) ","); if (!driver || !port) { MessageBox(win->hwndFrame, "Printer with given name doesn't exist", "Printing problem.", MB_ICONEXCLAMATION | MB_OK); return; } BOOL fOk = OpenPrinter((LPSTR)printerName, &printer, NULL); if (!fOk) { MessageBox(win->hwndFrame, _TR("Could not open Printer"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK); return; } HDC hdcPrint = NULL; structSize = DocumentProperties(NULL, printer, /* Handle to our printer. */ (LPSTR) printerName, /* Name of the printer. */ NULL, /* Asking for size, so */ NULL, /* these are not used. */ 0); /* Zero returns buffer size. */ devMode = (LPDEVMODE)malloc(structSize); if (!devMode) goto Exit; // Get the default DevMode for the printer and modify it for your needs. returnCode = DocumentProperties(NULL, printer, (LPSTR) printerName, devMode, /* The address of the buffer to fill. */ NULL, /* Not using the input buffer. */ DM_OUT_BUFFER); /* Have the output buffer filled. */ if (IDOK != returnCode) { // If failure, inform the user, cleanup and return failure. MessageBox(win->hwndFrame, "Could not obtain Printer properties", "Printing problem.", MB_ICONEXCLAMATION | MB_OK); goto Exit; } .......... if (bitmapDx >bitmapDy) { devMode->dmOrientation = DMORIENT_LANDSCAPE; } else { devMode->dmOrientation = DMORIENT_PORTRAIT; } DocumentProperties(NULL, printer, (LPSTR) printerName, devMode, /* Reuse our buffer for output. */ devMode, /* Pass the driver our changes. */ DM_IN_BUFFER | /* Commands to Merge our changes and */ DM_OUT_BUFFER); /* write the result. */ ClosePrinter(printer); hdcPrint = CreateDC(driver, printerName, port, devMode); if (!hdcPrint) { MessageBox(win->hwndFrame, "Couldn't initialize printer", "Printing pro
-
Hello, We would like to print some simple drawing output using GDI. We have used the PrintDlgEx function to obtain a device context handle to a printer, but are unsure of how to proceed. We have not been able to find much example code and are a little stuck. Basically, we have the DC handle. Presumably we then call Rectangle(x,x,x,x) etc to do the painting. What must be done then to initiate the actual printing? Any help would be appreciated. Thanks, Steve
static bool CheckPrinterStretchDibSupport(HWND hwndForMsgBox, HDC hdc) { // most printers can support stretchdibits, // whereas a lot of printers do not support bitblt // quit if printer doesn't support StretchDIBits int rasterCaps = GetDeviceCaps(hdc, RASTERCAPS); int supportsStretchDib = rasterCaps & RC_STRETCHDIB; if (supportsStretchDib) return true; MessageBox(hwndForMsgBox, "This printer doesn't support StretchDIBits function", "Printing problem.", MB_ICONEXCLAMATION | MB_OK); return false; } static void PrintToDevice(DisplayModel *dm, HDC hdc, LPDEVMODE devMode, int nPageRanges, LPPRINTPAGERANGE pr, int printRange = 0) { ................ DOCINFO di = {0}; di.cbSize = sizeof (DOCINFO); di.lpszDocName = filename; if (StartDoc(hdc, &di) <= 0) return; ................. SetMapMode(hdc, MM_TEXT); int printAreaWidth = GetDeviceCaps(hdc, HORZRES); int printAreaHeight = GetDeviceCaps(hdc, VERTRES); int topMargin = GetDeviceCaps(hdc, PHYSICALOFFSETY); int leftMargin = GetDeviceCaps(hdc, PHYSICALOFFSETX); ......... // use pixel sizes for printer with non square pixels float fLogPixelsx= (float)GetDeviceCaps(hdc, LOGPIXELSX); float fLogPixelsy= (float)GetDeviceCaps(hdc, LOGPIXELSY); bool bPrintPortrait=fLogPixelsx*printAreaWidth<flogpixelsy*printareaheight;> BOOL isSameFile = IsSameFile(dm); int realWidth = printAreaWidth; int realHeight = printAreaHeight; // print all the pages the user requested unless // bContinue flags there is a problem. for (int i=0; i < nPageRanges; i++) { assert(pr->nFromPage <= pr->nToPage); for (DWORD pageNo = pr->nFromPage; pageNo <= pr->nToPage; pageNo++) { ............ StartPage(hdc); .............. bmp->stretchDIBits(hdc, leftMargin, topMargin, realWidth, realHeight); delete bmp; if (EndPage(hdc) <= 0) { AbortDoc(hdc); return; } } pr++; } Error: EndDoc(hdc); }
-
Hello, We would like to print some simple drawing output using GDI. We have used the PrintDlgEx function to obtain a device context handle to a printer, but are unsure of how to proceed. We have not been able to find much example code and are a little stuck. Basically, we have the DC handle. Presumably we then call Rectangle(x,x,x,x) etc to do the painting. What must be done then to initiate the actual printing? Any help would be appreciated. Thanks, Steve
also you can do like this: PRINTDLGEX pd; LPPRINTPAGERANGE ppr=NULL; ....... ZeroMemory(&pd, sizeof(PRINTDLGEX)); pd.lStructSize = sizeof(PRINTDLGEX); pd.hwndOwner = hwndFrame; pd.hDevMode = NULL; pd.hDevNames = NULL; pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE | PD_NOSELECTION; pd.nCopies = 1; /* by default print all pages */ pd.nPageRanges =1; pd.nMaxPageRanges = MAXPAGERANGES; ppr = (LPPRINTPAGERANGE)malloc(MAXPAGERANGES*sizeof(PRINTPAGERANGE)); pd.lpPageRanges = ppr; ppr->nFromPage = 1; ppr->nToPage = dm->pageCount(); pd.nMinPage = 1; pd.nMaxPage = dm->pageCount(); pd.nStartPage = START_PAGE_GENERAL; if (PrintDlgEx(&pd) == S_OK) { if (pd.dwResultAction==PD_RESULT_PRINT) { if (CheckPrinterStretchDibSupport(hwndFrame, pd.hDC)){ if (pd.Flags & PD_CURRENTPAGE) { pd.nPageRanges=1; pd.lpPageRanges->nFromPage=currentPageNo(); pd.lpPageRanges->nToPage =currentPageNo(); } else if (!(pd.Flags & PD_PAGENUMS)) { pd.nPageRanges=1; pd.lpPageRanges->nFromPage=1; pd.lpPageRanges->nToPage =pageCount(); } PrintToDevice(dm, pd.hDC, (LPDEVMODE)pd.hDevMode, pd.nPageRanges, pd.lpPageRanges); } } } else { if (CommDlgExtendedError()) { /* if PrintDlg was cancelled then CommDlgExtendedError is zero, otherwise it returns the error code, which we could look at here if we wanted. for now just warn the user that printing has stopped becasue of an error */ MessageBox(win->hwndFrame, "Cannot initialise printer", "Printing problem.", MB_ICONEXCLAMATION | MB_OK); } } free(ppr); if (pd.hDC != NULL) DeleteDC(pd.hDC); if (pd.hDevNames != NULL) GlobalFree(pd.hDevNames); if (pd.hDevMode != NULL) GlobalFree(pd.hDevMode); }
-
Hello, We would like to print some simple drawing output using GDI. We have used the PrintDlgEx function to obtain a device context handle to a printer, but are unsure of how to proceed. We have not been able to find much example code and are a little stuck. Basically, we have the DC handle. Presumably we then call Rectangle(x,x,x,x) etc to do the painting. What must be done then to initiate the actual printing? Any help would be appreciated. Thanks, Steve
You will need to put all GDI calls between
StartDoc
/EndDoc
andStartPage
/EndPage
APIs. The Doc indicates a print job and the Page indicates a new page. So basically you will have one pair ofStartDoc
/EndDoc
and several pairs ofStartPage
/EndPage
(One for each page).«_Superman_»
-
Hello, We would like to print some simple drawing output using GDI. We have used the PrintDlgEx function to obtain a device context handle to a printer, but are unsure of how to proceed. We have not been able to find much example code and are a little stuck. Basically, we have the DC handle. Presumably we then call Rectangle(x,x,x,x) etc to do the painting. What must be done then to initiate the actual printing? Any help would be appreciated. Thanks, Steve
If you haven't already been swamped with help, Roger Allen did many printing articles way back when: http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=3798[^] Throughly nice chap, and a good writer. Shame real life made him stop posting... Iain.
Codeproject MVP for C++, I can't believe it's for my lounge posts...