.NET Forum / Windows Forms / WinForm General / May 2006
Exception with PrintPreviewControl while showing document
|
|
Thread rating:  |
Bob Dankert - 22 May 2006 22:44 GMT 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
Luke Zhang [MSFT] - 23 May 2006 12:21 GMT 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.)
Bob Dankert - 23 May 2006 14:23 GMT 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
> Hello, > [quoted text clipped - 17 lines] > (This posting is provided "AS IS", with no warranties, and confers no > rights.) Bob Dankert - 23 May 2006 15:18 GMT 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
> Luke, > [quoted text clipped - 52 lines] >> (This posting is provided "AS IS", with no warranties, and confers no >> rights.) Linda Liu [MSFT] - 24 May 2006 09:37 GMT 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. ====================================================
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|