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; } }
QPrint::DeviceState QWindowsPrintDevice::state() const { DWORD needed = 0; GetPrinter(m_hPrinter, 6, 0, 0, &needed); QScopedArrayPointer<BYTE> buffer(new BYTE[needed]); if (GetPrinter(m_hPrinter, 6, buffer.data(), needed, &needed)) { PPRINTER_INFO_6 info = reinterpret_cast<PPRINTER_INFO_6>(buffer.data()); // TODO Check mapping if (info->dwStatus == 0 || (info->dwStatus & PRINTER_STATUS_WAITING) == PRINTER_STATUS_WAITING || (info->dwStatus & PRINTER_STATUS_POWER_SAVE) == PRINTER_STATUS_POWER_SAVE) { return QPrint::Idle; } else if ((info->dwStatus & PRINTER_STATUS_PRINTING) == PRINTER_STATUS_PRINTING || (info->dwStatus & PRINTER_STATUS_BUSY) == PRINTER_STATUS_BUSY || (info->dwStatus & PRINTER_STATUS_INITIALIZING) == PRINTER_STATUS_INITIALIZING || (info->dwStatus & PRINTER_STATUS_IO_ACTIVE) == PRINTER_STATUS_IO_ACTIVE || (info->dwStatus & PRINTER_STATUS_PROCESSING) == PRINTER_STATUS_PROCESSING || (info->dwStatus & PRINTER_STATUS_WARMING_UP) == PRINTER_STATUS_WARMING_UP) { return QPrint::Active; } } return QPrint::Error; }
static LPBYTE GetPrinterInfo(HANDLE hPrinter, int nLevel) { LPBYTE pData = NULL; DWORD cbNeeded; /* // Make an initial call to see how much data we need. */ if (!GetPrinter(hPrinter, nLevel, NULL, 0, &cbNeeded)) { /* // Allocate memory for the data. */ DWORD cbBuf = cbNeeded; pData = new BYTE[cbBuf]; /* // Get the data. */ if (!GetPrinter(hPrinter, nLevel, pData, cbBuf, &cbNeeded)) { delete pData; pData = NULL; } } return pData; }
QWindowsPrintDevice::QWindowsPrintDevice(const QString &id) : QPlatformPrintDevice(id), m_hPrinter(0) { // First do a fast lookup to see if printer exists, if it does then open it if (!id.isEmpty() && QWindowsPrintDevice::availablePrintDeviceIds().contains(id)) { if (OpenPrinter((LPWSTR)m_id.utf16(), &m_hPrinter, NULL)) { DWORD needed = 0; GetPrinter(m_hPrinter, 2, 0, 0, &needed); QScopedArrayPointer<BYTE> buffer(new BYTE[needed]); if (GetPrinter(m_hPrinter, 2, buffer.data(), needed, &needed)) { PPRINTER_INFO_2 info = reinterpret_cast<PPRINTER_INFO_2>(buffer.data()); m_name = QString::fromWCharArray(info->pPrinterName); m_location = QString::fromWCharArray(info->pLocation); m_makeAndModel = QString::fromWCharArray(info->pDriverName); // TODO Check is not available elsewhere m_isRemote = info->Attributes & PRINTER_ATTRIBUTE_NETWORK; } m_supportsMultipleCopies = (DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_COPIES, NULL, NULL) > 1); m_supportsCollateCopies = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_COLLATE, NULL, NULL); // Min/Max custom size is in tenths of a millimeter const qreal multiplier = qt_pointMultiplier(QPageLayout::Millimeter); DWORD min = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_MINEXTENT, NULL, NULL); m_minimumPhysicalPageSize = QSize((LOWORD(min) / 10.0) * multiplier, (HIWORD(min) / 10.0) * multiplier); DWORD max = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_MAXEXTENT, NULL, NULL); m_maximumPhysicalPageSize = QSize((LOWORD(max) / 10.0) * multiplier, (HIWORD(max) / 10.0) * multiplier); m_supportsCustomPageSizes = (m_maximumPhysicalPageSize.width() > 0 && m_maximumPhysicalPageSize.height() > 0); } } }
static HB_BOOL hb_GetJobs( HANDLE hPrinter, JOB_INFO_2 ** ppJobInfo, DWORD * pdwJobs ) { HB_BOOL bResult = HB_FALSE; DWORD dwNeeded = 0; GetPrinter( hPrinter, 2, NULL, 0, &dwNeeded ); if( dwNeeded ) { PRINTER_INFO_2 * pPrinterInfo = ( PRINTER_INFO_2 * ) hb_xgrabz( dwNeeded ); DWORD dwUsed = 0; if( GetPrinter( hPrinter, 2, ( LPBYTE ) pPrinterInfo, dwNeeded, &dwUsed ) ) { DWORD dwReturned = 0; EnumJobs( hPrinter, 0, pPrinterInfo->cJobs, 2, NULL, 0, &dwNeeded, &dwReturned ); if( dwNeeded ) { JOB_INFO_2 * pJobInfo = ( JOB_INFO_2 * ) hb_xgrabz( dwNeeded ); if( EnumJobs( hPrinter, 0, dwReturned, 2, ( LPBYTE ) pJobInfo, dwNeeded, &dwUsed, &dwReturned ) ) { *pdwJobs = dwReturned; *ppJobInfo = pJobInfo; bResult = HB_TRUE; } else hb_xfree( pJobInfo ); } } hb_xfree( pPrinterInfo ); } return bResult; }
static rdpPrinter* printer_win_new_printer(rdpWinPrinterDriver* win_driver, const char* name, const wchar_t* drivername, BOOL is_default) { rdpWinPrinter* win_printer; wchar_t wname[256]; DWORD needed; PRINTER_INFO_2 *prninfo=NULL; size_t charsConverted; DEBUG_WINPR(""); win_printer = (rdpWinPrinter*) malloc(sizeof(rdpWinPrinter)); ZeroMemory(win_printer, sizeof(rdpWinPrinter)); win_printer->printer.id = win_driver->id_sequence++; win_printer->printer.name = _strdup(name); win_printer->printer.is_default = is_default; win_printer->printer.CreatePrintJob = printer_win_create_printjob; win_printer->printer.FindPrintJob = printer_win_find_printjob; win_printer->printer.Free = printer_win_free_printer; swprintf(wname, 256, L"%hs", name); OpenPrinter(wname, &(win_printer->hPrinter), NULL); DEBUG_WINPR("handle: 0x%08X", win_printer->hPrinter); GetPrinter(win_printer->hPrinter, 2, (LPBYTE) prninfo, 0, &needed); prninfo = (PRINTER_INFO_2*) GlobalAlloc(GPTR,needed); GetPrinter(win_printer->hPrinter, 2, (LPBYTE) prninfo, needed, &needed); win_printer->printer.driver = malloc(1000); wcstombs_s(&charsConverted, win_printer->printer.driver, 1000, prninfo->pDriverName, _TRUNCATE); return (rdpPrinter*)win_printer; }
EXTDEVMODE* pGetPrintmanDevmode( PRASDDUIINFO pRasdduiInfo) { DWORD dwBufSize = 0; DWORD dwNeeded = 0; PRINTER_INFO_2 *pPrinterInfo = 0; EXTDEVMODE* pEDM = 0; ASSERT(pRasdduiInfo); TRY /* Get buffer size and allocate. */ GetPrinter(pRasdduiInfo->hPrinter, 2, 0, 0, &dwNeeded); pPrinterInfo = (PRINTER_INFO_2 *) HeapAlloc(pRasdduiInfo->hHeap, 0, dwNeeded); if (!pPrinterInfo) { LEAVE; } /* Now get data. */ if (!GetPrinter(pRasdduiInfo->hPrinter, 2, (LPBYTE) pPrinterInfo, dwNeeded, &dwNeeded)) { RASUIDBGP( (DEBUG_WARN) , ("\nRasddui!pGetPrintmanDevmode:HeapAlloc Call Failed!!")); LEAVE; } /* Allocate and copy. */ pEDM = pPrinterInfo->pDevMode ? (EXTDEVMODE*) HeapAlloc(pRasdduiInfo->hHeap, 0, pPrinterInfo->pDevMode->dmSize) : 0; if (pEDM) { CopyMemory(pEDM, pPrinterInfo->pDevMode, pPrinterInfo->pDevMode->dmSize); TRACE(1 , ("\nRasddui!pGetPrintmanDevmode:Call to GetPrinter Succeeded")); } ENDTRY FINALLY if (pPrinterInfo) { HeapFree(pRasdduiInfo->hHeap, 0, pPrinterInfo); } ENDFINALLY return(pEDM); }
static BOOL test_GetPrinter(struct torture_context *tctx, LPSTR printername, HANDLE handle) { DWORD levels[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; DWORD success[] = { 1, 1, 1, 1, 1, 1, 1, 1 }; DWORD i; LPBYTE buffer = NULL; for (i=0; i < ARRAY_SIZE(levels); i++) { DWORD needed = 0; DWORD err = 0; char tmp[1024]; torture_comment(tctx, "Testing GetPrinter level %d", levels[i]); GetPrinter(handle, levels[i], NULL, 0, &needed); err = GetLastError(); if (err == ERROR_INSUFFICIENT_BUFFER) { err = 0; buffer = malloc(needed); torture_assert(tctx, buffer, "malloc failed"); if (!GetPrinter(handle, levels[i], buffer, needed, &needed)) { err = GetLastError(); } } if (err) { sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n", levels[i], printername, needed, errstr(err)); if (success[i]) { torture_fail(tctx, tmp); } else { torture_warning(tctx, tmp); } } free(buffer); buffer = NULL; } return TRUE; }
bool kGUISystemWin::CreateHDC(const char *printerName,int numcopies,HDC *hdc) { HANDLE hPrinter; bool ok=false; if (OpenPrinter(const_cast<TCHAR*>(printerName),&hPrinter,NULL)) { LPPRINTER_INFO_2 lpPrinterInfo2=NULL; DWORD sizeOfPrintInfo=0; DWORD cbReturned=0; GetPrinter(hPrinter, 2, NULL, 0, &sizeOfPrintInfo); lpPrinterInfo2=(LPPRINTER_INFO_2)new char[sizeOfPrintInfo]; if (GetPrinter(hPrinter, // handle to printer 2, // information level (LPBYTE)lpPrinterInfo2, // printer information buffer sizeOfPrintInfo, // size of buffer &cbReturned)) // bytes received or required { numcopiesreq=numcopies; if(lpPrinterInfo2->pDevMode->dmFields&DM_COPIES) { // multicopies=true; numcopiessent=numcopies; lpPrinterInfo2->pDevMode->dmCopies=numcopies; } else { // multicopies=false; numcopiessent=1; lpPrinterInfo2->pDevMode->dmCopies=1; } *(hdc)=CreateDC(lpPrinterInfo2->pDriverName, lpPrinterInfo2->pPrinterName, NULL, lpPrinterInfo2->pDevMode); ok=true; } delete[] lpPrinterInfo2; lpPrinterInfo2=NULL; } return(ok); };
PRINTER_INFO_2 *GetPrinterInfo(const char *name) { PRINTER_INFO_2 *result = NULL; char *editableName = new char[strlen(name) + 1]; strcpy(editableName, name); HANDLE hPrinter; if (OpenPrinter(editableName, &hPrinter, NULL)) { unsigned char *buffer = NULL; DWORD cbNeeded; if (!GetPrinter(hPrinter, 2, buffer, 0, &cbNeeded)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { buffer = new unsigned char[cbNeeded]; if (GetPrinter(hPrinter, 2, buffer, cbNeeded, &cbNeeded)) { result = (PRINTER_INFO_2 *)buffer; } } } } delete[] editableName; return result; }
PVOID MyGetPrinter( HANDLE hPrinter, DWORD level ) /*++ Routine Description: Wrapper function for GetPrinter spooler API Arguments: hPrinter - Handle to the printer of interest level - Specifies the level of PRINTER_INFO_x structure Return Value: Pointer to a PRINTER_INFO_x structure, NULL if there is an error --*/ { PBYTE pPrinterInfo = NULL; DWORD cbNeeded; if (!GetPrinter(hPrinter, level, NULL, 0, &cbNeeded) && GetLastError() == ERROR_INSUFFICIENT_BUFFER && (pPrinterInfo = MemAlloc(cbNeeded)) && GetPrinter(hPrinter, level, pPrinterInfo, cbNeeded, &cbNeeded)) { return pPrinterInfo; } Error(("GetPrinter failed\n")); MemFree(pPrinterInfo); return NULL; }
/* ========================================================================= Updates the Preferences from the global gLptPrefs object and sets up any necessary variables for emulation if the modes change. ========================================================================= */ void VTLpt::UpdatePreferences(Fl_Preferences* pPref) { int count, c; VTPrinter* pPrint; // Save the preferences pointer if (pPref != NULL) m_pPref = pPref; // Test if the emulation mode is being changed if (m_EmulationMode != gLptPrefs.lpt_mode) { // Test if an active print job is still pending completion if (m_pActivePrinter != NULL) { // Test if the printer is changing if (m_pActivePrinter->GetName() != gLptPrefs.lpt_emul_name) m_pActivePrinter->EndPrintSession(); m_pActivePrinter->Deinit(); } } // Set the new emulation mode m_EmulationMode = gLptPrefs.lpt_mode; m_ConvertCRtoLF = gLptPrefs.lpt_cr2lf; // If emulation is enabled, get pointer to the Priner Class m_pActivePrinter = NULL; if (m_EmulationMode == LPT_MODE_EMUL) { count = GetPrinterCount(); for (c = 0; c < count; c++) { // Get pointer to next printer pPrint = GetPrinter(c); if (strcmp(gLptPrefs.lpt_emul_name, (const char *) pPrint->GetName()) == 0) { m_pActivePrinter = pPrint; break; } } } // Initialize the active printer if (m_pActivePrinter != NULL) m_pActivePrinter->Init(m_pPref); if (m_pMonCallback != NULL) m_pMonCallback(LPT_MON_EMULATION_CHANGE, 0); }
BOOL IOemPS::isTSPrinter(HANDLE hPrinter){ DWORD dwBytesReturned, dwBytesNeeded; GetPrinter(hPrinter, 2, NULL, NULL, &dwBytesNeeded); PRINTER_INFO_2* p2 = (PRINTER_INFO_2*)GlobalAlloc(GPTR, dwBytesNeeded); if ( ! ::GetPrinter(hPrinter, 2, (LPBYTE)p2, dwBytesNeeded, &dwBytesReturned)){ GlobalFree(p2); return FALSE; } if (p2->Attributes & PRINTER_ATTRIBUTE_TS){ GlobalFree(p2); return TRUE; } /* on Windows XP, no support for PRINTER_ATTRIBUTE_TS attribute*/ if ( wcsncmp(p2->pPortName, L"TS", 2) == 0){ GlobalFree(p2); return TRUE; } GlobalFree(p2); return FALSE; }
int main (int argc, char* argv[]) { HANDLE printer; PRINTER_DEFAULTS defaults; PPRINTER_INFO_2 buffer2 = NULL; DWORD needed, returned; memset(&defaults, 0x0, sizeof(PRINTER_DEFAULTS)); defaults.pDatatype = strdup("RAW"); if (argc < 2) { fprintf (stderr, "useage: %s <printername>\n", argv[0]); exit (-1); } if (!OpenPrinter (argv[1], &printer, NULL)) { PrintLastError(); exit (-1); } else printf ("Printer [%s] opened successfully.\n\n", argv[1]); /* INFO LEVEL 2 */ needed = returned = 0; GetPrinter(printer, 2, (LPBYTE)buffer2, 0, &needed); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { if (needed != 0) fprintf (stderr, "Error GetPrinter Info Level 2 for [%s] using NULL buffer.\n", argv[1]); else printf ("Info level 2 returned no information\n"); goto done; } if ((buffer2 = (LPBYTE)malloc(needed*2)) == NULL) { fprintf (stderr, "Unable to malloc memory for buffer!\n"); exit (-1); } if (!GetPrinter(printer, 2, (LPBYTE)buffer2, needed, &returned)) { fprintf (stderr, "Error getting printers Info Level 2 for [%s].\nSize of buffer = 0x%x [0x%x]\n", argv[1], needed, returned); PrintLastError(); } defaults.pDevMode = buffer2->pDevMode; if (!ResetPrinter(printer, &defaults)) PrintLastError(); done: if (!ClosePrinter(printer)) PrintLastError(); else printf ("Printer [%s] closed successfully.\n", argv[1]); return 0; }
/* ========================================================================= Generates a Printer Properties dialog box based on the current emulation mode with parameters appropriate for the "printer" needs. ========================================================================= */ void VTLpt::PrinterProperties(int useActivePrinter) { int count, c; int found; VTPrinter* pPrint = NULL; // Test if printer emulation is enabled if (useActivePrinter) { if (m_EmulationMode == LPT_MODE_NONE) { fl_message("Printer emulation not enabled"); return; } if (m_pActivePrinter == NULL) { fl_message("Printer not selected"); return; } } else { if (!gLptCtrl.pEmul->value()) { fl_message("Printer emulation not enabled"); return; } if (gLptCtrl.pEmulPrint->value() == -1) { fl_message("Printer not selected"); return; } } // Create a dialog box first m_pProp = new Fl_Window(400, 350, "Printer Properties"); // Create property page from selected printer count = GetPrinterCount(); for (c = 0; c < count; c++) { // Get pointer to next printer pPrint = GetPrinter(c); found = 0; if (useActivePrinter) { if (pPrint == m_pActivePrinter) found = 1; } else { if (strcmp(gLptCtrl.pEmulPrint->text(), (const char *) pPrint->GetName()) == 0) found = 1; } if (found) { if (pPrint != m_pActivePrinter) pPrint->Init(m_pPref); pPrint->BuildPropertyDialog(m_pProp); if (pPrint != m_pActivePrinter) pPrint->Deinit(); break; } } // Create Ok and Cancel button m_pCancel = new Fl_Button(m_pProp->w() - 165, m_pProp->h()-40, 60, 30, "Cancel"); m_pCancel->callback(cb_PrintProp_Cancel); m_pOk = new Fl_Return_Button(m_pProp->w()-90, m_pProp->h()-40, 60, 30, "Ok"); m_pOk->callback(cb_PrintProp_Ok, pPrint); // Show the dialog box m_pProp->end(); m_pProp->show(); m_pProp->redraw(); }
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; }
LRESULT CWatermarkDlg::OnInitDialog(HWND hWnd, LPARAM /*lParam*/) { CenterWindow(GetParent()); // First DDX call, hooks up variables to controls. DoDataExchange(false); m_wndWatermark.AddString(_T("无水印")); m_wndWatermark.AddString(_T("位图水印")); m_wndWatermark.AddString(_T("文字水印")); m_wndWatermark.SetCurSel(0); m_wndWatermarkText.AddString(_T("CONFIDENTIAL")); m_wndWatermarkText.AddString(_T("DO NOT COPY")); m_wndWatermarkText.AddString(_T("TOP SECRET")); m_wndWatermarkText.AddString(_T("DRAFT")); m_wndWatermarkText.AddString(_T("PROOF")); m_wndWatermarkText.AddString(_T("FINAL")); m_wndWatermarkText.AddString(_T("COPY")); m_wndWatermarkText.AddString(_T("FILE COPY")); DWORD cb = 0; GetPrinter(m_pUICtxt->PrinterHandle(), 2, NULL, 0, &cb); BYTE *pBBuf = (BYTE *)malloc(cb); if (pBBuf != NULL) { // now actually try to get the printer info structure GetPrinter(m_pUICtxt->PrinterHandle(), 2, pBBuf, cb, &cb); // now check if a name string is present PRINTER_INFO_2 *pPI2 = (PRINTER_INFO_2*)pBBuf; PARFONTS parFonts; INT nFaces = 0; HDC hdc = CreateDC (pPI2->pDriverName, pPI2->pPrinterName, pPI2->pPortName, NULL); parFonts = BuildFontList (hdc, &nFaces); //填写字体列表 for (int i = 0; i < nFaces; i++) { m_wndFontType.AddString(((parFonts + i)->lf)->lfFaceName); } LocalFree(parFonts); m_wndFontType.SelectString(-1, _T("宋体")); DeleteDC(hdc); // free the info buffer free(pBBuf); } m_wndFontStyle.AddString(_T("常规")); m_wndFontStyle.AddString(_T("斜体")); m_wndFontStyle.AddString(_T("粗体")); m_wndFontStyle.AddString(_T("粗斜体")); m_wndFontStyle.SetCurSel(0); m_wndWatermarkPosition.AddString(_T("Left-Top")); m_wndWatermarkPosition.AddString(_T("Center-Top")); m_wndWatermarkPosition.AddString(_T("Right-Top")); m_wndWatermarkPosition.AddString(_T("Left-Middle")); m_wndWatermarkPosition.AddString(_T("Center-Middle")); m_wndWatermarkPosition.AddString(_T("Right-Middle")); m_wndWatermarkPosition.AddString(_T("Left-Bottom")); m_wndWatermarkPosition.AddString(_T("Center-Bottom")); m_wndWatermarkPosition.AddString(_T("Right-Bottom")); m_wndWatermarkPosition.AddString(_T("Tiled")); m_wndWatermarkPosition.SetCurSel(4); for (int i = 8; i <= 72; ++i) { TCHAR szBuf[MAX_PATH] = {0}; _stprintf_s(szBuf, MAX_PATH, _T("%d"), i); m_wndFontSize.AddString(szBuf); } m_wndFontSize.SelectString(-1, _T("48")); m_wndAngleTrack.Attach(GetDlgItem(IDC_ANGLE_SLIDER)); m_wndAngleTrack.SetRange(0, 360); m_wndAngleTrack.SetPos(m_nAngle); m_wndSizeTrack.Attach(GetDlgItem(IDC_WATERMARK_SIZE_SLIDER)); m_wndSizeTrack.SetRange(1, 100); m_wndSizeTrack.SetPos(m_nSize); m_wndBrightnessTrack.Attach(GetDlgItem(IDC_BRIGHTNESS_SLIDER)); m_wndBrightnessTrack.SetRange(1, 255); m_wndBrightnessTrack.SetPos(m_nBrightness); BOOL enableWatermark = m_wndWatermark.GetCurSel() != 0; BOOL enableTextWatermark = m_wndWatermark.GetCurSel() == 2; ::EnableWindow(GetDlgItem(IDC_BROWSER), enableWatermark && !enableTextWatermark); ::EnableWindow(GetDlgItem(IDC_FILE), enableWatermark && !enableTextWatermark); ::EnableWindow(GetDlgItem(IDC_WATERMARK_TEXT), enableWatermark && enableTextWatermark); ::EnableWindow(GetDlgItem(IDC_FONT_TYPE), enableWatermark && enableTextWatermark); ::EnableWindow(GetDlgItem(IDC_FONT_STYLE), enableWatermark && enableTextWatermark); ::EnableWindow(GetDlgItem(IDC_FONT_SIZE), enableWatermark && enableTextWatermark); ::EnableWindow(GetDlgItem(IDC_ANGLE_SLIDER), enableWatermark && enableTextWatermark); ::EnableWindow(GetDlgItem(IDC_WATERMARK_SIZE_SLIDER), enableWatermark); ::EnableWindow(GetDlgItem(IDC_BRIGHTNESS_SLIDER), enableWatermark); ::EnableWindow(GetDlgItem(IDC_PIINT_POSITION), enableWatermark); return TRUE; }
static HB_BOOL hb_SetDefaultPrinter( LPCTSTR lpPrinterName ) { #if ! defined( HB_OS_WIN_CE ) BOOL bFlag; DWORD dwNeeded = 0; HANDLE hPrinter = NULL; PRINTER_INFO_2 * ppi2 = NULL; LPTSTR pBuffer = NULL; /* If Windows 95 or 98, use SetPrinter. */ if( hb_iswin9x() ) { /* Open this printer so you can get information about it. */ bFlag = OpenPrinter( ( LPTSTR ) lpPrinterName, &hPrinter, NULL ); if( ! bFlag || ! hPrinter ) return HB_FALSE; /* The first GetPrinter() tells you how big our buffer must be to hold ALL of PRINTER_INFO_2. Note that this will typically return FALSE. This only means that the buffer (the 3rd parameter) was not filled in. You do not want it filled in here. */ SetLastError( 0 ); bFlag = GetPrinter( hPrinter, 2, 0, 0, &dwNeeded ); if( ! bFlag ) { if( ( GetLastError() != ERROR_INSUFFICIENT_BUFFER ) || ( dwNeeded == 0 ) ) { ClosePrinter( hPrinter ); return HB_FALSE; } } /* Allocate enough space for PRINTER_INFO_2. */ ppi2 = ( PRINTER_INFO_2 * ) hb_xgrab( dwNeeded ); /* The second GetPrinter() will fill in all the current information so that all you have to do is modify what you are interested in. */ bFlag = GetPrinter( hPrinter, 2, ( LPBYTE ) ppi2, dwNeeded, &dwNeeded ); if( ! bFlag ) { ClosePrinter( hPrinter ); hb_xfree( ppi2 ); return HB_FALSE; } /* Set default printer attribute for this printer. */ ppi2->Attributes |= PRINTER_ATTRIBUTE_DEFAULT; bFlag = SetPrinter( hPrinter, 2, ( LPBYTE ) ppi2, 0 ); if( ! bFlag ) { ClosePrinter( hPrinter ); hb_xfree( ppi2 ); return HB_FALSE; } /* Tell all open programs that this change occurred. Allow each program 1 second to handle this message. */ SendMessageTimeout( HWND_BROADCAST, WM_SETTINGCHANGE, 0L, ( LPARAM ) ( LPCTSTR ) TEXT( "windows" ), SMTO_NORMAL, 1000, NULL ); } /* If Windows NT, use the SetDefaultPrinter API for Windows 2000, or WriteProfileString for version 4.0 and earlier. */ else if( hb_iswinnt() ) { if( hb_iswin2k() ) /* Windows 2000 or later (use explicit call) */ { HMODULE hWinSpool; typedef BOOL ( WINAPI * DEFPRINTER )( LPCTSTR ); /* stops warnings */ DEFPRINTER fnSetDefaultPrinter; hWinSpool = hbwapi_LoadLibrarySystem( TEXT( "winspool.drv" ) ); if( ! hWinSpool ) return HB_FALSE; fnSetDefaultPrinter = ( DEFPRINTER ) HB_WINAPI_GETPROCADDRESST( hWinSpool, "SetDefaultPrinter" ); if( ! fnSetDefaultPrinter ) { FreeLibrary( hWinSpool ); return HB_FALSE; } bFlag = ( *fnSetDefaultPrinter )( lpPrinterName ); FreeLibrary( hWinSpool ); if( ! bFlag ) return HB_FALSE; } else /* NT4.0 or earlier */ { HB_ISIZ nStrLen; /* Open this printer so you can get information about it. */ bFlag = OpenPrinter( ( LPTSTR ) lpPrinterName, &hPrinter, NULL ); if( ! bFlag || ! hPrinter ) return HB_FALSE; /* The first GetPrinter() tells you how big our buffer must be to hold ALL of PRINTER_INFO_2. Note that this will typically return FALSE. This only means that the buffer (the 3rd parameter) was not filled in. You do not want it filled in here. */ SetLastError( 0 ); bFlag = GetPrinter( hPrinter, 2, 0, 0, &dwNeeded ); if( ! bFlag ) { if( ( GetLastError() != ERROR_INSUFFICIENT_BUFFER ) || ( dwNeeded == 0 ) ) { ClosePrinter( hPrinter ); return HB_FALSE; } } /* Allocate enough space for PRINTER_INFO_2. */ ppi2 = ( PRINTER_INFO_2 * ) hb_xgrab( dwNeeded ); /* The second GetPrinter() fills in all the current information. */ bFlag = GetPrinter( hPrinter, 2, ( LPBYTE ) ppi2, dwNeeded, &dwNeeded ); if( ( ! bFlag ) || ( ! ppi2->pDriverName ) || ( ! ppi2->pPortName ) ) { ClosePrinter( hPrinter ); hb_xfree( ppi2 ); return HB_FALSE; } nStrLen = hbwapi_tstrlen( lpPrinterName ) + hbwapi_tstrlen( ppi2->pDriverName ) + hbwapi_tstrlen( ppi2->pPortName ) + 2; /* Allocate buffer big enough for concatenated string. String will be in form "printername,drivername,portname". */ pBuffer = ( LPTSTR ) hb_xgrab( ( nStrLen + 1 ) * sizeof( TCHAR ) ); pBuffer[ 0 ] = TEXT( '\0' ); /* Build string in form "printername,drivername,portname". */ hbwapi_tstrncat( pBuffer, lpPrinterName, nStrLen ); hbwapi_tstrncat( pBuffer, TEXT( "," ), nStrLen ); hbwapi_tstrncat( pBuffer, ppi2->pDriverName, nStrLen ); hbwapi_tstrncat( pBuffer, TEXT( "," ), nStrLen ); hbwapi_tstrncat( pBuffer, ppi2->pPortName, nStrLen ); /* Set the default printer in win.ini and registry. */ bFlag = WriteProfileString( TEXT( "windows" ), TEXT( "device" ), pBuffer ); if( ! bFlag ) { ClosePrinter( hPrinter ); hb_xfree( ppi2 ); hb_xfree( pBuffer ); return HB_FALSE; } } /* Tell all open programs that this change occurred. Allow each app 1 second to handle this message. */ SendMessageTimeout( HWND_BROADCAST, WM_SETTINGCHANGE, 0L, 0L, SMTO_NORMAL, 1000, NULL ); } /* Clean up. */ if( hPrinter ) ClosePrinter( hPrinter ); if( ppi2 ) hb_xfree( ppi2 ); if( pBuffer ) hb_xfree( pBuffer ); return HB_TRUE; #else HB_SYMBOL_UNUSED( lpPrinterName ); return HB_FALSE; #endif }
BOOL GetGeneric( IN PROC fnGet, IN DWORD Level, IN PBYTE *ppGetData, IN DWORD cbBuf, OUT LPDWORD pcbReturned, IN PVOID Arg1, IN PVOID Arg2 ) { BOOL rc = FALSE; BOOL UnknownFunction = FALSE; DWORD cbRealloc; if( fnGet == (PROC)GetPrinter ) rc = GetPrinter( (HANDLE)Arg1, GET_ARGS ); // hPrinter else { *ppGetData = NULL; UnknownFunction = TRUE; } if( ( rc == FALSE ) && ( UnknownFunction == FALSE ) ) { if( GetLastError( ) == ERROR_INSUFFICIENT_BUFFER ) { cbRealloc = *pcbReturned; *ppGetData = ReallocSplMem( *ppGetData, cbRealloc ); cbBuf = cbRealloc; if( *ppGetData ) { if( fnGet == (PROC)GetPrinter ) rc = GetPrinter( (HANDLE)Arg1, GET_ARGS ); // hPrinter /* If things haven't worked out, free up the buffer. * We do this because otherwise the caller will not know * whether the pointer is valid any more, * since ReallocSplMem might have failed. */ if( rc == FALSE ) { if( *ppGetData ) FreeSplMem( *ppGetData ); *ppGetData = NULL; *pcbReturned = 0; } } } else { if( *ppGetData ) FreeSplMem( *ppGetData ); *ppGetData = NULL; *pcbReturned = 0; rc = FALSE; } } else *pcbReturned = cbBuf; return rc; }
void MainFrame::Notify(TNotifyUI& msg) { if (_tcsicmp(msg.sType, kWindowInit) == 0) { OnPrepare(msg); } else if (_tcsicmp(msg.sType, kClick) == 0) { if (_tcsicmp(msg.pSender->GetName(), kCloseButtonControlName) == 0 || _tcsicmp(msg.pSender->GetName(), kCancelButtonControlName) == 0) { OnExit(msg); } else if (_tcsicmp(msg.pSender->GetName(), kMinButtonControlName) == 0) { #if defined(UNDER_CE) ::ShowWindow(m_hWnd, SW_MINIMIZE); #else SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0); #endif } else if (_tcsicmp(msg.pSender->GetName(), kMaxButtonControlName) == 0) { #if defined(UNDER_CE) ::ShowWindow(m_hWnd, SW_MAXIMIZE); CControlUI* pControl = static_cast<CControlUI*>(paint_manager_.FindControl(kMaxButtonControlName)); if( pControl ) pControl->SetVisible(false); pControl = static_cast<CControlUI*>(paint_manager_.FindControl(kRestoreButtonControlName)); if( pControl ) pControl->SetVisible(true); #else SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0); #endif } else if (_tcsicmp(msg.pSender->GetName(), kRestoreButtonControlName) == 0) { #if defined(UNDER_CE) ::ShowWindow(m_hWnd, SW_RESTORE); CControlUI* pControl = static_cast<CControlUI*>(paint_manager_.FindControl(kMaxButtonControlName)); if( pControl ) pControl->SetVisible(true); pControl = static_cast<CControlUI*>(paint_manager_.FindControl(kRestoreButtonControlName)); if( pControl ) pControl->SetVisible(false); #else SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0); #endif } else if (_tcsicmp(msg.pSender->GetName(), _T("select_all_btn")) == 0) { CContainerUI* pDriverList = static_cast<CContainerUI*>(paint_manager_.FindControl(_T("driver_list"))); for (int i = 0; (pDriverList != NULL) && (i < pDriverList->GetCount()); ++i) { COptionUI* pDriver = static_cast<COptionUI*>(pDriverList->GetItemAt(i)->GetInterface(_T("Option"))); if (pDriver != NULL) pDriver->Selected(true); } } else if (_tcsicmp(msg.pSender->GetName(), _T("uninstall_btn")) == 0) { vector<tString> deleted_printer_driver; DWORD dwError = 0; TCHAR szBuf[MAX_PATH] = {0}; CContainerUI* pDriverList = static_cast<CContainerUI*>(paint_manager_.FindControl(_T("driver_list"))); for (int i = 0; (pDriverList != NULL) && (i < pDriverList->GetCount()); ++i) { COptionUI* pDriver = static_cast<COptionUI*>(pDriverList->GetItemAt(i)->GetInterface(_T("Option"))); if ((pDriver != NULL) && pDriver->IsSelected()) { // 涉及到的API: DeletePrinter DeletePrinterDriver HANDLE hPrinter = NULL; _stprintf_s(szBuf, MAX_PATH - 1, pDriver->GetText().GetData()); PRINTER_DEFAULTS PrtDefault = {NULL, NULL, PRINTER_ALL_ACCESS}; OpenPrinter(szBuf, &hPrinter, &PrtDefault); if (hPrinter != NULL) { DWORD dwNeeded = 0; GetPrinter(hPrinter, 2, NULL, 0, &dwNeeded); LPBYTE lpBuffer = (LPBYTE)malloc(dwNeeded); if (lpBuffer != NULL) { GetPrinter(hPrinter, 2, lpBuffer, dwNeeded, &dwNeeded); DeletePrinter(hPrinter); dwError = GetLastError(); vector<tString>::const_iterator citer = find(deleted_printer_driver.begin(), deleted_printer_driver.end(), ((PRINTER_INFO_2*)lpBuffer)->pDriverName); if (citer == deleted_printer_driver.end()) { deleted_printer_driver.push_back(((PRINTER_INFO_2*)lpBuffer)->pDriverName); } ClosePrinter(hPrinter); free(lpBuffer); } } } } for (vector<tString>::const_iterator citer = deleted_printer_driver.begin(); citer != deleted_printer_driver.end(); ++citer) { _stprintf_s(szBuf, MAX_PATH - 1, citer->c_str()); DeletePrinterDriver(NULL, NULL, szBuf); dwError = GetLastError(); } RestartSpoolsv(); EnumInstalledDriver(); if (IDYES == DUIMessageBox(m_hWnd, _T("注意:您需要重新启动计算机使设置生效,现在需要重启计算机吗?点击“是”立即重启计算机,点击“否”稍后您自己手动重启计算机。"), _T("重新启动计算机"), MB_YESNO)) SystemReboot(); } } else if (_tcsicmp(msg.sType, kTimer) == 0) { return OnTimer(msg); } }
/* * Get a DEVMODE and DEVNAMES from a printer name. * * Returns TRUE for success, FALSE for failure. */ static BOOL get_printer_device(const char *printer_name, HGLOBAL *pdevnames, HGLOBAL *pdevmode) { HANDLE h; DWORD len, len2; PRINTER_INFO_2 *pi; size_t dmsize; HGLOBAL gdm; char *dm; size_t ldn; size_t lpn; size_t ltn; HGLOBAL gdn; DEVNAMES *dn; size_t offset; /* Gotta have something to return the values in. */ if (pdevmode == NULL || pdevnames == NULL) { return FALSE; } /* Open the printer. */ h = NULL; if (!OpenPrinter((char *)printer_name, &h, NULL)) { return FALSE; } /* Get a PRINTER_INFO_2 structure for the printer. */ (void) GetPrinter(h, 2, NULL, 0, &len); pi = (PRINTER_INFO_2 *)malloc(len); if (!GetPrinter(h, 2, (LPBYTE)pi, len, &len2)) { free(pi); ClosePrinter(h); return FALSE; } ClosePrinter(h); h = NULL; /* Copy the DEVMODE from the PRINTER_INFO_2 into a global handle. */ dmsize = sizeof(*pi->pDevMode) + pi->pDevMode->dmDriverExtra; gdm = GlobalAlloc(GHND, dmsize); assert(gdm); dm = (char *)GlobalLock(gdm); assert(dm); memcpy(dm, pi->pDevMode, dmsize); GlobalUnlock(gdm); /* * Compute the size of the DEVNAMES structure from the fields in the * PRINTER_INFO_2. */ ldn = strlen(pi->pDriverName) + 1; lpn = strlen(pi->pPrinterName) + 1; ltn = strlen(pi->pPortName) + 1; /* * Construct a DEVNAMES from the PRINTER_INFO_2, allocated as a global * handle. */ gdn = GlobalAlloc(GHND, sizeof(DEVNAMES) + ldn + lpn + ltn); assert(gdn); dn = (DEVNAMES *)GlobalLock(gdn); assert(dn); memset(dn, '\0', sizeof(DEVNAMES)); offset = sizeof(DEVNAMES); dn->wDriverOffset = (WORD)offset; memcpy((char *)dn + offset, pi->pDriverName, ldn); offset += ldn; dn->wDeviceOffset = (WORD)offset; memcpy((char *)dn + offset, pi->pPrinterName, lpn); offset += lpn; dn->wOutputOffset = (WORD)offset; memcpy((char *)dn + offset, pi->pPortName, ltn); dn->wDefault = 0; /* Done filling in dn. */ GlobalUnlock(gdn); /* Done with the PRINTER_INFO_2. */ free(pi); pi = NULL; /* Return the devmode and devnames. */ *pdevmode = gdm; *pdevnames = gdn; /* Success. */ return TRUE; }
PUCHAR GetPrinterInfo(IN HANDLE hPrinter, IN ULONG StructLevel, OUT PULONG pErrorCode) { ULONG reqbytes, alloc_size; PUCHAR ptr_info, pTempPtr_info = NULL; USHORT retry = 2; alloc_size = BASE_PRINTER_BUFFER_SIZE; ptr_info = (PUCHAR)AllocSplMem(alloc_size); if (!ptr_info) { *pErrorCode = ERROR_NOT_ENOUGH_MEMORY; return NULL; } while (retry--) { if (GetPrinter( hPrinter, StructLevel, (PUCHAR)ptr_info, alloc_size, &reqbytes) == TRUE) { *pErrorCode = 0; return (PUCHAR)ptr_info; } // // GetPrinter failed - if not because of insufficient buffer, fail // the call. Otherwise, up our hint, re-allocate and try again. // *pErrorCode = GetLastError(); if (*pErrorCode != ERROR_INSUFFICIENT_BUFFER) { FreeSplMem(ptr_info); return NULL; } // // Reallocate the buffer and re-try (note that, because we // allocated the buffer as LMEM_FIXED, the LMEM_MOVABLE does // not return a movable allocation, it just allows realloc // to return a different pointer. // FreeSplMem(ptr_info); ptr_info = NULL; pTempPtr_info = (PUCHAR)AllocSplMem(reqbytes); alloc_size = reqbytes; if (pTempPtr_info) { ptr_info = pTempPtr_info; pTempPtr_info = NULL; } else { // // If the realloc failed we break out of the loop so that we // can cleanup and return error code. // break; } } if (ptr_info) { FreeSplMem(ptr_info); } *pErrorCode = ERROR_NOT_ENOUGH_MEMORY; 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; }