Exception with PrintPreviewControl while showing document

B

Bob Dankert

Hello,

I have a control which utilizes the PrintPreviewControl class to provide a
more powerful print preview than the provided PrintPreviewDialog class. I
am having troubles when the default printer on the computer is a network
printer which is not currently accessible (for example, on a laptop removed
from the network). When this happens an exception is thrown while the
PrintPreviewControl is trying to display the print document with details of
the exception being:
Type: System.Exception
Text: No printers are installed
(Stack Trace provided at the end of the message)

The odd part of this is that there are numerous printers installed, however
the default printer happens to not be available since it is a network
printer and is not on the network. I have queried the printer status using
the following WMI query:
SELECT Name, PrinterStatus,Default FROM Win32_Printer
and have found that the PrinterStatus of the default printer is 2 which is
Unknown. It seems to be odd behavior that an exception of "No printers are
installed" is thrown when the PrinterStatus should be Unknown. The real
trouble here is trying to catch and handle these exceptions. Given that the
exception is thrown while trying to display the document and this is done
automatically by the control, I have no idea where I can use a try/catch to
catch this exception and handle it gracefully. Currently I am catching the
error in a try/catch which surrounds the Application.Run command which
starts my program.

After additional testing, I tried taking out the try/catch from around the
Application.Run to see what would happen in debug mode. The results of this
seem even odder to me in that I get a FatalExecutionEngineError being
recorded with the following details:
The runtime has encountered a fatal error. The address of the error was at
0x7f570c2b, on thread 0x197c. The error code is 0xc0000005. This error may
be a bug in the CLR or in the unsafe or non-verifiable portions of user
code. Common sources of this bug include user marshaling errors for
COM-interop or PInvoke, which may corrupt the stack.

If anyone can provide assistance in regards to how I can gracefully handle
or even prevent these exceptions/errors, I would be very much appreciative.

Bob Dankert

Additional Info: This is Windows XP x64 and .Net 2.0

Stack Trace from first "No printers are installed" Exception:

at System.Drawing.Printing.PrinterSettings.GetHdevmodeInternal()
at System.Drawing.Printing.PrinterSettings.GetHdevmode(PageSettings
pageSettings)
at System.Drawing.Printing.PrintController.OnStartPrint(PrintDocument
document, PrintEventArgs e)
at
System.Windows.Forms.PrintControllerWithStatusDialog.OnStartPrint(PrintDocument
document, PrintEventArgs e)
at System.Drawing.Printing.PrintController.Print(PrintDocument document)
at System.Drawing.Printing.PrintDocument.Print()
at System.Windows.Forms.PrintPreviewControl.ComputePreview()

at System.Windows.Forms.PrintPreviewControl.CalculatePageInfo()
at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at
System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode
code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,
ContextCallback callback, Object state)
at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry
tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32
msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at
System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32
dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32
reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32
reason, ApplicationContext context)
at PrintPreviewControl.Program.Main() in
C:\\Programming\\Projects\\PrintPreviewControl\\PrintPreviewControl\\Program.cs:line
19
 
L

Luke Zhang [MSFT]

Hello,

Could you please explain more about how you show PrintPreviewControl in
your user control, with code? If so, is it possible to detect the printer
before you set the PrintPreviewControl's properties. If the default printer
is not accessible, you may generate your own error message before
PrintPreviewControl is shown?

Regards

Luke Zhang
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
B

Bob Dankert

Luke,

I simply create a new UserControl and in the designer interface for the new
UserControl, I drag a PrintPreviewControl from the toolbox into the
UserControl. I also add a few buttons and other standard controls to the
UserControl. My current plan was to try to detect the default printer
status (hence my use of the WMI query) but what are all of the situations
which will cause the control to throw an exception? It seems like awfully
poor design to have the Microsoft-provided control throw an exception which
can not be caught and which must be prevented by a large amount of code
before even displaying the control. It seems like even worse design to not
have documented this anywhere. Aside from that, I still would like to know
which situations will cause the control to throw an exception. So far, I
have the following condition:
- If the default printer has a PrinterStatus (as queried from Win32_Printer)
of 2 (Unknown), do not allow the PrintPreviewControl to be displayed.

This seems like an awfully large limitation on my program if I implement
this. In today's world many, many people are using laptops and other
portable computers. Also, most businesses use networked printers. This
means that anytime someone is travelling and not connected to their standard
printers, this software will no longer work. This does not seem like an
acceptable answer, especially given that the PrintPreviewDialog does not
suffer these problems.

Is there any way I can tell the PrintPreviewControl to simply draw the
document using some sort of default settings if the default printer is not
available, or if there are no printers installed?

I look forward to any ideas you have that will allow me to make practical
use out of the PrintPreviewControl.

Bob Dankert
 
B

Bob Dankert

Luke,

I wanted to follow-up from my previous comments. Previously, I stated that
the PrintPreviewDialog does not suffer the same problems, but it seems I was
incorrect and it does have the same problems. Using reflector, it seems
that PrintPreviewDialog does the following:

protected override void CreateHandle()
{
if ((this.Document != null) && !this.Document.PrinterSettings.IsValid)
{
throw new
InvalidPrinterException(this.Document.PrinterSettings);
}
base.CreateHandle();
}

Given this code, it seems as though one possibility would be to check if the
IsValid is true, otherwise do not proceed. It seems as though I can simply
change the PrinterSettings to that of a valid printer and make this check
any time the PrintDocument is set (through the Document property of the
control).

Pleae let me know if you have any feedback regarding this idea.

Thanks,

Bob Dankert
 
L

Linda Liu [MSFT]

Hi Bob,

Yes, I think you could add an overrided CreateHandle() method in your user
control and check if the
PrintPreviewControl.Document.PrinterSettings.IsValid is true. If the value
is false, you might throw an exception and do not proceed, or change the
PrinterSettings to a valid printer if possible.


Sincerely,
Linda Liu
Microsoft Online Community Support

====================================================
When responding to posts,please "Reply to Group" via
your newsreader so that others may learn and benefit
from your issue.
====================================================
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top