cancel
Showing results for 
Search instead for 
Did you mean: 

CR XI R2 Sp6 - How do you change the default printer used by the Viewer?

anders_gustafsson
Participant
0 Kudos

CR XI R2 Sp6

.NET

VS2005, C++

The app selects printer for the job as m_Report->PrintOptions->PrinterName = ss_Device;

This works nicely for printouts to the printer, but is ignored by the viewer. There, the machine default printer is always selected when I hit the print button.

Found this which is sortof similar:

http://forums.sdn.sap.com/thread.jspa?threadID=1275149

Is there any way to fix this? If no, then is it fixed in more recent versions of CR?

Accepted Solutions (1)

Accepted Solutions (1)

former_member184995
Active Contributor
0 Kudos

I thought that the viewer print control would always automatically select the default printer for that machine.

0 Kudos

Correct,

As Ludek indicated the Print Button on our Viewer will ALWAYS select the default printer. If you want other functionality then create your own Print Button and then you have full control. You can hide our print button and drop your own control in it's place or have a Print Report button in your form somewhere outside of the viewer.

Don

anders_gustafsson
Participant
0 Kudos

Well, this definitely changed as we went from CR9 to XI. In CR9 the print dialogue was very rudimentary. You could not select printer, only pagerange. It would honour the applications printer selection though. Ie what was set for the job with m_Job->SelectPrinter(driver,name,port);

In CR XI the default print dialogue is better, but completely ignores what we set for the job,

0 Kudos

I should also mention that you should use the PrintOutputController to print reports rather than PrintToPrinter. Lot's of sample code in this forum on how to use it.

Don

anders_gustafsson
Participant
0 Kudos

I was under the assumption that those calls required a dedicated server running somewhere?

Anyway. I am already working on replacing the export button as a lot of good functionality there was dropped in the CR XI viewer so I already have the skeleton code for fixing that. The code to override the print button is identical.

I guess I am no different from the next person in assuming that new versions bring improvements, so I get upset when stuff is dropped from an upgrade

Edited by: Anders Gustafsson on Feb 8, 2012 8:29 PM

Edited by: Anders Gustafsson on Feb 8, 2012 8:31 PM

0 Kudos

Hi Anders,

There are 2 flavors of RAS, one is InProc RAS which comes with all full versions of CR Designer installs or CR for VS 2010 and the other is the Managed RAS which connects to a BOE Server where RAS is running as a service. Just a few lines of code to change from inProc to a Service when opening the report.

And yes there have been updates to the Print methods and how Printers are handled in CR itself. The old ActiveX report engines used DEVMODE structure to handle Printing. .NET uses the Framework to do the printing so those legacy Common Controls where updated and changed.

Unfortunately when MS changes their platform and Development back end we have to follow. I agree with you it was so much simpler in the old days.... But then we don't have all of the feature rich environments we have these days either....

Give the Controller and inProc RAS a try...

Thanks

Don

former_member183750
Active Contributor
0 Kudos

Re. few lines of code to change from inProc to a Service when opening the report.

The following would do it in C#:

using CrystalDecisions.CrystalReports.Engine;

using CrystalDecisions.Shared;

using CrystalDecisions.ReportAppServer.ClientDoc;

using CrystalDecisions.ReportAppServer.Controllers;

using CrystalDecisions.ReportAppServer.ReportDefModel;

using CrystalDecisions.ReportAppServer.DataSetConversion;

using CrystalDecisions.ReportAppServer.DataDefModel;

CrystalDecisions.CrystalReports.Engine.ReportDocument rpt = new CrystalDecisions.CrystalReports.Engine.ReportDocument();

ISCDReportClientDocument rptClientDoc;

To open the report use:

object rptName = openFileDialog.FileName;

rpt.Load(rptName.ToString());

rptClientDoc = rpt.ReportClientDocument;

More info is in [How to Use The RAS SDK .NET With In-Process RAS Server|https://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/10b840c0-623f-2b10-03b5-9d1913866b32].

- Ludek

anders_gustafsson
Participant
0 Kudos

Thanks both, I will have a look at those documents, but right now am I a bit weary to change anything, unless absolutely necessary, as most things work as they should.

This is quite a large C++ app. Close to a thousand source files and hundreds of reports, many of which are modified at runtime, to change parameters, sort order etc. We have been working with Crystal since version 4 or 5 and yes, we have the full, licensed developer version.

I guess that the reason to go the way you suggest is that at some point the curent .NET interface will be deprecated?

0 Kudos

Hi Anders,

Wow, I've been here since 4.5 and Ludek 2 or 3 years more than me.... RCAPI back then was editing the report file in notepad....

Are you an OEM Partner of ours?

When MS announced they were dropping COM we had to also, they changed their minds but then it was too late for us, we committed to moving to the .NET framework. So yes you can still use .NET in C++ but it has to be Managed Code, or at least easier to use Managed.

So the RDC ( craxdrt.dll ) has been deprecated since CR 9 as well as the crpe32.dll and header files. I hope you are not using them... and the RDC is no longer shipped in any supported versions of CR now, .NET is your only option to be in a supported platform.

There are few samples to use .NET in C++ app's on this page:

http://wiki.sdn.sap.com/wiki/display/BOBJ/CrystalReportsfor.NETSDK+Samples

Look for the CPP in the name.

One option is to create a CR dll and you can simply pass the report object to the dll and use RCAPI to update/change/add to the reports.

Thanks again

Don

anders_gustafsson
Participant
0 Kudos

No, we are not a OEM partner. We just ship ready-made reports with out app.

Yes, when going from CR9 to CRXI R2, we used the .NET api's and compiled those classes as managed code. Most of the app is still unmanaged C++, but luckily were the printing parts well-thought out classes so the move to CRXI meant we only had to rewrite one class completely and then just do minor changes elsewhere.

Took us some thinking before we realised that though and before that several alternate venues were contemplated, such as isolating all printing into a separate app, etc.

The new version that uses CRXI was rolled out dec-jan after lots of programming and testing during 2011. What we are faced with now are those "small" issues that pop up on every CR upgrade. Ie stuff that do not exactly work the way it used to. Annoying as they are many simply were not caught during development and testing and some may pop up just for one client.

The lack of C++ docs is a bit of a PITA and I have been meaning o write a short howto on how to move from RDC to NET without undue pain.

When I look at other apps/vendors, I see lots and I do mean LOTS of apps that still use CR9 or even, $DEITY forbid CR 8.0 and 8.5. How they manage to support their apps on Windows 7 is beyond me.

Printing seems a lot more stable now with CRXI on Win7 though and some of the new features of the new CR versions are neat and useful, so I am not all as grumpy as I might sometimes sound.

Answers (1)

Answers (1)

former_member188030
Active Contributor
0 Kudos

See if below documens help.

[Printing Web based reports with Crystal Reports for Visual Studio .NET|http://www.sdn.sap.com/irj/boc/index?rid=/library/uuid/600c24a3-ab1d-2b10-1bb4-c50562e353cb]

[Server side printing with Crystal .NET SDK|http://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/23359]

- Bhushan.

anders_gustafsson
Participant
0 Kudos

No. The problem is not printing per se. Printing works flawlessly. Problem is that if I print the report to screen and then hit the print button in the viewer, the wrong printer is selected.

former_member183750
Active Contributor
0 Kudos

Hello Anders

Here is how CR works as far as printers go:

1) A report created on a default printer driver will always look for a default printer driver to print to (any default)

2) A report created on a specific - non default printer driver, will always look for that printer driver and if available, default to print / select that driver (I suspect this is what is happening in your case)

3) If a report is created on a specific - non default printer driver and that specific printer driver is not installed, CR will substitute and use the default printer driver

All of that above can be changed at runtime, but you'd somehow need to figure out what the default printer driver is on each machine and then assign it to the report.

Alternatively, open the report in the CR designer. Go to the File menu and select Page Setup and enable the "No Printer" option. Save the report. Go back to the File menu and select Page Setup. Disable the "No Printer" option. Save the report. The report will now use a default printer driver - on any computer.

- Ludek

anders_gustafsson
Participant
0 Kudos

All of that above can be changed at runtime, but you'd somehow need to figure out what the default printer driver is on each machine and then assign it to the report.

Yes,but that is exactly what I do. The app normally uses the Windows default printer just as any C++/MFC app will do. On the file menu there is an option to select printer which calls CWinApp::OnFilePrintSetup(); which sets the application default printer setup.

In the app there is a function to retrieve the default printer:


CString CLpApp::GetDefaultPrinter()
{
	PRINTDLG	pd ;
	CString		printer("Failed") ;
	
	pd.lStructSize = (DWORD)sizeof(PRINTDLG) ;
	BOOL bRet = GetPrinterDeviceDefaults(&pd) ;
	if (bRet)
		{
		// protect memory handle with ::GlobalLock and ::GlobalUnlock
		DEVMODE *pDevMode = (DEVMODE*)::GlobalLock(m_hDevMode) ;
		printer = pDevMode->dmDeviceName ;
		::GlobalUnlock(m_hDevMode) ;
		}
	return printer ;
}

When I print, I do:


void CSkrivDlg::StartReport(CLpReportJob^ jobb)
{
	jobb->SelectPrinter("",theApp.GetDefaultPrinter(),"");
	//
	if(m_tillSkrivare)
	{
		jobb->OutputToPrinter(1);
	}
	else
	{
		jobb->OutputToWindow("Fönsternamn", 0, 0, 200, 200, 0, NULL, NULL);
	}
}

This works correctly for OutputToPrinter(1);, but not for OutputToWindow() which are simply wrappers for the CR functions:


bool CReportJob::OutputToPrinter(int nCopies)
{
	bool rc = true;
	try
	{
		m_Report->PrintToPrinter(nCopies,true,0,0);
	}
	catch (Exception ^e)
	{
		TRACE("
 %s",e->Message);
		m_LastError = e->Message;
		rc = false;
	}
	return rc;
}

//
// OutputToWindow()
// a,b,c,d = Fönsterkoordinater eller noll för default
// style = flaggor för fönsterposition
// window = fönster efter vilket vi dyker upp
// child = rapportfönstrets handle om vi vill ha den
//
bool CReportJob::OutputToWindow(CString Namn, int a, int b, int c, int d, int style, CWnd* window, CWnd **child)
{
	bool rc = 0;
	CString title="Dummy1";
	title = m_Report->SummaryInfo->ReportTitle;
	CFloaterDlg *Floater = new CFloaterDlg(NULL);			// TODO: Get window
	Floater->Create(IDD_FLOATER_DLG, NULL);
	//
	if(Floater != NULL)
	{
		m_Report->ExportOptions->ExportFormatType = CrystalDecisions::Shared::ExportFormatType::PortableDocFormat;

		Floater->m_Viewer->ReportSource = m_Report;
		Floater->m_Viewer->Zoom(theApp.m_ScreenZoom);
		//
		// Sätt fönsterrubrik från rapporten
		//
		Floater->SetWindowText(title);
		//
		// Puffa på så att den kan ändra storlek på Crystal-kontrollen
		//
		Floater->Size();
		//
		// Visa fönstret om det är stängt
		//
		if(!Floater->IsWindowVisible())
			Floater->ShowWindow(SW_SHOW);

		rc = true;
		//
		if (child!=NULL) *child=Floater;
	}
	else
	{
		AfxMessageBox("Kunde inte skapa fönster för utskrift",MB_OK);
		rc = false;
	}
	return rc;
}

Floater is simply a dialog that holds the Viewer control.

For some reason does the Viewer not obey the printer selection done in the report