void RenamePrinter(const std::tstring& currentPrinterName, const std::tstring& newPrinterName) { HANDLE printer = 0; PRINTER_INFO_2 *printerInfo = 0; DEVMODE *pDevMode = 0; try { // get the printer and it's info structure... PRINTER_DEFAULTS printerDefaults; ZeroMemory(&printerDefaults, sizeof(printerDefaults)); printerDefaults.DesiredAccess = PRINTER_ALL_ACCESS; BOOL result = OpenPrinter((LPTSTR)currentPrinterName.c_str(), &printer, &printerDefaults); if (!result || (0 == printer)) throw Workshare::Exception(_T("Failed to open printer.")); DWORD bufferSize = 0; SetLastError(0); result = GetPrinter(printer, 2, 0, 0, &bufferSize); if ((!result) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (bufferSize == 0)) throw Workshare::Exception(_T("Failed to get printer info buffer size.")); printerInfo = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, bufferSize); if (0 == printerInfo) throw Workshare::System::SystemException(_T("Failed to allocate printer info buffer.")); result = GetPrinter(printer, 2, (LPBYTE)printerInfo, bufferSize, &bufferSize); if (!result) throw Workshare::Exception(_T("Failed to get printer info.")); // If GetPrinter didn't fill in the DEVMODE, try to get it by calling DocumentProperties... LONG lFlag; if (0 == printerInfo->pDevMode) { bufferSize = DocumentProperties(0, printer, (LPTSTR)currentPrinterName.c_str(), 0, 0, 0); if (bufferSize <= 0) throw Workshare::Exception(_T("Failed to get document properties buffer size.")); pDevMode = (DEVMODE *)GlobalAlloc(GPTR, bufferSize); if (0 == pDevMode) throw Workshare::System::SystemException(_T("Failed to allocate document properties buffer.")); lFlag = DocumentProperties(0, printer, (LPTSTR)currentPrinterName.c_str(), pDevMode, 0, DM_OUT_BUFFER); if (lFlag != IDOK || 0 == pDevMode) throw Workshare::Exception(_T("Failed to get document properties.")); printerInfo->pDevMode = pDevMode; } if (!(printerInfo->pDevMode->dmFields & DM_ORIENTATION)) throw Workshare::Exception(_T("Printer does not support the required name change.")); // Specify the new printer name... printerInfo->pPrinterName = (LPTSTR)newPrinterName.c_str() ; // Do not attempt to set security descriptor... printerInfo->pSecurityDescriptor = 0; lFlag = DocumentProperties(0, printer, (LPTSTR)currentPrinterName.c_str(), printerInfo->pDevMode, printerInfo->pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER); if (IDOK != lFlag) throw Workshare::Exception(_T("Failed to update the devmode part of document properties.")); result = SetPrinter(printer, 2, (LPBYTE)printerInfo, 0); if (!result) throw Workshare::Exception(_T("Failed to update printer information.")); // Tell other apps that there was a change... SendMessageTimeout(HWND_BROADCAST, WM_DEVMODECHANGE, 0L, (LPARAM)(LPCTSTR)(LPTSTR)currentPrinterName.c_str(), SMTO_NORMAL, 1000, 0); return; } catch(...) { if (printerInfo) GlobalFree(printerInfo); if (printer) ClosePrinter(printer); if (pDevMode) GlobalFree(pDevMode); throw; } }
static LPDEVMODE getDevmode(HANDLE hPrinter, const QString &printerId) { LPWSTR printerIdUtf16 = const_cast<LPWSTR>(reinterpret_cast<LPCWSTR>(printerId.utf16())); // Allocate the required DEVMODE buffer LONG dmSize = DocumentProperties(NULL, hPrinter, printerIdUtf16, NULL, NULL, 0); if (dmSize < 0) return Q_NULLPTR; LPDEVMODE pDevMode = reinterpret_cast<LPDEVMODE>(malloc(dmSize)); // Get the default DevMode LONG result = DocumentProperties(NULL, hPrinter, printerIdUtf16, pDevMode, NULL, DM_OUT_BUFFER); if (result != IDOK) { free(pDevMode); pDevMode = Q_NULLPTR; } return pDevMode; }
Bool apc_prn_setup( Handle self) { void * lph; LONG sz, ret; DEVMODE * dm; HWND who = GetActiveWindow(); HDC dc; objCheck false; if ( !OpenPrinter( sys s. prn. ppi. pPrinterName, &lph, nil)) apiErrRet; sz = DocumentProperties( nil, lph, sys s. prn. ppi. pPrinterName, nil, nil, 0); if ( sz <= 0) { apiErr; ClosePrinter( lph); return false; } dm = ( DEVMODE * ) malloc( sz); if ( !dm) { ClosePrinter( lph); return false; } sys s. prn. ppi. pDevMode-> dmFields = -1; ret = DocumentProperties( hwnd_to_view( who) ? who : nil, lph, sys s. prn. ppi. pPrinterName, dm, sys s. prn. ppi. pDevMode, DM_IN_BUFFER|DM_IN_PROMPT|DM_OUT_BUFFER); ClosePrinter( lph); if ( ret != IDOK) { free( dm); return false; } free( sys s. prn. ppi. pDevMode); sys s. prn. ppi. pDevMode = dm; if ( !( dc = prn_info_dc( self))) return false; sys res. x = ( float) GetDeviceCaps( dc, LOGPIXELSX); sys res. y = ( float) GetDeviceCaps( dc, LOGPIXELSY); sys lastSize. x = GetDeviceCaps( dc, HORZRES); sys lastSize. y = GetDeviceCaps( dc, VERTRES); if ( !DeleteDC( dc)) apiErr; return true; }
void getDefaultDevmodeC(char *printSetup, LPHANDLE phPrinter, char **device) { int size,r1; size = ((int*)printSetup)[0]; printSetup +=4; r1 = DocumentProperties(NULL,phPrinter,((char*)device)+4, (DEVMODE*)printSetup,NULL,DM_OUT_BUFFER); ClosePrinter(phPrinter); }
QPageSize QWindowsPrintDevice::defaultPageSize() const { if (!m_havePageSizes) loadPageSizes(); QPageSize pageSize; // Allocate the required DEVMODE buffer DWORD dmSize = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), NULL, NULL, 0); LPDEVMODE pDevMode = (LPDEVMODE)malloc(dmSize); // Get the default DevMode DWORD result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), pDevMode, NULL, DM_OUT_BUFFER); // Get the default paper size if (result == IDOK && pDevMode->dmFields & DM_PAPERSIZE) { // Find the supported page size that matches, in theory default should be one of them foreach (const QPageSize &ps, m_pageSizes) { if (ps.windowsId() == pDevMode->dmPaperSize) { pageSize = ps; break; } } }
void getDevmodeSizeC(int *size, HANDLE *phPrinter, char **device, char **driver, char **output) { char szPrinter[80]; char *szDevice, *szDriver, *szOutput; GetProfileString("windows", "device", ",,,", szPrinter, 80); szDevice = strtok(szPrinter,","); szDriver = strtok(NULL,", "); szOutput = strtok(NULL,", "); *device = PassString(szDevice); *driver = PassString(szDriver); *output = PassString(szOutput); if (*szDevice=='\0' || *szDriver=='\0' || *szOutput=='\0') { *size = 0; return; }; OpenPrinter(szDevice,phPrinter,NULL); *size = DocumentProperties(NULL,*phPrinter,szDevice,NULL,NULL,0); }
bool PrintFile(const WCHAR *fileName, const WCHAR *printerName, bool displayErrors, const WCHAR *settings) { if (!HasPermission(Perm_PrinterAccess)) return false; ScopedMem<WCHAR> fileName2(path::Normalize(fileName)); BaseEngine *engine = EngineManager::CreateEngine(!gUseEbookUI, fileName2); if (!engine || !engine->AllowsPrinting()) { if (displayErrors) MessageBox(NULL, _TR("Cannot print this file"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0)); return false; } HANDLE printer; bool ok = OpenPrinter((WCHAR *)printerName, &printer, NULL); if (!ok) { if (displayErrors) MessageBox(NULL, _TR("Printer with given name doesn't exist"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0)); return false; } // get printer driver information DWORD needed = 0; GetPrinter(printer, 2, NULL, 0, &needed); ScopedMem<PRINTER_INFO_2> infoData((PRINTER_INFO_2 *)AllocArray<BYTE>(needed)); if (infoData) ok = GetPrinter(printer, 2, (LPBYTE)infoData.Get(), needed, &needed); if (!ok || !infoData || needed <= sizeof(PRINTER_INFO_2)) goto Exit; LONG structSize = DocumentProperties(NULL, printer, /* Handle to our printer. */ (WCHAR *)printerName, /* Name of the printer. */ NULL, /* Asking for size, so */ NULL, /* these are not used. */ 0); /* Zero returns buffer size. */ if (structSize < sizeof(DEVMODE)) { // If failure, inform the user, cleanup and return failure. if (displayErrors) MessageBox(NULL, _TR("Could not obtain Printer properties"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0)); goto Exit; } LPDEVMODE devMode = (LPDEVMODE)malloc(structSize); if (!devMode) goto Exit; // Get the default DevMode for the printer and modify it for your needs. LONG returnCode = DocumentProperties(NULL, printer, (WCHAR *)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. if (displayErrors) MessageBox(NULL, _TR("Could not obtain Printer properties"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0)); goto Exit; } ClosePrinter(printer); printer = NULL; { Print_Advanced_Data advanced; Vec<PRINTPAGERANGE> ranges; ApplyPrintSettings(settings, engine->PageCount(), ranges, advanced); PrintData pd(engine, infoData, devMode, ranges, advanced); ok = PrintToDevice(pd); if (!ok && displayErrors) MessageBox(NULL, _TR("Couldn't initialize printer"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0)); } Exit: free(devMode); if (printer) ClosePrinter(printer); delete engine; return ok; }
bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data ) { WinPrinter printer; LPTSTR szPrinterName = wxMSW_CONV_LPTSTR(data.GetPrinterName()); if (!m_devMode) InitializeDevMode(data.GetPrinterName(), &printer); HGLOBAL hDevMode = static_cast<HGLOBAL>(m_devMode); if ( hDevMode ) { GlobalPtrLock lockDevMode(hDevMode); DEVMODE * const devMode = static_cast<DEVMODE *>(lockDevMode.Get()); //// Orientation devMode->dmOrientation = (short)data.GetOrientation(); //// Collation devMode->dmCollate = (data.GetCollate() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE); devMode->dmFields |= DM_COLLATE; //// Number of copies devMode->dmCopies = (short)data.GetNoCopies(); devMode->dmFields |= DM_COPIES; //// Printer name wxString name = data.GetPrinterName(); if (!name.empty()) { // NB: the cast is needed in the ANSI build, strangely enough // dmDeviceName is BYTE[] and not char[] there wxStrlcpy(reinterpret_cast<wxChar *>(devMode->dmDeviceName), name.t_str(), WXSIZEOF(devMode->dmDeviceName)); } //// Colour if (data.GetColour()) devMode->dmColor = DMCOLOR_COLOR; else devMode->dmColor = DMCOLOR_MONOCHROME; devMode->dmFields |= DM_COLOR; //// Paper size // Paper id has priority over paper size. If id is specified, then size // is ignored (as it can be filled in even for standard paper sizes) wxPrintPaperType *paperType = NULL; const wxPaperSize paperId = data.GetPaperId(); if ( paperId != wxPAPER_NONE && wxThePrintPaperDatabase ) { paperType = wxThePrintPaperDatabase->FindPaperType(paperId); } if ( paperType ) { devMode->dmPaperSize = (short)paperType->GetPlatformId(); devMode->dmFields |= DM_PAPERSIZE; } else // custom (or no) paper size { const wxSize paperSize = data.GetPaperSize(); if ( paperSize != wxDefaultSize ) { // Fall back on specifying the paper size explicitly if(m_customWindowsPaperId != 0) devMode->dmPaperSize = m_customWindowsPaperId; else devMode->dmPaperSize = DMPAPER_USER; devMode->dmPaperWidth = (short)(paperSize.x * 10); devMode->dmPaperLength = (short)(paperSize.y * 10); devMode->dmFields |= DM_PAPERWIDTH; devMode->dmFields |= DM_PAPERLENGTH; // A printer driver may or may not also want DM_PAPERSIZE to // be specified. Also, if the printer driver doesn't implement the DMPAPER_USER // size, then this won't work, and even if you found the correct id by // enumerating the driver's paper sizes, it probably won't change the actual size, // it'll just select that custom paper type with its own current setting. // For a discussion on this, see http://www.codeguru.com/forum/showthread.php?threadid=458617 // Although m_customWindowsPaperId is intended to work around this, it's // unclear how it can help you set the custom paper size programmatically. } //else: neither paper type nor size specified, don't fill DEVMODE // at all so that the system defaults are used } //// Duplex short duplex; switch (data.GetDuplex()) { case wxDUPLEX_HORIZONTAL: duplex = DMDUP_HORIZONTAL; break; case wxDUPLEX_VERTICAL: duplex = DMDUP_VERTICAL; break; default: // in fact case wxDUPLEX_SIMPLEX: duplex = DMDUP_SIMPLEX; break; } devMode->dmDuplex = duplex; devMode->dmFields |= DM_DUPLEX; //// Quality short quality; switch (data.GetQuality()) { case wxPRINT_QUALITY_MEDIUM: quality = DMRES_MEDIUM; break; case wxPRINT_QUALITY_LOW: quality = DMRES_LOW; break; case wxPRINT_QUALITY_DRAFT: quality = DMRES_DRAFT; break; case wxPRINT_QUALITY_HIGH: quality = DMRES_HIGH; break; default: quality = (short)data.GetQuality(); devMode->dmYResolution = quality; devMode->dmFields |= DM_YRESOLUTION; break; } devMode->dmPrintQuality = quality; devMode->dmFields |= DM_PRINTQUALITY; if (data.GetPrivDataLen() > 0) { memcpy( (char *)devMode+devMode->dmSize, data.GetPrivData(), data.GetPrivDataLen() ); devMode->dmDriverExtra = (WXWORD)data.GetPrivDataLen(); } if (data.GetBin() != wxPRINTBIN_DEFAULT) { switch (data.GetBin()) { case wxPRINTBIN_ONLYONE: devMode->dmDefaultSource = DMBIN_ONLYONE; break; case wxPRINTBIN_LOWER: devMode->dmDefaultSource = DMBIN_LOWER; break; case wxPRINTBIN_MIDDLE: devMode->dmDefaultSource = DMBIN_MIDDLE; break; case wxPRINTBIN_MANUAL: devMode->dmDefaultSource = DMBIN_MANUAL; break; case wxPRINTBIN_ENVELOPE: devMode->dmDefaultSource = DMBIN_ENVELOPE; break; case wxPRINTBIN_ENVMANUAL: devMode->dmDefaultSource = DMBIN_ENVMANUAL; break; case wxPRINTBIN_AUTO: devMode->dmDefaultSource = DMBIN_AUTO; break; case wxPRINTBIN_TRACTOR: devMode->dmDefaultSource = DMBIN_TRACTOR; break; case wxPRINTBIN_SMALLFMT: devMode->dmDefaultSource = DMBIN_SMALLFMT; break; case wxPRINTBIN_LARGEFMT: devMode->dmDefaultSource = DMBIN_LARGEFMT; break; case wxPRINTBIN_LARGECAPACITY: devMode->dmDefaultSource = DMBIN_LARGECAPACITY; break; case wxPRINTBIN_CASSETTE: devMode->dmDefaultSource = DMBIN_CASSETTE; break; case wxPRINTBIN_FORMSOURCE: devMode->dmDefaultSource = DMBIN_FORMSOURCE; break; default: devMode->dmDefaultSource = (short)(DMBIN_USER + data.GetBin() - wxPRINTBIN_USER); // 256 + data.GetBin() - 14 = 242 + data.GetBin() break; } devMode->dmFields |= DM_DEFAULTSOURCE; } if (data.GetMedia() != wxPRINTMEDIA_DEFAULT) { devMode->dmMediaType = data.GetMedia(); devMode->dmFields |= DM_MEDIATYPE; } if( printer ) { // Step 3: // Merge the new settings with the old. // This gives the driver an opportunity to update any private // portions of the DevMode structure. DocumentProperties( NULL, printer, szPrinterName, (LPDEVMODE)hDevMode, // Reuse our buffer for output. (LPDEVMODE)hDevMode, // Pass the driver our changes DM_IN_BUFFER | // Commands to Merge our changes and DM_OUT_BUFFER ); // write the result. } } if ( m_devNames ) { ::GlobalFree(static_cast<HGLOBAL>(m_devNames)); } // TODO: I hope it's OK to pass some empty strings to DEVNAMES. m_devNames = wxCreateDevNames(wxEmptyString, data.GetPrinterName(), wxEmptyString); return true; }
void wxWindowsPrintNativeData::InitializeDevMode(const wxString& printerName, WinPrinter* printer) { if (m_devMode) return; LPTSTR szPrinterName = wxMSW_CONV_LPTSTR(printerName); // From MSDN: How To Modify Printer Settings with the DocumentProperties() Function // The purpose of this is to fill the DEVMODE with privdata from printer driver. // If we have a printer name and OpenPrinter successfully returns // this replaces the PrintDlg function which creates the DEVMODE filled only with data from default printer. if ( !m_devMode && !printerName.IsEmpty() ) { // Open printer if ( printer && printer->Open( printerName ) == TRUE ) { DWORD dwNeeded, dwRet; // Step 1: // Allocate a buffer of the correct size. dwNeeded = DocumentProperties( NULL, *printer, // Handle to our printer. szPrinterName, // Name of the printer. NULL, // Asking for size, so NULL, // these are not used. 0 ); // Zero returns buffer size. LPDEVMODE tempDevMode = static_cast<LPDEVMODE>( GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, dwNeeded ) ); // Step 2: // Get the default DevMode for the printer dwRet = DocumentProperties( NULL, *printer, szPrinterName, tempDevMode, // The address of the buffer to fill. NULL, // Not using the input buffer. DM_OUT_BUFFER ); // Have the output buffer filled. if ( dwRet != IDOK ) { // If failure, cleanup GlobalFree( tempDevMode ); printer->Close(); } else { m_devMode = tempDevMode; tempDevMode = NULL; } } } if ( !m_devMode ) { // Use PRINTDLG as a way of creating a DEVMODE object PRINTDLG pd; memset(&pd, 0, sizeof(PRINTDLG)); #ifdef __WXWINCE__ pd.cbStruct = sizeof(PRINTDLG); #else pd.lStructSize = sizeof(PRINTDLG); #endif pd.hwndOwner = NULL; pd.hDevMode = NULL; // Will be created by PrintDlg pd.hDevNames = NULL; // Ditto pd.Flags = PD_RETURNDEFAULT; pd.nCopies = 1; // Fill out the DEVMODE structure // so we can use it as input in the 'real' PrintDlg if (!PrintDlg(&pd)) { if ( pd.hDevMode ) GlobalFree(pd.hDevMode); if ( pd.hDevNames ) GlobalFree(pd.hDevNames); pd.hDevMode = NULL; pd.hDevNames = NULL; #if wxDEBUG_LEVEL wxLogDebug(wxT("Printing error: ") + wxGetPrintDlgError()); #endif // wxDEBUG_LEVEL } else { m_devMode = pd.hDevMode; pd.hDevMode = NULL; // We'll create a new DEVNAMEs structure below. if ( pd.hDevNames ) GlobalFree(pd.hDevNames); pd.hDevNames = NULL; // hDevNames = pd->hDevNames; // m_devNames = (void*)(long) hDevNames; // pd->hDevnames = NULL; } } }
static HANDLE LoadCustomPrinterHDEVMODE(HWND hWnd, const char *filepath) { char device[MAX_PATH]; HANDLE hPrinter = NULL; int sizeof_devmode; HGLOBAL hDevMode = NULL; DEVMODE *devmode = NULL; int res; FILE *fp = NULL; int block_size; int block_read; if ((fp = fopen(filepath, "rb")) == NULL) return NULL; if (fread(device, 1, dmDeviceNameSize, fp) != dmDeviceNameSize) goto err_exit; if (!OpenPrinter(device, &hPrinter, NULL)) goto err_exit; sizeof_devmode = (int) DocumentProperties(hWnd, hPrinter, device, NULL, NULL, 0); if (!sizeof_devmode) goto err_exit; hDevMode = GlobalAlloc(GHND, sizeof_devmode); if (!hDevMode) goto err_exit; devmode = (DEVMODE *) GlobalLock(hDevMode); if (!devmode) goto err_exit; res = DocumentProperties(hWnd, hPrinter, device, devmode, NULL, DM_OUT_BUFFER); if (res != IDOK) goto err_exit; block_size = devmode->dmSize + devmode->dmDriverExtra; block_read = fread(devmode, 1, block_size, fp); if (block_size != block_read) goto err_exit; fclose(fp); res = DocumentProperties(hWnd, hPrinter, device, devmode, devmode, DM_IN_BUFFER | DM_OUT_BUFFER); if (res != IDOK) goto err_exit; GlobalUnlock(hDevMode); ClosePrinter(hPrinter); return hDevMode; err_exit: if (fp) fclose(fp); if (devmode) GlobalUnlock(hDevMode); if (hDevMode) GlobalFree(hDevMode); if (hPrinter) ClosePrinter(hPrinter); return NULL; }
bool PrintFile(BaseEngine *engine, WCHAR *printerName, bool displayErrors, const WCHAR *settings) { bool ok = false; if (!HasPermission(Perm_PrinterAccess)) return false; #ifndef DISABLE_DOCUMENT_RESTRICTIONS if (engine && !engine->AllowsPrinting()) engine = NULL; #endif if (!engine) { if (displayErrors) MessageBoxWarning(NULL, _TR("Cannot print this file"), _TR("Printing problem.")); return false; } ScopedMem<WCHAR> defaultPrinter; if (!printerName) { defaultPrinter.Set(GetDefaultPrinterName()); printerName = defaultPrinter; } HANDLE printer; BOOL res = OpenPrinter(printerName, &printer, NULL); if (!res) { if (displayErrors) MessageBoxWarning(NULL, _TR("Printer with given name doesn't exist"), _TR("Printing problem.")); return false; } LPDEVMODE devMode = NULL; // get printer driver information DWORD needed = 0; GetPrinter(printer, 2, NULL, 0, &needed); ScopedMem<PRINTER_INFO_2> infoData((PRINTER_INFO_2 *)AllocArray<BYTE>(needed)); if (infoData) res = GetPrinter(printer, 2, (LPBYTE)infoData.Get(), needed, &needed); if (!res || !infoData || needed <= sizeof(PRINTER_INFO_2)) goto Exit; LONG structSize = DocumentProperties(NULL, printer, printerName, NULL, /* Asking for size, so */ NULL, /* not used. */ 0); /* Zero returns buffer size. */ if (structSize < sizeof(DEVMODE)) { // If failure, inform the user, cleanup and return failure. if (displayErrors) MessageBoxWarning(NULL, _TR("Could not obtain Printer properties"), _TR("Printing problem.")); goto Exit; } devMode = (LPDEVMODE)malloc(structSize); if (!devMode) goto Exit; // Get the default DevMode for the printer and modify it for your needs. LONG returnCode = DocumentProperties(NULL, printer, 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. if (displayErrors) MessageBoxWarning(NULL, _TR("Could not obtain Printer properties"), _TR("Printing problem.")); goto Exit; } ClosePrinter(printer); printer = NULL; { Print_Advanced_Data advanced; Vec<PRINTPAGERANGE> ranges; ApplyPrintSettings(settings, engine->PageCount(), ranges, advanced, devMode); PrintData pd(engine, infoData, devMode, ranges, advanced); ok = PrintToDevice(pd); if (!ok && displayErrors) MessageBoxWarning(NULL, _TR("Couldn't initialize printer"), _TR("Printing problem.")); } Exit: free(devMode); if (printer) ClosePrinter(printer); return ok; }
int _tmain(int argc, _TCHAR* argv[]) { // Before we can do anything, we need to unlock the DLL // NOTE: If you are evaluating FOXIT READER SDK, you don’t need unlock the DLL, // then evaluation marks will be shown with all rendered pages. FPDF_UnlockDLL("license_id", "unlock_code"); // first, load the document (no password specified) pdf_doc = FPDF_LoadDocument("testdoc.pdf", NULL); // error handling if (pdf_doc == NULL) { fprintf(stderr, "ERROR - doc\n"); exit(1); } // Open the out file fopen_s(&out, "test.spl", "wb"); // Send the StartDoc header wchar_t* dname = L"desktop.ini - Editor"; wchar_t* prn = L"c:\\output.prn"; { if (wcsnlen(dname, 255) == 255) ErrorExit(L"dname too long"); if (wcsnlen(prn, 255) == 255) ErrorExit(L"prn too long"); SPL_HEADER spl; spl.SIGNATURE=SPLMETA_SIGNATURE; spl.nSize=(DWORD)sizeof(spl)+wcslen(dname)*2+wcslen(prn)*2+4; // +4, because \0\0 is after dname and prn spl.offDocumentName=(DWORD)sizeof(spl); spl.offPort=(DWORD)sizeof(spl)+wcslen(dname)*2+2; // +2 because \0\0 is after dname fwrite(&spl, sizeof(spl), 1, out); fwrite(dname, wcslen(dname)*2, 1, out); fwrite("\0\0", 2, 1, out); fwrite(prn, wcslen(prn)*2, 1, out); fwrite("\0\0", 2, 1, out); } // Load the first page and calculate the bbox // based on the printer margins pdf_page = FPDF_LoadPage(pdf_doc, 0); if (pdf_page == NULL) ErrorExit(L"FPDF_LoadPage"); double page_width, page_height; page_width = FPDF_GetPageWidth(pdf_page); page_height = FPDF_GetPageHeight(pdf_page); #ifdef EXT_PRINT #ifdef EXT_PRNDLG PRINTDLG pd; HWND hwnd = NULL; // Initialize PRINTDLG ZeroMemory(&pd, sizeof(pd)); pd.lStructSize = sizeof(pd); pd.hwndOwner = hwnd; pd.hDevMode = NULL; // Don't forget to free or store hDevMode pd.hDevNames = NULL; // Don't forget to free or store hDevNames pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC; pd.nCopies = 1; pd.nFromPage = 0xFFFF; pd.nToPage = 0xFFFF; pd.nMinPage = 1; pd.nMaxPage = 0xFFFF; if (PrintDlg(&pd) != TRUE) ErrorExit(L"PrintDialog\n"); hDC = pd.hDC; #else wchar_t* printer=L"FF"; if (!OpenPrinter(printer, &hPrinter, NULL)) ErrorExit(L"OpenPrinter\n"); DWORD dwNeeded = DocumentProperties(NULL, hPrinter, printer, NULL, NULL, 0); lpDevMode = (LPDEVMODE)malloc(dwNeeded); DocumentProperties(NULL, hPrinter, printer, lpDevMode, NULL, DM_OUT_BUFFER); /* Try to set a higher print quality */ lpDevMode->dmPrintQuality=1200; lpDevMode->dmFields|=DM_PRINTQUALITY; DocumentProperties(NULL, hPrinter, printer, lpDevMode, lpDevMode, DM_IN_BUFFER | DM_OUT_BUFFER); #ifdef EXT_PRNOPTS DocumentProperties(NULL, hPrinter, printer, lpDevMode, lpDevMode, DM_IN_BUFFER | DM_PROMPT | DM_OUT_BUFFER); #endif hDC = CreateDC(L"WINEPS.DRV", printer, NULL, lpDevMode); ClosePrinter(&hPrinter); #endif #else hDC = CreateDC(L"WINEPS.DRV", L"FF", NULL, lpDevMode); #endif #ifdef PRINT DOCINFO doc_info; doc_info.cbSize=sizeof(DOCINFO)+12; doc_info.lpszDocName=dname; doc_info.lpszOutput=prn; doc_info.lpszDatatype=NULL; doc_info.fwType=0; // Start a printer job StartDoc(hDC, &doc_info); #endif // get number of pixels per inch (horizontally and vertically) logpixelsx = GetDeviceCaps(hDC, LOGPIXELSX); logpixelsy = GetDeviceCaps(hDC, LOGPIXELSY); // convert points into pixels size_x = (int)page_width / 72 * logpixelsx; size_y = (int)page_height / 72 * logpixelsy; DWORD p_width =GetDeviceCaps(hDC, HORZSIZE)*100; DWORD p_height=GetDeviceCaps(hDC, VERTSIZE)*100; SetRect( &rect, 0, 0, p_width, p_height ); #ifdef DEBUG //fprintf(stderr, "x=%u, y=%u, pw=%u, ph=%u,sx=%u,sy=%u,lpx=%u,lpy=%u,size_x=%u,size_y=%u\n",x,y,page_width,page_height,sx,sy,logpixelsx,logpixelsy,size_x,size_y); #endif // now load the pages one after another for (i=0; i < FPDF_GetPageCount(pdf_doc); i++) { #ifdef DEBUG fprintf(stderr, "Load page %d/%d\n", i, FPDF_GetPageCount(pdf_doc)); #endif // Load the next page pdf_page = FPDF_LoadPage(pdf_doc, i); if (pdf_page == NULL) ErrorExit(L"FPDF_LoadPage"); fbuf=NULL; #ifdef DEBUG sprintf_s(buf, 255, "test-%d.emf", i); //fbuf=buf; #endif // Create a metafile to render to hMeta = CreateEnhMetaFileA(hDC, fbuf, &rect, "SPLFilter.exe\0Created by Fabian\0\0"); if (hMeta == NULL) ErrorExit(L"CreateEnhMetaFileA"); // Call FPDF_RenderPage function to render the whole page FPDF_RenderPage(hMeta, pdf_page, 0, 0, size_x, size_y, 0, 0); #ifdef PRINT // Start a new printing page StartPage(hDC); FPDF_RenderPage(hDC, pdf_page, 0, 0, size_x, size_y, 0, 0); EndPage(hDC); #endif // Close PDF page FPDF_ClosePage(pdf_page); efile=CloseEnhMetaFile(hMeta); if (efile == NULL) ErrorExit(L"CloseEnhMetaFile"); // Write EMF data - via enumeration, because we want to embed fonts later EnumEnhMetaFile(hDC, efile, enum_it, NULL, &rect); // Write EndPage() record { SMR_EOPAGE smr_eopage; smr_eopage.smrext.smr.iType=SRT_EXT_EOPAGE_VECTOR; smr_eopage.smrext.smr.nSize=sizeof(smr_eopage)-sizeof(smr_eopage.smrext.smr); /* FIXME: Need to calcualte low and high correctly */ smr_eopage.smrext.DistanceLow=bufSize+smr_eopage.smrext.smr.nSize; smr_eopage.smrext.DistanceHigh=0; fwrite(&smr_eopage, sizeof(smr_eopage), 1, out); } DeleteEnhMetaFile(efile); } #ifdef PRINT EndDoc(hDC); #endif fclose(out); out=NULL; DeleteDC(hDC); FPDF_CloseDocument(pdf_doc); #ifdef DEBUG fprintf(stderr, "SPLFilter: Conversion successful!\n"); #endif exit(0); }
/* Get Device Context for printer */ static int win_pr2_getdc(gx_device_win_pr2 * wdev) { char *device; char *devices; char *p; char driverbuf[512]; char *driver; char *output; char *devcap; int devcapsize; int devmode_size; int i, n; POINT *pp; int paperindex; int paperwidth, paperheight; int orientation; int papersize; char papername[64]; LPDEVMODE podevmode, pidevmode; HANDLE hprinter; /* first try to derive the printer name from -sOutputFile= */ /* is printer if name prefixed by \\spool\ or by %printer% */ if (is_spool(wdev->fname)) { device = wdev->fname + 8; /* skip over \\spool\ */ wdev->use_old_spool_name = true; } else if (strncmp("%printer%",wdev->fname,9) == 0) { device = wdev->fname + 9; /* skip over %printer% */ wdev->use_old_spool_name = false; } else { return FALSE; } /* now try to match the printer name against the [Devices] section */ if ((devices = gs_malloc(wdev->memory, 4096, 1, "win_pr2_getdc")) == (char *)NULL) return FALSE; GetProfileString("Devices", NULL, "", devices, 4096); p = devices; while (*p) { if (stricmp(p, device) == 0) break; p += strlen(p) + 1; } if (*p == '\0') p = NULL; gs_free(wdev->memory, devices, 4096, 1, "win_pr2_getdc"); if (p == NULL) return FALSE; /* doesn't match an available printer */ /* the printer exists, get the remaining information from win.ini */ GetProfileString("Devices", device, "", driverbuf, sizeof(driverbuf)); driver = strtok(driverbuf, ","); output = strtok(NULL, ","); if (!OpenPrinter(device, &hprinter, NULL)) return FALSE; devmode_size = DocumentProperties(NULL, hprinter, device, NULL, NULL, 0); if ((podevmode = gs_malloc(wdev->memory, devmode_size, 1, "win_pr2_getdc")) == (LPDEVMODE) NULL) { ClosePrinter(hprinter); return FALSE; } if ((pidevmode = gs_malloc(wdev->memory, devmode_size, 1, "win_pr2_getdc")) == (LPDEVMODE) NULL) { gs_free(wdev->memory, podevmode, devmode_size, 1, "win_pr2_getdc"); ClosePrinter(hprinter); return FALSE; } DocumentProperties(NULL, hprinter, device, podevmode, NULL, DM_OUT_BUFFER); /* now find out what paper sizes are available */ devcapsize = DeviceCapabilities(device, output, DC_PAPERSIZE, NULL, NULL); devcapsize *= sizeof(POINT); if ((devcap = gs_malloc(wdev->memory, devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL) return FALSE; n = DeviceCapabilities(device, output, DC_PAPERSIZE, devcap, NULL); paperwidth = (int)(wdev->MediaSize[0] * 254 / 72); paperheight = (int)(wdev->MediaSize[1] * 254 / 72); papername[0] = '\0'; papersize = 0; paperindex = -1; orientation = 0; pp = (POINT *) devcap; for (i = 0; i < n; i++, pp++) { if ((pp->x < paperwidth + 20) && (pp->x > paperwidth - 20) && (pp->y < paperheight + 20) && (pp->y > paperheight - 20)) { paperindex = i; paperwidth = pp->x; paperheight = pp->y; orientation = DMORIENT_PORTRAIT; break; } } if (paperindex < 0) { /* try again in landscape */ pp = (POINT *) devcap; for (i = 0; i < n; i++, pp++) { if ((pp->x < paperheight + 20) && (pp->x > paperheight - 20) && (pp->y < paperwidth + 20) && (pp->y > paperwidth - 20)) { paperindex = i; paperwidth = pp->x; paperheight = pp->y; orientation = DMORIENT_LANDSCAPE; break; } } } gs_free(wdev->memory, devcap, devcapsize, 1, "win_pr2_getdc"); /* get the dmPaperSize */ devcapsize = DeviceCapabilities(device, output, DC_PAPERS, NULL, NULL); devcapsize *= sizeof(WORD); if ((devcap = gs_malloc(wdev->memory, devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL) return FALSE; n = DeviceCapabilities(device, output, DC_PAPERS, devcap, NULL); if ((paperindex >= 0) && (paperindex < n)) papersize = ((WORD *) devcap)[paperindex]; gs_free(wdev->memory, devcap, devcapsize, 1, "win_pr2_getdc"); /* get the paper name */ devcapsize = DeviceCapabilities(device, output, DC_PAPERNAMES, NULL, NULL); devcapsize *= 64; if ((devcap = gs_malloc(wdev->memory, devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL) return FALSE; n = DeviceCapabilities(device, output, DC_PAPERNAMES, devcap, NULL); if ((paperindex >= 0) && (paperindex < n)) strcpy(papername, devcap + paperindex * 64); gs_free(wdev->memory, devcap, devcapsize, 1, "win_pr2_getdc"); memcpy(pidevmode, podevmode, devmode_size); pidevmode->dmFields = 0; wdev->paper_name[0] = 0; if ( (wdev->user_paper) && (wdev->user_paper != papersize) ) { papersize = wdev->user_paper; paperheight = 0; paperwidth = 0; papername[0] = 0; } if (wdev->user_orient) { orientation = wdev->user_orient; } pidevmode->dmFields &= ~(DM_PAPERSIZE | DM_ORIENTATION | DM_COLOR | DM_PAPERLENGTH | DM_PAPERWIDTH | DM_DUPLEX); pidevmode->dmFields |= DM_DEFAULTSOURCE; pidevmode->dmDefaultSource = 0; if (orientation) { wdev->user_orient = orientation; } if (papersize) { wdev->user_paper = papersize; strcpy (wdev->paper_name, papername); } if (paperheight && paperwidth) { pidevmode->dmFields |= (DM_PAPERLENGTH | DM_PAPERWIDTH); pidevmode->dmPaperWidth = paperwidth; pidevmode->dmPaperLength = paperheight; wdev->user_media_size[0] = paperwidth / 254.0 * 72.0; wdev->user_media_size[1] = paperheight / 254.0 * 72.0; } if (DeviceCapabilities(device, output, DC_DUPLEX, NULL, NULL)) { wdev->Duplex_set = 1; } win_pr2_update_win(wdev, pidevmode); /* merge the entries */ DocumentProperties(NULL, hprinter, device, podevmode, pidevmode, DM_IN_BUFFER | DM_OUT_BUFFER); ClosePrinter(hprinter); /* now get a DC */ wdev->hdcprn = CreateDC(driver, device, NULL, podevmode); if (wdev->win32_hdevmode == NULL) wdev->win32_hdevmode = GlobalAlloc(0, devmode_size); if (wdev->win32_hdevmode) { LPDEVMODE pdevmode = (LPDEVMODE) GlobalLock(wdev->win32_hdevmode); if (pdevmode) { memcpy(pdevmode, podevmode, devmode_size); GlobalUnlock(wdev->win32_hdevmode); } } gs_free(wdev->memory, pidevmode, devmode_size, 1, "win_pr2_getdc"); gs_free(wdev->memory, podevmode, devmode_size, 1, "win_pr2_getdc"); if (wdev->hdcprn != (HDC) NULL) return TRUE; /* success */ /* fall back to prompting user */ return FALSE; }
void setAttributes(const char *printer, const int pdcID, AttributesUnion attributes) { HDC pdc = printerDCs[pdcID]; if (pdc != NULL) { DEVMODE *pDevMode = NULL; HANDLE hPrinter; if (OpenPrinter((LPTSTR)printer, &hPrinter, NULL) != 0) { int size = DocumentProperties(NULL, hPrinter, NULL, pDevMode, NULL, 0); pDevMode = (DEVMODE *)malloc(size); if (DocumentProperties(NULL, hPrinter, NULL, pDevMode, NULL, DM_OUT_BUFFER) == IDOK) { pDevMode->dmFields = 0; if (attributes.fields.PaperID > 0) { pDevMode->dmPaperSize = (short)attributes.fields.PaperID; pDevMode->dmFields |= DM_PAPERSIZE; } if (attributes.fields.Copies > 0) { pDevMode->dmCopies = (short)attributes.fields.Copies; pDevMode->dmFields |= DM_COPIES; } if (attributes.fields.Collate > 0) { if (attributes.fields.Collate == 1) { pDevMode->dmCollate = DMCOLLATE_TRUE; } else { pDevMode->dmCollate = DMCOLLATE_FALSE; } pDevMode->dmFields |= DM_COLLATE; } if (attributes.fields.Sides > 0) { pDevMode->dmDuplex = (short)attributes.fields.Sides; pDevMode->dmFields |= DM_DUPLEX; } if (attributes.fields.Chromaticity > 0) { if (attributes.fields.Chromaticity == 1) { pDevMode->dmColor = DMCOLOR_MONOCHROME; } else { pDevMode->dmColor = DMCOLOR_COLOR; } pDevMode->dmFields |= DM_COLOR; } if (attributes.fields.Orientation > 0) { if (attributes.fields.Orientation == 2) { pDevMode->dmOrientation = DMORIENT_LANDSCAPE; } else { pDevMode->dmOrientation = DMORIENT_PORTRAIT; } pDevMode->dmFields |= DM_ORIENTATION; } if (attributes.fields.XResolution > 0) { pDevMode->dmPrintQuality = (short)attributes.fields.XResolution; pDevMode->dmFields |= DM_PRINTQUALITY; } if (attributes.fields.YResolution > 0) { pDevMode->dmYResolution = (short)attributes.fields.YResolution; pDevMode->dmFields |= DM_YRESOLUTION; } if (pDevMode->dmFields != 0) { #ifdef PRINTING_DEBUG printf("Setting up print attributes.\n"); #endif /* PRINTING_DEBUG */ ResetDC(pdc, pDevMode); } } ClosePrinter(hPrinter); } } }
JNIEXPORT jint JNICALL Java_org_apache_harmony_x_print_GDIClient_startDocPrinter (JNIEnv *env, jclass owner, jstring printerName, jintArray printAttributes, jstring jobName, jstring destination) { const char *printer = env->GetStringUTFChars(printerName, 0); const char *jn = env->GetStringUTFChars(jobName, 0); char *jname = new char[strlen(jn) + 1]; char *fname = NULL; strcpy(jname, jn); if (destination != NULL) { const char *fn = env->GetStringUTFChars(destination, 0); fname = new char[strlen(fn) + 1]; strcpy(fname, fn); } AttributesUnion attributes; jboolean isCopy = JNI_FALSE; int *numbers = (int *)env->GetIntArrayElements(printAttributes, &isCopy); for (int i = 0; i < ATTRIBUTE_UNION_SIZE; i++) { attributes.numbers[i] = numbers[i]; } jint res = 0; HANDLE hPrinter = NULL; if (OpenPrinter((LPTSTR)printer, &hPrinter, NULL) != 0) { DOC_INFO_1 dinfo; dinfo.pDocName = jname; dinfo.pDatatype = "RAW"; dinfo.pOutputFile = fname; DEVMODE *pDevMode = NULL; int size = DocumentProperties(NULL, hPrinter, NULL, pDevMode, NULL, 0); pDevMode = (DEVMODE *)malloc(size); // if (DocumentProperties(NULL, hPrinter, NULL, pDevMode, NULL, DM_PROMPT) == IDOK) { if (DocumentProperties(NULL, hPrinter, NULL, pDevMode, NULL, DM_OUT_BUFFER) == IDOK) { #ifdef PRINTING_DEBUG printf("DEVMODE received successfuly!\n"); #endif /* PRINTING_DEBUG */ if (attributes.fields.Copies > 0) { pDevMode->dmCopies = (short)attributes.fields.Copies; pDevMode->dmFields |= DM_COPIES; } if (attributes.fields.Sides > 0) { pDevMode->dmDuplex = (short)attributes.fields.Sides; pDevMode->dmFields |= DM_DUPLEX; } if (attributes.fields.PaperID > 0) { pDevMode->dmPaperSize = (short)attributes.fields.PaperID; pDevMode->dmFields |= DM_PAPERSIZE; } if (DocumentProperties(NULL, hPrinter, NULL, pDevMode, pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER) == IDOK) { } } else { #ifdef PRINTING_DEBUG printf("Can't get initial DEVMODE.\n"); #endif /* PRINTING_DEBUG */ } if (StartDocPrinter(hPrinter, 1, (LPBYTE)&dinfo) != 0) { res = *((int *)&hPrinter); } } #ifdef PRINTING_DEBUG if (res == 0) { DWORD error = GetLastError(); printf("Error occurred while starting: %d.\n", error); } if (res != 0) { file = fopen("C:\\from_Native.ps", "wb+"); } #endif /* PRINTING_DEBUG */ return res; }