Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » Community » Newbie corner » Direct printing to a specific printer
Direct printing to a specific printer [message #46416] Mon, 09 May 2016 11:28 Go to next message
Giorgio is currently offline  Giorgio
Messages: 218
Registered: August 2015
Experienced Member
Hi there,
I have been asked to send a report directly to a specific printer. I understand how to send a report directly to the default printer, but in this case I should send the report to a printer that is not the default one. I know this makes little sense - generally speaking - , but in this case the application is installed in few PCs that I manage, so printer names are set by me. I told user that choosing the printer in the dialog window does not seem a big deal, but this chap is a bigmouth and told that in VB x.y you can do that, so I am investigating.
Thanks,
Gio
Re: Direct printing to a specific printer [message #46434 is a reply to message #46416] Wed, 11 May 2016 00:37 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 536
Registered: March 2007
Contributor
You should have no problem doing that. Maybe not out of box.

Look into Upp code PrinterJob.cpp, in particular Execute0()
bool PrinterJob::Execute0(bool dodlg)
{
	pdlg = new Win32PrintDlg_;
	PRINTDLG& dlg = *pdlg;
	dlg.Flags = PD_DISABLEPRINTTOFILE|PD_NOSELECTION|PD_HIDEPRINTTOFILE|PD_RETURNDEFAULT;
	dlg.nFromPage = current;
	dlg.nToPage = current;
	dlg.nMinPage = from;
	dlg.nMaxPage = to;
	if(from != to)
		dlg.Flags |= PD_ALLPAGES;
	dlg.hwndOwner = 0;
	dlg.Flags |= PD_RETURNDEFAULT;
	dlg.nCopies = 1;
	if(!PrintDlg(&dlg)) return false;
	if(dlg.hDevMode) {
		DEVMODE *pDevMode = (DEVMODE*)::GlobalLock(dlg.hDevMode);
		pDevMode->dmOrientation = landscape ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
		::GlobalUnlock(dlg.hDevMode);
	}
	HDC hdc;
	if(dodlg) {
		dlg.Flags = PD_DISABLEPRINTTOFILE|PD_NOSELECTION|PD_HIDEPRINTTOFILE|PD_RETURNDC|PD_USEDEVMODECOPIESANDCOLLATE;
		Vector< Ptr<Ctrl> > disabled = DisableCtrls(Ctrl::GetTopCtrls());
		bool b = PrintDlg(&dlg);
		EnableCtrls(disabled);
		if(!b) return false;
		hdc = dlg.hDC;
	}
	else {
		DEVNAMES *p = (DEVNAMES *)::GlobalLock(dlg.hDevNames);
		const char *driver = (const char *)p + p->wDriverOffset;
		const char *device = (const char *)p + p->wDeviceOffset;
		if(dlg.hDevMode) {
			DEVMODE *pDevMode = (DEVMODE*)::GlobalLock(dlg.hDevMode);
			hdc = CreateDC(driver, device, NULL, pDevMode);
			::GlobalUnlock(dlg.hDevMode);
		}
		else
			hdc = CreateDC(driver, device, NULL, NULL);
	}
	if(dlg.hDevMode)
		::GlobalFree(dlg.hDevMode);
	if(dlg.hDevNames)
		::GlobalFree(dlg.hDevNames);
	if(hdc) {
		draw = new PrintDraw(hdc, Nvl(name, Ctrl::GetAppName()));
		page.Clear();
		if(!(dlg.Flags & PD_PAGENUMS)) {
			dlg.nFromPage = dlg.nMinPage;
			dlg.nToPage = dlg.nMaxPage;
		}
		for(int i = dlg.nFromPage - 1; i <= dlg.nToPage - 1; i++)
			page.Add(i);
		return true;
	}
	return false;
}



Pay attention to this line:
	if(hdc) {
		draw = new PrintDraw(hdc, Nvl(name, Ctrl::GetAppName()));


That says with a standard win32 HDC, you can create a PrintDraw, which speaks U++. So your task is how to use win32 api to create a HDC with a given device (printer) name. The above listed Execute0 also gives you a lots of clue, some of the relevant code can be boiled down to
		DEVNAMES *p = (DEVNAMES *)::GlobalLock(dlg.hDevNames);
		const char *driver = (const char *)p + p->wDriverOffset;
		const char *device = (const char *)p + p->wDeviceOffset;
		hdc = CreateDC(driver, device, NULL, NULL);


now remaining question is what dlg.hDevNames is, how to map your printer name to that particular handle. This is probably a viable path. This is not the say that it's the smartest or shortest path. Check with somebody who is really familiar with Win32 programming.
Re: Direct printing to a specific printer [message #46435 is a reply to message #46434] Wed, 11 May 2016 01:18 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 536
Registered: March 2007
Contributor
Turns out it's even easier. The following code succeeded on my windows 8 system.

{
	HDC hdc = CreateDC( "WINSPOOL", "Microsoft XPS Document Writer", NULL, NULL);

	if(hdc) {
		One<PrintDraw> d = new PrintDraw(hdc, "My Printing Job Name");
		LOG("Printer Draw OK");

		d->DrawText(10,20,"Test",StdFont().Height(720),Black());
		
		d->EndPage();

		DeleteDC(hdc);
	}
}


You should replace "Microsoft XPS..." with your actual printer name (who doesn't need to be the default printer.

HTH,

Lance

[Updated on: Wed, 11 May 2016 01:25]

Report message to a moderator

Re: Direct printing to a specific printer [message #46444 is a reply to message #46435] Wed, 11 May 2016 14:45 Go to previous message
Giorgio is currently offline  Giorgio
Messages: 218
Registered: August 2015
Experienced Member
As usual... thanks a lot!
Previous Topic: Use Gstreamer with Upp
Next Topic: What is SegtorMap?
Goto Forum:
  


Current Time: Sun Jun 23 11:07:46 CEST 2024

Total time taken to generate the page: 0.03019 seconds