BOOL CWinPrint::PrintDlg(HWND hOwner, LONG lCopies, LONG lFrom, LONG lTo, LONG lMin, LONG lMax) { // Use new version instead //#if defined ( RULIB_USE_PRINTDLG ) // return PrintDlgEx( hOwner, lCopies, lFrom, lTo, lMin, lMax ); //#endif Destroy(); // Fill in print information m_pd.lStructSize = sizeof( m_pd ); m_pd.Flags = PD_RETURNDC; m_pd.hwndOwner = hOwner; m_pd.nFromPage = (WORD)lFrom; m_pd.nToPage = (WORD)lTo; m_pd.nMinPage = (WORD)lMin; m_pd.nMaxPage = (WORD)lMax; m_pd.nCopies = (WORD)lCopies; // Attempt to get printer if ( !::PrintDlg( &m_pd ) ) return FALSE; // Reset the abort flag m_bAbort = FALSE; // Set abort procedure SetAbortProc( m_pd.hDC, &CWinPrint::AbortProc ); return TRUE; }
BOOL CWinPrint::PrintDlgEx(HWND hOwner, LONG lCopies, LONG lFrom, LONG lTo, LONG lMin, LONG lMax) { Destroy(); PRINTPAGERANGE ppr = { lFrom, lTo }; // Fill in print information m_pdx.lStructSize = sizeof( m_pdx ); m_pdx.hwndOwner = hOwner; m_pdx.Flags = PD_ALLPAGES | PD_RETURNDC; m_pdx.nMinPage = lMin; m_pdx.nMaxPage = lMax; m_pdx.nCopies = lCopies; m_pdx.nStartPage = START_PAGE_GENERAL; // From to? if ( ( lFrom || lTo ) && lFrom != lTo ) { m_pdx.nMaxPageRanges = 1; m_pdx.lpPageRanges = &ppr; } // end if // Attempt to get printer if ( PD_RESULT_PRINT != ::PrintDlgEx( &m_pdx ) ) return FALSE; // Reset the abort flag m_bAbort = FALSE; // Set abort procedure SetAbortProc( m_pdx.hDC, &CWinPrint::AbortProc ); return TRUE; }
/********************************************************************** * SetAbortProc (GDI.381) */ INT16 WINAPI SetAbortProc16(HDC16 hdc, ABORTPROC16 abrtprc) { DC *dc = DC_GetDCPtr( hdc ); if (!dc) return FALSE; dc->pAbortProc16 = abrtprc; GDI_ReleaseObj( hdc ); return SetAbortProc( hdc, call_abort_proc16 ); }
////////////////// // Do abort dialog // int WPPrinter::doAbortDlg(WPWin *w) { pwin = w; Abort = FALSE; assert(DlgAbort==NULL); DlgAbort = new WPDlgPrintAbort(pwin); if (pwin) pwin->enableWin(FALSE); return SetAbortProc(hdc, WPPrintAbortProc); }
void SimplePrint(int nPages) { TCHAR temp[MAX_PATH]; DWORD size = MAX_PATH; GetDefaultPrinter(temp, & size); // default printer name HDC hDC = CreateDC(NULL, temp, NULL, NULL); // DC with default setting if ( hDC ) { nCall_AbortProc = 0; SetAbortProc(hDC, SimpleAbortProc); DOCINFO docinfo; docinfo.cbSize = sizeof(docinfo); docinfo.lpszDocName = _T("SimplePrint"); docinfo.lpszOutput = NULL; docinfo.lpszDatatype = _T("EMF"); docinfo.fwType = 0; if ( StartDoc(hDC, & docinfo) > 0 ) { for (int p=0; p<nPages; p++) // one page at a time if ( StartPage(hDC) <= 0 ) break; else { int width = GetDeviceCaps(hDC, HORZRES); int height = GetDeviceCaps(hDC, VERTRES); int dpix = GetDeviceCaps(hDC, LOGPIXELSX); int dpiy = GetDeviceCaps(hDC, LOGPIXELSY); wsprintf(temp, _T("Page %d of %d"), p+1, nPages); SetTextAlign(hDC, TA_TOP | TA_RIGHT ); TextOut(hDC, width, 0, temp, _tcslen(temp)); Rectangle(hDC, 0, 0, dpix, dpiy); Rectangle(hDC, width, height, width-dpix, height-dpiy); if ( EndPage(hDC)<0 ) break; } EndDoc(hDC); } DeleteDC(hDC); } wsprintf(temp, "AbortProc called %d times", nCall_AbortProc); MessageBox(NULL, temp, "SimlePrint", MB_OK); }
GPrintDC::GPrintDC(void *Handle, const char *PrintJobName, const char *PrinterName) { d = new GPrintDCPrivate; hDC = (HDC) Handle; SetAbortProc(hDC, LgiAbortProc); // Start document if (hDC) { DOCINFO Info; ZeroObj(Info); Info.cbSize = sizeof(DOCINFO); Info.lpszDocName = PrintJobName ? PrintJobName : "Lgi Print Job"; if (PrinterName && stristr(PrinterName, "XPS")) { GFile::Path p(LSP_USER_DOCUMENTS); GString FileName; FileName.Printf("%s.xps", PrintJobName); p += FileName; if (FileExists(p.GetFull())) { for (unsigned i=1; i<1000; i++) { p.Parent(); FileName.Printf("%s%i.xps", PrintJobName, i); p += FileName; if (!FileExists(p.GetFull())) break; } } Info.lpszOutput = d->OutputFileName = p.GetFull(); } d->DocOpen = StartDoc(hDC, &Info) > 0; if (!d->DocOpen) { DeleteDC(hDC); hDC = 0; } } }
wBool_t wPrintDocStart( const char * title, int fpageCount, int * copiesP ) { printStatus = FALSE; pageCount = fpageCount; pageNumber = 0; print_d.hDc = mswGetPrinterDC(); if (print_d.hDc == (HDC)0) { return FALSE; } printStatus = TRUE; docInfo.cbSize = sizeof docInfo; docInfo.lpszDocName = title; docInfo.lpszOutput = NULL; lpAbortDlg = MakeProcInstance( (FARPROC)mswAbortDlg, mswHInst ); lpAbortProc = MakeProcInstance( (FARPROC)mswAbortProc, mswHInst ); SetAbortProc( print_d.hDc, (ABORTPROC)lpAbortProc ); if (StartDoc( print_d.hDc, &docInfo ) < 0) { MessageBox( mswHWnd, "Unable to start print job", NULL, MB_OK|MB_ICONHAND ); FreeProcInstance( lpAbortDlg ); FreeProcInstance( lpAbortProc ); DeleteDC( print_d.hDc ); return FALSE; } printAbort = FALSE; hAbortDlgWnd = CreateDialog( mswHInst, "MswAbortDlg", mswHWnd, (DLGPROC)lpAbortDlg ); /*SetDlgItemText( hAbortDlgWnd, IDM_PRINTAPP, title );*/ SetWindowText( hAbortDlgWnd, title ); ShowWindow( hAbortDlgWnd, SW_NORMAL ); UpdateWindow( hAbortDlgWnd ); EnableWindow( mswHWnd, FALSE ); if (copiesP) *copiesP = printDlg.nCopies; if (printDlg.nCopies>1) pageCount *= printDlg.nCopies; if ( (GetDeviceCaps( printDlg.hDC, RASTERCAPS ) & RC_PALETTE) ) { newPrintPalette = mswCreatePalette(); oldPrintPalette = SelectPalette( printDlg.hDC, newPrintPalette, 0 ); RealizePalette( printDlg.hDC ); } return TRUE; }
static int winprint_start (struct winprint_data *wd, Tcl_Interp *interp, PRINTDLG *pd, const struct print_text_options *pto, int *cancelled) { DOCINFO di; *cancelled = 0; wd->aborted = 0; /* We have no way to pass information to the abort function, so we need to use a global variable. */ abort_wd = wd; if (! SetAbortProc (pd->hDC, abort_function)) { windows_error (interp, "SetAbortFunc"); return TCL_ERROR; } di.cbSize = sizeof (DOCINFO); di.lpszDocName = pto->name; di.lpszOutput = NULL; di.lpszDatatype = NULL; di.fwType = 0; if (StartDoc (pd->hDC, &di) <= 0) { if (GetLastError () == ERROR_CANCELLED) *cancelled = 1; else { windows_error (interp, "StartDoc"); return TCL_ERROR; } } return TCL_OK; }
void print_mswin(const char *file_name) { HDC hDC; DOCINFO di; short int width, height; HWND hWndParent = HWND_DESKTOP; /* would be better to be a real window */ /* Need a printer DC to print to. */ hDC = get_printer_dc(&width, &height); /* Did you get a good DC?, Cancel will return NULL also, so what to do? */ if (!hDC) { return; } /* You always have to use an AbortProc(). */ if (SetAbortProc(hDC, abort_proc) == SP_ERROR) { MessageBox(NULL, "Error setting up AbortProc", "Error", MB_APPLMODAL | MB_OK); return; } /* Init the DOCINFO and start the document. */ init_doc_struct(&di, "MyDoc"); StartDoc(hDC, &di); /* Print one page. */ StartPage(hDC); print_file(file_name, hDC, width, height); EndPage(hDC); /* Indicate end of document. */ EndDoc(hDC); /* Clean up */ DeleteDC(hDC); }
BOOL PrintMyPage (HWND hwnd) { static DOCINFO di = { sizeof (DOCINFO), TEXT ("Print2: Printing") } ; BOOL bSuccess = TRUE ; HDC hdcPrn ; short xPage, yPage ; if (NULL == (hdcPrn = GetPrinterDC ())) return FALSE ; xPage = GetDeviceCaps (hdcPrn, HORZRES) ; yPage = GetDeviceCaps (hdcPrn, VERTRES) ; EnableWindow (hwnd, FALSE) ; SetAbortProc (hdcPrn, AbortProc) ; if (StartDoc (hdcPrn, &di) > 0) { if (StartPage (hdcPrn) > 0) { PageGDICalls (hdcPrn, xPage, yPage) ; if (EndPage (hdcPrn) > 0) EndDoc (hdcPrn) ; else bSuccess = FALSE ; } } else bSuccess = FALSE ; EnableWindow (hwnd, TRUE) ; DeleteDC (hdcPrn) ; return bSuccess ; }
/************************************************************************ * Escape [GDI32.@] */ INT WINAPI Escape( HDC hdc, INT escape, INT in_count, LPCSTR in_data, LPVOID out_data ) { INT ret; POINT *pt; switch (escape) { case ABORTDOC: return AbortDoc( hdc ); case ENDDOC: return EndDoc( hdc ); case GETPHYSPAGESIZE: pt = out_data; pt->x = GetDeviceCaps( hdc, PHYSICALWIDTH ); pt->y = GetDeviceCaps( hdc, PHYSICALHEIGHT ); return 1; case GETPRINTINGOFFSET: pt = out_data; pt->x = GetDeviceCaps( hdc, PHYSICALOFFSETX ); pt->y = GetDeviceCaps( hdc, PHYSICALOFFSETY ); return 1; case GETSCALINGFACTOR: pt = out_data; pt->x = GetDeviceCaps( hdc, SCALINGFACTORX ); pt->y = GetDeviceCaps( hdc, SCALINGFACTORY ); return 1; case NEWFRAME: return EndPage( hdc ); case SETABORTPROC: return SetAbortProc( hdc, (ABORTPROC)in_data ); case STARTDOC: { DOCINFOA doc; char *name = NULL; /* in_data may not be 0 terminated so we must copy it */ if (in_data) { name = HeapAlloc( GetProcessHeap(), 0, in_count+1 ); memcpy( name, in_data, in_count ); name[in_count] = 0; } /* out_data is actually a pointer to the DocInfo structure and used as * a second input parameter */ if (out_data) doc = *(DOCINFOA *)out_data; else { doc.cbSize = sizeof(doc); doc.lpszOutput = NULL; doc.lpszDatatype = NULL; doc.fwType = 0; } doc.lpszDocName = name; ret = StartDocA( hdc, &doc ); HeapFree( GetProcessHeap(), 0, name ); if (ret > 0) ret = StartPage( hdc ); return ret; } case QUERYESCSUPPORT: { const INT *ptr = (const INT *)in_data; if (in_count < sizeof(INT)) return 0; switch(*ptr) { case ABORTDOC: case ENDDOC: case GETPHYSPAGESIZE: case GETPRINTINGOFFSET: case GETSCALINGFACTOR: case NEWFRAME: case QUERYESCSUPPORT: case SETABORTPROC: case STARTDOC: return TRUE; } break; } } /* if not handled internally, pass it to the driver */ return ExtEscape( hdc, escape, in_count, in_data, 0, out_data ); }
int Print(HWND win) { BOOL rv = TRUE; int start, end; PRINTDLG pd; HWND hDlgCancel = 0; memset(&pd, 0, sizeof(pd)); pd.lStructSize = sizeof(pd); pd.hwndOwner = hwndFrame; pd.Flags = PD_NOPAGENUMS | PD_RETURNDC | PD_COLLATE ; pd.hInstance = hInstance; SendDlgItemMessage(win, ID_EDITCHILD, EM_GETSEL, (WPARAM) &start, (LPARAM) &end); tabSetting = PropGetInt(NULL, "TAB_INDENT"); leftmargin = PropGetInt(NULL, "PRINTER_LEFT"); rightmargin = PropGetInt(NULL, "PRINTER_RIGHT"); topmargin = PropGetInt(NULL, "PRINTER_TOP"); bottommargin = PropGetInt(NULL, "PRINTER_BOTTOM"); PropGetString(NULL, "PRINTER_HEADER", printHeader, sizeof(printHeader)); PropGetString(NULL, "PRINTER_FOOTER", printFooter, sizeof(printFooter)); if (tabSetting <= 0) tabSetting = 4; if (end != start) pd.Flags |= PD_SELECTION; if (PrintDlg(&pd)) { DOCINFO di; HWND child; char *buf, *pos, *savepos1; if (pd.Flags &PD_SELECTION) { if (end <= start) return TRUE ; } child = GetDlgItem(win, ID_EDITCHILD); buf = GetEditData(child); if (!buf) return TRUE ; if (pd.Flags &PD_SELECTION) { savepos1 = pos = buf + start; buf[end] = 0; } else savepos1 = pos = buf; printing = TRUE; memset(&di, 0, sizeof(di)); di.cbSize = sizeof(di); di.lpszDocName = (char*)SendMessage(win, WM_FILETITLE, 0, 0); if (pd.Flags &PD_PRINTTOFILE) di.lpszOutput = "FILE:"; SetAbortProc(pd.hDC, &AbortProc); if (StartDoc(pd.hDC, &di) > 0) { int pelsx, pelsy; int width, height, rows, cols; int done = FALSE; char headerLeft[256],headerRight[256],headerCenter[256]; char FooterLeft[256],FooterRight[256],FooterCenter[256]; SIZE strsize ; HFONT hFont, oldhFont; pelsx = GetDeviceCaps(pd.hDC, LOGPIXELSX); pelsy = GetDeviceCaps(pd.hDC, LOGPIXELSY); fontdata.lfHeight = - MulDiv(11, pelsx, 72); hFont = CreateFontIndirect(&fontdata); oldhFont = SelectObject(pd.hDC, hFont); GetTextExtentPoint32(pd.hDC, "A", 1, &strsize); width = GetDeviceCaps(pd.hDC, HORZRES); height = GetDeviceCaps(pd.hDC, VERTRES); // buf = GetEditData(win); rows = (height - (topmargin + bottommargin) *pelsy * 10 / 254) / strsize.cy ; cols = (width - (leftmargin + rightmargin) *pelsx * 10 / 254) / strsize.cx; if (rows <= 0 || cols <= 0) { AbortDoc(pd.hDC); free(buf); DeleteObject(hFont); if (pd.hDC != NULL) DeleteDC(pd.hDC); if (pd.hDevMode != NULL) GlobalFree(pd.hDevMode); if (pd.hDevNames != NULL) GlobalFree(pd.hDevNames); return FALSE; } SelectObject(pd.hDC, oldhFont); if (printHeader[0]) rows -= 2; if (printFooter[0]) rows -= 2; total_pages = countPages(savepos1, rows, cols); setTimeFormats(); split(printHeader, headerLeft, headerRight, headerCenter); split(printFooter, FooterLeft, FooterRight, FooterCenter); hDlgCancel = CreateDialog(hInstance, "PRINTABORTDLG", 0, (DLGPROC) CancelProc); EnableWindow(hwndFrame, FALSE); do { int colcount = pd.nCopies; int pagenum = 1; pos = savepos1; while (printing && *pos && StartPage(pd.hDC) > 0) { int i, j, k; int hdrlines = 0; char line[512]; char *savepos2 = pos; oldhFont = SelectObject(pd.hDC, hFont); if (printHeader[0]) { char buf[256]; int cx ; int cy = topmargin * pelsy * 10/ 254; cx = subs(pd.hDC, buf, headerLeft, di.lpszDocName, pagenum); cx = leftmargin * pelsx * 10 / 254; TextOut(pd.hDC, cx, cy, buf, strlen(buf)); cx = subs(pd.hDC, buf, headerCenter, di.lpszDocName, pagenum); cx = (width - cx)/2 ; TextOut(pd.hDC, cx, cy, buf, strlen(buf)); cx = subs(pd.hDC, buf, headerRight, di.lpszDocName, pagenum); cx = width - cx - rightmargin * pelsx * 10 / 254; TextOut(pd.hDC, cx, cy, buf, strlen(buf)); hdrlines = 2; } for (i = 0; i < rows; i++) { int count = 0; if (*pos == '\n') { pos++; } else if (*pos == '\f') { pos += 2; break; } else { for (j = 0; j < cols; j++) { if (*pos == '\t') { int n = tabSetting - j % tabSetting; pos++; for (k = 0; k < n; k++) line[count++] = ' '; j += n - 1; } else { if (*pos < 32 || *pos > 126) { if (*pos == '\n') pos++; break; } line[count++] = *pos++; } } TextOut(pd.hDC, leftmargin *pelsx * 10 / 254, (i + hdrlines) *strsize.cy + topmargin * pelsy * 10 / 254, line, count); } if (! *pos) break; } if (printFooter[0]) { char buf[256]; int cx ; int cy = height - strsize.cy - bottommargin * pelsy * 10 / 254; cx = subs(pd.hDC, buf, FooterLeft, di.lpszDocName, pagenum); cx = leftmargin * pelsx * 10 / 254; TextOut(pd.hDC, cx, cy, buf, strlen(buf)); cx = subs(pd.hDC, buf, FooterCenter, di.lpszDocName, pagenum); cx = (width - cx) / 2; TextOut(pd.hDC, cx, cy, buf, strlen(buf)); cx = subs(pd.hDC, buf, FooterRight, di.lpszDocName, pagenum); cx = width - cx - rightmargin * pelsx * 10 / 254; TextOut(pd.hDC, cx, cy, buf, strlen(buf)); } SelectObject(pd.hDC, oldhFont); if (printing) if (EndPage(pd.hDC) <= 0) goto doneprinting; if (!(pd.Flags &PD_COLLATE)) { if (--colcount) { pos = savepos2; } else { colcount = pd.nCopies; pagenum++; } } else { pagenum++; } } } while (printing && (pd.Flags &PD_COLLATE) && --pd.nCopies) ; if (!printing) AbortDoc(pd.hDC); doneprinting: if (printing) EndDoc(pd.hDC); EnableWindow(hwndFrame, TRUE); if (hDlgCancel) DestroyWindow(hDlgCancel); DeleteObject(hFont); } FreeEditData(buf); } if (pd.hDC != NULL) DeleteDC(pd.hDC); if (pd.hDevMode != NULL) GlobalFree(pd.hDevMode); if (pd.hDevNames != NULL) GlobalFree(pd.hDevNames); return rv; }
BOOL PrintWindowDriver( HINSTANCE hInst, HWND hwnd, LPSTR szTitleName) { BOOL bSuccess, deleteFont = FALSE; LPCTSTR pstrBuffer ; int yChar, iLinesPerPage, iTotalLines = 0; long iCharsPerLine; int displayStart = 0; int iTotalPages; TEXTMETRIC tm ; HFONT hfont, ofont; HDC dc; LOGFONT lf; HWND hwndEdit; struct statusWindowData *theStatusData; struct displayWindowData *theDisplayData; /*===========================*/ /* Display the print dialog. */ /*===========================*/ if (! PrintDlg(&PrintDialog)) { return TRUE ; } /*===========================================*/ /* If there is nothing to print then return. */ /*===========================================*/ if (((ATOM) GetClassLongPtr(hwnd,GCW_ATOM)) == EditAtomClass) { hwndEdit = GetDlgItem(hwnd,ID_EDIT_CONTROL); iTotalLines = (short) SendMessage(hwndEdit,EM_GETLINECOUNT,0,0L); ofont = GetWindowFont(hwndEdit); } else if (((ATOM) GetClassLongPtr(hwnd,GCW_ATOM)) == StatusAtomClass) { theStatusData = (struct statusWindowData *) GetWindowLongPtr(hwnd,GWLP_USERDATA); if (theStatusData == NULL) { return TRUE; } iTotalLines = (*theStatusData->getCount)(GetCurrentEnvironment()); memset(&lf,0,sizeof(LOGFONT)); lf.lfHeight = -13; strcpy(lf.lfFaceName,"Courier New"); ofont = CreateFontIndirect(&lf); deleteFont = TRUE; } else if (((ATOM) GetClassLongPtr(hwnd,GCW_ATOM)) == DisplayAtomClass) { theDisplayData = (struct displayWindowData *) GetWindowLongPtr(hwnd,GWLP_USERDATA); if (theDisplayData == NULL) { return TRUE; } DisplayLineCountAndStart(hwnd,&iTotalLines,&displayStart); memset(&lf,0,sizeof(LOGFONT)); lf.lfHeight = -13; strcpy(lf.lfFaceName,"Courier New"); ofont = CreateFontIndirect(&lf); deleteFont = TRUE; } else { iTotalLines = 0; } if (iTotalLines == 0) { return TRUE; } /*=================================================*/ /* Create a logical font for use with the printer. */ /*=================================================*/ memset(&lf,0,sizeof(LOGFONT)); dc = GetDC(hwnd); SelectObject(dc,ofont); GetTextFace(dc,LF_FACESIZE,lf.lfFaceName); GetTextMetrics(dc,&tm); lf.lfHeight = tm.tmHeight * (GetDeviceCaps(PrintDialog.hDC,LOGPIXELSY) / GetDeviceCaps(dc,LOGPIXELSY)); lf.lfPitchAndFamily = tm.tmPitchAndFamily; hfont = CreateFontIndirect(&lf); if (hfont != NULL) { SelectObject(PrintDialog.hDC,hfont); } ReleaseDC(hwnd,dc); if (deleteFont) { DeleteFont(ofont); } GetTextMetrics(PrintDialog.hDC,&tm); yChar = tm.tmHeight + tm.tmExternalLeading; iCharsPerLine = GetDeviceCaps(PrintDialog.hDC,HORZRES) / tm.tmAveCharWidth; iLinesPerPage = GetDeviceCaps(PrintDialog.hDC,VERTRES) / yChar; iTotalPages = (iTotalLines + iLinesPerPage - 1) / iLinesPerPage; pstrBuffer = (LPCTSTR) HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, (unsigned long) iCharsPerLine + 1); /*=============================================*/ /* Disable the parent window of the dialog so */ /* all messages go to the cancel print dialog. */ /*=============================================*/ EnableWindow(hwnd,FALSE); /*=============================*/ /* Set the success/abort flags */ /* to their initial value. */ /*=============================*/ bUserAbort = FALSE; /*=================================*/ /* Create the cancel print dialog. */ /*=================================*/ hDlgPrint = CreateDialog(hInst,(LPCTSTR) "PrintDlgBox",hwnd,PrintDlgProc); SetDlgItemText(hDlgPrint,IDD_FNAME,szTitleName); /*=========================================*/ /* Set the abort procedure which handles */ /* dispatching of messages while printing. */ /*=========================================*/ SetAbortProc(PrintDialog.hDC,AbortProc); GetWindowText(hwnd,(PTSTR) di.lpszDocName,sizeof (PTSTR)); if (StartDoc (PrintDialog.hDC, &di) > 0) { bSuccess = PrintIt(iTotalPages,iLinesPerPage,iTotalLines,iCharsPerLine, yChar,pstrBuffer,hwnd); } else { bSuccess = FALSE; } if (bSuccess) { EndDoc(PrintDialog.hDC); } if (! bUserAbort) { EnableWindow(hwnd,TRUE); DestroyWindow (hDlgPrint) ; } HeapFree(GetProcessHeap(),0,(LPVOID) pstrBuffer); DeleteDC(PrintDialog.hDC); if (hfont != NULL) { DeleteFont(hfont); } return (bSuccess && (! bUserAbort)); }
static void PrintPiecesThread(void* pv) { CFrameWndEx* pFrame = (CFrameWndEx*)pv; CView* pView = pFrame->GetActiveView(); CPrintDialog PD(FALSE, PD_ALLPAGES|PD_USEDEVMODECOPIES|PD_NOPAGENUMS|PD_NOSELECTION, pFrame); if (theApp.DoPrintDialog(&PD) != IDOK) return; if (PD.m_pd.hDC == NULL) return; Project* project = lcGetActiveProject(); ObjArray<lcPiecesUsedEntry> PiecesUsed; project->GetPiecesUsed(PiecesUsed); PiecesUsed.Sort(PiecesUsedSortFunc, NULL); // gather file to print to if print-to-file selected CString strOutput; if (PD.m_pd.Flags & PD_PRINTTOFILE) { CString strDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULTEXT)); CString strPrintDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULT)); CString strFilter(MAKEINTRESOURCE(AFX_IDS_PRINTFILTER)); CString strCaption(MAKEINTRESOURCE(AFX_IDS_PRINTCAPTION)); CFileDialog dlg(FALSE, strDef, strPrintDef,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, strFilter); dlg.m_ofn.lpstrTitle = strCaption; if (dlg.DoModal() != IDOK) return; strOutput = dlg.GetPathName(); } CString DocName; char* Ext = strrchr(project->m_strTitle, '.'); DocName.Format("LeoCAD - %.*s BOM", Ext ? Ext - project->m_strTitle : strlen(project->m_strTitle), project->m_strTitle); DOCINFO docInfo; memset(&docInfo, 0, sizeof(DOCINFO)); docInfo.cbSize = sizeof(DOCINFO); docInfo.lpszDocName = DocName; CString strPortName; int nFormatID; if (strOutput.IsEmpty()) { docInfo.lpszOutput = NULL; strPortName = PD.GetPortName(); nFormatID = AFX_IDS_PRINTONPORT; } else { docInfo.lpszOutput = strOutput; AfxGetFileTitle(strOutput, strPortName.GetBuffer(_MAX_PATH), _MAX_PATH); nFormatID = AFX_IDS_PRINTTOFILE; } SetAbortProc(PD.m_pd.hDC, _AfxAbortProc); pFrame->EnableWindow(FALSE); CPrintingDialog dlgPrintStatus(NULL); CString strTemp; dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, DocName); dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PRINTERNAME, PD.GetDeviceName()); AfxFormatString1(strTemp, nFormatID, strPortName); dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PORTNAME, strTemp); dlgPrintStatus.ShowWindow(SW_SHOW); dlgPrintStatus.UpdateWindow(); if (StartDoc(PD.m_pd.hDC, &docInfo) == SP_ERROR) { pFrame->EnableWindow(TRUE); dlgPrintStatus.DestroyWindow(); AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT); return; } int ResX = GetDeviceCaps(PD.m_pd.hDC, LOGPIXELSX); int ResY = GetDeviceCaps(PD.m_pd.hDC, LOGPIXELSY); CRect RectDraw(0, 0, GetDeviceCaps(PD.m_pd.hDC, HORZRES), GetDeviceCaps(PD.m_pd.hDC, VERTRES)); DPtoLP(PD.m_pd.hDC, (LPPOINT)(RECT*)&RectDraw, 2); RectDraw.DeflateRect((int)(ResX*(float)theApp.GetProfileInt("Default","Margin Left", 50)/100.0f), (int)(ResY*(float)theApp.GetProfileInt("Default","Margin Top", 50)/100.0f), (int)(ResX*(float)theApp.GetProfileInt("Default","Margin Right", 50)/100.0f), (int)(ResY*(float)theApp.GetProfileInt("Default","Margin Bottom", 50)/100.0f)); CRect HeaderRect = RectDraw; HeaderRect.top -= (int)(ResY*theApp.GetProfileInt("Default", "Margin Top", 50) / 200.0f); HeaderRect.bottom += (int)(ResY*theApp.GetProfileInt("Default", "Margin Bottom", 50) / 200.0f); int RowsPerPage = AfxGetApp()->GetProfileInt("Default", "Catalog Rows", 10); int ColsPerPage = AfxGetApp()->GetProfileInt("Default", "Catalog Columns", 3); int PicHeight = RectDraw.Height() / RowsPerPage; int PicWidth = RectDraw.Width() / ColsPerPage; int TotalRows = (PiecesUsed.GetSize() + ColsPerPage - 1) / ColsPerPage; int TotalPages = (TotalRows + RowsPerPage - 1) / RowsPerPage; int RowHeight = RectDraw.Height() / RowsPerPage; int ColWidth = RectDraw.Width() / ColsPerPage; PD.m_pd.nMinPage = 1; PD.m_pd.nMaxPage = TotalPages + 1; UINT EndPage = PD.m_pd.nToPage; UINT StartPage = PD.m_pd.nFromPage; if (PD.PrintAll()) { EndPage = PD.m_pd.nMaxPage; StartPage = PD.m_pd.nMinPage; } lcClamp(EndPage, PD.m_pd.nMinPage, PD.m_pd.nMaxPage); lcClamp(StartPage, PD.m_pd.nMinPage, PD.m_pd.nMaxPage); int StepPage = (EndPage >= StartPage) ? 1 : -1; VERIFY(strTemp.LoadString(AFX_IDS_PRINTPAGENUM)); // begin page printing loop BOOL bError = FALSE; // Creating Compatible Memory Device Context CDC *pMemDC = new CDC; if (!pMemDC->CreateCompatibleDC(pView->GetDC())) return; BITMAPINFO bi; ZeroMemory(&bi, sizeof(BITMAPINFO)); bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi.bmiHeader.biWidth = PicWidth; bi.bmiHeader.biHeight = PicHeight; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 24; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = PicWidth * PicHeight * 3; bi.bmiHeader.biXPelsPerMeter = 2925; bi.bmiHeader.biYPelsPerMeter = 2925; bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; LPBITMAPINFOHEADER lpbi[1]; HBITMAP hBm, hBmOld; hBm = CreateDIBSection(pView->GetDC()->GetSafeHdc(), &bi, DIB_RGB_COLORS, (void **)&lpbi, NULL, (DWORD)0); if (!hBm) return; hBmOld = (HBITMAP)::SelectObject(pMemDC->GetSafeHdc(), hBm); PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI, PFD_TYPE_RGBA, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; int pixelformat = ChoosePixelFormat(pMemDC->m_hDC, &pfd); DescribePixelFormat(pMemDC->m_hDC, pixelformat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); SetPixelFormat(pMemDC->m_hDC, pixelformat, &pfd); HGLRC hmemrc = wglCreateContext(pMemDC->GetSafeHdc()); wglMakeCurrent(pMemDC->GetSafeHdc(), hmemrc); GL_DisableVertexBufferObject(); float Aspect = (float)PicWidth/(float)PicHeight; glViewport(0, 0, PicWidth, PicHeight); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(0.5f, 0.1f); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(1, 1, 1, 1); LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); lf.lfHeight = -MulDiv(12, ResY, 72); lf.lfWeight = FW_REGULAR; lf.lfCharSet = DEFAULT_CHARSET; lf.lfQuality = PROOF_QUALITY; strcpy (lf.lfFaceName , "Arial"); HFONT HeaderFont = CreateFontIndirect(&lf); HFONT OldFont = (HFONT)SelectObject(PD.m_pd.hDC, HeaderFont); SetBkMode(PD.m_pd.hDC, TRANSPARENT); SetTextColor(PD.m_pd.hDC, 0x000000); SetTextAlign(PD.m_pd.hDC, TA_CENTER|TA_NOUPDATECP); DWORD PrintOptions = AfxGetApp()->GetProfileInt("Settings", "Print", PRINT_NUMBERS | PRINT_BORDER/*|PRINT_NAMES*/); bool DrawNames = 1;//(PrintOptions & PRINT_NAMES) != 0; bool Horizontal = 1;//(PrintOptions & PRINT_HORIZONTAL) != 0; pMemDC->SetTextColor(0x000000); pMemDC->SetBkMode(TRANSPARENT); // lf.lfHeight = -MulDiv(40, GetDeviceCaps(pMemDC->m_hDC, LOGPIXELSY), 72); // lf.lfWeight = FW_BOLD; HFONT CatalogFont = CreateFontIndirect(&lf); lf.lfHeight = -MulDiv(80, GetDeviceCaps(pMemDC->m_hDC, LOGPIXELSY), 72); HFONT CountFont = CreateFontIndirect(&lf); HFONT OldMemFont = (HFONT)SelectObject(pMemDC->m_hDC, CatalogFont); HPEN hpOld = (HPEN)SelectObject(pMemDC->m_hDC, GetStockObject(BLACK_PEN)); for (UINT CurPage = StartPage; CurPage != EndPage; CurPage += StepPage) { TCHAR szBuf[80]; wsprintf(szBuf, strTemp, CurPage); dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PAGENUM, szBuf); if (::StartPage(PD.m_pd.hDC) < 0) { bError = TRUE; break; } // Draw header and footer. SelectObject(PD.m_pd.hDC, HeaderFont); CString Header; UINT Align; FormatHeader(Header, Align, AfxGetApp()->GetProfileString("Default", "Catalog Header", ""), project->m_strTitle, project->m_strAuthor, project->m_strDescription, CurPage, TotalPages); Align |= DT_TOP|DT_SINGLELINE; DrawText(PD.m_pd.hDC, (LPCTSTR)Header, Header.GetLength(), HeaderRect, Align); FormatHeader(Header, Align, AfxGetApp()->GetProfileString("Default", "Catalog Footer", "Page &P"), project->m_strTitle, project->m_strAuthor, project->m_strDescription, CurPage, TotalPages); Align |= DT_BOTTOM|DT_SINGLELINE; DrawText(PD.m_pd.hDC, (LPCTSTR)Header, Header.GetLength(), HeaderRect, Align); int StartPiece = (CurPage - 1) * RowsPerPage * ColsPerPage; int EndPiece = lcMin(StartPiece + RowsPerPage * ColsPerPage, PiecesUsed.GetSize()); for (int CurPiece = StartPiece; CurPiece < EndPiece; CurPiece++) { FillRect(pMemDC->m_hDC, CRect(0, PicHeight, PicWidth, 0), (HBRUSH)GetStockObject(WHITE_BRUSH)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); PieceInfo* pInfo = PiecesUsed[CurPiece].Info; pInfo->ZoomExtents(30.0f, Aspect); pInfo->RenderPiece(PiecesUsed[CurPiece].ColorIndex); glFinish(); // Draw description text at the bottom. CRect TextRect(0, 0, PicWidth, PicHeight); if (DrawNames) { SelectObject(pMemDC->m_hDC, CatalogFont); pMemDC->DrawText(pInfo->m_strDescription, strlen(pInfo->m_strDescription), TextRect, DT_CALCRECT | DT_WORDBREAK); TextRect.OffsetRect(0, PicHeight - TextRect.Height() - 5); pMemDC->DrawText(pInfo->m_strDescription, strlen(pInfo->m_strDescription), TextRect, DT_WORDBREAK); } // Draw count. SelectObject(pMemDC->m_hDC, CountFont); TextRect = CRect(0, 0, PicWidth, TextRect.top); TextRect.DeflateRect(5, 5); char CountStr[16]; sprintf(CountStr, "%dx", PiecesUsed[CurPiece].Count); pMemDC->DrawText(CountStr, strlen(CountStr), TextRect, DT_BOTTOM | DT_LEFT | DT_SINGLELINE); LPBITMAPINFOHEADER lpbi[1]; lpbi[0] = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(hBm, 24)); BITMAPINFO bi; ZeroMemory(&bi, sizeof(BITMAPINFO)); memcpy (&bi.bmiHeader, lpbi[0], sizeof(BITMAPINFOHEADER)); SetStretchBltMode(PD.m_pd.hDC, COLORONCOLOR); int CurRow, CurCol; if (Horizontal) { CurRow = (CurPiece - StartPiece) / ColsPerPage; CurCol = (CurPiece - StartPiece) % ColsPerPage; } else { CurRow = (CurPiece - StartPiece) % RowsPerPage; CurCol = (CurPiece - StartPiece) / RowsPerPage; } int Left = RectDraw.left + ColWidth * CurCol + (ColWidth - PicWidth) / 2; int Top = RectDraw.top + RowHeight * CurRow + (RowHeight - PicHeight) / 2; StretchDIBits(PD.m_pd.hDC, Left, Top, PicWidth, PicHeight, 0, 0, PicWidth, PicHeight, (LPBYTE)lpbi[0] + lpbi[0]->biSize + lpbi[0]->biClrUsed * sizeof(RGBQUAD), &bi, DIB_RGB_COLORS, SRCCOPY); if (lpbi[0]) GlobalFreePtr(lpbi[0]); } if (::EndPage(PD.m_pd.hDC) < 0 || !_AfxAbortProc(PD.m_pd.hDC, 0)) { bError = TRUE; break; } } SelectObject(pMemDC->m_hDC, hpOld); SelectObject(PD.m_pd.hDC, OldFont); DeleteObject(HeaderFont); SelectObject(pMemDC->m_hDC, OldMemFont); DeleteObject(CatalogFont); DeleteObject(CountFont); GL_EnableVertexBufferObject(); wglMakeCurrent(NULL, NULL); wglDeleteContext(hmemrc); SelectObject(pMemDC->GetSafeHdc(), hBmOld); DeleteObject(hBm); delete pMemDC; if (!bError) EndDoc(PD.m_pd.hDC); else AbortDoc(PD.m_pd.hDC); pFrame->EnableWindow(); dlgPrintStatus.DestroyWindow(); if (PD.m_pd.hDC != NULL) { ::DeleteDC(PD.m_pd.hDC); PD.m_pd.hDC = NULL; } }
static void test_abort_proc(void) { HDC print_dc; RECT rect = {0, 0, 100, 100}; DOCINFOA doc_info = {0}; PRINTDLGA pd = {0}; char filename[MAX_PATH]; if (!GetTempFileNameA(".", "prn", 0, filename)) { skip("Failed to create a temporary file name\n"); return; } pd.lStructSize = sizeof(pd); pd.Flags = PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC | PD_PRINTTOFILE; pd.nFromPage = 1; pd.nToPage = 1; pd.nCopies = 1; if (!PrintDlgA(&pd)) { skip("No default printer available.\n"); ok(DeleteFileA(filename), "Failed to delete temporary file\n"); return; } ok(pd.hDC != NULL, "PrintDlg didn't return a DC.\n"); if (!(print_dc = pd.hDC)) { ok(DeleteFileA(filename), "Failed to delete temporary file\n"); return; } ok(SetAbortProc(print_dc, abort_proc) > 0, "SetAbortProc failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by SetAbortProc.\n"); abort_proc_called = FALSE; doc_info.cbSize = sizeof(doc_info); doc_info.lpszDocName = "Some document"; doc_info.lpszOutput = filename; ok(StartDocA(print_dc, &doc_info) > 0, "StartDocA failed\n"); ok(abort_proc_called, "AbortProc didn't get called by StartDoc.\n"); abort_proc_called = FALSE; ok(StartPage(print_dc) > 0, "StartPage failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by StartPage.\n"); abort_proc_called = FALSE; ok(FillRect(print_dc, &rect, (HBRUSH)(COLOR_BACKGROUND + 1)), "FillRect failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by StretchBlt.\n"); abort_proc_called = FALSE; ok(EndPage(print_dc) > 0, "EndPage failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by EndPage.\n"); abort_proc_called = FALSE; ok(EndDoc(print_dc) > 0, "EndDoc failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by EndDoc.\n"); abort_proc_called = FALSE; ok(DeleteDC(print_dc), "DeleteDC failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by DeleteDC.\n"); abort_proc_called = FALSE; ok(DeleteFileA(filename), "Failed to delete temporary file\n"); }
/* * @unimplemented */ INT WINAPI Escape( _In_ HDC hdc, _In_ INT nEscape, _In_ INT cbInput, _In_ LPCSTR lpvInData, _Out_ LPVOID lpvOutData) { INT retValue = SP_ERROR; ULONG ulObjType; ulObjType = GDI_HANDLE_GET_TYPE(hdc); if (ulObjType == GDILoObjType_LO_METADC16_TYPE) { return METADC16_Escape(hdc, nEscape, cbInput, lpvInData, lpvOutData); } switch (nEscape) { case ABORTDOC: /* Note: Windows checks if the handle has any user data for the ABORTDOC command * ReactOS copies this behavior to be compatible with windows 2003 */ if (GdiGetDcAttr(hdc) == NULL) { GdiSetLastError(ERROR_INVALID_HANDLE); retValue = FALSE; } else { retValue = AbortDoc(hdc); } break; case DRAFTMODE: case FLUSHOUTPUT: case SETCOLORTABLE: /* Note 1: DRAFTMODE, FLUSHOUTPUT, SETCOLORTABLE are outdated */ /* Note 2: Windows checks if the handle has any user data for the DRAFTMODE, FLUSHOUTPUT, SETCOLORTABLE commands * ReactOS copies this behavior to be compatible with windows 2003 */ if (GdiGetDcAttr(hdc) == NULL) { GdiSetLastError(ERROR_INVALID_HANDLE); } retValue = FALSE; break; case SETABORTPROC: /* Note: Windows checks if the handle has any user data for the SETABORTPROC command * ReactOS copies this behavior to be compatible with windows 2003 */ if (GdiGetDcAttr(hdc) == NULL) { GdiSetLastError(ERROR_INVALID_HANDLE); retValue = FALSE; } retValue = SetAbortProc(hdc, (ABORTPROC)lpvInData); break; case GETCOLORTABLE: retValue = GetSystemPaletteEntries(hdc, (UINT)*lpvInData, 1, (LPPALETTEENTRY)lpvOutData); if (!retValue) { retValue = SP_ERROR; } break; case ENDDOC: /* Note: Windows checks if the handle has any user data for the ENDDOC command * ReactOS copies this behavior to be compatible with windows 2003 */ if (GdiGetDcAttr(hdc) == NULL) { GdiSetLastError(ERROR_INVALID_HANDLE); retValue = FALSE; } retValue = EndDoc(hdc); break; case GETSCALINGFACTOR: /* Note GETSCALINGFACTOR is outdated have been replace by GetDeviceCaps */ if (ulObjType == GDI_OBJECT_TYPE_DC) { if (lpvOutData) { PPOINT ptr = (PPOINT)lpvOutData; ptr->x = 0; ptr->y = 0; } } retValue = FALSE; break; case GETEXTENDEDTEXTMETRICS: retValue = GetETM(hdc, (EXTTEXTMETRIC *)lpvOutData) != 0; break; case STARTDOC: { DOCINFOA di; /* Note: Windows checks if the handle has any user data for the STARTDOC command * ReactOS copies this behavior to be compatible with windows 2003 */ if (GdiGetDcAttr(hdc) == NULL) { GdiSetLastError(ERROR_INVALID_HANDLE); retValue = FALSE; } di.cbSize = sizeof(DOCINFOA); di.lpszOutput = 0; di.lpszDatatype = 0; di.fwType = 0; di.lpszDocName = lpvInData; /* NOTE : doc for StartDocA/W at msdn http://msdn2.microsoft.com/en-us/library/ms535793(VS.85).aspx */ retValue = StartDocA(hdc, &di); /* Check if StartDocA failed */ if (retValue < 0) { { retValue = GetLastError(); /* Translate StartDocA error code to STARTDOC error code * see msdn http://msdn2.microsoft.com/en-us/library/ms535472.aspx */ switch(retValue) { case ERROR_NOT_ENOUGH_MEMORY: retValue = SP_OUTOFMEMORY; break; case ERROR_PRINT_CANCELLED: retValue = SP_USERABORT; break; case ERROR_DISK_FULL: retValue = SP_OUTOFDISK; break; default: retValue = SP_ERROR; break; } } } } break; default: UNIMPLEMENTED; SetLastError(ERROR_CALL_NOT_IMPLEMENTED); } return retValue; }
static void test_abort_proc(void) { HDC print_dc; RECT rect = {0, 0, 100, 100}; DOCINFOA doc_info = {0}; PRINTDLGA pd = {0}; char filename[MAX_PATH]; int job_id; if (!GetTempFileNameA(".", "prn", 0, filename)) { skip("Failed to create a temporary file name\n"); return; } pd.lStructSize = sizeof(pd); pd.Flags = PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC | PD_PRINTTOFILE; pd.nFromPage = 1; pd.nToPage = 1; pd.nCopies = 1; if (!PrintDlgA(&pd)) { skip("No default printer available.\n"); goto end; } GlobalFree(pd.hDevMode); GlobalFree(pd.hDevNames); ok(pd.hDC != NULL, "PrintDlg didn't return a DC.\n"); if (!(print_dc = pd.hDC)) goto end; ok(SetAbortProc(print_dc, abort_proc) > 0, "SetAbortProc failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by SetAbortProc.\n"); abort_proc_called = FALSE; doc_info.cbSize = sizeof(doc_info); doc_info.lpszDocName = "Some document"; doc_info.lpszOutput = filename; job_id = StartDocA(print_dc, &doc_info); ok(job_id > 0 || GetLastError() == ERROR_SPL_NO_STARTDOC, /* Vista can fail with this error when using the XPS driver */ "StartDocA failed ret %d gle %d\n", job_id, GetLastError()); if(job_id <= 0) { skip("StartDoc failed\n"); goto end; } /* StartDoc may or may not call abort proc */ abort_proc_called = FALSE; ok(StartPage(print_dc) > 0, "StartPage failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by StartPage.\n"); abort_proc_called = FALSE; /* following functions sometimes call abort proc too */ ok(FillRect(print_dc, &rect, (HBRUSH)(COLOR_BACKGROUND + 1)), "FillRect failed\n"); ok(EndPage(print_dc) > 0, "EndPage failed\n"); ok(EndDoc(print_dc) > 0, "EndDoc failed\n"); abort_proc_called = FALSE; ok(DeleteDC(print_dc), "DeleteDC failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by DeleteDC.\n"); abort_proc_called = FALSE; end: SetLastError(0xdeadbeef); if(!DeleteFileA(filename)) trace("Failed to delete temporary file (err = %x)\n", GetLastError()); }
static void PrintCatalogThread (CWnd* pParent, CFrameWndEx* pMainFrame) { CCADView* pView = (CCADView*)pMainFrame->GetActiveView(); CPrintDialog* PD = new CPrintDialog(FALSE, PD_ALLPAGES|PD_USEDEVMODECOPIES|PD_NOSELECTION|PD_ENABLEPRINTHOOK, pParent); lcPiecesLibrary *pLib = lcGetPiecesLibrary(); int bricks = 0; for (int j = 0; j < pLib->mPieces.GetSize(); j++) if (pLib->mPieces[j]->m_strDescription[0] != '~') bricks++; int rows = theApp.GetProfileInt("Default", "Catalog Rows", 10); int cols = theApp.GetProfileInt("Default", "Catalog Columns", 3); PD->m_pd.lpfnPrintHook = PrintHookProc; PD->m_pd.nFromPage = PD->m_pd.nMinPage = 1; PD->m_pd.nMaxPage = bricks/(rows*cols); if (bricks%(rows*cols) != 0) PD->m_pd.nMaxPage++; PD->m_pd.nToPage = PD->m_pd.nMaxPage; PD->m_pd.lCustData= (LONG)pMainFrame; // bring up the print dialog and allow user to change things if (theApp.DoPrintDialog(PD) != IDOK) return; if (PD->m_pd.hDC == NULL) return; // update page range rows = theApp.GetProfileInt("Default","Catalog Rows", 10); cols = theApp.GetProfileInt("Default","Catalog Columns", 3); PD->m_pd.nMaxPage = bricks/(rows*cols); if (bricks%(rows*cols) != 0) PD->m_pd.nMaxPage++; // gather file to print to if print-to-file selected CString strOutput; if (PD->m_pd.Flags & PD_PRINTTOFILE) { // construct CFileDialog for browsing CString strDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULTEXT)); CString strPrintDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULT)); CString strFilter(MAKEINTRESOURCE(AFX_IDS_PRINTFILTER)); CString strCaption(MAKEINTRESOURCE(AFX_IDS_PRINTCAPTION)); CFileDialog dlg(FALSE, strDef, strPrintDef, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, strFilter); dlg.m_ofn.lpstrTitle = strCaption; if (dlg.DoModal() != IDOK) return; // set output device to resulting path name strOutput = dlg.GetPathName(); } DOCINFO docInfo; memset(&docInfo, 0, sizeof(DOCINFO)); docInfo.cbSize = sizeof(DOCINFO); docInfo.lpszDocName = "LeoCAD pieces catalog"; CString strPortName; int nFormatID; if (strOutput.IsEmpty()) { docInfo.lpszOutput = NULL; strPortName = PD->GetPortName(); nFormatID = AFX_IDS_PRINTONPORT; } else { docInfo.lpszOutput = strOutput; AfxGetFileTitle(strOutput, strPortName.GetBuffer(_MAX_PATH), _MAX_PATH); nFormatID = AFX_IDS_PRINTTOFILE; } // setup the printing DC SetAbortProc(PD->m_pd.hDC, _AfxAbortProc); // disable main window while printing & init printing status dialog pParent->EnableWindow(FALSE); CPrintingDialog dlgPrintStatus(NULL); CString strTemp; dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, "LeoCAD parts catalog"); dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PRINTERNAME, PD->GetDeviceName()); AfxFormatString1(strTemp, nFormatID, strPortName); dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PORTNAME, strTemp); dlgPrintStatus.ShowWindow(SW_SHOW); dlgPrintStatus.UpdateWindow(); // start document printing process if (StartDoc(PD->m_pd.hDC, &docInfo) == SP_ERROR) { pParent->EnableWindow(TRUE); dlgPrintStatus.DestroyWindow(); AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT); return; } // Guarantee values are in the valid range UINT nEndPage = PD->m_pd.nToPage; UINT nStartPage = PD->m_pd.nFromPage; if (PD->PrintAll()) { nEndPage = PD->m_pd.nMaxPage; nStartPage = PD->m_pd.nMinPage; } if (nEndPage < PD->m_pd.nMinPage) nEndPage = PD->m_pd.nMinPage; if (nEndPage > PD->m_pd.nMaxPage) nEndPage = PD->m_pd.nMaxPage; if (nStartPage < PD->m_pd.nMinPage) nStartPage = PD->m_pd.nMinPage; if (nStartPage > PD->m_pd.nMaxPage) nStartPage = PD->m_pd.nMaxPage; int nStep = (nEndPage >= nStartPage) ? 1 : -1; nEndPage = nEndPage + nStep; VERIFY(strTemp.LoadString(AFX_IDS_PRINTPAGENUM)); // begin page printing loop BOOL bError = FALSE; // set up drawing rect to entire page (in logical coordinates) CRect rectDraw (0, 0, GetDeviceCaps(PD->m_pd.hDC, HORZRES), GetDeviceCaps(PD->m_pd.hDC, VERTRES)); DPtoLP(PD->m_pd.hDC, (LPPOINT)(RECT*)&rectDraw, 2); rectDraw.DeflateRect( GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSX)*theApp.GetProfileInt("Default","Margin Left", 50)/100, GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSY)*theApp.GetProfileInt("Default","Margin Top", 50)/100, GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSX)*theApp.GetProfileInt("Default","Margin Right", 50)/100, GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSY)*theApp.GetProfileInt("Default","Margin Bottom", 50)/100); int w = rectDraw.Width()/cols; int h = rectDraw.Height()/rows; // Creating Compatible Memory Device Context CDC *pMemDC = new CDC; if (!pMemDC->CreateCompatibleDC(pView->GetDC())) return; // Preparing bitmap header for DIB section BITMAPINFO bi; ZeroMemory(&bi, sizeof(BITMAPINFO)); bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi.bmiHeader.biWidth = w; bi.bmiHeader.biHeight = h; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 24; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = w * h * (24/8); bi.bmiHeader.biXPelsPerMeter = 2925; bi.bmiHeader.biYPelsPerMeter = 2925; bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; LPBITMAPINFOHEADER lpbi[1]; // Creating a DIB surface HBITMAP hBm, hBmOld; hBm = CreateDIBSection(pView->GetDC()->GetSafeHdc(), &bi, DIB_RGB_COLORS, (void **)&lpbi, NULL, (DWORD)0); if (!hBm) return; // Selecting the DIB Surface hBmOld = (HBITMAP)::SelectObject(pMemDC->GetSafeHdc(), hBm); if (!hBmOld) return; // Setting up a Pixel format for the DIB surface PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1,PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI, PFD_TYPE_RGBA, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; int pixelformat = ChoosePixelFormat(pMemDC->m_hDC, &pfd); DescribePixelFormat(pMemDC->m_hDC, pixelformat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); SetPixelFormat(pMemDC->m_hDC, pixelformat, &pfd); // Creating a OpenGL context HGLRC hmemrc = wglCreateContext(pMemDC->GetSafeHdc()); // Setting up the current OpenGL context GL_DisableVertexBufferObject(); wglMakeCurrent(pMemDC->GetSafeHdc(), hmemrc); double aspect = (float)w/(float)h; glMatrixMode(GL_MODELVIEW); glViewport(0, 0, w, h); // Sort pieces by description struct BRICKSORT { char name[64]; int actual; struct BRICKSORT *next; } start, *node, *previous, *news; start.next = NULL; for (int j = 0; j < pLib->mPieces.GetSize(); j++) { char* desc = pLib->mPieces[j]->m_strDescription; if (desc[0] != '~') continue; // Find the correct location previous = &start; node = start.next; while ((node) && (strcmp(desc, node->name) > 0)) { node = node->next; previous = previous->next; } news = (struct BRICKSORT*) malloc(sizeof(struct BRICKSORT)); news->next = node; previous->next = news; strcpy(news->name, desc); news->actual = j; } node = start.next; if (PD->PrintRange()) { for (int j = 0; j < (int)(nStartPage - 1)*rows*cols; j++) if (node) node = node->next; } LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); lf.lfHeight = -MulDiv(12, GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSY), 72); lf.lfWeight = FW_REGULAR; lf.lfCharSet = DEFAULT_CHARSET; lf.lfQuality = PROOF_QUALITY; strcpy (lf.lfFaceName , "Arial"); HFONT HeaderFont = CreateFontIndirect(&lf); HFONT OldFont = (HFONT)SelectObject(PD->m_pd.hDC, HeaderFont); SetBkMode(PD->m_pd.hDC, TRANSPARENT); SetTextColor(PD->m_pd.hDC, 0x000000); SetTextAlign (PD->m_pd.hDC, TA_TOP|TA_LEFT|TA_NOUPDATECP); SetTextColor (pMemDC->m_hDC, 0x000000); lf.lfHeight = -MulDiv(10, GetDeviceCaps(pMemDC->m_hDC, LOGPIXELSY), 72); lf.lfWeight = FW_BOLD; HFONT CatalogFont = CreateFontIndirect(&lf); HFONT OldMemFont = (HFONT)SelectObject(pMemDC->m_hDC, CatalogFont); HPEN hpOld = (HPEN)SelectObject(pMemDC->m_hDC,(HPEN)GetStockObject(BLACK_PEN)); for (UINT nCurPage = nStartPage; nCurPage != nEndPage; nCurPage += nStep) { // write current page TCHAR szBuf[80]; wsprintf(szBuf, strTemp, nCurPage); dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PAGENUM, szBuf); // attempt to start the current page if (StartPage(PD->m_pd.hDC) < 0) { bError = TRUE; break; } int printed = 0; // page successfully started, so now render the page for (int r = 0; r < rows; r++) for (int c = 0; c < cols; c++) { if (node == NULL) continue; printed++; glDepthFunc(GL_LEQUAL); glClearColor(1,1,1,1); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glDisable(GL_DITHER); glShadeModel(GL_FLAT); lcSetColor(lcGetActiveProject()->GetCurrentColor()); // dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, node->name); node = node->next; PieceInfo* pInfo = pLib->mPieces[node->actual]; pInfo->ZoomExtents(30.0f, (float)aspect); float pos[4] = { 0, 0, 10, 0 }; glLightfv(GL_LIGHT0, GL_POSITION, pos); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); FillRect(pMemDC->m_hDC, CRect(0,h,w,0), (HBRUSH)GetStockObject(WHITE_BRUSH)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); pInfo->RenderPiece(lcGetActiveProject()->GetCurrentColor()); glFlush(); TextOut (pMemDC->m_hDC, 5, 5, pInfo->m_strDescription, strlen(pInfo->m_strDescription)); // BitBlt(PD->m_pd.hDC, rectDraw.left+(w*c), rectDraw.top+(h*r), w, h, pMemDC->m_hDC, 0, 0, SRCCOPY); LPBITMAPINFOHEADER lpbi[1]; lpbi[0] = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(hBm, 24)); BITMAPINFO bi; ZeroMemory(&bi, sizeof(BITMAPINFO)); memcpy (&bi.bmiHeader, lpbi[0], sizeof(BITMAPINFOHEADER)); SetStretchBltMode(PD->m_pd.hDC, COLORONCOLOR); StretchDIBits(PD->m_pd.hDC, rectDraw.left+(w*c), rectDraw.top+(h*r), w, h, 0, 0, w, h, (LPBYTE) lpbi[0] + lpbi[0]->biSize + lpbi[0]->biClrUsed * sizeof(RGBQUAD), &bi, DIB_RGB_COLORS, SRCCOPY); if (lpbi[0]) GlobalFreePtr(lpbi[0]); } DWORD dwPrint = theApp.GetProfileInt("Settings","Print", PRINT_NUMBERS|PRINT_BORDER); if (dwPrint & PRINT_BORDER) for (int r = 0; r < rows; r++) for (int c = 0; c < cols; c++) { if (printed == 0) continue; printed--; if (r == 0) { MoveToEx(PD->m_pd.hDC, rectDraw.left+(w*c), rectDraw.top+(h*r), NULL); LineTo(PD->m_pd.hDC, rectDraw.left+(w*(c+1)), rectDraw.top+(h*r)); } if (c == 0) { MoveToEx(PD->m_pd.hDC, rectDraw.left+(w*c), rectDraw.top+(h*r), NULL); LineTo(PD->m_pd.hDC, rectDraw.left+(w*c), rectDraw.top+(h*(r+1))); } MoveToEx(PD->m_pd.hDC, rectDraw.left+(w*(c+1)), rectDraw.top+(h*r), NULL); LineTo(PD->m_pd.hDC, rectDraw.left+(w*(c+1)), rectDraw.top+(h*(r+1))); MoveToEx(PD->m_pd.hDC, rectDraw.left+(w*c), rectDraw.top+(h*(r+1)), NULL); LineTo(PD->m_pd.hDC, rectDraw.left+(w*(c+1)), rectDraw.top+(h*(r+1))); } CRect r2 = rectDraw; r2.top -= GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSY)*theApp.GetProfileInt("Default","Margin Top", 50)/200; r2.bottom += GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSY)*theApp.GetProfileInt("Default","Margin Bottom", 50)/200; pView->PrintHeader(FALSE, PD->m_pd.hDC, r2, nCurPage, nEndPage, TRUE); pView->PrintHeader(TRUE, PD->m_pd.hDC, r2, nCurPage, nEndPage, TRUE); if (EndPage(PD->m_pd.hDC) < 0 || !_AfxAbortProc(PD->m_pd.hDC, 0)) { bError = TRUE; break; } } SelectObject(pMemDC->m_hDC, hpOld); SelectObject(PD->m_pd.hDC, OldFont); DeleteObject(HeaderFont); SelectObject(pMemDC->m_hDC, OldMemFont); DeleteObject(CatalogFont); node = start.next; while (node) { previous = node; node = node->next; free(previous); } GL_EnableVertexBufferObject(); wglMakeCurrent(NULL, NULL); wglDeleteContext(hmemrc); SelectObject(pMemDC->GetSafeHdc(), hBmOld); DeleteObject(hBm); delete pMemDC; // cleanup document printing process if (!bError) EndDoc(PD->m_pd.hDC); else AbortDoc(PD->m_pd.hDC); pParent->EnableWindow(); dlgPrintStatus.DestroyWindow(); if (PD != NULL && PD->m_pd.hDC != NULL) { ::DeleteDC(PD->m_pd.hDC); PD->m_pd.hDC = NULL; } delete PD; }
/* GetWindowLong(hwnd, 4) must be available for use */ void WDPROC DumpPrinter(HWND hwnd, LPSTR szAppName, LPSTR szFileName) { HDC printer; PRINTDLG pd; GP_PRINT pr; DOCINFO di; char *buf; WORD *bufcount; int count; FILE *f; long lsize; long ldone; char pcdone[10]; memset(&pd, 0, sizeof(PRINTDLG)); pd.lStructSize = sizeof(PRINTDLG); pd.hwndOwner = hwnd; pd.Flags = PD_PRINTSETUP | PD_RETURNDC; if ((f = fopen(szFileName, "rb")) == (FILE *)NULL) return; fseek(f, 0L, SEEK_END); lsize = ftell(f); if (lsize <= 0) lsize = 1; fseek(f, 0L, SEEK_SET); ldone = 0; if (PrintDlg(&pd)) { printer = pd.hDC; if (printer != (HDC)NULL) { pr.hdcPrn = printer; SetWindowLong(hwnd, 4, (LONG)((GP_LPPRINT)&pr)); PrintRegister((GP_LPPRINT)&pr); if ( (buf = malloc(4096+2)) != (char *)NULL ) { bufcount = (WORD *)buf; EnableWindow(hwnd,FALSE); pr.bUserAbort = FALSE; /* is parent set correctly */ pr.hDlgPrint = CreateDialogParam(hdllInstance, "CancelDlgBox", hwnd, PrintDlgProc, (LPARAM) szAppName); SetAbortProc(printer, PrintAbortProc); di.cbSize = sizeof(DOCINFO); di.lpszDocName = szAppName; di.lpszOutput = NULL; if (StartDoc(printer, &di) > 0) { while ( pr.hDlgPrint && !pr.bUserAbort && (count = fread(buf+2, 1, 4096, f)) != 0 ) { *bufcount = count; Escape(printer, PASSTHROUGH, count+2, (LPSTR)buf, NULL); ldone += count; sprintf(pcdone, "%d%% done", (int) (ldone * 100 / lsize)); SetWindowText(GetDlgItem(pr.hDlgPrint, CANCEL_PCDONE), pcdone); if (pr.bUserAbort) AbortDoc(printer); else EndDoc(printer); } if (!pr.bUserAbort) { EnableWindow(hwnd,TRUE); DestroyWindow(pr.hDlgPrint); } free(buf); } } DeleteDC(printer); SetWindowLong(hwnd, 4, (LONG)(0L)); PrintUnregister((GP_LPPRINT)&pr); } } fclose(f); }
/* Open the win_pr2 driver */ static int win_pr2_open(gx_device * dev) { int code; int depth; PRINTDLG pd; POINT offset; POINT size; float m[4]; FILE *pfile; DOCINFO docinfo; float ratio = 1.0; win_pr2_copy_check(wdev); /* get a HDC for the printer */ if ((wdev->win32_hdevmode) && (wdev->win32_hdevnames)) { /* The user has already had the opportunity to choose the output */ /* file interactively. Just use the specified parameters. */ LPDEVMODE devmode = (LPDEVMODE) GlobalLock(wdev->win32_hdevmode); LPDEVNAMES devnames = (LPDEVNAMES) GlobalLock(wdev->win32_hdevnames); const char* driver = (char*)(devnames)+(devnames->wDriverOffset); const char* device = (char*)(devnames)+(devnames->wDeviceOffset); const char* output = (char*)(devnames)+(devnames->wOutputOffset); wdev->hdcprn = CreateDC(driver, device, output, devmode); GlobalUnlock(wdev->win32_hdevmode); GlobalUnlock(wdev->win32_hdevnames); if (wdev->hdcprn == NULL) { return gs_error_Fatal; } } else if (!win_pr2_getdc(wdev)) { /* couldn't get a printer from -sOutputFile= */ /* Prompt with dialog box */ LPDEVMODE devmode = NULL; memset(&pd, 0, sizeof(pd)); pd.lStructSize = sizeof(pd); pd.hwndOwner = PARENT_WINDOW; pd.Flags = PD_RETURNDC; pd.nMinPage = wdev->doc_page_begin; pd.nMaxPage = wdev->doc_page_end; pd.nFromPage = wdev->user_page_begin; pd.nToPage = wdev->user_page_end; pd.nCopies = wdev->user_copies; if (!PrintDlg(&pd)) { /* device not opened - exit ghostscript */ return gs_error_Fatal; /* exit Ghostscript cleanly */ } devmode = GlobalLock(pd.hDevMode); win_pr2_update_dev(wdev,devmode); GlobalUnlock(pd.hDevMode); if (wdev->win32_hdevmode) GlobalFree(wdev->win32_hdevmode); if (wdev->win32_hdevnames) GlobalFree(wdev->win32_hdevnames); wdev->hdcprn = pd.hDC; wdev->win32_hdevmode = pd.hDevMode; wdev->win32_hdevnames = pd.hDevNames; pd.hDevMode = NULL; pd.hDevNames = NULL; } if (!(GetDeviceCaps(wdev->hdcprn, RASTERCAPS) != RC_DIBTODEV)) { errprintf(dev->memory, "Windows printer does not have RC_DIBTODEV\n"); DeleteDC(wdev->hdcprn); return gs_error_limitcheck; } /* initialise printer, install abort proc */ wdev->lpfnAbortProc = (DLGPROC) AbortProc2; SetAbortProc(wdev->hdcprn, (ABORTPROC) wdev->lpfnAbortProc); /* * Some versions of the Windows headers include lpszDatatype and fwType, * and some don't. Since we want to set these fields to zero anyway, * we just start by zeroing the whole structure. */ memset(&docinfo, 0, sizeof(docinfo)); docinfo.cbSize = sizeof(docinfo); docinfo.lpszDocName = wdev->doc_name; /*docinfo.lpszOutput = NULL;*/ /*docinfo.lpszDatatype = NULL;*/ /*docinfo.fwType = 0;*/ if (docinfo.lpszDocName[0] == 0) { docinfo.lpszDocName = "Ghostscript output"; } if (StartDoc(wdev->hdcprn, &docinfo) <= 0) { errprintf(dev->memory, "Printer StartDoc failed (error %08x)\n", GetLastError()); DeleteDC(wdev->hdcprn); return gs_error_limitcheck; } dev->x_pixels_per_inch = (float)GetDeviceCaps(wdev->hdcprn, LOGPIXELSX); dev->y_pixels_per_inch = (float)GetDeviceCaps(wdev->hdcprn, LOGPIXELSY); wdev->ratio = 1; if (wdev->max_dpi > 50) { float dpi_x = dev->x_pixels_per_inch; float dpi_y = dev->y_pixels_per_inch; while ((dev->x_pixels_per_inch > wdev->max_dpi) || (dev->y_pixels_per_inch > wdev->max_dpi)) { ratio += 1.0; wdev->ratio ++; dev->x_pixels_per_inch = dpi_x / ratio; dev->y_pixels_per_inch = dpi_y / ratio; } } size.x = GetDeviceCaps(wdev->hdcprn, PHYSICALWIDTH); size.y = GetDeviceCaps(wdev->hdcprn, PHYSICALHEIGHT); gx_device_set_width_height(dev, (int)(size.x / ratio), (int)(size.y / ratio)); offset.x = GetDeviceCaps(wdev->hdcprn, PHYSICALOFFSETX); offset.y = GetDeviceCaps(wdev->hdcprn, PHYSICALOFFSETY); /* m[] gives margins in inches */ m[0] /*left */ = offset.x / dev->x_pixels_per_inch / ratio; m[3] /*top */ = offset.y / dev->y_pixels_per_inch / ratio; m[2] /*right */ = (size.x - offset.x - GetDeviceCaps(wdev->hdcprn, HORZRES)) / dev->x_pixels_per_inch / ratio; m[1] /*bottom */ = (size.y - offset.y - GetDeviceCaps(wdev->hdcprn, VERTRES)) / dev->y_pixels_per_inch / ratio; gx_device_set_margins(dev, m, true); depth = dev->color_info.depth; if (depth == 0) { /* Set parameters that were unknown before opening device */ /* Find out if the device supports color */ /* We recognize 1, 4 (but use only 3), 8 and 24 bit color devices */ depth = GetDeviceCaps(wdev->hdcprn, PLANES) * GetDeviceCaps(wdev->hdcprn, BITSPIXEL); } win_pr2_set_bpp(dev, depth); /* gdev_prn_open opens a temporary file which we don't want */ /* so we specify the name now so we can delete it later */ wdev->fname[0] = '\0'; pfile = gp_open_scratch_file(dev->memory, gp_scratch_file_name_prefix, wdev->fname, "wb"); fclose(pfile); code = gdev_prn_open(dev); if ((code < 0) && wdev->fname[0]) unlink(wdev->fname); if (!wdev->nocancel) { /* inform user of progress with dialog box and allow cancel */ wdev->lpfnCancelProc = (DLGPROC) CancelDlgProc; wdev->hDlgModeless = CreateDialog(phInstance, "CancelDlgBox", PARENT_WINDOW, wdev->lpfnCancelProc); ShowWindow(wdev->hDlgModeless, SW_HIDE); } return code; };
BOOL PopPrntPrintFile (HINSTANCE hInst, HWND hwnd, HWND hwndEdit, LPSTR szTitleName) { static DOCINFO di = { sizeof (DOCINFO), "", NULL } ; static PRINTDLG pd ; BOOL bSuccess ; LPCTSTR pstrBuffer ; int yChar, iCharsPerLine, iLinesPerPage, iTotalLines, iTotalPages, iPage, iLine, iLineNum ; TEXTMETRIC tm ; WORD iColCopy, iNoiColCopy ; pd.lStructSize = sizeof (PRINTDLG) ; pd.hwndOwner = hwnd ; pd.hDevMode = NULL ; pd.hDevNames = NULL ; pd.hDC = NULL ; pd.Flags = PD_ALLPAGES | PD_COLLATE | PD_RETURNDC ; pd.nFromPage = 0 ; pd.nToPage = 0 ; pd.nMinPage = 0 ; pd.nMaxPage = 0 ; pd.nCopies = 1 ; pd.hInstance = NULL ; pd.lCustData = 0L ; pd.lpfnPrintHook = NULL ; pd.lpfnSetupHook = NULL ; pd.lpPrintTemplateName = NULL ; pd.lpSetupTemplateName = NULL ; pd.hPrintTemplate = NULL ; pd.hSetupTemplate = NULL ; if (!PrintDlg (&pd)) return TRUE ; // iTotalLines = (short) SendMessage (hwndEdit, EM_GETLINECOUNT, 0, 0L) ; iTotalLines = (short)FootyGetLines(activeFootyID); if (iTotalLines == 0) return TRUE ; GetTextMetrics (pd.hDC, &tm) ; yChar = tm.tmHeight + tm.tmExternalLeading ; iCharsPerLine = GetDeviceCaps (pd.hDC, HORZRES) / tm.tmAveCharWidth ; iLinesPerPage = GetDeviceCaps (pd.hDC, VERTRES) / yChar ; iTotalPages = (iTotalLines + iLinesPerPage - 1) / iLinesPerPage ; EnableWindow (hwnd, FALSE) ; bSuccess = TRUE ; bUserAbort = FALSE ; hDlgPrint = CreateDialog (hInst, (LPCTSTR) "PrintDlgBox", hwnd, (DLGPROC)PrintDlgProc) ; SetDlgItemText (hDlgPrint, IDD_FNAME, szTitleName) ; SetAbortProc (pd.hDC, (ABORTPROC)AbortProc) ; di.lpszDocName = szTitleName; if (StartDoc (pd.hDC, &di) > 0) { for (iColCopy = 0 ; iColCopy < ((WORD) pd.Flags & PD_COLLATE ? pd.nCopies : 1) ; iColCopy++) { for (iPage = 0 ; iPage < iTotalPages ; iPage++) { for (iNoiColCopy = 0 ; iNoiColCopy < (pd.Flags & PD_COLLATE ? 1 : pd.nCopies) ; iNoiColCopy++) { if (StartPage (pd.hDC) < 0) { bSuccess = FALSE ; break ; } for (iLine = 0 ; iLine < iLinesPerPage ; iLine++) { iLineNum = iLinesPerPage * iPage + iLine ; if (iLineNum >= iTotalLines) break ; // TextOut (pd.hDC, 0, yChar * iLine, pstrBuffer, // (int) SendMessage (hwndEdit, EM_GETLINE, // (WPARAM) iLineNum, (LPARAM) pstrBuffer)) ; pstrBuffer = FootyGetLineData(activeFootyID, iLineNum+1); TextOut(pd.hDC, 0, yChar * iLine, pstrBuffer, FootyGetLineLen(activeFootyID, iLineNum+1)); } if (EndPage (pd.hDC) < 0) { bSuccess = FALSE ; break ; } if (bUserAbort) break ; } if (!bSuccess || bUserAbort) break ; } if (!bSuccess || bUserAbort) break ; } } else bSuccess = FALSE ; if (bSuccess) EndDoc (pd.hDC) ; if (!bUserAbort) { EnableWindow (hwnd, TRUE) ; DestroyWindow (hDlgPrint) ; } DeleteDC (pd.hDC) ; return bSuccess && !bUserAbort ; }
/* GetWindowLong(hwnd, 4) must be available for use */ void WDPROC DumpPrinter(HWND hwnd, LPSTR szAppName, LPSTR szFileName) { HDC printer; PRINTDLG pd; /* FIXME: share these with CopyPrint */ static DEVNAMES * pDevNames = NULL; static DEVMODE * pDevMode = NULL; LPCTSTR szDriver, szDevice, szOutput; GP_PRINT pr; DOCINFO di; char *buf; WORD *bufcount; int count; FILE *f; long lsize; long ldone; char pcdone[10]; if ((f = fopen(szFileName, "rb")) == NULL) return; fseek(f, 0L, SEEK_END); lsize = ftell(f); if (lsize <= 0) lsize = 1; fseek(f, 0L, SEEK_SET); ldone = 0; /* Print Setup Dialog */ /* See http://support.microsoft.com/kb/240082 */ memset(&pd, 0, sizeof(pd)); pd.lStructSize = sizeof(pd); pd.hwndOwner = hwnd; pd.Flags = PD_PRINTSETUP; pd.hDevNames = pDevNames; pd.hDevMode = pDevMode; if (PrintDlg(&pd)) { pDevNames = (DEVNAMES *) GlobalLock(pd.hDevNames); pDevMode = (DEVMODE *) GlobalLock(pd.hDevMode); szDriver = (LPCTSTR)pDevNames + pDevNames->wDriverOffset; szDevice = (LPCTSTR)pDevNames + pDevNames->wDeviceOffset; szOutput = (LPCTSTR)pDevNames + pDevNames->wOutputOffset; printer = CreateDC(szDriver, szDevice, szOutput, pDevMode); GlobalUnlock(pd.hDevMode); GlobalUnlock(pd.hDevNames); /* We no longer free these structures, but preserve them for the next time GlobalFree(pd.hDevMode); GlobalFree(pd.hDevNames); */ if (printer == NULL) return; /* abort */ pr.hdcPrn = printer; SetWindowLongPtr(hwnd, 4, (LONG_PTR)((GP_LPPRINT)&pr)); PrintRegister((GP_LPPRINT)&pr); if ((buf = malloc(4096 + 2)) != NULL) { bufcount = (WORD *)buf; EnableWindow(hwnd,FALSE); pr.bUserAbort = FALSE; pr.hDlgPrint = CreateDialogParam(hdllInstance, "CancelDlgBox", hwnd, PrintDlgProc, (LPARAM)szAppName); SetAbortProc(printer, PrintAbortProc); memset(&di, 0, sizeof(DOCINFO)); di.cbSize = sizeof(DOCINFO); di.lpszDocName = szAppName; if (StartDoc(printer, &di) > 0) { while (pr.hDlgPrint && !pr.bUserAbort && (count = fread(buf + 2, 1, 4096, f)) != 0 ) { int ret; *bufcount = count; ret = Escape(printer, PASSTHROUGH, count + 2, (LPSTR)buf, NULL); ldone += count; if (ret != SP_ERROR) { sprintf(pcdone, "%d%% done", (int)(ldone * 100 / lsize)); SetWindowText(GetDlgItem(pr.hDlgPrint, CANCEL_PCDONE), pcdone); } else { SetWindowText(GetDlgItem(pr.hDlgPrint, CANCEL_PCDONE), "Passthrough Error!"); } if (pr.bUserAbort) AbortDoc(printer); else EndDoc(printer); } if (!pr.bUserAbort) { EnableWindow(hwnd, TRUE); DestroyWindow(pr.hDlgPrint); } free(buf); } } DeleteDC(printer); SetWindowLong(hwnd, 4, 0L); PrintUnregister((GP_LPPRINT)&pr); } fclose(f); }
int Printer_print (void (*draw) (void *boss, Graphics g), void *boss) { #if defined (UNIX) structMelderFile tempFile = { 0 }; char tempPath_utf8 [] = "/tmp/picXXXXXX"; close (mkstemp (tempPath_utf8)); Melder_pathToFile (Melder_peekUtf8ToWcs (tempPath_utf8), & tempFile); thePrinter. graphics = Graphics_create_postscriptjob (& tempFile, thePrinter. resolution, thePrinter. spots, thePrinter. paperSize, thePrinter. orientation, thePrinter. magnification); if (! thePrinter. graphics) return Melder_error1 (L"Cannot create temporary PostScript file for printing."); draw (boss, thePrinter. graphics); forget (thePrinter. graphics); char command [500]; sprintf (command, Melder_peekWcsToUtf8 (Site_getPrintCommand ()), tempPath_utf8); system (command); MelderFile_delete (& tempFile); #elif defined (_WIN32) int postScriptCode = POSTSCRIPT_PASSTHROUGH; DOCINFO docInfo; DEVMODE *devMode; initPrinter (); if (! theWinPrint. hDevMode) { memset (& theWinPrint, 0, sizeof (PRINTDLG)); theWinPrint. lStructSize = sizeof (PRINTDLG); theWinPrint. Flags = PD_RETURNDEFAULT; if (! PrintDlg (& theWinPrint)) return Melder_error1 (L"Cannot initialize printer."); } if (Melder_backgrounding) { theWinPrint. Flags = PD_RETURNDEFAULT | PD_RETURNDC; if (! PrintDlg (& theWinPrint) || theWinPrint. hDC == NULL) { return Melder_error1 (L"Cannot print from a script on this computer."); } } else { theWinPrint. Flags &= ~ PD_RETURNDEFAULT; theWinPrint. Flags |= PD_RETURNDC; if (! PrintDlg (& theWinPrint)) return 1; } theWinDC = theWinPrint. hDC; thePrinter. postScript = thePrinter. allowDirectPostScript && Escape (theWinDC, QUERYESCSUPPORT, sizeof (int), (LPSTR) & postScriptCode, NULL); /* * The HP colour inkjet printer returns in dmFields: * 0, 1, 8, 9, 10, 11, 12, 13, 14, 15, 23, 24, 25, 26 = DM_ORIENTATION | * DM_PAPERSIZE | DM_COPIES | DM_DEFAULTSOURCE | DM_PRINTQUALITY | * DM_COLOR | DM_DUPLEX | DM_YRESOLUTION | DM_TTOPTION | DM_COLLATE | * DM_ICMMETHOD | DM_ICMINTENT | DM_MEDIATYPE | DM_DITHERTYPE */ devMode = * (DEVMODE **) theWinPrint. hDevMode; thePrinter. resolution = devMode -> dmFields & DM_YRESOLUTION ? devMode -> dmYResolution : devMode -> dmFields & DM_PRINTQUALITY ? ( devMode -> dmPrintQuality > 0 ? devMode -> dmPrintQuality : 300 ) : 300; if (devMode -> dmFields & DM_PAPERWIDTH) { thePrinter. paperWidth = devMode -> dmPaperWidth * thePrinter. resolution / 254; thePrinter. paperHeight = devMode -> dmPaperLength * thePrinter. resolution / 254; } else if (devMode -> dmFields & DM_PAPERSIZE) { static struct { float width, height; } sizes [] = { { 0, 0 }, { 8.5, 11 }, { 8.5, 11 }, { 11, 17 }, { 17, 11 }, { 8.5, 14 }, { 5.5, 8.5 }, { 7.25, 10.5 }, { 297/25.4, 420/25.4 }, { 210/25.4, 297/25.4 }, { 210/25.4, 297/25.4 }, { 148.5/25.4, 210/25.4 }, { 250/25.4, 354/25.4 }, { 182/25.4, 257/25.4 }, { 8.5, 13 }, { 215/25.4, 275/25.4 }, { 10, 14 }, { 11, 17 }, { 8.5, 11 }, { 3.875, 8.875 }, { 4.125, 9.5 }, { 4.5, 10.375 } }; int paperSize = devMode -> dmPaperSize; if (paperSize <= 0 || paperSize > 21) paperSize = 1; thePrinter. paperWidth = sizes [paperSize]. width * thePrinter. resolution; thePrinter. paperHeight = sizes [paperSize]. height * thePrinter. resolution; if (devMode -> dmOrientation == DMORIENT_LANDSCAPE) { long dummy = thePrinter. paperWidth; thePrinter. paperWidth = thePrinter. paperHeight; thePrinter. paperHeight = dummy; } } else { thePrinter. paperWidth = 1000; thePrinter. paperHeight = 1000; } EnableWindow ((HWND) XtWindow (theCurrentPraatApplication -> topShell), FALSE); SetAbortProc (theWinDC, AbortFunc); memset (& docInfo, 0, sizeof (DOCINFO)); docInfo. cbSize = sizeof (DOCINFO); docInfo. lpszDocName = L"Praatjes"; docInfo. lpszOutput = NULL; if (thePrinter. postScript) { StartDoc (theWinDC, & docInfo); StartPage (theWinDC); initPostScriptPage (); thePrinter. graphics = Graphics_create_postscriptprinter (); if (! thePrinter. graphics) return Melder_error1 (L"Cannot open printer."); draw (boss, thePrinter. graphics); forget (thePrinter. graphics); exitPostScriptPage (); EndPage (theWinDC); EndDoc (theWinDC); } else { StartDoc (theWinDC, & docInfo); StartPage (theWinDC); thePrinter. graphics = Graphics_create_screenPrinter (NULL, (unsigned long) theWinDC); if (! thePrinter. graphics) return Melder_error1 (L"Cannot open printer."); draw (boss, thePrinter. graphics); forget (thePrinter. graphics); if (EndPage (theWinDC) < 0) { Melder_error1 (L"Cannot print page."); } else { EndDoc (theWinDC); } } EnableWindow ((HWND) XtWindow (theCurrentPraatApplication -> topShell), TRUE); DeleteDC (theWinDC), theWinDC = NULL; #elif defined (macintosh) Boolean result; initPrinter (); if (Melder_backgrounding) { PMSessionValidatePageFormat (theMacPrintSession, theMacPageFormat, & result); PMSessionValidatePrintSettings (theMacPrintSession, theMacPrintSettings, & result); } else { Boolean accepted; PMSessionPrintDialog (theMacPrintSession, theMacPrintSettings, theMacPageFormat, & accepted); if (! accepted) return 1; /* Normal cancelled return. */ } PMSessionValidatePageFormat (theMacPrintSession, theMacPageFormat, & result); PMSessionValidatePrintSettings (theMacPrintSession, theMacPrintSettings, & result); PMResolution res; PMGetResolution (theMacPageFormat, & res); thePrinter. resolution = res. hRes; PMGetAdjustedPaperRect (theMacPageFormat, & paperSize); thePrinter. paperWidth = paperSize. right - paperSize. left; thePrinter. paperHeight = paperSize. bottom - paperSize. top; Boolean isPostScriptDriver = FALSE; //PMSessionIsDocumentFormatSupported (theMacPrintSession, // kPMDocumentFormatPICTPS, & isPostScriptDriver); CFArrayRef supportedFormats; PMSessionGetDocumentFormatGeneration (theMacPrintSession, & supportedFormats); CFIndex numberOfSupportedFormats = CFArrayGetCount (supportedFormats); if (Melder_debug == 21) { MelderInfo_open (); MelderInfo_writeLine1 (L"Supported document formats:"); } for (CFIndex i = 0; i < numberOfSupportedFormats; i ++) { CFStringRef supportedFormat = CFArrayGetValueAtIndex (supportedFormats, i); if (CFStringCompare (supportedFormat, kPMDocumentFormatPICTPS, 0) == 0) { isPostScriptDriver = TRUE; } if (Melder_debug == 21) { MelderInfo_writeLine3 (Melder_integer (i), L": ", Melder_peekUtf8ToWcs (CFStringGetCStringPtr (supportedFormat, kCFStringEncodingUTF8))); } } if (Melder_debug == 21) { MelderInfo_close (); } CFRelease (supportedFormats); isPostScriptDriver = FALSE; // OVERRIDE, because from 10.4 on we have something better: we'll be sending PDF thePrinter. postScript = thePrinter. allowDirectPostScript && isPostScriptDriver; if (thePrinter. postScript) { CFStringRef strings [1]; strings [0] = kPMGraphicsContextQuickdraw; CFArrayRef array = CFArrayCreate (kCFAllocatorDefault, (const void **) strings, 1, & kCFTypeArrayCallBacks); OSStatus err = PMSessionSetDocumentFormatGeneration (theMacPrintSession, kPMDocumentFormatPICTPS, array, NULL); CFRelease (array); if (err != 0) { return Melder_error2 (L"PMSessionSetDocumentFormatGeneration: error ", Melder_integer (err)); } } PMOrientation orientation; PMGetOrientation (theMacPageFormat, & orientation); thePrinter. orientation = orientation == kPMLandscape || orientation == kPMReverseLandscape ? kGraphicsPostscript_orientation_LANDSCAPE : kGraphicsPostscript_orientation_PORTRAIT; PMSessionBeginDocument (theMacPrintSession, theMacPrintSettings, theMacPageFormat); PMSessionBeginPage (theMacPrintSession, theMacPageFormat, NULL); PMSessionGetGraphicsContext (theMacPrintSession, kPMGraphicsContextQuickdraw, (void **) & theMacPort); /* * On PostScript, the point (0, 0) is the bottom left corner of the paper, which is fine. * On the screen, however, the point (0, 0) is the top left corner of the writable page. * Since we want paper-related margins, not writable-page-related margins, * we require that this point gets the coordinates (250, 258) or so, * so that the top left corner of the paper gets coordinates (0, 0). * The "left" and "top" attributes of rPaper are negative values (e.g. -250 and -258), * so multiply them by -1. * * Under Carbon, the port has to be set inside the page. */ SetPort (theMacPort); if (! thePrinter. postScript) SetOrigin (- paperSize. left, - paperSize. top); if (thePrinter. postScript) { if (! openPostScript ()) error1 (L"Cannot print PostScript.") thePrinter. graphics = Graphics_create_postscriptprinter (); if (! thePrinter. graphics) goto end; draw (boss, thePrinter. graphics); forget (thePrinter. graphics); closePostScript (); } else { thePrinter. graphics = Graphics_create_screenPrinter (NULL, (unsigned long) theMacPort); draw (boss, thePrinter. graphics); forget (thePrinter. graphics); } end: if (theMacPort) { PMSessionEndPage (theMacPrintSession); PMSessionEndDocument (theMacPrintSession); theMacPort = NULL; } #endif iferror return 0; return 1; }