2006-05-10 Peter Dennis Bartok <pbartok@novell.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Control.cs
index 95391d2bdcdbf83bd8bb89d3c5320ae6a93fa0ea..a23b86308881afcbfde200ab39205cadbcc11071 100644 (file)
@@ -122,6 +122,7 @@ namespace System.Windows.Forms
 
 #if NET_2_0
                internal bool                   use_compatible_text_rendering;
+               static internal bool            verify_thread_handle;
                private Padding                 padding;
 #endif
 
@@ -163,10 +164,6 @@ namespace System.Windows.Forms
                #region Public Classes
                [ComVisible(true)]
                public class ControlAccessibleObject : AccessibleObject {                       
-                       #region ControlAccessibleObject Local Variables
-                       private Control owner;
-                       #endregion      // ControlAccessibleObject Local Variables
-
                        #region ControlAccessibleObject Constructors
                        public ControlAccessibleObject(Control ownerControl) {
                                this.owner = ownerControl;
@@ -284,7 +281,7 @@ namespace System.Windows.Forms
                                }
                        }
 
-                       public virtual bool IsReadOnly {
+                       public bool IsReadOnly {
                                get {
                                        return list.IsReadOnly;
                                }
@@ -445,7 +442,7 @@ namespace System.Windows.Forms
                                return Contains (value) || ImplicitContains (value);
                        }
 
-                       public virtual void CopyTo (Array array, int index)
+                       public void CopyTo (Array array, int index)
                        {
                                list.CopyTo(array, index);
                        }
@@ -584,12 +581,6 @@ namespace System.Windows.Forms
                                }
                        }
 
-                       bool IList.IsReadOnly {
-                               get {
-                                       return list.IsReadOnly;
-                               }
-                       }
-
                        bool ICollection.IsSynchronized {
                                get {
                                        return list.IsSynchronized;
@@ -648,12 +639,6 @@ namespace System.Windows.Forms
                                list.Remove(value);
                        }
 
-                       void ICollection.CopyTo(Array array, int index) {
-                               if (list.Count>0) {
-                                       list.CopyTo(array, index);
-                               }
-                       }
-
                        Object ICloneable.Clone() {
                                ControlCollection clone = new ControlCollection(this.owner);
                                clone.list=(ArrayList)list.Clone();             // FIXME: Do we need this?
@@ -746,7 +731,6 @@ namespace System.Windows.Forms
                private delegate void RemoveDelegate(object c);
 
                protected override void Dispose(bool disposing) {
-                       is_disposed = true;
                        if (dc_mem!=null) {
                                dc_mem.Dispose();
                                dc_mem=null;
@@ -766,6 +750,8 @@ namespace System.Windows.Forms
                                DestroyHandle();
                                controls.Remove(this);
                        }
+                       is_disposed = true;
+                       base.Dispose(disposing);
                }
                #endregion      // Public Constructors
 
@@ -974,6 +960,26 @@ namespace System.Windows.Forms
                // This method exists so controls overriding OnPaintBackground can have default background painting done
                internal virtual void PaintControlBackground (PaintEventArgs pevent)
                {
+                       if (GetStyle(ControlStyles.SupportsTransparentBackColor) && (BackColor.A != 0xff)) {
+                               if (parent != null) {
+                                       PaintEventArgs  parent_pe;
+                                       GraphicsState   state;
+
+                                       parent_pe = new PaintEventArgs(pevent.Graphics, new Rectangle(pevent.ClipRectangle.X + Left, pevent.ClipRectangle.Y + Top, pevent.ClipRectangle.Width, pevent.ClipRectangle.Height));
+
+                                       state = parent_pe.Graphics.Save();
+                                       parent_pe.Graphics.TranslateTransform(-Left, -Top);
+                                       parent.OnPaintBackground(parent_pe);
+                                       parent_pe.Graphics.Restore(state);
+
+                                       state = parent_pe.Graphics.Save();
+                                       parent_pe.Graphics.TranslateTransform(-Left, -Top);
+                                       parent.OnPaint(parent_pe);
+                                       parent_pe.Graphics.Restore(state);
+                                       parent_pe.SetGraphics(null);
+                               }
+                       }
+
                        if (background_image == null) {
                                pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), new Rectangle(pevent.ClipRectangle.X - 1, pevent.ClipRectangle.Y - 1, pevent.ClipRectangle.Width + 2, pevent.ClipRectangle.Height + 2));
                                return;
@@ -1311,10 +1317,12 @@ namespace System.Windows.Forms
                [MonoTODO]
                public static bool CheckForIllegalCrossThreadCalls 
                {
-                       set {
-                       }
                        get {
-                               return false;
+                               return verify_thread_handle;
+                       }
+
+                       set {
+                               verify_thread_handle = value;
                        }
                }
 #endif
@@ -1348,6 +1356,7 @@ namespace System.Windows.Forms
 
                [Localizable(true)]
                [DefaultValue(null)]
+               [MWFCategory("Accessibility")]
                public string AccessibleDescription {
                        get {
                                return AccessibilityObject.description;
@@ -1360,6 +1369,7 @@ namespace System.Windows.Forms
 
                [Localizable(true)]
                [DefaultValue(null)]
+               [MWFCategory("Accessibility")]
                public string AccessibleName {
                        get {
                                return AccessibilityObject.Name;
@@ -1383,6 +1393,7 @@ namespace System.Windows.Forms
                }
 
                [DefaultValue(false)]
+               [MWFCategory("Behavior")]
                public virtual bool AllowDrop {
                        get {
                                return allow_drop;
@@ -1392,14 +1403,17 @@ namespace System.Windows.Forms
                                if (allow_drop == value)
                                        return;
                                allow_drop = value;
-                               UpdateStyles();
-                               XplatUI.SetAllowDrop (Handle, value);
+                               if (IsHandleCreated) {
+                                       UpdateStyles();
+                                       XplatUI.SetAllowDrop (Handle, value);
+                               }
                        }
                }
 
                [Localizable(true)]
                [RefreshProperties(RefreshProperties.Repaint)]
-               [DefaultValue(AnchorStyles.Top | AnchorStyles.Left)]
+               [DefaultValue(AnchorStyles.Top | AnchorStyles.Left)]
+               [MWFCategory("Layout")]
                public virtual AnchorStyles Anchor {
                        get {
                                return anchor_style;
@@ -1431,11 +1445,14 @@ namespace System.Windows.Forms
 #endif // NET_2_0
 
                [DispId(-501)]
+               [MWFCategory("Appearance")]
                public virtual Color BackColor {
                        get {
                                if (background_color.IsEmpty) {
                                        if (parent!=null) {
-                                               return parent.BackColor;
+                                               Color pcolor = parent.BackColor;
+                                               if (pcolor.A == 0xff || GetStyle(ControlStyles.SupportsTransparentBackColor))
+                                                       return pcolor;
                                        }
                                        return DefaultBackColor;
                                }
@@ -1443,6 +1460,10 @@ namespace System.Windows.Forms
                        }
 
                        set {
+                               if (!value.IsEmpty && (value.A != 0xff) && !GetStyle(ControlStyles.SupportsTransparentBackColor)) {
+                                       throw new ArgumentException("Transparent background colors are not supported on this control");
+                               }
+
                                background_color=value;
                                SetChildColor(this);
                                OnBackColorChanged(EventArgs.Empty);
@@ -1452,6 +1473,7 @@ namespace System.Windows.Forms
 
                [Localizable(true)]
                [DefaultValue(null)]
+               [MWFCategory("Appearance")]
                public virtual Image BackgroundImage {
                        get {
                                return background_image;
@@ -1542,6 +1564,16 @@ namespace System.Windows.Forms
                        }
                }
 
+               internal virtual bool InternalCapture {
+                       get {
+                               return Capture;
+                       }
+
+                       set {
+                               Capture = value;
+                       }
+               }
+
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                [Browsable(false)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
@@ -1564,6 +1596,7 @@ namespace System.Windows.Forms
                }
 
                [DefaultValue(true)]
+               [MWFCategory("Focus")]
                public bool CausesValidation {
                        get {
                                return this.causes_validation;
@@ -1636,6 +1669,7 @@ namespace System.Windows.Forms
                }
 
                [DefaultValue(null)]
+               [MWFCategory("Behavior")]
                public virtual ContextMenu ContextMenu {
                        get {
                                return context_menu;
@@ -1667,6 +1701,7 @@ namespace System.Windows.Forms
                }
 
                [AmbientValue(null)]
+               [MWFCategory("Appearance")]
                public virtual Cursor Cursor {
                        get {
                                if (cursor != null) {
@@ -1713,6 +1748,7 @@ namespace System.Windows.Forms
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [ParenthesizePropertyName(true)]
                [RefreshProperties(RefreshProperties.All)]
+               [MWFCategory("Data")]
                public ControlBindingsCollection DataBindings {
                        get {
                                if (data_bindings == null)
@@ -1742,6 +1778,7 @@ namespace System.Windows.Forms
                [Localizable(true)]
                [RefreshProperties(RefreshProperties.Repaint)]
                [DefaultValue(DockStyle.None)]
+               [MWFCategory("Layout")]
                public virtual DockStyle Dock {
                        get {
                                return dock_style;
@@ -1764,6 +1801,7 @@ namespace System.Windows.Forms
 
                [DispId(-514)]
                [Localizable(true)]
+               [MWFCategory("Behavior")]
                public bool Enabled {
                        get {
                                if (!is_enabled) {
@@ -1809,6 +1847,7 @@ namespace System.Windows.Forms
                [DispId(-512)]
                [AmbientValue(null)]
                [Localizable(true)]
+               [MWFCategory("Appearance")]
                public virtual Font Font {
                        get {
                                if (font != null) {
@@ -1822,6 +1861,7 @@ namespace System.Windows.Forms
                                return DefaultFont;
                        }
 
+                       [param:MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Font))]
                        set {
                                if (font != null && font.Equals (value)) {
                                        return;
@@ -1834,6 +1874,7 @@ namespace System.Windows.Forms
                }
 
                [DispId(-513)]
+               [MWFCategory("Appearance")]
                public virtual Color ForeColor {
                        get {
                                if (foreground_color.IsEmpty) {
@@ -1859,6 +1900,13 @@ namespace System.Windows.Forms
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
                public IntPtr Handle {                                                  // IWin32Window
                        get {
+#if NET_2_0
+                               if (verify_thread_handle) {
+                                       if (this.InvokeRequired) {
+                                               throw new InvalidOperationException("Cross-thread access of handle detected. Handle access only valid on thread that created the control");
+                                       }
+                               }
+#endif
                                if (!IsHandleCreated) {
                                        CreateHandle();
                                }
@@ -1893,6 +1941,7 @@ namespace System.Windows.Forms
 
                [AmbientValue(ImeMode.Inherit)]
                [Localizable(true)]
+               [MWFCategory("Behavior")]
                public ImeMode ImeMode {
                        get {
                                 if (ime_mode == DefaultImeMode) {
@@ -1974,6 +2023,7 @@ namespace System.Windows.Forms
                }
 
                [Localizable(true)]
+               [MWFCategory("Layout")]
                public Point Location {
                        get {
                                return new Point(bounds.X, bounds.Y);
@@ -2103,6 +2153,7 @@ namespace System.Windows.Forms
 
                [AmbientValue(RightToLeft.Inherit)]
                [Localizable(true)]
+               [MWFCategory("Appearance")]
                public virtual RightToLeft RightToLeft {
                        get {
                                if (right_to_left == RightToLeft.Inherit) {
@@ -2142,6 +2193,7 @@ namespace System.Windows.Forms
                }
 
                [Localizable(true)]
+               [MWFCategory("Layout")]
                public Size Size {
                        get {
                                return new Size(Width, Height);
@@ -2154,6 +2206,7 @@ namespace System.Windows.Forms
 
                [Localizable(true)]
                [MergableProperty(false)]
+               [MWFCategory("Behavior")]
                public int TabIndex {
                        get {
                                if (tab_index != -1) {
@@ -2172,6 +2225,7 @@ namespace System.Windows.Forms
 
                [DispId(-516)]
                [DefaultValue(true)]
+               [MWFCategory("Behavior")]
                public bool TabStop {
                        get {
                                return tab_stop;
@@ -2189,6 +2243,7 @@ namespace System.Windows.Forms
                [Bindable(true)]
                [TypeConverter(typeof(StringConverter))]
                [DefaultValue(null)]
+               [MWFCategory("Data")]
                public object Tag {
                        get {
                                return control_tag;
@@ -2202,6 +2257,7 @@ namespace System.Windows.Forms
                [DispId(-517)]
                [Localizable(true)]
                [BindableAttribute(true)]
+               [MWFCategory("Appearance")]
                public virtual string Text {
                        get {
                                // Our implementation ignores ControlStyles.CacheText - we always cache
@@ -2252,6 +2308,7 @@ namespace System.Windows.Forms
                }
 
                [Localizable(true)]
+               [MWFCategory("Behavior")]
                public bool Visible {
                        get {
                                if (!is_visible) {
@@ -2345,7 +2402,7 @@ namespace System.Windows.Forms
                                        create_params.ExStyle |= (int)WindowExStyles.WS_EX_ACCEPTFILES;
                                }
 
-                               if (parent!=null) {
+                               if ((parent!=null) && (parent.IsHandleCreated)) {
                                        create_params.Parent = parent.Handle;
                                }
 
@@ -2932,7 +2989,6 @@ namespace System.Windows.Forms
 
                public virtual void Refresh() {                 
                        if (IsHandleCreated == true) {
-
                                Invalidate();
                                XplatUI.UpdateWindow(window.Handle);
 
@@ -2950,9 +3006,8 @@ namespace System.Windows.Forms
                }
 
                [EditorBrowsable(EditorBrowsableState.Never)]
-               [MonoTODO]
                public void ResetBindings() {
-                       // Do something
+                       data_bindings.Clear();
                }
 
                [EditorBrowsable(EditorBrowsableState.Never)]
@@ -3137,8 +3192,10 @@ namespace System.Windows.Forms
                                        }
                                }
 
-                               // Find out where the window manager placed us
                                UpdateStyles();
+                               XplatUI.SetAllowDrop (Handle, allow_drop);
+
+                               // Find out where the window manager placed us
                                if ((CreateParams.Style & (int)WindowStyles.WS_CHILD) != 0) {
                                        XplatUI.SetBorderStyle(window.Handle, (FormBorderStyle)border_style);
                                }
@@ -3542,7 +3599,6 @@ namespace System.Windows.Forms
                        } else {
                                control_style &= ~flag;
                        }
-                       OnStyleChanged(EventArgs.Empty);
                }
 
                protected void SetTopLevel(bool value) {
@@ -3566,6 +3622,10 @@ namespace System.Windows.Forms
 
                protected virtual void SetVisibleCore(bool value) {
                        if (value!=is_visible) {
+                               if (value && !is_created) {
+                                       CreateControl();
+                               }
+
                                is_visible=value;
 
                                if (IsHandleCreated) {
@@ -3577,10 +3637,6 @@ namespace System.Windows.Forms
                                        }
                                }
 
-                               if (is_visible && !is_created) {
-                                       CreateControl();
-                               }
-
                                OnVisibleChanged(EventArgs.Empty);
 
                                if (value == false && parent != null) {
@@ -3621,13 +3677,23 @@ namespace System.Windows.Forms
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected void UpdateBounds(int x, int y, int width, int height) {
+                       CreateParams    cp;
+                       Rectangle       rect;
+
+                       // Calculate client rectangle
+                       rect = new Rectangle(0, 0, 0, 0);
+                       cp = CreateParams;
+
+                       XplatUI.CalculateWindowRect(ref rect, cp.Style, cp.ExStyle, cp.menu, out rect);
+                       UpdateBounds(x, y, width, height, width - (rect.Right - rect.Left), height - (rect.Bottom - rect.Top));
+               }
+
+               [EditorBrowsable(EditorBrowsableState.Advanced)]
+               protected void UpdateBounds(int x, int y, int width, int height, int clientWidth, int clientHeight) {
                        // UpdateBounds only seems to set our sizes and fire events but not update the GUI window to match
                        bool    moved   = false;
                        bool    resized = false;
 
-                       int     client_x_diff = this.bounds.Width-this.client_size.Width;
-                       int     client_y_diff = this.bounds.Height-this.client_size.Height;
-
                        // Needed to generate required notifications
                        if ((this.bounds.X!=x) || (this.bounds.Y!=y)) {
                                moved=true;
@@ -3642,9 +3708,8 @@ namespace System.Windows.Forms
                        bounds.Width=width;
                        bounds.Height=height;
 
-                       // Update client rectangle as well
-                       client_size.Width=width-client_x_diff;
-                       client_size.Height=height-client_y_diff;
+                       client_size.Width=clientWidth;
+                       client_size.Height=clientHeight;
 
                        if (moved) {
                                OnLocationChanged(EventArgs.Empty);
@@ -3655,14 +3720,6 @@ namespace System.Windows.Forms
                        }
                }
 
-               [EditorBrowsable(EditorBrowsableState.Advanced)]
-               protected void UpdateBounds(int x, int y, int width, int height, int clientWidth, int clientHeight) {
-                       UpdateBounds(x, y, width, height);
-
-                       this.client_size.Width=clientWidth;
-                       this.client_size.Height=clientHeight;
-               }
-
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected void UpdateStyles() {
                        if (!IsHandleCreated) {
@@ -3670,6 +3727,7 @@ namespace System.Windows.Forms
                        }
 
                        XplatUI.SetWindowStyle(window.Handle, CreateParams);
+                       OnStyleChanged(EventArgs.Empty);
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
@@ -3716,6 +3774,9 @@ namespace System.Windows.Forms
                                        return;
                                }
 
+                               // Nice description of what should happen when handling WM_PAINT
+                               // can be found here: http://pluralsight.com/wiki/default.aspx/Craig/FlickerFreeControlDrawing.html
+                               // and here http://msdn.microsoft.com/msdnmag/issues/06/03/WindowsFormsPerformance/
                                case Msg.WM_PAINT: {
                                        PaintEventArgs  paint_event;
 
@@ -3734,10 +3795,17 @@ namespace System.Windows.Forms
                                                        dc = paint_event.SetGraphics (DeviceContext);
                                                }
 
-                                       OnPaintBackground(paint_event);
-                                       // Leave out for now, our controls can do Paint += ... as well
-                                       //OnPaintInternal(paint_event);
-                                       OnPaint(paint_event);
+                                       if (!GetStyle(ControlStyles.Opaque)) {
+                                               OnPaintBackground(paint_event);
+                                       }
+
+                                       // Button-derived controls choose to ignore their Opaque style, give them a chance to draw their background anyways
+                                       OnPaintBackgroundInternal(paint_event);
+
+                                       OnPaintInternal(paint_event);
+                                       if (!paint_event.Handled) {
+                                               OnPaint(paint_event);
+                                       }
 
                                        if (ThemeEngine.Current.DoubleBufferingSupported)
                                                if ((control_style & ControlStyles.DoubleBuffer) != 0) {
@@ -3753,6 +3821,8 @@ namespace System.Windows.Forms
                                        
                                case Msg.WM_ERASEBKGND: {
                                        // The DefWndProc will never have to handle this, we always paint the background in managed code
+                                       // In theory this code would look at ControlStyles.AllPaintingInWmPaint and and call OnPaintBackground
+                                       // here but it just makes things more complicated...
                                        m.Result = (IntPtr)1;
                                        return;
                                }
@@ -3768,8 +3838,8 @@ namespace System.Windows.Forms
                                        HandleClick(mouse_clicks, me);
                                        OnMouseUp (me);
 
-                                       if (Capture) {
-                                               Capture = false;
+                                       if (InternalCapture) {
+                                               InternalCapture = false;
                                        }
 
                                        if (mouse_clicks > 1) {
@@ -3782,7 +3852,7 @@ namespace System.Windows.Forms
                                        if (CanSelect && !is_selected) {
                                                Select(this);
                                        }
-                                       Capture = true;
+                                       InternalCapture = true;
                                        OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
                                                mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
                                                0));
@@ -3791,7 +3861,7 @@ namespace System.Windows.Forms
                                }
 
                                case Msg.WM_LBUTTONDBLCLK: {
-                                       Capture = true;
+                                       InternalCapture = true;
                                        mouse_clicks++;
                                        OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
                                                mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
@@ -3810,8 +3880,8 @@ namespace System.Windows.Forms
 
                                        HandleClick(mouse_clicks, me);
                                        OnMouseUp (me);
-                                       if (Capture) {
-                                               Capture = false;
+                                       if (InternalCapture) {
+                                               InternalCapture = false;
                                        }
                                        if (mouse_clicks > 1) {
                                                mouse_clicks = 1;
@@ -3820,7 +3890,7 @@ namespace System.Windows.Forms
                                }
                                        
                                case Msg.WM_MBUTTONDOWN: {                                      
-                                       Capture = true;
+                                       InternalCapture = true;
                                        OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
                                                mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
                                                0));
@@ -3829,7 +3899,7 @@ namespace System.Windows.Forms
                                }
 
                                case Msg.WM_MBUTTONDBLCLK: {
-                                       Capture = true;
+                                       InternalCapture = true;
                                        mouse_clicks++;
                                        OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
                                                mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
@@ -3838,11 +3908,14 @@ namespace System.Windows.Forms
                                }
 
                                case Msg.WM_RBUTTONUP: {
-                                       MouseEventArgs me;
+                                       MouseEventArgs  me;
+                                       Point           pt;
+
+                                       pt = new Point(LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()));
+                                       pt = PointToScreen(pt);
+
+                                       XplatUI.SendMessage(m.HWnd, Msg.WM_CONTEXTMENU, m.HWnd, (IntPtr)(pt.X + (pt.Y << 16)));
 
-                                       if (context_menu != null) {
-                                               context_menu.Show(this, new Point(LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ())));
-                                       }
                                        me = new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Right, 
                                                mouse_clicks, 
                                                LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
@@ -3851,8 +3924,8 @@ namespace System.Windows.Forms
                                        HandleClick(mouse_clicks, me);
                                        OnMouseUp (me);
 
-                                       if (Capture) {
-                                               Capture = false;
+                                       if (InternalCapture) {
+                                               InternalCapture = false;
                                        }
 
                                        if (mouse_clicks > 1) {
@@ -3862,7 +3935,7 @@ namespace System.Windows.Forms
                                }
                                        
                                case Msg.WM_RBUTTONDOWN: {                                      
-                                       Capture = true;
+                                       InternalCapture = true;
                                        OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
                                                mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
                                                0));
@@ -3870,7 +3943,7 @@ namespace System.Windows.Forms
                                }
 
                                case Msg.WM_RBUTTONDBLCLK: {
-                                       Capture = true;
+                                       InternalCapture = true;
                                        mouse_clicks++;
                                        OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
                                                mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
@@ -3878,6 +3951,19 @@ namespace System.Windows.Forms
                                        return;
                                }
 
+                               case Msg.WM_CONTEXTMENU: {
+                                       if (context_menu != null) {
+                                               Point   pt;
+
+                                               pt = new Point(LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()));
+                                               context_menu.Show(this, PointToClient(pt));
+                                               return;
+                                       }
+
+                                       DefWndProc(ref m);
+                                       return;
+                               }
+
                                case Msg.WM_MOUSEWHEEL: {                               
 
                                        OnMouseWheel (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
@@ -4257,6 +4343,10 @@ namespace System.Windows.Forms
                        if (Paint!=null) Paint(this, e);
                }
 
+               internal virtual void OnPaintBackgroundInternal(PaintEventArgs e) {
+                       // Override me
+               }
+
                internal virtual void OnPaintInternal(PaintEventArgs e) {
                        // Override me
                }