Limited time promo

C++ Sample - Multiple printers

English

This help topic applies only to novaPDF. If you don't have it yet, you must download it first.

Download now Buy licenses
Mar 22, 2022
novaPDF 11.x
We strive to keep our help as accurate as possible. If you notice any inconsistencies or outdated info please let us know.
Multiple printers sample is similar with the Temporary printer sample but it uses several threads.

Source code

// HelloWorld.cpp
#include "stdafx.h"

//Include novaPDF headers
#include "..\..\..\include\novaOptions.h"

//NovaPdfOptions
#include "..\..\..\include\novapi.h"

#include "nova.h"

//name of novaPDF Printer Demo
#define PRINTER_NAME1    L"novaPDF temporary printer1"
#define PRINTER_NAME2    L"novaPDF temporary printer2"
#define PRINTER_NAME3    L"novaPDF temporary printer3"

#define PORT_NAME1    L"novaPDF11temp1"
#define PORT_NAME2    L"novaPDF11temp2"
#define PORT_NAME3    L"novaPDF11temp3"

#define FILE_NAME1    L"first.pdf"
#define FILE_NAME2    L"second.pdf"
#define FILE_NAME3    L"third.pdf"

//text to be written in the PDF file
#define PDF_TEXT        L"Hello world!"

//PDF file name
#define PDF_FILE_NAME   L"HelloWorld.pdf"

//Print profile name
#define PROFILE_NAME       L"HelloWorld Profile"
#define PROFILE_IS_PUBLIC  0

typedef struct _PRT_THREAD_PARAM {
	WCHAR wsPrinterName[255];
	WCHAR wsPortName[255];
	WCHAR wsFileName[255];
} PRT_THREAD_PARAM;

DWORD WINAPI PrtThreadProc(LPVOID lpParameter);
HANDLE CreatePrtThread(LPWSTR p_strPrinterName, LPWSTR p_wsFileName);

//entry point for the console application
int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hThread1 = CreatePrtThread(PRINTER_NAME1, PORT_NAME1, FILE_NAME1);
	HANDLE hThread2 = CreatePrtThread(PRINTER_NAME2, PORT_NAME2, FILE_NAME2);
	HANDLE hThread3 = CreatePrtThread(PRINTER_NAME3, PORT_NAME3, FILE_NAME3);

	if (hThread1 > 0){
		//wait to stop processing events
		WaitForSingleObject(hThread1, INFINITE);
		CloseHandle(hThread1);
	}

	if (hThread2 > 0){
		//wait to stop processing events
		WaitForSingleObject(hThread2, INFINITE);
		CloseHandle(hThread2);
	}

	if (hThread3 > 0){
		//wait to stop processing events
		WaitForSingleObject(hThread3, INFINITE);
		CloseHandle(hThread3);
	}

	return 0;
}


HANDLE CreatePrtThread(LPWSTR p_strPrinterName, LPWSTR p_wsPortName, LPWSTR p_wsFileName)
{
	PRT_THREAD_PARAM* pParams;
	DWORD dwThreadId; 

	// Transmit parameters for thread: pipe handle and PDF temp file name
	pParams = (PRT_THREAD_PARAM*)GlobalAlloc(LPTR, sizeof(PRT_THREAD_PARAM));
	wcscpy(pParams->wsPrinterName, p_strPrinterName);
	wcscpy(pParams->wsPortName, p_wsPortName);
	wcscpy(pParams->wsFileName, p_wsFileName);
	// Create the thread
	HANDLE hThread =CreateThread( 
		NULL,              // no security attribute 
		0,                 // default stack size 
		(LPTHREAD_START_ROUTINE) PrtThreadProc, 
		(LPVOID) pParams,    // thread parameter 
		0,                 // not suspended 
		&dwThreadId);      // returns thread ID 
	return hThread;
}

DWORD WINAPI PrtThreadProc(LPVOID lpParameter)
{

	HRESULT hr = S_OK;

	//initialize COM
	hr = CoInitialize(NULL);
	if (FAILED (hr)) 
	{ 
		MessageBox(NULL, L"Failed to initialize COM", L"novaPDF", MB_OK); 
		return hr; 
	} 

	// Read thread's parameter: a handle to a pipe instance and the name of the temporary PDF file
	PRT_THREAD_PARAM* pParams = ((PRT_THREAD_PARAM*)lpParameter); 

	INovaPdfOptions *pNova = 0;
	hr = CoCreateInstance(__uuidof(NovaPdfOptions11), NULL, CLSCTX_INPROC_SERVER, __uuidof(INovaPdfOptions11), (LPVOID*) &pNova);

	//if you have an application license for novaPDF SDK, call the RegisterLicenseKey() function 
	//hr = pNova->RegisterLicenseKey"<registration name>", "<license key>", "<application name>");

	if (SUCCEEDED(hr)) 
	{
		//add temporary printer
		pNova->AddNovaPrinter(pParams->wsPrinterName, pParams->wsPortName, L"nPdfSdk11_Softland", L"8501", L"");

		// set optional PDF settings 
		LPWSTR pwsNewProfileID = NULL;
		//create a new profile with default settings
		hr = pNova->AddProfile(PROFILE_NAME, PROFILE_IS_PUBLIC, &pwsNewProfileID);

		//load the newly created profile
		if (SUCCEEDED(hr) && pwsNewProfileID) 
		{
			hr = pNova->LoadProfile(pwsNewProfileID);
		}
		else
		{
			pNova->Release();
			return hr;
		}

		if (SUCCEEDED(hr) && pwsNewProfileID) 
		{
			// set novaPDF options 
			// set resulting file name
			pNova->SetOptionLong(NOVAPDF_SAVE_FOLDER_TYPE, SAVEFOLDER_CUSTOM);
			pNova->SetOptionLong(NOVAPDF_SAVE_LOCATION, LOCATION_TYPE_LOCAL);
			pNova->SetOptionLong(NOVAPDF_SAVE_FOLDER_TYPE, SAVEFOLDER_CUSTOM);
			pNova->SetOptionString(NOVAPDF_SAVE_FOLDER, L"C:\\temp\\novaPDF");
			pNova->SetOptionString(NOVAPDF_SAVE_FILE_NAME, pParams->wsFileName);
			//do not show prompt dialog
			pNova->SetOptionLong(NOVAPDF_SAVE_PROMPT_TYPE, PROMPT_SAVE_NONE);
			//if file exists, override
			pNova->SetOptionLong(NOVAPDF_SAVE_FILEEXIST_ACTION, FILE_CONFLICT_STRATEGY_AUTONUMBER_NEW);
			//do not open
			pNova->SetOptionBool(NOVAPDF_ACTION_DEFAULT_VIEWER, FALSE);

			//save profile changes
			hr = pNova->SaveProfile();
			//set as active profile for printer
			pNova->SetActiveProfile(pwsNewProfileID);

			HANDLE     hPrinter;
			BOOL bTimeout;
			PDEVMODEW  pDevmode = NULL;
			PRINTER_DEFAULTS pd = { NULL, NULL, PRINTER_ACCESS_USE };

			for (int i = 1; i <= 10; i++)
			{
				
				//start print job
				if (OpenPrinter(pParams->wsPrinterName, &hPrinter, &pd))
				{
					//register to wait for a nova event - wait until PDf is finished
					pNova->RegisterNovaEvent(L"NOVAPDF_EVENT_START_DOC");
					//get default printer DEVMODE      
					int nSize = DocumentProperties(NULL, hPrinter, pParams->wsPrinterName, NULL, NULL, 0);
					pDevmode = (PDEVMODEW)LocalAlloc(LPTR, nSize);
					DocumentProperties(NULL, hPrinter, pParams->wsPrinterName, pDevmode, NULL, DM_OUT_BUFFER);

					//set page size in DEVMODE
					pDevmode->dmPaperSize = DMPAPER_USER;
					pDevmode->dmPaperLength = 2970;//5940;
					pDevmode->dmPaperWidth = 2100;//4200;
					pDevmode->dmFields = DM_PAPERSIZE | DM_PAPERLENGTH | DM_PAPERWIDTH;
					DocumentProperties(NULL, hPrinter, pParams->wsPrinterName, pDevmode, pDevmode, DM_IN_BUFFER | DM_OUT_BUFFER);

					//Print a page
					HDC hDC = CreateDC(L"", pParams->wsPrinterName, NULL, pDevmode);
					DOCINFO docInfo = {sizeof(DOCINFO)};
					// PDF document name and path
					docInfo.lpszDocName = PDF_FILE_NAME; 
					StartDoc(hDC,&docInfo);
					StartPage(hDC);
					// Draw text on page
					TextOut(hDC, 100, 80, PDF_TEXT, (int) wcslen(PDF_TEXT)); 
					EndPage(hDC);
					EndDoc(hDC);
					DeleteDC(hDC);
					LocalFree(pDevmode);
					ClosePrinter(hPrinter);
					pNova->WaitForNovaEvent(-1, &bTimeout);
				}
			}

			//delete profile
			pNova->DeleteProfile(pwsNewProfileID);
			CoTaskMemFree(pwsNewProfileID);
		}
		//delete temporarry printer
		pNova->DeleteNovaPrinter(pParams->wsPrinterName);
	}
	
	//release NovaPdfOptions
	pNova->Release();
	return 0;
}