#if NET_2_0
internal bool use_compatible_text_rendering;
+ static internal bool verify_thread_handle;
private Padding padding;
#endif
#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;
}
}
- public virtual bool IsReadOnly {
+ public bool IsReadOnly {
get {
return list.IsReadOnly;
}
return Contains (value) || ImplicitContains (value);
}
- public virtual void CopyTo (Array array, int index)
+ public void CopyTo (Array array, int index)
{
list.CopyTo(array, index);
}
}
}
- bool IList.IsReadOnly {
- get {
- return list.IsReadOnly;
- }
- }
-
bool ICollection.IsSynchronized {
get {
return list.IsSynchronized;
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?
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;
DestroyHandle();
controls.Remove(this);
}
+ is_disposed = true;
+ base.Dispose(disposing);
}
#endregion // Public Constructors
// 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;
[MonoTODO]
public static bool CheckForIllegalCrossThreadCalls
{
- set {
- }
get {
- return false;
+ return verify_thread_handle;
+ }
+
+ set {
+ verify_thread_handle = value;
}
}
#endif
[Localizable(true)]
[DefaultValue(null)]
+ [MWFCategory("Accessibility")]
public string AccessibleDescription {
get {
return AccessibilityObject.description;
[Localizable(true)]
[DefaultValue(null)]
+ [MWFCategory("Accessibility")]
public string AccessibleName {
get {
return AccessibilityObject.Name;
}
[DefaultValue(false)]
+ [MWFCategory("Behavior")]
public virtual bool AllowDrop {
get {
return allow_drop;
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;
#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;
}
}
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);
[Localizable(true)]
[DefaultValue(null)]
+ [MWFCategory("Appearance")]
public virtual Image BackgroundImage {
get {
return background_image;
}
}
+ internal virtual bool InternalCapture {
+ get {
+ return Capture;
+ }
+
+ set {
+ Capture = value;
+ }
+ }
+
[EditorBrowsable(EditorBrowsableState.Advanced)]
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
}
[DefaultValue(true)]
+ [MWFCategory("Focus")]
public bool CausesValidation {
get {
return this.causes_validation;
}
[DefaultValue(null)]
+ [MWFCategory("Behavior")]
public virtual ContextMenu ContextMenu {
get {
return context_menu;
}
[AmbientValue(null)]
+ [MWFCategory("Appearance")]
public virtual Cursor Cursor {
get {
if (cursor != null) {
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[ParenthesizePropertyName(true)]
[RefreshProperties(RefreshProperties.All)]
+ [MWFCategory("Data")]
public ControlBindingsCollection DataBindings {
get {
if (data_bindings == null)
[Localizable(true)]
[RefreshProperties(RefreshProperties.Repaint)]
[DefaultValue(DockStyle.None)]
+ [MWFCategory("Layout")]
public virtual DockStyle Dock {
get {
return dock_style;
[DispId(-514)]
[Localizable(true)]
+ [MWFCategory("Behavior")]
public bool Enabled {
get {
if (!is_enabled) {
[DispId(-512)]
[AmbientValue(null)]
[Localizable(true)]
+ [MWFCategory("Appearance")]
public virtual Font Font {
get {
if (font != null) {
return DefaultFont;
}
+ [param:MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Font))]
set {
if (font != null && font.Equals (value)) {
return;
}
[DispId(-513)]
+ [MWFCategory("Appearance")]
public virtual Color ForeColor {
get {
if (foreground_color.IsEmpty) {
[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();
}
[AmbientValue(ImeMode.Inherit)]
[Localizable(true)]
+ [MWFCategory("Behavior")]
public ImeMode ImeMode {
get {
if (ime_mode == DefaultImeMode) {
}
[Localizable(true)]
+ [MWFCategory("Layout")]
public Point Location {
get {
return new Point(bounds.X, bounds.Y);
[AmbientValue(RightToLeft.Inherit)]
[Localizable(true)]
+ [MWFCategory("Appearance")]
public virtual RightToLeft RightToLeft {
get {
if (right_to_left == RightToLeft.Inherit) {
}
[Localizable(true)]
+ [MWFCategory("Layout")]
public Size Size {
get {
return new Size(Width, Height);
[Localizable(true)]
[MergableProperty(false)]
+ [MWFCategory("Behavior")]
public int TabIndex {
get {
if (tab_index != -1) {
[DispId(-516)]
[DefaultValue(true)]
+ [MWFCategory("Behavior")]
public bool TabStop {
get {
return tab_stop;
[Bindable(true)]
[TypeConverter(typeof(StringConverter))]
[DefaultValue(null)]
+ [MWFCategory("Data")]
public object Tag {
get {
return control_tag;
[DispId(-517)]
[Localizable(true)]
[BindableAttribute(true)]
+ [MWFCategory("Appearance")]
public virtual string Text {
get {
// Our implementation ignores ControlStyles.CacheText - we always cache
}
[Localizable(true)]
+ [MWFCategory("Behavior")]
public bool Visible {
get {
if (!is_visible) {
create_params.ExStyle |= (int)WindowExStyles.WS_EX_ACCEPTFILES;
}
- if (parent!=null) {
+ if ((parent!=null) && (parent.IsHandleCreated)) {
create_params.Parent = parent.Handle;
}
public virtual void Refresh() {
if (IsHandleCreated == true) {
-
Invalidate();
XplatUI.UpdateWindow(window.Handle);
}
[EditorBrowsable(EditorBrowsableState.Never)]
- [MonoTODO]
public void ResetBindings() {
- // Do something
+ data_bindings.Clear();
}
[EditorBrowsable(EditorBrowsableState.Never)]
}
}
- // 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);
}
} else {
control_style &= ~flag;
}
- OnStyleChanged(EventArgs.Empty);
}
protected void SetTopLevel(bool value) {
protected virtual void SetVisibleCore(bool value) {
if (value!=is_visible) {
+ if (value && !is_created) {
+ CreateControl();
+ }
+
is_visible=value;
if (IsHandleCreated) {
}
}
- if (is_visible && !is_created) {
- CreateControl();
- }
-
OnVisibleChanged(EventArgs.Empty);
if (value == false && parent != null) {
[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;
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);
}
}
- [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) {
}
XplatUI.SetWindowStyle(window.Handle, CreateParams);
+ OnStyleChanged(EventArgs.Empty);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
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;
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) {
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;
}
HandleClick(mouse_clicks, me);
OnMouseUp (me);
- if (Capture) {
- Capture = false;
+ if (InternalCapture) {
+ InternalCapture = false;
}
if (mouse_clicks > 1) {
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));
}
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 ()),
HandleClick(mouse_clicks, me);
OnMouseUp (me);
- if (Capture) {
- Capture = false;
+ if (InternalCapture) {
+ InternalCapture = false;
}
if (mouse_clicks > 1) {
mouse_clicks = 1;
}
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));
}
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 ()),
}
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 ()),
HandleClick(mouse_clicks, me);
OnMouseUp (me);
- if (Capture) {
- Capture = false;
+ if (InternalCapture) {
+ InternalCapture = false;
}
if (mouse_clicks > 1) {
}
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));
}
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 ()),
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()),
if (Paint!=null) Paint(this, e);
}
+ internal virtual void OnPaintBackgroundInternal(PaintEventArgs e) {
+ // Override me
+ }
+
internal virtual void OnPaintInternal(PaintEventArgs e) {
// Override me
}