Home » Community » Newbie corner » Direct printing to a specific printer
Direct printing to a specific printer [message #46416] |
Mon, 09 May 2016 11:28 |
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 |
Lance
Messages: 526 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 |
Lance
Messages: 526 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
|
|
|
|
Goto Forum:
Current Time: Fri Mar 29 01:21:20 CET 2024
Total time taken to generate the page: 0.01111 seconds
|