static void EnumeratePrinters()
{
    PRINTER_INFO_5 *info5Arr = NULL;
    DWORD bufSize = 0, printersCount;
    bool fOk = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL,
        5, (LPBYTE)info5Arr, bufSize, &bufSize, &printersCount);
    if (!fOk) {
        info5Arr = (PRINTER_INFO_5 *)malloc(bufSize);
        fOk = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL,
            5, (LPBYTE)info5Arr, bufSize, &bufSize, &printersCount);
    }
    if (!info5Arr)
        return;
    assert(fOk);
    if (!fOk) return;
    printf("Printers: %ld\n", printersCount);
    for (DWORD i = 0; i < printersCount; i++) {
        const WCHAR *printerName = info5Arr[i].pPrinterName;
        const WCHAR *printerPort = info5Arr[i].pPortName;
        bool fDefault = false;
        if (info5Arr[i].Attributes & PRINTER_ATTRIBUTE_DEFAULT)
            fDefault = true;
        wprintf(L"Name: %s, port: %s, default: %d\n", printerName, printerPort, (int)fDefault);
    }
    WCHAR buf[512];
    bufSize = dimof(buf);
    fOk = GetDefaultPrinter(buf, &bufSize);
    if (!fOk) {
        if (ERROR_FILE_NOT_FOUND == GetLastError())
            printf("No default printer\n");
    }
    free(info5Arr);
}
Example #2
0
/*
 * Return the default printer name.
 */
static char *
get_default_printer_name(char *errbuf, size_t errbuf_size)
{
    DWORD size;
    char *buf;

    /* Figure out how much memory to allocate. */
    size = 0;
    (void) GetDefaultPrinter(NULL, &size);
    buf = Malloc(size);
    if (GetDefaultPrinter(buf, &size) == 0) {
	snprintf(errbuf, errbuf_size, "Cannot determine default printer");
	return NULL;
    }
    return buf;
}
/* Get the name of default printer or NULL if not exists.
   The caller needs to free() the result */
WCHAR *GetDefaultPrinterName()
{
    WCHAR buf[512];
    DWORD bufSize = dimof(buf);
    if (GetDefaultPrinter(buf, &bufSize))
        return str::Dup(buf);
    return NULL;
}
Example #4
0
/*
 * TODO:   support older systems.
 */
char * GetDefaultPrintService() {
    char *buffer = new char[MAX_PATH];
    DWORD buffer_size = MAX_PATH;

    if (GetDefaultPrinter(buffer, &buffer_size)) {
        return buffer;
    } else {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
            delete[] buffer;
            buffer = new char[buffer_size];
            if (GetDefaultPrinter(buffer, &buffer_size)) {
                return buffer;
            }
        }
    }
    return NULL;
}
Example #5
0
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);	
}
void MainFrame::EnumInstalledDriver()
{
	// 清空界面中list中显示的打印机列表
	CContainerUI* pDriverList = static_cast<CContainerUI*>(paint_manager_.FindControl(_T("driver_list")));
	if (pDriverList != NULL)
		pDriverList->RemoveAll();

	// 枚举本地计算机上所有安装的打印机驱动(实际使用时可以只枚举自家的打印机驱动)
	LPBYTE	lpBuffer = NULL;
	DWORD	dwNeeded = 0,dwReturned = 0;

	EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 1, NULL, 0, &dwNeeded, &dwReturned);
	if (dwNeeded == 0)
		return;

	lpBuffer = (LPBYTE)malloc(dwNeeded);
	if (lpBuffer == NULL)
		return;

	EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 1, lpBuffer, dwNeeded, &dwNeeded, &dwReturned);
	for (DWORD dwIndex = 0; (dwIndex < dwReturned) && (pDriverList != NULL); dwIndex++)
	{
		COptionUI* pDriver = new COptionUI();
		if (pDriver != NULL)
		{
			pDriver->ApplyAttributeList(_T("padding=\"15,0,0,0\" height=\"35\" textpadding=\"20,0,0,0\" align=\"left\" normalimage=\"res='124' restype='png' dest='0,10,15,25'\" hotimage=\"res='125' restype='png' dest='0,10,15,25'\" selectedimage=\"res='126' restype='png' dest='0,10,15,25'\""));
			pDriver->SetText(((PRINTER_INFO_1*)lpBuffer + dwIndex)->pName);
			pDriverList->Add(pDriver);
		}
	}

	LPTSTR lpDefaultPrinter;
	GetDefaultPrinter(NULL, &dwNeeded);

	lpDefaultPrinter = (LPTSTR)malloc(dwNeeded * sizeof(TCHAR));
	GetDefaultPrinter((LPTSTR)lpDefaultPrinter, &dwNeeded);

	free(lpDefaultPrinter);
	free(lpBuffer);
}
Example #7
0
static void AddToPrintersMenu(VMenu *PrinterList, PRINTER_INFO *pi, int PrinterNumber)
{
	// Получаем принтер по умолчанию
	string strDefaultPrinter;
	DWORD pcchBuffer = 0;

	if (!GetDefaultPrinter(nullptr, &pcchBuffer) && ERROR_INSUFFICIENT_BUFFER==GetLastError())
	{
		if (!GetDefaultPrinter(strDefaultPrinter.GetBuffer(pcchBuffer), &pcchBuffer))
			strDefaultPrinter.ReleaseBuffer(0);
		else
			strDefaultPrinter.ReleaseBuffer();
	}

	// Элемент меню
	MenuItemEx Item;
	// Признак наличия принтера по умолчанию
	bool bDefaultPrinterFound = false;

	// Заполняем список принтеров
	for (int i=0; i<PrinterNumber; i++)
	{
		PRINTER_INFO *printer = &pi[i];
		Item.Clear();
		Item.strName = printer->pPrinterName;

		if (!StrCmp(printer->pPrinterName, strDefaultPrinter))
		{
			bDefaultPrinterFound = true;
			Item.SetCheck(TRUE);
			Item.SetSelect(TRUE);
		}

		PrinterList->SetUserData(printer->pPrinterName,0,PrinterList->AddItem(&Item));
	}

	if (!bDefaultPrinterFound)
		PrinterList->SetSelectPos(0, 1);
}
Example #8
0
static void AddToPrintersMenu(VMenu2 *PrinterList, PRINTER_INFO *pi, int PrinterNumber)
{
	// Получаем принтер по умолчанию
	string strDefaultPrinter;
	DWORD pcchBuffer = 0;

	if (!GetDefaultPrinter(nullptr, &pcchBuffer) && ERROR_INSUFFICIENT_BUFFER==GetLastError())
	{
		wchar_t_ptr Buffer(pcchBuffer);
		if (!GetDefaultPrinter(Buffer.get(), &pcchBuffer))
			strDefaultPrinter.clear();
		else
			strDefaultPrinter.assign(Buffer.get(), Buffer.size());
	}

	// Признак наличия принтера по умолчанию
	bool bDefaultPrinterFound = false;

	// Заполняем список принтеров
	for (int i=0; i<PrinterNumber; i++)
	{
		PRINTER_INFO *printer = &pi[i];
		MenuItemEx Item(printer->pPrinterName);

		if (strDefaultPrinter == printer->pPrinterName)
		{
			bDefaultPrinterFound = true;
			Item.SetCheck(TRUE);
			Item.SetSelect(TRUE);
		}

		PrinterList->SetUserData(Item.strName.data(), (Item.strName.size()+1)*sizeof(wchar_t), PrinterList->AddItem(Item));
	}

	if (!bDefaultPrinterFound)
		PrinterList->SetSelectPos(0, 1);
}
Example #9
0
	virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam)
	{
		switch ( LOWORD(wParam) )
		{
			case IDM_FILE_DIRECTPRINT:
				Demo_WritePort();
				return TRUE;

			case IDM_FILE_OPENPRINTER:
				Demo_WritePrinter();
				return TRUE;

			case IDM_FILE_PRINTDIALOGDEFAULT:
				Demo_OutputSetup(false);
				return TRUE;

			case IDM_FILE_PRINTDIALOGPROMPT:
				Demo_OutputSetup(true);
				return TRUE;

			case IDM_FILE_DEFAULTPRINTERDC:
				{
					TCHAR name[64];

					DWORD size = 64;
					GetDefaultPrinter(name, & size);

					HDC hDC = CreateDC(NULL, name, NULL, NULL);
					
					if ( hDC )
						MessageBox(NULL, "Printer DC Created", name, MB_OK);
					DeleteDC(hDC);
				}
				return TRUE;

			case IDM_FILE_SIMPLEPRINT:
				SimplePrint(2);
				return TRUE;

			case IDM_FILE_NEW:
			{
				CreatePageCanvas(_T("Test Printer "));
				return TRUE;
			}
		}

		return FALSE;
	}
void TPrinter::SetDevice(Pchar ADevice, Pchar ADriver, Pchar APort)
{
  char DriverName[80];
  DEVMODE StubDevMode;

  if (Equal(Device, ADevice) && Equal(Driver, ADriver) &&
    Equal(Port, APort))
        return;
  ClearDevice();
  if (ADevice == NULL)
    GetDefaultPrinter();
  else {
    Device = newstrdup(ADevice);
    Driver = newstrdup(ADriver);
    Port = newstrdup(APort);
  }
  Status = PS_OK;
  strncpy(DriverName, Driver, sizeof(DriverName) - 1);
  strncat(DriverName, ".DRV", sizeof(DriverName) - strlen(DriverName) - 1);
  DeviceModule = LoadLibrary(DriverName);
        if ((int)DeviceModule < 32)
        Status = PS_INVALIDDEVICE;
  else {
    // Grab the DevMode procedures
    ExtDeviceMode = (LPFNDEVMODE) GetProcAddress(DeviceModule, "ExtDeviceMode");
    DeviceMode = (PTDeviceModeFcn) GetProcAddress(DeviceModule, "DeviceMode");
    if ((DeviceMode == NULL) && (ExtDeviceMode == NULL))
      Status = PS_INVALIDDEVICE;
    if (ExtDeviceMode != NULL) {
      // Get default printer settings
      DevSettingSize = ExtDeviceMode(0, DeviceModule, &StubDevMode,
        Device, Port, &StubDevMode, NULL, 0);
      DevSettings = (PDEVMODE) new char[DevSettingSize];
      ExtDeviceMode(0, DeviceModule, DevSettings, Device, Port,
        DevSettings, NULL, DM_OUT_BUFFER);
    }
    else
      DevSettings = NULL;  // Cannot use local settings
  }
}
static void
create_printer_dc (win32_target_closure_t *ptc)
{
    char *printer_name;
    DWORD size;
    int x_dpi, y_dpi, left_margin, top_margin, page_height, printable_height;
    XFORM xform;

    ptc->dc = NULL;
    GetDefaultPrinter (NULL, &size);
    printer_name = malloc (size);

    if (printer_name == NULL)
	return;

    if (GetDefaultPrinter (printer_name, &size) == 0) {
	free (printer_name);
	return;
    }

    /* printf("\nPrinting to : %s\n", printer_name); */
    ptc->dc = CreateDC (NULL, printer_name, NULL, NULL);
    free (printer_name);

    if (!printer_is_postscript_level_3 (ptc->dc)) {
	printf("The default printer driver must be a color PostScript level 3 printer\n");
	ptc->dc = NULL;
	return;
    }

    /* The printer device units on win32 are 1 unit == 1 dot and the
     * origin is the start of the printable area. We transform the
     * cordinate space to 1 unit is 1 point as expected by the
     * tests. As the page size is larger than the test surface, the
     * origin is translated down so that the each test is drawn at the
     * bottom left corner of the page. This is because the bottom left
     * corner of the PNG image that ghostscript creates is positioned
     * at origin of the PS coordinates (ie the bottom left of the
     * page).  The left and bottom margins are stored in
     * win32_target_closure as size of the PNG image needs to be
     * increased because the test output is offset from the bottom
     * left by the non printable margins. After the PNG is created the
     * margins will be chopped off so the image matches the reference
     * image.
     */
    printable_height = GetDeviceCaps (ptc->dc, VERTRES);
    x_dpi = GetDeviceCaps (ptc->dc, LOGPIXELSX);
    y_dpi = GetDeviceCaps (ptc->dc, LOGPIXELSY);
    left_margin = GetDeviceCaps (ptc->dc, PHYSICALOFFSETX);
    top_margin = GetDeviceCaps (ptc->dc, PHYSICALOFFSETY);
    page_height = GetDeviceCaps (ptc->dc, PHYSICALHEIGHT);

    SetGraphicsMode (ptc->dc, GM_ADVANCED);
    xform.eM11 = x_dpi/72.0;
    xform.eM12 = 0;
    xform.eM21 = 0;
    xform.eM22 = y_dpi/72.0;
    xform.eDx = 0;
    xform.eDy = printable_height - ptc->height*y_dpi/72.0;
    if (!SetWorldTransform (ptc->dc, &xform)) {
	_cairo_win32_print_gdi_error ("cairo-boilerplate-win32-printing:SetWorldTransform");
	return;
    }

    ptc->left_margin = 72.0*left_margin/x_dpi;
    ptc->bottom_margin = 72.0*(page_height - printable_height - top_margin)/y_dpi;
}
Example #12
0
/* get number of printers, default printer number and printer names */
void kGUISystemMINGW::GetPrinters(void)
{
	DWORD numprinters;
	DWORD defprinter=0;
	DWORD				dwSizeNeeded=0;
	DWORD				dwItem;
	LPPRINTER_INFO_2	printerinfo = NULL;

	// Get buffer size
	kGUI::Trace("EnumPrinters ( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS , NULL, 2, NULL, 0, &dwSizeNeeded, &numprinters );\n");

	EnumPrinters ( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS , NULL, 2, NULL, 0, &dwSizeNeeded, &numprinters );

	// allocate memory
	//printerinfo = (LPPRINTER_INFO_2)HeapAlloc ( GetProcessHeap (), HEAP_ZERO_MEMORY, dwSizeNeeded );
	kGUI::Trace("printerinfo = (LPPRINTER_INFO_2)new char[%d];\n",dwSizeNeeded);
	printerinfo = (LPPRINTER_INFO_2)new char[dwSizeNeeded];

	kGUI::Trace("EnumPrinters ( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,NULL,2,(LPBYTE)printerinfo,dwSizeNeeded,&dwSizeNeeded,&numprinters);\n");
	if ( EnumPrinters ( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,		// what to enumerate
			    NULL,			// printer name (NULL for all)
			    2,				// level
			    (LPBYTE)printerinfo,		// buffer
			    dwSizeNeeded,		// size of buffer
			    &dwSizeNeeded,		// returns size
			    &numprinters			// return num. items
			  ) == 0 )
	{
		kGUI::Trace("No printers found!;\n");
		numprinters=0;
	}

	{
		DWORD size=0;	/* if no default printer is set then GetDefaultPrinter will leave this unitlzd */

		// Get the size of the default printer name.
		kGUI::Trace("GetDefaultPrinter(NULL, &size);\n");
		GetDefaultPrinter(NULL, &size);
		kGUI::Trace("done GetDefaultPrinter size=%d;\n",size);
		if(size)
		{
		   // Allocate a buffer large enough to hold the printer name.
			kGUI::Trace("TCHAR* buffer = new TCHAR[%d];\n",size);
			TCHAR* buffer = new TCHAR[size];

			  // Get the printer name.
			kGUI::Trace("GetDefaultPrinter(buffer, &size);\n");
			GetDefaultPrinter(buffer, &size);

			for ( dwItem = 0; dwItem < numprinters; dwItem++ )
			{
				kGUI::Trace("printername[%d]='%s'\n",dwItem,printerinfo[dwItem].pPrinterName);
				if(!strcmp(buffer,printerinfo[dwItem].pPrinterName))
					defprinter=dwItem;
			}
			kGUI::Trace("delete buffer;\n");
			delete buffer;
		}
	}
	kGUI::Trace("copying printer names numprinters=%d,defaultprinter=%d;\n",numprinters,defprinter);

	/* copy printer info */
	m_numprinters=numprinters;
	m_defprinternum=defprinter;

	if(m_numprinters)
	{
		m_printers.Init(m_numprinters,0);
		for(unsigned int i=0;i<m_numprinters;++i)
			m_printers.GetEntryPtr(i)->SetName(printerinfo[i].pPrinterName);
	}
	if(printerinfo)
		delete []printerinfo;

	/* if no printers, then add a default 'no printer' so print code doesn't crash */
	if(!m_numprinters)
	{
		m_numprinters=1;
		m_printers.Init(m_numprinters,0);
		m_printers.GetEntryPtr(0)->SetName("No Printers");
		m_printers.GetEntryPtr(0)->SetDefaultPageSize();
	}
	kGUI::Trace("exiting GetPrinters();\n");
}
Example #13
0
short InitPrinterListBox(
/***********************************************************************/
  /* This function initializes the list of devices in the GetDevice dialog box.
     The list box in the dialog box contains a list of all devices installed in
     the system.  The user will select from among these various strings to
     select the current printer.  The number of printers listed in the list
     box is returned as a result.  The currently selected device (lpDevice)
     should have the form "NAME,DRIVER,PORT", and will be highlighted initially
     in the list box. */
HWND 	hDlg,
LPSTR 	lpDevice)
{
short nDevice;
char KeyBuffer[KEY_LENGTH];
STRING szDevice, Buffer, szString;
LPSTR lp, lpName, lpDriver, lpPort, lpNext;
LPSTR lpActiveName, lpActiveDriver, lpActivePort;
int CurrDevice; /* index of currently selected device */

if ( !(*lpDevice) )
	GetDefaultPrinter( lpDevice );
// Format of the device string is NAME,DRIVER,PORT etc.

lstrcpy( szDevice, lpDevice ); // Copy the device string so we won't destroy it

if ( AstralStr( IDS_PORT_SEPARATOR, &lp ) )
	lstrcpy( Separator, lp );

lpActiveName = szDevice; // get the name
if ( lpActiveDriver = GetNextParm( lpActiveName ) ) // get the driver
	{
	*lpActiveDriver++ = '\0';
	if ( lpActivePort = GetNextParm( lpActiveDriver ) ) // get the port
		*lpActivePort++ = '\0';
	}

nDevice = 0;
CurrDevice = -1;
GetProfileString( PRINTERS, NULL, "\0\0", KeyBuffer, KEY_LENGTH );
lpName = KeyBuffer;
while ( *lpName )
	{
	GetProfileString( PRINTERS, lpName, "\0", Buffer, MAX_STR_LEN );
	// Format of the buffer is DRIVER,PORT,15,45,PORT,15,45,PORT,15,45 etc.
	lpDriver = Buffer;
	lpPort = GetNextParm( lpDriver ); // skip over driver to get the port
	while ( lpPort )
		{
		*lpPort++ = '\0';
		if ( lpNext = GetNextParm( lpPort ) )
			*lpNext++ = '\0';
		lstrcpy( szString, lpName );
		lstrcat( szString, Separator );
		lstrcat( szString, lpPort );
		if ( hDlg )
			SendDlgItemMessage( hDlg, IDC_PRINTSELECT,
				LB_INSERTSTRING, -1, (long)(LPSTR)szString );
		if ( lpActiveName && !lstrcmp(lpActiveName,lpName) &&
		     lpActivePort && !lstrcmp(lpActivePort,lpPort) )
			CurrDevice = nDevice;
		nDevice++;
		if ( lpNext = GetNextParm( lpNext ) ) // skip the 15
			lpNext++;
		lpPort = GetNextParm( lpNext ); // skip the 45
		}
	lpName += (lstrlen(lpName) + 1);
	}

if ( !nDevice && hDlg )
	{
	GetProfileString( "windows", "NullPort", "None", NullPort, MAX_STR_LEN);
	SendDlgItemMessage( hDlg, IDC_PRINTSELECT, LB_INSERTSTRING, -1,
		(long)(LPSTR)NullPort );
	nDevice++;
	}

if ( CurrDevice < 0 ) // the name wasn't in the list, so pass back the default
	GetDefaultPrinter( lpDevice );

if ( hDlg )
	{
	if ( CurrDevice < 0 ) // the name wasn't in the list...
		SendDlgItemMessage( hDlg, IDC_PRINTSELECT, LB_SELECTSTRING,
			-1, (long)lpDevice );
	else	SendDlgItemMessage( hDlg, IDC_PRINTSELECT, LB_SETCURSEL,
			CurrDevice, 0L );
	}

return( nDevice );
}
// ---------------------------------------------
// Monitor the print spool and prompt users to confirm print jobs
// ---------------------------------------------
DWORD CGreenPrintMonitorThread::OnSpoolMonitorThread(void)
{
	DWORD cchPrinterName = 0;

	// ---------------------------------------------
	// Get the buffer size needed to hold the printer name
	// ---------------------------------------------
	GetDefaultPrinter( NULL, &cchPrinterName );

	if ( cchPrinterName > 0 )
	{
		WCHAR *PrinterName = (WCHAR*)LocalAlloc( LMEM_ZEROINIT, cchPrinterName * sizeof(WCHAR) );

		if ( NULL != PrinterName )
		{
			// ---------------------------------------------
			// Get the name of the print
			// ---------------------------------------------
			if ( GetDefaultPrinter( PrinterName, &cchPrinterName ) )
			{
				HANDLE hPrinter = NULL;

				if ( OpenPrinter( PrinterName, &hPrinter, NULL ) )
				{
					HANDLE hChangeNotification = NULL;

					// ---------------------------------------------
					// Setup the structures needed to register for print spool notifications
					// ---------------------------------------------

					PRINTER_NOTIFY_INFO_DATA NotifyInfoData[] = {
						JOB_NOTIFY_TYPE,
						JOB_NOTIFY_FIELD_TOTAL_PAGES,
						0, // Reserved
						JOB_NOTIFY_TYPE,
						0
					};

					PRINTER_NOTIFY_OPTIONS_TYPE NotifyOptionsType[] = {
						JOB_NOTIFY_TYPE,
						0, // Reserved 0
						0, // Reserved 1
						0, // Reserved 2
						_countof(NotifyInfoData),
						(PWORD)NotifyInfoData
					};

					PRINTER_NOTIFY_OPTIONS NotifyOptions;
					ZeroMemory( &NotifyOptions, sizeof(NotifyOptions) );
					NotifyOptions.Version = 2;
					NotifyOptions.Count = _countof(NotifyOptionsType);
					NotifyOptions.pTypes = NotifyOptionsType;

					// ---------------------------------------------
					// Request a notification handle that will be signaled when a new print job is queued
					// ---------------------------------------------
					hChangeNotification = 
						FindFirstPrinterChangeNotification( 
						hPrinter, 
						PRINTER_CHANGE_ADD_JOB, 
						0, // Reserved 
						&NotifyOptions
						);

					if ( INVALID_HANDLE_VALUE != hChangeNotification )
					{
						do
						{
							// ---------------------------------------------
							// The order of these handles is important to the code below that checks which event was signaled
							// ---------------------------------------------
							HANDLE HandleList[] = {
								hChangeNotification, 
								m_hExitSpoolMonitorThread
							};

							// ---------------------------------------------
							// Wait for the print job notification handle or the exit handle to be signaled
							// ---------------------------------------------
							DWORD WaitReason = WaitForMultipleObjects( 
								_countof(HandleList), 
								HandleList, 
								FALSE, 
								INFINITE );

							if ( WAIT_OBJECT_0 == WaitReason )
							{
								PRINTER_NOTIFY_INFO *pPrinterNotifyInfo = NULL;

								// ---------------------------------------------
								// The notification handle was signaled so get the info about the print job
								// ---------------------------------------------
								if ( FindNextPrinterChangeNotification( 
										hChangeNotification,
										NULL,
										&NotifyOptions,
										(LPVOID*)&pPrinterNotifyInfo ) )
								{
									if ( NULL != pPrinterNotifyInfo )
									{
										// ---------------------------------------------
										// Required code to make the FindNextPrinterChangeNotification happy (see MSDN documentation)
										// ---------------------------------------------
										if ( PRINTER_NOTIFY_INFO_DISCARDED & pPrinterNotifyInfo->Flags )
										{
											FreePrinterNotifyInfo( pPrinterNotifyInfo );
											pPrinterNotifyInfo = NULL;

											DWORD Flags = NotifyOptions.Flags;

											NotifyOptions.Flags = PRINTER_NOTIFY_OPTIONS_REFRESH;

											FindNextPrinterChangeNotification( 
													hChangeNotification,
													NULL,
													&NotifyOptions,
													(LPVOID*)&pPrinterNotifyInfo );

											NotifyOptions.Flags = Flags;
										}
									}

									// ---------------------------------------------
									// Get the needed information from the job
									// ---------------------------------------------
									DWORD JobId = 0;
									DWORD JobPages = 0;

									if ( NULL != pPrinterNotifyInfo )
									{
										GetJobInfoFromPrinterNotifyInfo( pPrinterNotifyInfo, &JobId, &JobPages );

										FreePrinterNotifyInfo( pPrinterNotifyInfo );
										pPrinterNotifyInfo = NULL;
									}

									// ---------------------------------------------
									// Pause the print job 
									// ---------------------------------------------
									if ( SetJob( hPrinter,
											JobId,
											0,
											NULL,
											JOB_CONTROL_PAUSE ) )
									{
										// ---------------------------------------------
										// If we weren't able to get the number of pages already
										// then get the count from the job itself
										// ---------------------------------------------
										if ( 0 == JobPages )
										{
											JobPages = JobPagesFromJobId( hPrinter, JobId );
										}

										// ---------------------------------------------
										// Interact with the user to determine if they would really like to print
										// ---------------------------------------------
										BOOL ResumeJob = ShouldResumePrintJob( JobPages );
										
										if ( ResumeJob )
										{
											if ( !SetJob( hPrinter,
												JobId,
												0,
												NULL,
												JOB_CONTROL_RESUME ) )
											{
												m_pLogging->Log( L"Failed resuming print job." );
											}
										}
										else
										{
											if ( !SetJob( hPrinter,
												JobId,
												0,
												NULL,
												JOB_CONTROL_DELETE ) )
											{
												m_pLogging->Log( L"Failed deleting print job." );
											}											
										}
									}
								}
								else
								{
									m_pLogging->Log( L"Failed getting information concerning a print job." );
								}
							}
							else if ( ( WAIT_OBJECT_0 + 1 ) == WaitReason ) 
							{
								// ---------------------------------------------
								// The exit handle was signaled. Stop checking for print jobs.
								// ---------------------------------------------
								break;
							}
							else
							{
								m_pLogging->Log( L"Unexpected notification while waiting for print job." );
							}
						}
						while( TRUE );
					}
					else
					{
						m_pLogging->Log( L"Failed trying to get print job notification handle." );
					}

					if ( INVALID_HANDLE_VALUE != hChangeNotification )
					{
						FindClosePrinterChangeNotification( hChangeNotification );
						hChangeNotification = NULL;
					}

					if ( NULL != hPrinter )
					{
						ClosePrinter( hPrinter );
						hPrinter = NULL;
					}
				}
			}

			if ( NULL != PrinterName )
			{
				cchPrinterName = 0;

				LocalFree( PrinterName );
				PrinterName = NULL;
			}
		}
	}

	return NO_ERROR;
}
Example #15
0
void sys_PrintDirect2Driver( PA_PluginParameters params )
{
	PRINTDLG pd;                      // Structure to hold information about printer
	DOCINFO di;                       // Structure to hold "document" information
	char printerName[MAXBUF] = "";    // String to hold the printerName param ($1)
	char data[MAXLABELBUF] = "";      // String to hold the data param ($2) REB 6/5/08 #17022 Changed MAXBUF to MAXLABELBUF which is twice as big.
	char *origDefault;                // String to hold the original default printer
	INT_PTR printerName_len;              // Int to hold maximum length of printer name
	INT_PTR ret;                          // Int to hold return value of functions                 
	INT_PTR iErrCode = 0;                 // Int to hold the error code.
	ULONG_PTR ulBytesNeeded;      // Holds size information

	// Set needed bytes to default value
	ulBytesNeeded = MAXLABELBUF; // REB 6/5/08 #17022 Changed MAXBUF to MAXLABELBUF

	// Set this to 255.
	printerName_len = 255;

	// Get the function parameters.
	PA_GetTextParameter(params, 1, printerName);
	PA_GetTextParameter(params, 2, data);

	// Allocate memory for Storing string for Original Default Printer & pBuf
	origDefault = (char *)malloc(ulBytesNeeded);
	memset(origDefault, 0, ulBytesNeeded);
	
    // Get name of current Default Printer
	GetDefaultPrinter(origDefault, &ulBytesNeeded);
    
	// Set the new Default Printer to our label printer, with the name obtained from the registry
	ret = SetDefaultPrinter((char *)printerName);
	
	// We set the default printer just fine, now let's do the printing.
	if (ret != 0)
	{
		            
  	// Allocate memory for PRINTDLG structure
	  memset( &pd, 0, sizeof( pd ) );

	  // Define properties of the PRINTDLG structure
	  pd.lStructSize = sizeof( pd );

	  // PD_RETURNDEFAULT causes the PrintDlg function to automatically use the properties from
	  // the default printer.  PD_RETURNDC causes the function to return the device context
	  // for the printer.  This device context allows us to print a label
	  pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;

		// These two structures must be NULL to use the PD_RETURNDC flag.
		// Do this explicitly, just in case
		pd.hDevMode = NULL;
		pd.hDevNames = NULL;
			
	  // Retrieve the Device Context.  It will be accessible as a member of the PRINTDLG structure
	  if(!PrintDlg( &pd ))
		{
			// Get the error from the common dialog box
			// Error code will not work properly with FormatMessage, so use this instead.
		  iErrCode = CommDlgExtendedError();
		}
		
		if(iErrCode == 0)
		{
      // Initialize the DOCINFO structure
      memset(&di, 0, sizeof(di));
      di.cbSize = sizeof(DOCINFO);
	  	di.lpszDocName = "Label"; 
      di.lpszOutput = (LPTSTR) NULL; 
      di.lpszDatatype = "raw";
      di.fwType = 0; 
    	
	  	// Start a document in the print spooler
	  	if(!StartDoc(pd.hDC, &di))
			{
	  	  iErrCode = GetLastError();
			} // end if
		}
					
		if(iErrCode == 0)
		{
		  // Start a new page in the print spooler
	    if(!StartPage(pd.hDC))
			{
			  iErrCode = GetLastError();
			} // end if !
		}

		if(iErrCode == 0)
		{
		  if(!TextOut(pd.hDC, 1, 1, data, strlen(data)))
			{
			  iErrCode = GetLastError();
			}
		}

		// De-allocate commandList
		
		// Let the print spooler know that the page is done
		EndPage(pd.hDC);
			
    // Let the print spooler know that the document is done
	  EndDoc(pd.hDC);
			
		
		// Delete the Device Context
		DeleteDC(pd.hDC);
			
		
		// Now reset our default printer.
    
		// Set the Default Printer back to the original.
  		ret = SetDefaultPrinter(origDefault);

		PA_ReturnLong(params, (LONG_PTR)iErrCode); 
	} else {
	  PA_ReturnLong(params, (LONG_PTR)GetLastError());
	}	// end if
}//end function