Handle paint exceptions, showing a red cross like .NET does. Fixes bug 694908.
authorEberhard Beilharz <eb1@sil.org>
Thu, 16 Jun 2011 18:17:31 +0000 (20:17 +0200)
committerThomas Goldstein <stifu@free.fr>
Thu, 16 Jun 2011 18:32:47 +0000 (20:32 +0200)
mcs/class/Managed.Windows.Forms/System.Windows.Forms/NativeWindow.cs

index 8f0a723f2bc2cde06cddd0ee79f38ac5feb7fff9..56edd81c76036afffbb5878046bc17837b9618d0 100644 (file)
@@ -35,6 +35,7 @@ using System.Runtime.CompilerServices;
 using System.Threading;
 using System.Collections;
 using System.Diagnostics;
+using System.Drawing;
 
 namespace System.Windows.Forms
 {
@@ -257,8 +258,19 @@ namespace System.Windows.Forms
                        }
                        catch (Exception ex) {
 #if !ExternalExceptionHandler
-                               if (window != null)
-                                       window.OnThreadException (ex);
+                               if (window != null) {
+                                       if (msg == Msg.WM_PAINT && window is Control.ControlNativeWindow) {
+                                               // Replace control with a red cross
+                                               var control = ((Control.ControlNativeWindow)window).Owner;
+                                               control.Hide ();
+                                               var redCross = new Control (control.Parent, string.Empty);
+                                               redCross.BackColor = Color.White;
+                                               redCross.ForeColor = Color.Red;
+                                               redCross.Bounds = control.Bounds;
+                                               redCross.Paint += HandleRedCrossPaint;
+                                       }
+                                       window.OnThreadException (ex);
+                               }
 #else
                                throw;
 #endif
@@ -270,6 +282,27 @@ namespace System.Windows.Forms
                        return result;
                }
 
+               private static void HandleRedCrossPaint (object sender, PaintEventArgs e)
+               {
+                       var control = sender as Control;
+                       using (var pen = new Pen (control.ForeColor, 2)) {
+                               var paintRect = control.DisplayRectangle;
+                               e.Graphics.DrawRectangle (pen, paintRect.Left + 1,
+                                       paintRect.Top + 1, paintRect.Width - 1, paintRect.Height - 1);
+                               // NOTE: .NET's drawing of the red cross seems to have a bug
+                               // that draws the bottom and right of the rectangle only 1 pixel
+                               // wide. We would get a nicer rectangle using the following code,
+                               // but that runs into a problem with libgdiplus.
+                               //var paintRect = control.DisplayRectangle;
+                               //paintRect.Inflate (-1, -1);
+                               //e.Graphics.DrawRectangle (pen, paintRect);
+                               e.Graphics.DrawLine (pen, paintRect.Location,
+                                       paintRect.Location + paintRect.Size);
+                               e.Graphics.DrawLine (pen, new Point (paintRect.Left, paintRect.Bottom),
+                                       new Point (paintRect.Right, paintRect.Top));
+                       }
+               }
+
                private static NativeWindow EnsureCreated (NativeWindow window, IntPtr hWnd)
                {
                        // we need to do this AssignHandle here instead of relying on