#if NET_2_0
internal bool use_compatible_text_rendering;
+ static internal bool verify_thread_handle;
+ private Padding padding;
#endif
#endregion // Local Variables
#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 class ControlCollection : IList, ICollection, ICloneable, IEnumerable {
#region ControlCollection Local Variables
private ArrayList list;
- private ArrayList impl_list;
+ internal ArrayList impl_list;
private Control [] all_controls;
internal Control owner;
#endregion // ControlCollection Local Variables
}
}
- public virtual bool IsReadOnly {
+ public bool IsReadOnly {
get {
return list.IsReadOnly;
}
impl_list = new ArrayList ();
all_controls = null;
impl_list.Add (control);
+
control.ChangeParent (owner);
+ control.InitLayout ();
owner.UpdateZOrder ();
owner.PerformLayout (control, "Parent");
owner.OnControlAdded (new ControlEventArgs (control));
return Contains (value) || ImplicitContains (value);
}
- public virtual void CopyTo (Array array, int index)
+ public void CopyTo (Array array, int index)
{
list.CopyTo(array, index);
}
if (impl_list == null)
return (Control []) list.ToArray (typeof (Control));
+
Control [] res = new Control [list.Count + impl_list.Count];
- list.CopyTo (res);
- impl_list.CopyTo (res, list.Count);
+ impl_list.CopyTo (res);
+ list.CopyTo (res, impl_list.Count);
+
return res;
}
return;
}
- RemoveAt(old_index);
+ list.RemoveAt(old_index);
if (newIndex>list.Count) {
list.Add(child);
} else {
list.Insert(newIndex, child);
}
- child.parent = owner;
owner.UpdateZOrder();
}
#endregion // ControlCollection Private Instance Methods
}
}
- 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?
#if NET_2_0
use_compatible_text_rendering = Application.use_compatible_text_rendering;
+ padding = new Padding(0);
#endif
control_style = ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint |
child_controls = CreateControlsInstance();
client_size = new Size(DefaultSize.Width, DefaultSize.Height);
client_rect = new Rectangle(0, 0, DefaultSize.Width, DefaultSize.Height);
- XplatUI.CalculateWindowRect(IntPtr.Zero, ref client_rect, CreateParams.Style, CreateParams.ExStyle, null, out bounds);
+ XplatUI.CalculateWindowRect(ref client_rect, CreateParams.Style, CreateParams.ExStyle, null, out bounds);
if ((CreateParams.Style & (int)WindowStyles.WS_CHILD) == 0) {
bounds.X=-1;
bounds.Y=-1;
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
XplatUI.ClientToScreen (Handle, ref x, ref y);
}
+ private bool IsRecreating {
+ get {
+ if (is_recreating) {
+ return true;
+ }
+
+ if (parent != null) {
+ return parent.IsRecreating;
+ }
+
+ return false;
+ }
+ }
+
+ private bool ParentIsRecreating {
+ get {
+ if (parent != null) {
+ return parent.IsRecreating;
+ }
+ return false;
+ }
+ }
+
internal Graphics DeviceContext {
get {
if (dc_mem==null) {
// 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;
return found;
}
- private void HandleClick(int clicks) {
+ private void HandleClick(int clicks, MouseEventArgs me) {
if (GetStyle(ControlStyles.StandardClick)) {
- if (clicks > 1) {
- if (GetStyle(ControlStyles.StandardDoubleClick)) {
- OnDoubleClick(EventArgs.Empty);
- } else {
- OnClick(EventArgs.Empty);
- }
+ if ((clicks > 1) && GetStyle(ControlStyles.StandardDoubleClick)) {
+#if !NET_2_0
+ OnDoubleClick(EventArgs.Empty);
} else {
OnClick(EventArgs.Empty);
+#else
+ OnDoubleClick(me);
+ } else {
+ OnClick(me);
+#endif
}
}
}
}
private void UpdateDistances() {
- dist_left = bounds.X;
- dist_top = bounds.Y;
if ((parent != null) && (parent.layout_suspended == 0)) {
+ dist_left = bounds.X;
+ dist_top = bounds.Y;
dist_right = parent.ClientSize.Width - bounds.X - bounds.Width;
dist_bottom = parent.ClientSize.Height - bounds.Y - bounds.Height;
}
[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;
}
}
+#if NET_2_0
+ // XXX: Implement me!
+ bool auto_size;
+
+ public virtual bool AutoSize {
+ get {
+ Console.Error.WriteLine("Unimplemented: Control::get_AutoSize()");
+ return auto_size;
+ }
+ set {
+ Console.Error.WriteLine("Unimplemented: Control::set_AutoSize(bool)");
+ auto_size = value;
+ }
+ }
+#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;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool CanFocus {
get {
- if (Visible && is_enabled && GetStyle(ControlStyles.Selectable)) {
+ if (IsHandleCreated && Visible && Enabled) {
return true;
}
return false;
get {
Control parent;
- if (!GetStyle(ControlStyles.Selectable) || this.parent == null) {
+ if (!GetStyle(ControlStyles.Selectable)) {
return false;
}
- parent = this.parent;
+ parent = this;
while (parent != null) {
if (!parent.is_visible || !parent.is_enabled) {
return false;
}
}
+ 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;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Created {
get {
- if (!this.is_disposed && (this.window.Handle != IntPtr.Zero)) {
- return true;
- }
- return false;
+ return (!is_disposed && is_created);
}
}
[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) {
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsHandleCreated {
get {
- if ((window!=null) && (window.Handle!=IntPtr.Zero)) {
+ if ((window != null) && (window.Handle != IntPtr.Zero)) {
return true;
}
}
[Localizable(true)]
+ [MWFCategory("Layout")]
public Point Location {
get {
return new Point(bounds.X, bounds.Y);
[Browsable(false)]
public string Name {
get {
- return this.name;
+ return name;
}
set {
- this.name=value;
+ name = value;
}
}
+#if NET_2_0
+ [Localizable(true)]
+ public Padding Padding {
+ get {
+ return padding;
+ }
+
+ set {
+ padding = value;
+ }
+ }
+#endif
+
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Control Parent {
[AmbientValue(RightToLeft.Inherit)]
[Localizable(true)]
+ [MWFCategory("Appearance")]
public virtual RightToLeft RightToLeft {
get {
if (right_to_left == RightToLeft.Inherit) {
set {
base.Site = value;
+
+ AmbientProperties ap = (AmbientProperties) value.GetService (typeof (AmbientProperties));
+ if (ap != null) {
+ BackColor = ap.BackColor;
+ ForeColor = ap.ForeColor;
+ Cursor = ap.Cursor;
+ Font = ap.Font;
+ }
}
}
[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.Param = 0;
if (allow_drop) {
- create_params.ExStyle |= (int)WindowStyles.WS_EX_ACCEPTFILES;
+ create_params.ExStyle |= (int)WindowExStyles.WS_EX_ACCEPTFILES;
}
- if (parent!=null) {
+ if ((parent!=null) && (parent.IsHandleCreated)) {
create_params.Parent = parent.Handle;
}
create_params.Style |= (int) WindowStyles.WS_BORDER;
break;
case BorderStyle.Fixed3D:
- create_params.ExStyle |= (int) WindowStyles.WS_EX_CLIENTEDGE;
+ create_params.ExStyle |= (int) WindowExStyles.WS_EX_CLIENTEDGE;
break;
}
protected virtual Size DefaultSize {
get {
- return new Size(100, 23);
+ return new Size(0, 0);
}
}
#region Public Instance Methods
[EditorBrowsable(EditorBrowsableState.Advanced)]
public IAsyncResult BeginInvoke(Delegate method) {
- return BeginInvokeInternal(method, null, false);
+ object [] prms = null;
+ if (method is EventHandler)
+ prms = new object [] { this, EventArgs.Empty };
+ return BeginInvokeInternal(method, prms, false);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
if (parent.child_controls.Contains(this)) {
parent.child_controls.SetChildIndex(this, 0);
}
+ } else if (parent != null) {
+ if (parent.child_controls.impl_list != null) {
+ Control last_impl = (Control) parent.child_controls.impl_list [parent.child_controls.impl_list.Count - 1];
+ if (IsHandleCreated) {
+ XplatUI.SetZOrder (this.window.Handle, last_impl.Handle, false, false);
+ }
+ } else {
+ if (IsHandleCreated) {
+ XplatUI.SetZOrder(this.window.Handle, IntPtr.Zero, true, false);
+ }
+ }
}
- XplatUI.SetZOrder(this.window.Handle, IntPtr.Zero, true, false);
-
if (parent != null) {
parent.Refresh();
}
}
public bool Focus() {
- if (IsHandleCreated && !has_focus) {
- has_focus = true;
+ if (CanFocus && IsHandleCreated && !has_focus) {
XplatUI.SetFocus(window.Handle);
}
- return true;
+ return has_focus;
}
public Control GetChildAtPoint(Point pt) {
AnchorStyles anchor;
Rectangle space;
- space=this.DisplayRectangle;
+ space= DisplayRectangle;
// Deal with docking; go through in reverse, MS docs say that lowest Z-order is closest to edge
Control [] controls = child_controls.GetAllControls ();
for (int i = controls.Length - 1; i >= 0; i--) {
child = controls [i];
+
+ if (!child.Visible) {
+ continue;
+ }
+
switch (child.Dock) {
case DockStyle.None: {
// Do nothing
for (int i = controls.Length - 1; i >= 0; i--) {
child=controls[i];
- if (child.Dock == DockStyle.Fill) {
+ if (child.Visible && (child.Dock == DockStyle.Fill)) {
child.SetBounds(space.Left, space.Top, space.Width, space.Height);
space.Width=0;
space.Height=0;
}
}
- space=this.DisplayRectangle;
+ space=DisplayRectangle;
for (int i=0; i < controls.Length; i++) {
int left;
int height;
child = controls[i];
+
+ // If the control is docked we don't need to do anything
+ if (child.Dock != DockStyle.None) {
+ continue;
+ }
+
anchor = child.Anchor;
left = child.Left;
width = child.Width;
height = child.Height;
- // If the control is docked we don't need to do anything
- if (child.Dock != DockStyle.None) {
- continue;
- }
-
if ((anchor & AnchorStyles.Left) !=0 ) {
if ((anchor & AnchorStyles.Right) != 0) {
- width = client_size.Width - child.dist_right - left;
+ width = space.Width - child.dist_right - left;
} else {
; // Left anchored only, nothing to be done
}
} else if ((anchor & AnchorStyles.Right) != 0) {
- left = client_size.Width - child.dist_right - width;
+ left = space.Width - child.dist_right - width;
} else {
// left+=diff_width/2 will introduce rounding errors (diff_width removed from svn after r51780)
// This calculates from scratch every time:
- left = child.dist_left + (client_size.Width - (child.dist_left + width + child.dist_right)) / 2;
+ left = child.dist_left + (space.Width - (child.dist_left + width + child.dist_right)) / 2;
}
if ((anchor & AnchorStyles.Top) !=0 ) {
if ((anchor & AnchorStyles.Bottom) != 0) {
- height = client_size.Height - child.dist_bottom - top;
+ height = space.Height - child.dist_bottom - top;
} else {
; // Top anchored only, nothing to be done
}
} else if ((anchor & AnchorStyles.Bottom) != 0) {
- top = client_size.Height - child.dist_bottom - height;
+ top = space.Height - child.dist_bottom - height;
} else {
// top += diff_height/2 will introduce rounding errors (diff_height removed from after r51780)
// This calculates from scratch every time:
- top = child.dist_top + (client_size.Height - (child.dist_top + height + child.dist_bottom)) / 2;
+ top = child.dist_top + (space.Height - (child.dist_top + height + child.dist_bottom)) / 2;
}
// Sanity
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)]
}
public void ResumeLayout(bool performLayout) {
- layout_suspended--;
-
if (layout_suspended > 0) {
- return;
+ layout_suspended--;
}
- Control [] controls = child_controls.GetAllControls ();
- for (int i=0; i<controls.Length; i++) {
- controls [i].UpdateDistances ();
- }
+ if (layout_suspended == 0) {
+ Control [] controls = child_controls.GetAllControls ();
+ for (int i=0; i<controls.Length; i++) {
+ controls [i].UpdateDistances ();
+ }
- if (performLayout || layout_pending) {
- PerformLayout();
+ if (performLayout && layout_pending) {
+ PerformLayout();
+ }
}
}
}
}
- XplatUI.SetZOrder(this.window.Handle, IntPtr.Zero, false, true);
+ if (IsHandleCreated) {
+ XplatUI.SetZOrder(this.window.Handle, IntPtr.Zero, false, true);
+ }
+
if (parent != null) {
parent.Refresh();
}
}
public void Show() {
- if (!IsHandleCreated) {
+ if (!is_created) {
this.CreateControl();
}
throw new ObjectDisposedException(Name);
}
- if (IsHandleCreated) {
+ if (IsHandleCreated && !is_recreating) {
return;
}
}
}
- // 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);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected void RecreateHandle() {
- IEnumerator child = child_controls.GetAllEnumerator();
-
is_recreating=true;
if (IsHandleCreated) {
DestroyHandle();
- CreateHandle();
-
- // FIXME ZOrder?
-
- while (child.MoveNext()) {
- ((Control)child.Current).RecreateHandle();
- }
+ // WM_DESTROY will CreateHandle for us
} else {
- CreateControl();
+ if (!is_created) {
+ CreateControl();
+ } else {
+ CreateHandle();
+ }
}
is_recreating = false;
location = new Point((int)(Left * dx), (int)(Top * dy));
size = this.ClientSize;
-
if (!GetStyle(ControlStyles.FixedWidth)) {
size.Width = (int)(size.Width * dx);
size.Height = (int)(size.Height * dy);
}
- Location = location;
- ClientSize = size;
+ SetBoundsCore(location.X, location.Y, size.Width, size.Height, BoundsSpecified.All);
/* Now scale our children */
Control [] controls = child_controls.GetAllControls ();
}
UpdateBounds(x, y, width, height);
+
+ UpdateDistances();
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
ClientRect = new Rectangle(0, 0, x, y);
cp = this.CreateParams;
- if (XplatUI.CalculateWindowRect(Handle, ref ClientRect, cp.Style, cp.ExStyle, null, out WindowRect)==false) {
+ if (XplatUI.CalculateWindowRect(ref ClientRect, cp.Style, cp.ExStyle, null, out WindowRect)==false) {
return;
}
} 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) {
- if (dc_mem != null) {
- dc_mem.Dispose();
- dc_mem = null;
- }
-
- if (bmp_mem != null) {
- bmp_mem.Dispose();
- bmp_mem = null;
- }
- } else {
- this.CreateBuffers(bounds.Width, bounds.Height);
- 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;
-
- UpdateDistances();
+ 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)]
case Msg.WM_DESTROY: {
OnHandleDestroyed(EventArgs.Empty);
window.InvalidateHandle();
+
+ if (ParentIsRecreating) {
+ RecreateHandle();
+ } else if (is_recreating) {
+ CreateHandle();
+ }
return;
}
return;
}
- case Msg.WM_PAINT: {
+ // 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;
paint_event = XplatUI.PaintEventStart(Handle, true);
}
Graphics dc = null;
- if ((control_style & ControlStyles.DoubleBuffer) != 0) {
- dc = paint_event.SetGraphics (DeviceContext);
+ if (ThemeEngine.Current.DoubleBufferingSupported)
+ if ((control_style & ControlStyles.DoubleBuffer) != 0) {
+ dc = paint_event.SetGraphics (DeviceContext);
+ }
+
+ if (!GetStyle(ControlStyles.Opaque)) {
+ OnPaintBackground(paint_event);
}
- OnPaintBackground(paint_event);
- // Leave out for now, our controls can do Paint += ... as well
- //OnPaintInternal(paint_event);
- OnPaint(paint_event);
+ // Button-derived controls choose to ignore their Opaque style, give them a chance to draw their background anyways
+ OnPaintBackgroundInternal(paint_event);
- if ((control_style & ControlStyles.DoubleBuffer) != 0) {
- dc.DrawImage (ImageBuffer, paint_event.ClipRectangle, paint_event.ClipRectangle, GraphicsUnit.Pixel);
- paint_event.SetGraphics (dc);
- needs_redraw = false;
+ OnPaintInternal(paint_event);
+ if (!paint_event.Handled) {
+ OnPaint(paint_event);
}
+ if (ThemeEngine.Current.DoubleBufferingSupported)
+ if ((control_style & ControlStyles.DoubleBuffer) != 0) {
+ dc.DrawImage (ImageBuffer, paint_event.ClipRectangle, paint_event.ClipRectangle, GraphicsUnit.Pixel);
+ paint_event.SetGraphics (dc);
+ needs_redraw = false;
+ }
+
XplatUI.PaintEventEnd(Handle, true);
return;
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;
}
case Msg.WM_LBUTTONUP: {
- OnMouseUp (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Left,
+ MouseEventArgs me;
+
+ me = new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Left,
mouse_clicks,
LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
- 0));
- HandleClick(mouse_clicks);
+ 0);
+
+ HandleClick(mouse_clicks, me);
+ OnMouseUp (me);
+
+ if (InternalCapture) {
+ InternalCapture = false;
+ }
+
if (mouse_clicks > 1) {
mouse_clicks = 1;
}
if (CanSelect && !is_selected) {
Select(this);
}
+ 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: {
+ 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_MBUTTONUP: {
- HandleClick(mouse_clicks);
- OnMouseUp (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Middle,
+ MouseEventArgs me;
+
+ me = new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Middle,
mouse_clicks,
LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
- 0));
+ 0);
+
+ HandleClick(mouse_clicks, me);
+ OnMouseUp (me);
+ if (InternalCapture) {
+ InternalCapture = false;
+ }
if (mouse_clicks > 1) {
mouse_clicks = 1;
}
}
case Msg.WM_MBUTTONDOWN: {
+ 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: {
+ 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: {
- if (context_menu != null) {
- context_menu.Show(this, new Point(LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ())));
- }
+ MouseEventArgs me;
+ Point pt;
+
+ pt = new Point(LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()));
+ pt = PointToScreen(pt);
- HandleClick(mouse_clicks);
- OnMouseUp (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Right,
+ XplatUI.SendMessage(m.HWnd, Msg.WM_CONTEXTMENU, m.HWnd, (IntPtr)(pt.X + (pt.Y << 16)));
+
+ me = new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Right,
mouse_clicks,
LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
- 0));
+ 0);
+
+ HandleClick(mouse_clicks, me);
+ OnMouseUp (me);
+
+ if (InternalCapture) {
+ InternalCapture = false;
+ }
+
if (mouse_clicks > 1) {
mouse_clicks = 1;
}
}
case Msg.WM_RBUTTONDOWN: {
+ 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: {
+ 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()),
return;
}
- case Msg.WM_SYSKEYDOWN:
- case Msg.WM_KEYDOWN:
- case Msg.WM_SYSKEYUP:
- case Msg.WM_KEYUP:
- case Msg.WM_SYSCHAR:
- case Msg.WM_CHAR: {
+ case Msg.WM_SYSKEYUP: {
if (ProcessKeyMessage(ref m)) {
+ m.Result = IntPtr.Zero;
return;
}
- if ((m.Msg == (int)Msg.WM_SYSKEYUP) && ((m.WParam.ToInt32() & (int)Keys.KeyCode) == (int)Keys.Menu)) {
+ if ((m.WParam.ToInt32() & (int)Keys.KeyCode) == (int)Keys.Menu) {
Form form;
form = FindForm();
return;
}
+ case Msg.WM_SYSKEYDOWN:
+ case Msg.WM_KEYDOWN:
+ case Msg.WM_KEYUP:
+ case Msg.WM_SYSCHAR:
+ case Msg.WM_CHAR: {
+ if (ProcessKeyMessage(ref m)) {
+ m.Result = IntPtr.Zero;
+ return;
+ }
+ DefWndProc (ref m);
+ return;
+ }
+
case Msg.WM_HELP: {
Point mouse_pos;
if (m.LParam != IntPtr.Zero) {
case Msg.WM_SETCURSOR: {
- if (cursor == null) {
+ if ((cursor == null) || ((HitTest)(m.LParam.ToInt32() & 0xffff) != HitTest.HTCLIENT)) {
DefWndProc(ref m);
return;
}
if (Paint!=null) Paint(this, e);
}
+ internal virtual void OnPaintBackgroundInternal(PaintEventArgs e) {
+ // Override me
+ }
+
internal virtual void OnPaintInternal(PaintEventArgs e) {
// Override me
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnVisibleChanged(EventArgs e) {
- if (!is_visible) {
- if (dc_mem!=null) {
- dc_mem.Dispose ();
- dc_mem=null;
- }
-
- if (bmp_mem!=null) {
- bmp_mem.Dispose();
- bmp_mem=null;
- }
- } else {
+ if ((parent != null) && !Created && Visible) {
if (!is_disposed) {
- if (!this.IsHandleCreated) {
- this.CreateControl();
- }
+ CreateControl();
PerformLayout();
}
}
+
+ needs_redraw = true;
if (VisibleChanged!=null) VisibleChanged(this, e);
// We need to tell our kids
for (int i=0; i<child_controls.Count; i++) {
- child_controls[i].OnParentVisibleChanged(e);
+ if (child_controls[i].Visible) {
+ child_controls[i].OnParentVisibleChanged(e);
+ }
}
}
#endregion // OnXXX methods