// John Sohn jsohn@columbus.rr.com
//
-// COMPLETE
-
#undef DebugRecreate
#undef DebugFocus
Rectangle explicit_bounds; // explicitly set bounds
internal object creator_thread; // thread that created the control
internal ControlNativeWindow window; // object for native window handle
+ private IWindowTarget window_target;
string name; // for object naming
// State
bool is_created; // true if OnCreateControl has been sent
- internal bool has_focus; // true if control has focus
- internal bool is_visible; // true if control is visible
- internal bool is_entered; // is the mouse inside the control?
- internal bool is_enabled; // true if control is enabled (usable/not grayed out)
+ internal bool has_focus; // true if control has focus
+ internal bool is_visible; // true if control is visible
+ internal bool is_entered; // is the mouse inside the control?
+ internal bool is_enabled; // true if control is enabled (usable/not grayed out)
bool is_accessible; // true if the control is visible to accessibility applications
bool is_captured; // tracks if the control has captured the mouse
internal bool is_toplevel; // tracks if the control is a toplevel window
bool is_recreating; // tracks if the handle for the control is being recreated
bool causes_validation; // tracks if validation is executed on changes
bool is_focusing; // tracks if Focus has been called on the control and has not yet finished
- bool container_selected; // true if Select() or Focus() is called on a container, to prevent child controls from raising their GotFocus event
- int tab_index; // position in tab order of siblings
+ int tab_index; // position in tab order of siblings
bool tab_stop; // is the control a tab stop?
bool is_disposed; // has the window already been disposed?
Size client_size; // size of the client area (window excluding decorations)
Rectangle client_rect; // rectangle with the client area (window excluding decorations)
ControlStyles control_style; // rather win32-specific, style bits for control
ImeMode ime_mode;
- bool layout_pending; // true if our parent needs to re-layout us
object control_tag; // object that contains data about our control
internal int mouse_clicks; // Counter for mouse clicks
Cursor cursor; // Cursor for the window
internal BorderStyle border_style; // Border style of control
// Layout
+ internal enum LayoutType {
+ Anchor,
+ Dock
+ }
Layout.LayoutEngine layout_engine;
- int layout_suspended;
- internal AnchorStyles anchor_style; // anchoring requirements for our control
- internal DockStyle dock_style; // docking requirements for our control (supercedes anchoring)
-
- // Please leave the next 4 as internal until DefaultLayout (2.0) is rewritten
- internal int dist_left; // distance to the left border of the parent
- internal int dist_top; // distance to the top border of the parent
+ int layout_suspended;
+ bool layout_pending; // true if our parent needs to re-layout us
+ internal AnchorStyles anchor_style; // anchoring requirements for our control
+ internal DockStyle dock_style; // docking requirements for our control
+ LayoutType layout_type;
+
+ // Please leave the next 2 as internal until DefaultLayout (2.0) is rewritten
internal int dist_right; // distance to the right border of the parent
internal int dist_bottom; // distance to the bottom border of the parent
BindingContext binding_context;
RightToLeft right_to_left; // drawing direction for control
ContextMenu context_menu; // Context menu associated with the control
+ internal bool use_compatible_text_rendering;
// double buffering
- Graphics backbuffer_dc;
- object backbuffer;
- Region invalid_region;
+ DoubleBuffer backbuffer;
+
+ // to implement DeviceContext without depending on double buffering
+ Bitmap bmp;
+ Graphics bmp_g;
ControlBindingsCollection data_bindings;
#if NET_2_0
- internal bool use_compatible_text_rendering;
static bool verify_thread_handle;
Padding padding;
ImageLayout backgroundimage_layout;
Size maximum_size;
Size minimum_size;
- Size preferred_size;
Padding margin;
private ContextMenuStrip context_menu_strip;
#endif
}
}
+ protected override void OnHandleChange()
+ {
+ this.owner.WindowTarget.OnHandleChange(this.owner.Handle);
+ }
+
static internal Control ControlFromHandle(IntPtr hWnd) {
ControlNativeWindow window;
}
protected override void WndProc(ref Message m) {
- owner.WndProc(ref m);
+ owner.WindowTarget.OnMessage(ref m);
+ }
+ }
+
+ private class ControlWindowTarget : IWindowTarget
+ {
+ private Control control;
+
+ public ControlWindowTarget(Control control)
+ {
+ this.control = control;
+ }
+
+ public void OnHandleChange(IntPtr newHandle)
+ {
+ }
+
+ public void OnMessage(ref Message m)
+ {
+ control.WndProc(ref m);
}
}
#endregion
#region Public Classes
[ComVisible(true)]
public class ControlAccessibleObject : AccessibleObject {
- Control owner;
+ IntPtr handle;
#region ControlAccessibleObject Constructors
public ControlAccessibleObject(Control ownerControl)
: base (ownerControl)
{
- this.owner = ownerControl;
+ if (ownerControl == null)
+ throw new ArgumentNullException ("owner");
+
+ handle = ownerControl.Handle;
}
#endregion // ControlAccessibleObject Constructors
public IntPtr Handle {
get {
- return owner.Handle;
+ return handle;
}
set {
public Control Owner {
get {
- return owner;
+ return base.owner;
}
}
return base.GetHelpTopic (out FileName);
}
- [MonoTODO("Implement this and tie it into Control.AccessibilityNotifyClients")]
+ [MonoTODO ("Implement this")]
public void NotifyClients(AccessibleEvents accEvent) {
throw new NotImplementedException();
}
- [MonoTODO("Implement this and tie it into Control.AccessibilityNotifyClients")]
+ [MonoTODO ("Implement this")]
public void NotifyClients(AccessibleEvents accEvent, int childID) {
- throw new NotImplementedException();
}
public override string ToString() {
#endregion // ControlAccessibleObject Public Instance Methods
}
+ private class DoubleBuffer : IDisposable
+ {
+ public Region InvalidRegion;
+ private Stack real_graphics;
+ private object back_buffer;
+ private Control parent;
+ private bool pending_disposal;
+
+ public DoubleBuffer (Control parent) {
+ this.parent = parent;
+ real_graphics = new Stack ();
+ int width = parent.Width;
+ int height = parent.Height;
+
+ if (width < 1) width = 1;
+ if (height < 1) height = 1;
+
+ XplatUI.CreateOffscreenDrawable (parent.Handle, width, height, out back_buffer);
+ Invalidate ();
+ }
+
+ public void Blit (PaintEventArgs pe) {
+ Graphics buffered_graphics;
+ buffered_graphics = XplatUI.GetOffscreenGraphics (back_buffer);
+ XplatUI.BlitFromOffscreen (parent.Handle, pe.Graphics, back_buffer, buffered_graphics, pe.ClipRectangle);
+ buffered_graphics.Dispose ();
+ }
+
+ public void Start (PaintEventArgs pe) {
+ // We need to get the graphics for every paint.
+ real_graphics.Push(pe.SetGraphics (XplatUI.GetOffscreenGraphics (back_buffer)));
+ }
+
+ public void End (PaintEventArgs pe) {
+ Graphics buffered_graphics;
+ buffered_graphics = pe.SetGraphics ((Graphics) real_graphics.Pop ());
+
+ if (pending_disposal)
+ Dispose ();
+ else {
+ XplatUI.BlitFromOffscreen (parent.Handle, pe.Graphics, back_buffer, buffered_graphics, pe.ClipRectangle);
+ InvalidRegion.Exclude (pe.ClipRectangle);
+ }
+ buffered_graphics.Dispose ();
+ }
+
+ public void Invalidate () {
+ if (InvalidRegion != null)
+ InvalidRegion.Dispose ();
+ InvalidRegion = new Region (parent.ClientRectangle);
+ }
+
+ public void Dispose () {
+ if (real_graphics.Count > 0) {
+ pending_disposal = true;
+ return;
+ }
+
+ XplatUI.DestroyOffscreenDrawable (back_buffer);
+
+ if (InvalidRegion != null)
+ InvalidRegion.Dispose ();
+ InvalidRegion = null;
+ back_buffer = null;
+ GC.SuppressFinalize (this);
+ }
+
+ #region IDisposable Members
+ void IDisposable.Dispose () {
+ Dispose ();
+ }
+ #endregion
+
+ ~DoubleBuffer () {
+ Dispose ();
+ }
+ }
+
+ [ListBindable (false)]
#if NET_2_0
[ComVisible (false)]
+ public class ControlCollection : Layout.ArrangedElementCollection, IList, ICollection, ICloneable, IEnumerable {
#else
[DesignerSerializer("System.Windows.Forms.Design.ControlCollectionCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
-#endif
- [ListBindable(false)]
public class ControlCollection : IList, ICollection, ICloneable, IEnumerable {
+#endif
#region ControlCollection Local Variables
+#if !NET_2_0
ArrayList list;
+#endif
ArrayList impl_list;
Control[] all_controls;
Control owner;
#region ControlCollection Public Constructor
public ControlCollection(Control owner) {
this.owner=owner;
+#if !NET_2_0
this.list=new ArrayList();
+#endif
}
#endregion
#region ControlCollection Public Instance Properties
+ int ICollection.Count {
+ get { return Count; }
+ }
+
+
+#if !NET_2_0
public int Count {
- get {
- return list.Count;
- }
+ get { return list.Count; }
}
+#endif
- public bool IsReadOnly {
+#if NET_2_0
+ bool IList.IsReadOnly
+#else
+ public bool IsReadOnly
+#endif
+ {
get {
return list.IsReadOnly;
}
}
+#if NET_2_0
+ public Control Owner { get { return this.owner; } }
+
+ public virtual Control this[string key] {
+ get {
+ int index = IndexOfKey (key);
+
+ if (index >= 0)
+ return this[index];
+
+ return null;
+ }
+ }
+
+ new
+#endif
public virtual Control this[int index] {
get {
if (index < 0 || index >= list.Count) {
}
return (Control)list[index];
}
+
+
}
#endregion // ControlCollection Public Instance Properties
- #region ControlCollection Private Instance Methods
- public virtual void Add (Control value)
- {
+ #region ControlCollection Instance Methods
+ public virtual void Add (Control value) {
if (value == null)
return;
+
+ Form form_value = value as Form;
+ Form form_owner = owner as Form;
+ bool owner_permits_toplevels = (owner is MdiClient) || (form_owner != null && form_owner.IsMdiContainer);
+ bool child_is_toplevel = value.GetTopLevel();
+ bool child_is_mdichild = form_value != null && form_value.IsMdiChild;
+
+ if (child_is_toplevel && !(owner_permits_toplevels && child_is_mdichild))
+ throw new ArgumentException("Cannot add a top level control to a control.", "value");
+
+ if (child_is_mdichild && form_value.MdiParent != null && form_value.MdiParent != owner && form_value.MdiParent != owner.Parent) {
+ throw new ArgumentException ("Form cannot be added to the Controls collection that has a valid MDI parent.", "value");
+ }
if (Contains (value)) {
owner.PerformLayout();
value.InitLayout();
- owner.UpdateChildrenZOrder();
+ if (owner.Visible)
+ owner.UpdateChildrenZOrder();
owner.PerformLayout(value, "Parent");
owner.OnControlAdded(new ControlEventArgs(value));
}
- internal void AddToList (Control c)
- {
+ internal void AddToList (Control c) {
all_controls = null;
list.Add (c);
}
- internal virtual void AddImplicit (Control control)
- {
+ internal virtual void AddImplicit (Control control) {
if (impl_list == null)
impl_list = new ArrayList ();
- if (AllContains (control))
+ if (AllContains (control)) {
+ owner.PerformLayout ();
return;
+ }
+
+ if (control.parent != null) {
+ control.parent.Controls.Remove(control);
+ }
all_controls = null;
impl_list.Add (control);
control.ChangeParent (owner);
control.InitLayout ();
- owner.UpdateChildrenZOrder ();
- owner.PerformLayout (control, "Parent");
- owner.OnControlAdded (new ControlEventArgs (control));
+ if (owner.Visible)
+ owner.UpdateChildrenZOrder ();
+
+ // If we are adding a new control that isn't
+ // visible, don't trigger a layout
+ if (control.VisibleInternal)
+ owner.PerformLayout (control, "Parent");
}
#if NET_2_0
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
#endif
- public virtual void AddRange (Control[] controls)
- {
+ public virtual void AddRange (Control[] controls) {
if (controls == null)
throw new ArgumentNullException ("controls");
}
}
- internal virtual void AddRangeImplicit (Control [] controls)
- {
+ internal virtual void AddRangeImplicit (Control [] controls) {
if (controls == null)
throw new ArgumentNullException ("controls");
}
}
- public virtual void Clear ()
- {
+#if NET_2_0
+ new
+#endif
+ public virtual void Clear () {
all_controls = null;
// MS sends remove events in reverse order
}
}
- internal virtual void ClearImplicit ()
- {
+ internal virtual void ClearImplicit () {
if (impl_list == null)
return;
all_controls = null;
impl_list.Clear ();
}
- public bool Contains (Control value)
- {
+ public bool Contains (Control value) {
for (int i = list.Count; i > 0; ) {
i--;
return false;
}
- internal bool ImplicitContains (Control value)
- {
+ internal bool ImplicitContains (Control value) {
if (impl_list == null)
return false;
return false;
}
- internal bool AllContains (Control value)
- {
+ internal bool AllContains (Control value) {
return Contains (value) || ImplicitContains (value);
}
- public void CopyTo (Array array, int index)
+#if NET_2_0
+ public virtual bool ContainsKey (string key)
{
+ return IndexOfKey (key) >= 0;
+ }
+#endif
+
+ void ICollection.CopyTo (Array array, int index) {
+ CopyTo (array, index);
+ }
+
+#if !NET_2_0
+ public void CopyTo (Array array, int index) {
list.CopyTo(array, index);
}
- public override bool Equals(object other) {
+ public override bool Equals (object other) {
if (other is ControlCollection && (((ControlCollection)other).owner==this.owner)) {
return(true);
} else {
return(false);
}
}
+#endif
+
+#if NET_2_0
+ // LAMESPEC: MSDN says AE, MS implementation throws ANE
+ public Control[] Find (string key, bool searchAllChildren)
+ {
+ if (string.IsNullOrEmpty (key))
+ throw new ArgumentNullException ("key");
+
+ ArrayList al = new ArrayList ();
+
+ foreach (Control c in list) {
+ if (c.Name.Equals (key, StringComparison.CurrentCultureIgnoreCase))
+ al.Add (c);
+
+ if (searchAllChildren)
+ al.AddRange (c.Controls.Find (key, true));
+ }
+
+ return (Control[])al.ToArray (typeof (Control));
+ }
+#endif
public int GetChildIndex(Control child) {
return GetChildIndex(child, false);
}
- public int GetChildIndex(Control child, bool throwException) {
+#if NET_2_0
+ public virtual int
+#else
+ public int
+#endif
+ GetChildIndex(Control child, bool throwException) {
int index;
index=list.IndexOf(child);
return index;
}
- public IEnumerator GetEnumerator() {
+#if NET_2_0
+ public override IEnumerator
+#else
+ public IEnumerator
+#endif
+ GetEnumerator () {
return list.GetEnumerator();
}
- internal IEnumerator GetAllEnumerator ()
- {
+ internal IEnumerator GetAllEnumerator () {
Control [] res = GetAllControls ();
return res.GetEnumerator ();
}
- internal Control [] GetAllControls ()
- {
+ internal Control [] GetAllControls () {
if (all_controls != null)
return all_controls;
return all_controls;
}
+#if !NET_2_0
public override int GetHashCode() {
return base.GetHashCode();
}
+#endif
public int IndexOf(Control control) {
return list.IndexOf(control);
}
+#if NET_2_0
+ public virtual int IndexOfKey (string key)
+ {
+ if (string.IsNullOrEmpty (key))
+ return -1;
+
+ for (int i = 0; i < list.Count; i++)
+ if (((Control)list[i]).Name.Equals (key, StringComparison.CurrentCultureIgnoreCase))
+ return i;
+
+ return -1;
+ }
+#endif
+
public virtual void Remove(Control value) {
if (value == null)
return;
owner.UpdateChildrenZOrder();
}
- internal virtual void RemoveImplicit (Control control)
- {
+ internal virtual void RemoveImplicit (Control control) {
if (impl_list != null) {
all_controls = null;
owner.PerformLayout (control, "Parent");
owner.UpdateChildrenZOrder ();
}
+#if NET_2_0
+ new
+#endif
public void RemoveAt(int index) {
if (index < 0 || index >= list.Count) {
throw new ArgumentOutOfRangeException("index", index, "ControlCollection does not have that many controls");
Remove ((Control)list[index]);
}
- public void SetChildIndex(Control child, int newIndex) {
+#if NET_2_0
+ public virtual void RemoveByKey (string key)
+ {
+ int index = IndexOfKey (key);
+
+ if (index >= 0)
+ RemoveAt (index);
+ }
+#endif
+
+#if NET_2_0
+ public virtual void
+#else
+ public void
+#endif
+ SetChildIndex(Control child, int newIndex) {
if (child == null)
throw new ArgumentNullException ("child");
#region ControlCollection Interface Methods
int IList.Add(object value) {
- if (value == null) {
- throw new ArgumentNullException("value", "Cannot add null controls");
- }
-
if (!(value is Control)) {
throw new ArgumentException("Object of type Control required", "value");
}
+ if (value == null) {
+ throw new ArgumentException("value", "Cannot add null controls");
+ }
+
+ bool owner_permits_toplevels = (owner is MdiClient) || (owner is Form && ((Form)owner).IsMdiContainer);
+ bool child_is_toplevel = ((Control)value).GetTopLevel();
+ bool child_is_mdichild = (value is Form && ((Form)value).IsMdiChild);
+
+ if (child_is_toplevel && !(owner_permits_toplevels && child_is_mdichild))
+ throw new ArgumentException("Cannot add a top level control to a control.", "value");
+
return list.Add(value);
}
#endregion // ControlCollection Class
#region Public Constructors
- public Control()
+ public Control ()
{
+ layout_type = LayoutType.Anchor;
anchor_style = AnchorStyles.Top | AnchorStyles.Left;
is_created = false;
right_to_left = RightToLeft.Inherit;
border_style = BorderStyle.None;
background_color = Color.Empty;
- dist_left = 0;
dist_right = 0;
- dist_top = 0;
dist_bottom = 0;
tab_stop = true;
ime_mode = ImeMode.Inherit;
+ use_compatible_text_rendering = true;
- layout_engine = this.LayoutEngine;
- if (layout_engine == null)
- layout_engine = new Layout.DefaultLayout ();
#if NET_2_0
backgroundimage_layout = ImageLayout.Tile;
use_compatible_text_rendering = Application.use_compatible_text_rendering;
padding = new Padding(0);
maximum_size = new Size();
minimum_size = new Size();
- preferred_size = this.DefaultSize;
margin = this.DefaultMargin;
#endif
text = string.Empty;
name = string.Empty;
+ window_target = new ControlWindowTarget(this);
window = new ControlNativeWindow(this);
child_controls = CreateControlsInstance();
client_size = new Size(DefaultSize.Width, DefaultSize.Height);
client_rect = new Rectangle(0, 0, DefaultSize.Width, DefaultSize.Height);
- 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;
- }
+ bounds.Size = InternalSizeFromClientSize (client_size);
+ explicit_bounds = bounds;
}
- public Control(Control parent, string text) : this() {
+ public Control (Control parent, string text) : this()
+ {
Text=text;
Parent=parent;
}
- public Control(Control parent, string text, int left, int top, int width, int height) : this() {
+ public Control (Control parent, string text, int left, int top, int width, int height) : this()
+ {
Parent=parent;
bounds.X=left;
bounds.Y=top;
Text=text;
}
- public Control(string text) : this() {
+ public Control (string text) : this()
+ {
Text=text;
}
- public Control(string text, int left, int top, int width, int height) : this() {
+ public Control (string text, int left, int top, int width, int height) : this()
+ {
bounds.X=left;
bounds.Y=top;
bounds.Width=width;
private delegate void RemoveDelegate(object c);
- protected override void Dispose(bool disposing) {
+ protected override void Dispose (bool disposing)
+ {
if (!is_disposed && disposing) {
Capture = false;
DisposeBackBuffer ();
- if (invalid_region!=null) {
- invalid_region.Dispose();
- invalid_region=null;
+ if (bmp != null) {
+ bmp.Dispose ();
+ bmp = null;
}
+ if (bmp_g != null) {
+ bmp_g.Dispose ();
+ bmp_g = null;
+ }
+
if (this.InvokeRequired) {
- if (Application.MessageLoop) {
- this.BeginInvokeInternal(new MethodInvoker(DestroyHandle), null, true);
+ if (Application.MessageLoop && IsHandleCreated) {
+ this.BeginInvokeInternal(new MethodInvoker(DestroyHandle), null);
}
} else {
DestroyHandle();
#endregion // Public Constructors
#region Internal Properties
+ // Control is currently selected, like Focused, except maintains state
+ // when Form loses focus
+ internal bool InternalSelected {
+ get {
+ IContainerControl container;
+
+ container = GetContainerControl();
+
+ if (container != null && container.ActiveControl == this)
+ return true;
+
+ return false;
+ }
+ }
+
+ // Mouse is currently within the control's bounds
+ internal bool Entered {
+ get { return this.is_entered; }
+ }
+
+ internal bool VisibleInternal {
+ get { return is_visible; }
+ }
+
+ internal LayoutType ControlLayoutType {
+ get { return layout_type; }
+ }
+
internal BorderStyle InternalBorderStyle {
get {
return border_style;
border_style = value;
if (IsHandleCreated) {
- XplatUI.SetBorderStyle(window.Handle, (FormBorderStyle)border_style);
- Refresh();
+ XplatUI.SetBorderStyle (window.Handle, (FormBorderStyle)border_style);
+ RecreateHandle ();
+ Refresh ();
}
}
}
}
+
+ internal Size InternalClientSize { set { this.client_size = value; } }
+ internal virtual bool ActivateOnShow { get { return true; } }
#endregion // Internal Properties
#region Private & Internal Methods
}
#endif
- internal IAsyncResult BeginInvokeInternal (Delegate method, object [] args, bool disposing) {
+ internal IAsyncResult BeginInvokeInternal (Delegate method, object [] args) {
+ return BeginInvokeInternal (method, args, FindControlToInvokeOn ());
+ }
+
+ internal IAsyncResult BeginInvokeInternal (Delegate method, object [] args, Control control) {
AsyncMethodResult result;
AsyncMethodData data;
- if (!disposing) {
- Control p = this;
- do {
- if (!p.IsHandleCreated) {
- throw new InvalidOperationException("Cannot call Invoke or InvokeAsync on a control until the window handle is created");
- }
- p = p.parent;
- } while (p != null);
- }
-
result = new AsyncMethodResult ();
data = new AsyncMethodData ();
- data.Handle = window.Handle;
+ data.Handle = control.Handle;
data.Method = method;
data.Args = args;
data.Result = result;
}
- internal void PointToClient (ref int x, ref int y)
- {
+ internal void PointToClient (ref int x, ref int y) {
XplatUI.ScreenToClient (Handle, ref x, ref y);
}
- internal void PointToScreen (ref int x, ref int y)
- {
+ internal void PointToScreen (ref int x, ref int y) {
XplatUI.ClientToScreen (Handle, ref x, ref y);
}
}
internal Graphics DeviceContext {
- get { return Hwnd.bmp_g; }
+ get {
+ if (bmp_g == null) {
+ bmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+ bmp_g = Graphics.FromImage (bmp);
+ }
+ return bmp_g;
+ }
}
-
- private void InvalidateBackBuffer ()
+
+ private Control FindControlToInvokeOn ()
{
- if (invalid_region != null)
- invalid_region.Dispose();
- invalid_region = new Region (ClientRectangle);
+ Control p = this;
+ do {
+ if (p.IsHandleCreated)
+ break;
+ p = p.parent;
+ } while (p != null);
+
+ if (p == null || !p.IsHandleCreated)
+ throw new InvalidOperationException ("Cannot call Invoke or BeginInvoke on a control until the window handle is created");
+
+ return p;
}
- private void CreateBackBuffer ()
- {
+ private void InvalidateBackBuffer () {
if (backbuffer != null)
- return;
-
- int width = Width;
- int height = Height;
-
- if (width < 1) width = 1;
- if (height < 1) height = 1;
-
- XplatUI.CreateOffscreenDrawable (Handle, width, height, out backbuffer, out backbuffer_dc);
- InvalidateBackBuffer ();
+ backbuffer.Invalidate ();
}
- private void DisposeBackBuffer ()
- {
+ private DoubleBuffer GetBackBuffer () {
if (backbuffer == null)
- return;
-
- XplatUI.DestroyOffscreenDrawable (backbuffer, backbuffer_dc);
- backbuffer = null;
- backbuffer_dc = null;
-
+ backbuffer = new DoubleBuffer (this);
+ return backbuffer;
+ }
- if (invalid_region != null)
- invalid_region.Dispose ();
- invalid_region = null;
+ private void DisposeBackBuffer () {
+ if (backbuffer != null) {
+ backbuffer.Dispose ();
+ backbuffer = null;
+ }
}
internal static void SetChildColor(Control parent) {
}
container = GetContainerControl();
- if (container != null) {
+ if (container != null && (Control)container != control) {
container.ActiveControl = control;
}
- if (control.IsHandleCreated) {
+ else if (control.IsHandleCreated) {
XplatUI.SetFocus(control.window.Handle);
}
return true;
}
- internal void SelectChild (Control control)
- {
- if (control.IsHandleCreated)
- XplatUI.SetFocus (control.window.Handle);
- }
-
internal virtual void DoDefaultAction() {
// Only here to be overriden by our actual controls; this is needed by the accessibility class
}
}
// This method exists so controls overriding OnPaintBackground can have default background painting done
- internal virtual void PaintControlBackground (PaintEventArgs pevent)
- {
+ internal virtual void PaintControlBackground (PaintEventArgs pevent) {
if (GetStyle(ControlStyles.SupportsTransparentBackColor) && (BackColor.A != 0xff)) {
if (parent != null) {
PaintEventArgs parent_pe;
DrawBackgroundImage (pevent.Graphics);
}
- void DrawBackgroundImage (Graphics g)
- {
+ void DrawBackgroundImage (Graphics g) {
#if NET_2_0
Rectangle drawing_rectangle = new Rectangle ();
g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), ClientRectangle);
#endif
}
- internal virtual void DndEnter (DragEventArgs e)
- {
+ internal virtual void DndEnter (DragEventArgs e) {
try {
OnDragEnter (e);
} catch { }
}
- internal virtual void DndOver (DragEventArgs e)
- {
+ internal virtual void DndOver (DragEventArgs e) {
try {
OnDragOver (e);
} catch { }
}
- internal virtual void DndDrop (DragEventArgs e)
- {
+ internal virtual void DndDrop (DragEventArgs e) {
try {
OnDragDrop (e);
} catch (Exception exc) {
}
}
- internal virtual void DndLeave (EventArgs e)
- {
+ internal virtual void DndLeave (EventArgs e) {
try {
OnDragLeave (e);
} catch { }
}
- internal virtual void DndFeedback(GiveFeedbackEventArgs e)
- {
+ internal virtual void DndFeedback(GiveFeedbackEventArgs e) {
try {
OnGiveFeedback(e);
} catch { }
}
- internal virtual void DndContinueDrag(QueryContinueDragEventArgs e)
- {
+ internal virtual void DndContinueDrag(QueryContinueDragEventArgs e) {
try {
OnQueryContinueDrag(e);
} catch { }
}
- internal void FireEnter ()
- {
+ internal virtual void FireEnter () {
OnEnter (EventArgs.Empty);
}
- internal void FireLeave ()
- {
+ internal virtual void FireLeave () {
OnLeave (EventArgs.Empty);
}
- internal void FireValidating (CancelEventArgs ce)
- {
+ internal virtual void FireValidating (CancelEventArgs ce) {
OnValidating (ce);
}
- internal void FireValidated ()
- {
+ internal virtual void FireValidated () {
OnValidated (EventArgs.Empty);
}
OnClick(EventArgs.Empty);
#else
OnDoubleClick(me);
+ OnMouseDoubleClick (me);
} else {
OnClick(me);
+ OnMouseClick (me);
#endif
}
}
}
- internal void CaptureWithConfine (Control ConfineWindow)
- {
+ internal void CaptureWithConfine (Control ConfineWindow) {
if (this.IsHandleCreated && !is_captured) {
is_captured = true;
XplatUI.GrabWindow (this.window.Handle, ConfineWindow.Handle);
}
}
- private void CheckDataBindings ()
- {
+ private void CheckDataBindings () {
if (data_bindings == null)
return;
parent = new_parent;
- if (IsHandleCreated)
+ if (IsHandleCreated) {
XplatUI.SetParent(Handle,
(new_parent == null || !new_parent.IsHandleCreated) ? IntPtr.Zero : new_parent.Handle);
+ if (this is Form ) {
+ ((Form) this).ChangingParent (new_parent);
+ }
+ }
OnParentChanged(EventArgs.Empty);
OnRightToLeftChanged(EventArgs.Empty);
}
- if ((new_parent != null) && new_parent.Created && !Created) {
+ if ((new_parent != null) && new_parent.Created && is_visible && !Created) {
CreateControl();
}
}
}
+ // Sometimes we need to do this calculation without it being virtual (constructor)
+ internal Size InternalSizeFromClientSize (Size clientSize)
+ {
+ Rectangle ClientRect;
+ Rectangle WindowRect;
+ CreateParams cp;
+
+ ClientRect = new Rectangle (0, 0, clientSize.Width, clientSize.Height);
+ cp = this.CreateParams;
+
+ if (XplatUI.CalculateWindowRect (ref ClientRect, cp.Style, cp.ExStyle, null, out WindowRect))
+ return new Size (WindowRect.Width, WindowRect.Height);
+
+ return Size.Empty;
+ }
+
private void UpdateDistances() {
if (parent != null) {
- 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;
+ if (bounds.Width >= 0)
+ dist_right = parent.ClientSize.Width - bounds.X - bounds.Width;
+ if (bounds.Height >= 0)
+ dist_bottom = parent.ClientSize.Height - bounds.Y - bounds.Height;
+ }
+ }
+
+ private bool UseDoubleBuffering {
+ get {
+ if (!ThemeEngine.Current.DoubleBufferingSupported)
+ return false;
+
+#if NET_2_0
+ if (DoubleBuffered)
+ return true;
+#endif
+ return (control_style & ControlStyles.DoubleBuffer) != 0;
}
}
#endregion // Private & Internal Methods
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string AccessibleDefaultActionDescription {
get {
- return AccessibilityObject.default_action;
+ if (accessibility_object != null)
+ return accessibility_object.default_action;
+ else
+ return null;
}
set {
- AccessibilityObject.default_action=value;
+ if (accessibility_object != null)
+ accessibility_object.default_action = value;
}
}
[MWFCategory("Accessibility")]
public string AccessibleDescription {
get {
- return AccessibilityObject.description;
+ if (accessibility_object != null)
+ return accessibility_object.description;
+ else
+ return null;
}
set {
- AccessibilityObject.description=value;
+ if (accessibility_object != null)
+ accessibility_object.description = value;
}
}
[MWFCategory("Accessibility")]
public string AccessibleName {
get {
- return AccessibilityObject.Name;
+ if (accessibility_object != null)
+ return accessibility_object.Name;
+ else
+ return null;
}
set {
- AccessibilityObject.Name=value;
+ if (accessibility_object != null)
+ accessibility_object.Name = value;
}
}
[MWFDescription("Role of the control"), MWFCategory("Accessibility")]
public AccessibleRole AccessibleRole {
get {
- return AccessibilityObject.role;
+ if (accessibility_object != null)
+ return accessibility_object.role;
+ else
+ return AccessibleRole.Default;
}
set {
- AccessibilityObject.role=value;
+ if (accessibility_object != null)
+ accessibility_object.role = value;
}
}
}
set {
+ layout_type = LayoutType.Anchor;
+
+ if (anchor_style == value)
+ return;
+
anchor_style=value;
+ dock_style = DockStyle.None;
+
+ UpdateDistances ();
- if (parent != null) {
- parent.PerformLayout(this, "Parent");
- }
+ if (parent != null)
+ parent.PerformLayout(this, "Anchor");
}
}
[DefaultValue (false)]
[MonoTODO("This method currently does nothing")]
public virtual bool AutoSize {
- get {
- //Console.Error.WriteLine("Unimplemented: Control::get_AutoSize()");
- return auto_size;
- }
+ get { return auto_size; }
set {
- auto_size = value;
+ if (this.auto_size != value) {
+ auto_size = value;
+ OnAutoSizeChanged (EventArgs.Empty);
+ }
}
}
+#if NET_2_0
+ [AmbientValue ("{Width=0, Height=0}")]
+#else
[AmbientValue (typeof(Size), "0, 0")]
+#endif
public virtual Size MaximumSize {
get {
return maximum_size;
}
set {
- maximum_size = value;
+ if (maximum_size != value) {
+ maximum_size = value;
+ Size = PreferredSize;
+ }
}
}
return minimum_size;
}
set {
- minimum_size = value;
+ if (minimum_size != value) {
+ minimum_size = value;
+ Size = PreferredSize;
+ }
}
}
#endif // NET_2_0
if (value != backgroundimage_layout) {
backgroundimage_layout = value;
Invalidate ();
+ OnBackgroundImageLayoutChanged (EventArgs.Empty);
}
}
}
set {
- if (this.IsHandleCreated && value != is_captured) {
+ // Call OnMouseCaptureChanged when we get WM_CAPTURECHANGED.
+ if (value != is_captured) {
if (value) {
is_captured = true;
- XplatUI.GrabWindow(this.window.Handle, IntPtr.Zero);
+ XplatUI.GrabWindow(Handle, IntPtr.Zero);
} else {
- XplatUI.UngrabWindow(this.window.Handle);
+ if (IsHandleCreated)
+ XplatUI.UngrabWindow(Handle);
is_captured = false;
}
}
set {
this.SetClientSizeCore(value.Width, value.Height);
+#if NET_2_0
+ this.OnClientSizeChanged (EventArgs.Empty);
+#endif
}
}
}
}
- internal bool ContainerSelected {
- get { return container_selected; }
- set { container_selected = value; }
- }
-
[EditorBrowsable(EditorBrowsableState.Advanced)]
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
}
}
- internal virtual ContextMenu GetContextMenuInternal ()
- {
+ internal virtual ContextMenu GetContextMenuInternal () {
return context_menu;
}
#if NET_2_0
+ [DefaultValue (null)]
public virtual ContextMenuStrip ContextMenuStrip {
get { return this.context_menu_strip; }
set {
}
set {
+ layout_type = LayoutType.Dock;
+
if (dock_style == value) {
return;
}
}
dock_style = value;
+ anchor_style = AnchorStyles.Top | AnchorStyles.Left;
if (dock_style == DockStyle.None) {
if (explicit_bounds == Rectangle.Empty)
}
if (parent != null) {
- parent.PerformLayout(this, "Parent");
+ parent.PerformLayout(this, "Dock");
}
OnDockChanged(EventArgs.Empty);
#if NET_2_0
protected virtual bool DoubleBuffered {
get {
- return (control_style & ControlStyles.DoubleBuffer) != 0;
+ return (control_style & ControlStyles.OptimizedDoubleBuffer) != 0;
}
set {
- SetStyle (ControlStyles.DoubleBuffer, value);
+ if (value == DoubleBuffered)
+ return;
+ if (value) {
+ SetStyle (ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
+ } else {
+ SetStyle (ControlStyles.OptimizedDoubleBuffer, false);
+ }
+
}
}
#endif
}
set {
+ if (this.is_enabled != value) {
+ bool old_value = is_enabled;
- bool old_value = is_enabled;
+ is_enabled = value;
+ if (old_value != value && !value && this.has_focus)
+ SelectNextControl(this, true, true, true, true);
- is_enabled = value;
- if (old_value != value && !value && this.has_focus)
- SelectNextControl(this, true, true, true, true);
-
- OnEnabledChanged (EventArgs.Empty);
+ OnEnabledChanged (EventArgs.Empty);
+ }
}
}
font = value;
Invalidate();
OnFontChanged (EventArgs.Empty);
+ PerformLayout ();
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsHandleCreated {
get {
- if ((window != null) && (window.Handle != IntPtr.Zero)) {
- Hwnd hwnd = Hwnd.ObjectFromHandle (window.Handle);
- if (hwnd != null && !hwnd.zombie)
- return true;
- }
+ if (window == null || window.Handle == IntPtr.Zero)
+ return false;
- return false;
+ Hwnd hwnd = Hwnd.ObjectFromHandle (window.Handle);
+ if (hwnd != null && hwnd.zombie)
+ return false;
+
+ return true;
}
}
public virtual
#endif
Layout.LayoutEngine LayoutEngine {
- get { return new Layout.DefaultLayout (); }
- }
+ get {
+ if (layout_engine == null)
+ layout_engine = new Layout.DefaultLayout ();
+ return layout_engine;
+ }
+ }
[EditorBrowsable(EditorBrowsableState.Always)]
[Browsable(false)]
[Localizable (true)]
public Padding Margin {
get { return this.margin; }
- set { this.margin = value; }
+ set {
+ if (this.margin != value) {
+ this.margin = value;
+ OnMarginChanged (EventArgs.Empty);
+ }
+ }
}
#endif
}
set {
- padding = value;
- OnPaddingChanged (EventArgs.Empty);
+ if (padding != value) {
+ padding = value;
+ OnPaddingChanged (EventArgs.Empty);
+ PerformLayout ();
+ }
}
}
#endif
}
}
+#if NET_2_0
+ [Browsable (false)]
+ public Size PreferredSize {
+ get { return this.GetPreferredSize (Size.Empty); }
+ }
+#endif
+
[EditorBrowsable(EditorBrowsableState.Advanced)]
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
// set.
if (attrs != null && attrs.Length > 0)
a = (AssemblyProductAttribute) attrs [0];
+ if (a == null) {
+ return GetType ().Namespace;
+ }
return a.Product;
}
}
}
set {
- if (value != null && IsHandleCreated) {
- XplatUI.SetClipRegion(Handle, value);
+ if (clip_region != value) {
+ if (value != null && IsHandleCreated)
+ XplatUI.SetClipRegion(Handle, value);
+
+ clip_region = value;
+#if NET_2_0
+ OnRegionChanged (EventArgs.Empty);
+#endif
}
- clip_region = value;
}
}
if (value != right_to_left) {
right_to_left = value;
OnRightToLeftChanged(EventArgs.Empty);
+ PerformLayout ();
}
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public IWindowTarget WindowTarget {
- get {
- return null;
- }
-
- set {
- ; // MS Internal
- }
+ get { return window_target; }
+ set { window_target = value; }
}
#endregion // Public Instance Properties
create_params.ClassName = XplatUI.DefaultClassName;
- create_params.ClassStyle = 0;
+ create_params.ClassStyle = (int)(XplatUIWin32.ClassStyle.CS_OWNDC | XplatUIWin32.ClassStyle.CS_DBLCLKS);
create_params.ExStyle = 0;
create_params.Param = 0;
}
switch (border_style) {
- case BorderStyle.FixedSingle:
- create_params.Style |= (int) WindowStyles.WS_BORDER;
- break;
- case BorderStyle.Fixed3D:
- create_params.ExStyle |= (int) WindowExStyles.WS_EX_CLIENTEDGE;
- break;
+ case BorderStyle.FixedSingle:
+ create_params.Style |= (int) WindowStyles.WS_BORDER;
+ break;
+ case BorderStyle.Fixed3D:
+ create_params.ExStyle |= (int) WindowExStyles.WS_EX_CLIENTEDGE;
+ break;
}
return create_params;
}
}
+#if NET_2_0
+ protected virtual Cursor DefaultCursor { get { return Cursors.Default; } }
+#endif
+
protected virtual ImeMode DefaultImeMode {
get {
return ImeMode.Inherit;
protected virtual Padding DefaultMargin {
get { return new Padding (3); }
}
+
+ protected virtual Size DefaultMaximumSize { get { return new Size (); } }
+ protected virtual Size DefaultMinimumSize { get { return new Size (); } }
+ protected virtual Padding DefaultPadding { get { return new Padding (); } }
#endif
protected virtual Size DefaultSize {
object [] prms = null;
if (method is EventHandler)
prms = new object [] { this, EventArgs.Empty };
- return BeginInvokeInternal(method, prms, false);
+ return BeginInvokeInternal(method, prms);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
- public IAsyncResult BeginInvoke (Delegate method, object[] args) {
- return BeginInvokeInternal (method, args, false);
+#if NET_2_0
+ public IAsyncResult BeginInvoke (Delegate method, params object[] args)
+#else
+ public IAsyncResult BeginInvoke (Delegate method, object[] args)
+#endif
+ {
+ return BeginInvokeInternal (method, args);
}
public void BringToFront() {
if (parent != null) {
parent.child_controls.SetChildIndex(this, 0);
- parent.Refresh();
- } else {
+ }
+ else if (IsHandleCreated) {
XplatUI.SetZOrder(Handle, IntPtr.Zero, false, false);
}
}
return false;
}
- public void CreateControl() {
+ public void CreateControl () {
if (is_disposed) {
throw new ObjectDisposedException(GetType().FullName.ToString());
}
return;
}
+ if (!is_visible) {
+ return;
+ }
+
if (!IsHandleCreated) {
CreateHandle();
}
if (!is_created) {
is_created = true;
- }
-
- Control [] controls = child_controls.GetAllControls ();
- for (int i=0; i<controls.Length; i++) {
- controls [i].CreateControl ();
- }
- UpdateChildrenZOrder();
+ if (binding_context == null) { // seem to be sent whenever it's null?
+ OnBindingContextChanged(EventArgs.Empty);
+ }
- if (binding_context == null) { // seem to be sent whenever it's null?
- OnBindingContextChanged(EventArgs.Empty);
+ OnCreateControl();
}
-
- OnCreateControl();
}
public Graphics CreateGraphics() {
}
public DragDropEffects DoDragDrop(object data, DragDropEffects allowedEffects) {
- return XplatUI.StartDrag(this.window.Handle, data, allowedEffects);
+ if (IsHandleCreated)
+ return XplatUI.StartDrag(Handle, data, allowedEffects);
+ else
+ return DragDropEffects.None;
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
[EditorBrowsable (EditorBrowsableState.Advanced)]
#endif
public bool Focus() {
- if (CanFocus && IsHandleCreated && !has_focus && !is_focusing) {
+ return FocusInternal (false);
+ }
+
+ internal virtual bool FocusInternal (bool skip_check) {
+ if (skip_check || (CanFocus && IsHandleCreated && !has_focus && !is_focusing)) {
is_focusing = true;
Select(this);
is_focusing = false;
}
public Control GetChildAtPoint(Point pt) {
+ // MS's version causes the handle to be created. The stack trace shows that get_Handle is called here, but
+ // we'll just call CreateHandle instead.
+ CreateHandle ();
+
// Microsoft's version of this function doesn't seem to work, so I can't check
// if we only consider children or also grandchildren, etc.
// I'm gonna say 'children only'
#if NET_2_0
[EditorBrowsable (EditorBrowsableState.Advanced)]
public virtual Size GetPreferredSize (Size proposedSize) {
- return preferred_size;
+ Size retsize = this.explicit_bounds.Size;
+
+ // If we're bigger than the MaximumSize, fix that
+ if (this.maximum_size.Width != 0 && retsize.Width > this.maximum_size.Width)
+ retsize.Width = this.maximum_size.Width;
+ if (this.maximum_size.Height != 0 && retsize.Height > this.maximum_size.Height)
+ retsize.Height = this.maximum_size.Height;
+
+ // If we're smaller than the MinimumSize, fix that
+ if (this.minimum_size.Width != 0 && retsize.Width < this.minimum_size.Width)
+ retsize.Width = this.minimum_size.Width;
+ if (this.minimum_size.Height != 0 && retsize.Height < this.minimum_size.Height)
+ retsize.Height = this.minimum_size.Height;
+
+ return retsize;
}
#endif
}
public void Invalidate(System.Drawing.Rectangle rc, bool invalidateChildren) {
- if (!IsHandleCreated || !Visible || rc.Width == 0 || rc.Height == 0) {
+ // Win32 invalidates control including when Width and Height is equal 0
+ // or is not visible, only Paint event must be care about this.
+ if (!IsHandleCreated)
return;
- }
- NotifyInvalidate(rc);
+ if (rc.Width > 0 && rc.Height > 0) {
- XplatUI.Invalidate(Handle, rc, false);
+ NotifyInvalidate(rc);
- if (invalidateChildren) {
- Control [] controls = child_controls.GetAllControls ();
- for (int i=0; i<controls.Length; i++)
- controls [i].Invalidate ();
+ XplatUI.Invalidate(Handle, rc, false);
+
+ if (invalidateChildren) {
+ Control [] controls = child_controls.GetAllControls ();
+ for (int i=0; i<controls.Length; i++)
+ controls [i].Invalidate ();
+ }
}
OnInvalidated(new InvalidateEventArgs(rc));
}
return Invoke(method, prms);
}
-
+#if NET_2_0
+ public object Invoke (Delegate method, params object [] args) {
+#else
public object Invoke (Delegate method, object[] args) {
+#endif
+ Control control = FindControlToInvokeOn ();
+
if (!this.InvokeRequired) {
return method.DynamicInvoke(args);
}
- IAsyncResult result = BeginInvoke (method, args);
- return EndInvoke(result);
- }
-
- internal object InvokeInternal (Delegate method, bool disposing) {
- return InvokeInternal(method, null, disposing);
- }
-
- internal object InvokeInternal (Delegate method, object[] args, bool disposing) {
- if (!this.InvokeRequired) {
- return method.DynamicInvoke(args);
- }
-
- IAsyncResult result = BeginInvokeInternal (method, args, disposing);
+ IAsyncResult result = BeginInvokeInternal (method, args, control);
return EndInvoke(result);
}
PerformLayout(null, null);
}
- internal void SetImplicitBounds (int x, int y, int width, int height)
- {
+ internal void SetImplicitBounds (int x, int y, int width, int height) {
Rectangle saved_bounds = explicit_bounds;
SetBounds (x, y, width, height);
explicit_bounds = saved_bounds;
// Perform all Dock and Anchor calculations
try {
- layout_engine.Layout(this, levent);
-
- // Let everyone know
OnLayout(levent);
}
return new Rectangle(PointToScreen(r.Location), r.Size);
}
- public virtual void Refresh() {
- if (IsHandleCreated == true) {
+ public virtual void Refresh() {
+ if (IsHandleCreated && Visible) {
Invalidate();
XplatUI.UpdateWindow(window.Handle);
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetBindings() {
- data_bindings.Clear();
+ if (data_bindings != null)
+ data_bindings.Clear();
}
[EditorBrowsable(EditorBrowsableState.Never)]
}
if (layout_suspended == 0) {
- Control [] controls = child_controls.GetAllControls ();
if (performLayout && layout_pending) {
PerformLayout();
}
#endif
public void Select() {
- if (this is ContainerControl)
- ContainerSelected = true;
- else {
- Control c = this.Parent;
- while (c != null) {
- c.ContainerSelected = false;
- c = c.Parent;
- }
- }
Select(false, false);
- }
+ }
#if DebugFocus
private void printTree(Control c, string t) {
foreach(Control i in c.child_controls) {
- Console.WriteLine("{2}{0}.TabIndex={1}", i, i.tab_index, t);
- printTree(i, t+"\t");
+ Console.WriteLine ("{2}{0}.TabIndex={1}", i, i.tab_index, t);
+ printTree (i, t+"\t");
}
}
#endif
}
SetBoundsCore(x, y, width, height, specified);
- if (parent != null) {
+ if (parent != null)
parent.PerformLayout(this, "Bounds");
- }
}
- public void Show() {
- if (!is_created) {
- this.CreateControl();
- }
-
- this.Visible=true;
+ public void Show () {
+ this.Visible = true;
}
public void SuspendLayout() {
#region Protected Instance Methods
[EditorBrowsable(EditorBrowsableState.Advanced)]
- [MonoTODO("Implement this and tie it into Control.ControlAccessibleObject.NotifyClients")]
protected void AccessibilityNotifyClients(AccessibleEvents accEvent, int childID) {
- throw new NotImplementedException();
+ // turns out this method causes handle
+ // creation in 1.1. at first I thought this
+ // would be accomplished just by using
+ // get_AccessibilityObject, which would route
+ // through CreateAccessibilityInstance, which
+ // calls CreateControl. This isn't the case,
+ // though (as overriding
+ // CreateAccessibilityInstance and adding a
+ // CWL shows nothing. So we fudge it and put
+ // a CreateHandle here.
+
+#if ONLY_1_1
+ CreateHandle ();
+#endif
+
+ if (accessibility_object != null && accessibility_object is ControlAccessibleObject)
+ ((ControlAccessibleObject)accessibility_object).NotifyClients (accEvent, childID);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual AccessibleObject CreateAccessibilityInstance() {
+ CreateControl ();
return new Control.ControlAccessibleObject(this);
}
return;
}
- window.CreateHandle(CreateParams);
+ CreateParams create_params = CreateParams;
+ window.CreateHandle(create_params);
if (window.Handle != IntPtr.Zero) {
creator_thread = Thread.CurrentThread;
XplatUI.EnableWindow(window.Handle, is_enabled);
- XplatUI.SetVisible(window.Handle, is_visible, true);
if (clip_region != null) {
- XplatUI.SetClipRegion(Handle, clip_region);
+ XplatUI.SetClipRegion(window.Handle, clip_region);
}
// Set our handle with our parent
XplatUI.SetParent(window.Handle, parent.Handle);
}
- // Set our handle as parent for our children
- Control [] children;
-
- children = child_controls.GetAllControls ();
- for (int i = 0; i < children.Length; i++ ) {
- if (!children[i].RecreatingHandle)
- XplatUI.SetParent(children[i].Handle, window.Handle);
- }
-
UpdateStyles();
- XplatUI.SetAllowDrop (Handle, allow_drop);
+ XplatUI.SetAllowDrop (window.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);
}
UpdateBounds();
-
- OnHandleCreated(EventArgs.Empty);
}
}
#if NET_2_0
protected virtual AccessibleObject GetAccessibilityObjectById (int objectId)
{
- throw new NotImplementedException ();
+ // XXX need to implement this.
+ return null;
}
#endif
}
protected virtual bool IsInputChar (char charCode) {
+ // XXX on MS.NET this method causes the handle to be created..
+ CreateHandle ();
+
return true;
}
return false;
}
- protected virtual bool ProcessKeyEventArgs (ref Message msg)
- {
+ protected virtual bool ProcessKeyEventArgs (ref Message msg) {
KeyEventArgs key_event;
switch (msg.Msg) {
// MS Internal
}
- private void SetIsRecreating ()
- {
+ private void SetIsRecreating () {
is_recreating=true;
foreach (Control c in Controls.GetAllControls()) {
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected void RecreateHandle() {
+ if (!IsHandleCreated)
+ return;
+
#if DebugRecreate
Console.WriteLine("Recreating control {0}", XplatUI.Window(window.Handle));
#endif
IContainerControl container;
container = GetContainerControl();
- if (container != null)
+ if (container != null && (Control)container != this)
container.ActiveControl = this;
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void SetClientSizeCore(int x, int y) {
- // Calculate the actual window size from the client size (it usually stays the same or grows)
- Rectangle ClientRect;
- Rectangle WindowRect;
- CreateParams cp;
-
- ClientRect = new Rectangle(0, 0, x, y);
- cp = this.CreateParams;
-
- if (XplatUI.CalculateWindowRect(ref ClientRect, cp.Style, cp.ExStyle, null, out WindowRect)==false) {
- return;
- }
-
- SetBounds(bounds.X, bounds.Y, WindowRect.Width, WindowRect.Height, BoundsSpecified.Size);
+ Size NewSize = InternalSizeFromClientSize (new Size (x, y));
+
+ if (NewSize != Size.Empty)
+ SetBounds (bounds.X, bounds.Y, NewSize.Width, NewSize.Height, BoundsSpecified.Size);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected void SetTopLevel(bool value) {
if ((GetTopLevel() != value) && (parent != null)) {
- throw new Exception();
+ throw new ArgumentException ("Cannot change toplevel style of a parented control.");
}
if (this is Form) {
- if (value == true) {
- if (!Visible) {
- Visible = true;
- }
- } else {
- if (Visible) {
- Visible = false;
- }
+ if (IsHandleCreated && value != Visible) {
+ Visible = value;
}
+ } else {
+ // XXX MS.NET causes handle to be created here
+ CreateHandle ();
}
is_toplevel = value;
}
protected virtual void SetVisibleCore(bool value) {
- if (value!=is_visible) {
- if (value && (window.Handle == IntPtr.Zero) || !is_created) {
+ if (value != is_visible) {
+ is_visible = value;
+
+ if (is_visible && ((window.Handle == IntPtr.Zero) || !is_created)) {
CreateControl();
}
- is_visible=value;
-
if (IsHandleCreated) {
- XplatUI.SetVisible(Handle, value, true);
+ XplatUI.SetVisible(Handle, is_visible, true);
// Explicitly move Toplevel windows to where we want them;
// apparently moving unmapped toplevel windows doesn't work
if (is_visible && (this is Form)) {
XplatUI.SetWindowPos(window.Handle, bounds.X, bounds.Y, bounds.Width, bounds.Height);
}
}
-
- OnVisibleChanged(EventArgs.Empty);
-
- if (value == false && parent != null && Focused) {
- Control container;
-
- // Need to start at parent, GetContainerControl might return ourselves if we're a container
- container = (Control)parent.GetContainerControl();
- if (container != null) {
- container.SelectNextControl(this, true, true, true, true);
- }
- }
-
- if (parent != null) {
- parent.PerformLayout(this, "visible");
- } else {
- PerformLayout(this, "visible");
+ else {
+ OnVisibleChanged(EventArgs.Empty);
}
}
}
-
+
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+#if NET_2_0
+ protected
+#else
+ internal
+#endif
+ virtual Size SizeFromClientSize (Size clientSize) {
+ return InternalSizeFromClientSize (clientSize);
+ }
+
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected void UpdateBounds() {
+ if (!IsHandleCreated)
+ return;
+
int x;
int y;
int width;
int client_width;
int client_height;
- if (!IsHandleCreated) {
- CreateHandle();
- }
-
XplatUI.GetWindowPos(this.Handle, this is Form, out x, out y, out width, out height, out client_width, out client_height);
UpdateBounds(x, y, width, height, client_width, client_height);
if (moved) {
OnLocationChanged(EventArgs.Empty);
+
+ if (!background_color.IsEmpty && background_color.A < byte.MaxValue)
+ Invalidate ();
}
if (resized) {
OnSizeChanged(EventArgs.Empty);
+#if NET_2_0
+ OnClientSizeChanged (EventArgs.Empty);
+#endif
}
}
// Override this if there is a control that shall always remain on
// top of other controls (such as scrollbars). If there are several
// of these controls, the bottom-most should be returned.
- internal virtual IntPtr AfterTopMostControl ()
- {
+ internal virtual IntPtr AfterTopMostControl () {
return IntPtr.Zero;
}
- private void UpdateChildrenZOrder() {
+ // internal because we need to call it from ScrollableControl.OnVisibleChanged
+ internal void UpdateChildrenZOrder() {
Control [] controls;
if (!IsHandleCreated) {
return;
}
+ // XXX This code is severely broken. It leaks
+ // the "zero_sized" abstraction out of the X11
+ // backend and into Control.cs. It'll work on
+ // windows simply by virtue of windows never
+ // setting that field to true.
+ //
+ // basically what we need to guard against is
+ // calling XplatUI.SetZOrder on an hwnd that
+ // corresponds to an unmapped X window.
controls = child_controls.GetAllControls ();
- for (int i = 1; i < controls.Length; i++ ) {
- XplatUI.SetZOrder(controls[i].Handle, controls[i-1].Handle, false, false);
+
+ ArrayList children_to_order = new ArrayList ();
+
+ for (int i = 0; i < controls.Length; i ++) {
+ if (!controls[i].IsHandleCreated || !controls[i].VisibleInternal)
+ continue;
+
+ Hwnd hwnd = Hwnd.ObjectFromHandle (controls[i].Handle);
+ if (hwnd.zero_sized)
+ continue;
+
+ children_to_order.Add (controls[i]);
+ }
+
+ for (int i = 1; i < children_to_order.Count; i ++) {
+ Control upper = (Control)children_to_order[i-1];
+ Control lower = (Control)children_to_order[i];
+
+ XplatUI.SetZOrder(lower.Handle, upper.Handle, false, false);
}
}
}
switch((Msg)m.Msg) {
- case Msg.WM_DESTROY: {
- OnHandleDestroyed(EventArgs.Empty);
-#if DebugRecreate
- IntPtr handle = window.Handle;
-#endif
- window.InvalidateHandle();
+ case Msg.WM_DESTROY: {
+ WmDestroy(ref m);
+ return;
+ }
- if (is_recreating) {
-#if DebugRecreate
- Console.WriteLine ("Creating handle for {0:X}", handle.ToInt32());
-#endif
- CreateHandle();
-#if DebugRecreate
- Console.WriteLine (" + new handle = {0:X}", Handle.ToInt32());
-#endif
- is_recreating = false;
+ case Msg.WM_WINDOWPOSCHANGED: {
+ WmWindowPosChanged(ref m);
+ return;
}
- return;
- }
- case Msg.WM_WINDOWPOSCHANGED: {
- if (Visible) {
- Rectangle save_bounds = explicit_bounds;
- UpdateBounds();
- explicit_bounds = save_bounds;
- if (GetStyle(ControlStyles.ResizeRedraw)) {
- Invalidate();
- }
+ // 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: {
+ WmPaint (ref m);
+ return;
+ }
+
+ // 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...
+ case Msg.WM_ERASEBKGND: {
+ WmEraseBackground (ref m);
+ return;
}
- 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;
+ case Msg.WM_LBUTTONUP: {
+ WmLButtonUp (ref m);
+ return;
+ }
+
+ case Msg.WM_LBUTTONDOWN: {
+ WmLButtonDown (ref m);
+ return;
+ }
- paint_event = XplatUI.PaintEventStart(Handle, true);
+ case Msg.WM_LBUTTONDBLCLK: {
+ WmLButtonDblClick (ref m);
+ return;
+ }
- if (paint_event == null) {
+ case Msg.WM_MBUTTONUP: {
+ WmMButtonUp (ref m);
+ return;
+ }
+
+ case Msg.WM_MBUTTONDOWN: {
+ WmMButtonDown (ref m);
return;
}
- if (invalid_region != null && !invalid_region.IsVisible (paint_event.ClipRectangle)) {
+ case Msg.WM_MBUTTONDBLCLK: {
+ WmMButtonDblClick (ref m);
+ return;
+ }
- // Just blit the previous image
- XplatUI.BlitFromOffscreen (Handle, paint_event.Graphics, backbuffer, backbuffer_dc, paint_event.ClipRectangle);
- XplatUI.PaintEventEnd (Handle, true);
+ case Msg.WM_RBUTTONUP: {
+ WmRButtonUp (ref m);
+ return;
+ }
+
+ case Msg.WM_RBUTTONDOWN: {
+ WmRButtonDown (ref m);
return;
}
- Graphics dc = null;
- Graphics back_dc = null;
- object back = null;
- if (ThemeEngine.Current.DoubleBufferingSupported) {
- if ((control_style & ControlStyles.DoubleBuffer) != 0) {
- CreateBackBuffer ();
- back = backbuffer;
- back_dc = backbuffer_dc;
- dc = paint_event.SetGraphics (back_dc);
- }
+ case Msg.WM_RBUTTONDBLCLK: {
+ WmRButtonDblClick (ref m);
+ return;
+ }
+
+ case Msg.WM_CONTEXTMENU: {
+ WmContextMenu (ref m);
+ return;
}
- if (!GetStyle(ControlStyles.Opaque)) {
- OnPaintBackground(paint_event);
+ case Msg.WM_MOUSEWHEEL: {
+ WmMouseWheel (ref m);
+ return;
}
- // 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);
+ case Msg.WM_MOUSEMOVE: {
+ WmMouseMove (ref m);
+ return;
}
- if (ThemeEngine.Current.DoubleBufferingSupported)
- if ((control_style & ControlStyles.DoubleBuffer) != 0) {
- XplatUI.BlitFromOffscreen (Handle, dc, back, back_dc, paint_event.ClipRectangle);
- paint_event.SetGraphics (dc);
- invalid_region.Exclude (paint_event.ClipRectangle);
+ case Msg.WM_SHOWWINDOW: {
+ WmShowWindow (ref m);
+ return;
+ }
- if (back != backbuffer)
- XplatUI.DestroyOffscreenDrawable (back, back_dc);
- }
+ case Msg.WM_CREATE: {
+ WmCreate (ref m);
+ return;
+ }
- XplatUI.PaintEventEnd(Handle, true);
+ case Msg.WM_MOUSE_ENTER: {
+ WmMouseEnter (ref m);
+ return;
+ }
- 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_MOUSELEAVE: {
+ WmMouseLeave (ref m);
+ return;
+ }
- case Msg.WM_LBUTTONUP: {
- MouseEventArgs me;
+ case Msg.WM_MOUSEHOVER: {
+ WmMouseHover (ref m);
+ return;
+ }
- me = new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Left,
- mouse_clicks,
- LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
- 0);
+ case Msg.WM_SYSKEYUP: {
+ WmSysKeyUp (ref m);
+ return;
+ }
- HandleClick(mouse_clicks, me);
- OnMouseUp (me);
+ case Msg.WM_SYSKEYDOWN:
+ case Msg.WM_KEYDOWN:
+ case Msg.WM_KEYUP:
+ case Msg.WM_SYSCHAR:
+ case Msg.WM_CHAR: {
+ WmKeys (ref m);
+ return;
+ }
- if (InternalCapture) {
- InternalCapture = false;
+ case Msg.WM_HELP: {
+ WmHelp (ref m);
+ return;
}
- if (mouse_clicks > 1) {
- mouse_clicks = 1;
+ case Msg.WM_KILLFOCUS: {
+ WmKillFocus (ref m);
+ return;
+ }
+
+ case Msg.WM_SETFOCUS: {
+ WmSetFocus (ref m);
+ return;
}
- return;
- }
- case Msg.WM_LBUTTONDOWN: {
- if (CanSelect) {
- Select (true, true);
- }
- InternalCapture = true;
- OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
- mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
- 0));
-
- return;
- }
+ case Msg.WM_SYSCOLORCHANGE: {
+ WmSysColorChange (ref m);
+ return;
+ }
- 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 ()),
- 0));
- return;
+ case Msg.WM_SETCURSOR: {
+ WmSetCursor (ref m);
+ return;
+ }
+
+ case Msg.WM_CAPTURECHANGED: {
+ WmCaptureChanged (ref m);
+ return;
+ }
+
+ default:
+ DefWndProc(ref m);
+ return;
}
+ }
+ #endregion // Public Instance Methods
- case Msg.WM_MBUTTONUP: {
- MouseEventArgs me;
+ #region WM methods
+
+ private void WmDestroy (ref Message m) {
+ OnHandleDestroyed(EventArgs.Empty);
+#if DebugRecreate
+ IntPtr handle = window.Handle;
+#endif
+ window.InvalidateHandle();
- me = new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Middle,
- mouse_clicks,
- LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
- 0);
+ if (is_recreating) {
+#if DebugRecreate
+ Console.WriteLine ("Creating handle for {0:X}", handle.ToInt32());
+#endif
+ CreateHandle();
+#if DebugRecreate
+ Console.WriteLine (" + new handle = {0:X}", Handle.ToInt32());
+#endif
+ is_recreating = false;
+ }
+ }
- HandleClick(mouse_clicks, me);
- OnMouseUp (me);
- if (InternalCapture) {
- InternalCapture = false;
- }
- if (mouse_clicks > 1) {
- mouse_clicks = 1;
+ private void WmWindowPosChanged (ref Message m) {
+ if (Visible) {
+ Rectangle save_bounds = explicit_bounds;
+ UpdateBounds();
+ explicit_bounds = save_bounds;
+ if (GetStyle(ControlStyles.ResizeRedraw)) {
+ Invalidate();
}
- return;
}
-
- 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));
+ }
+
+
+ // 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/
+ private void WmPaint (ref Message m) {
+ PaintEventArgs paint_event;
+
+ IntPtr handle = Handle;
+
+ paint_event = XplatUI.PaintEventStart (handle, true);
+
+ if (paint_event == null)
return;
+
+ DoubleBuffer current_buffer = null;
+ if (UseDoubleBuffering) {
+ current_buffer = GetBackBuffer ();
+ if (!current_buffer.InvalidRegion.IsVisible (paint_event.ClipRectangle)) {
+ // Just blit the previous image
+ current_buffer.Blit (paint_event);
+ XplatUI.PaintEventEnd (handle, true);
+ return;
+ }
+ current_buffer.Start (paint_event);
+ }
+
+ if (!GetStyle(ControlStyles.Opaque)) {
+ OnPaintBackground (paint_event);
}
- 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 ()),
- 0));
- return;
+ // 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);
}
- case Msg.WM_RBUTTONUP: {
- MouseEventArgs me;
- Point pt;
+ if (current_buffer != null) {
+ current_buffer.End (paint_event);
+ }
- 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)));
+ XplatUI.PaintEventEnd (handle, true);
+ }
- me = new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Right,
- mouse_clicks,
- LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
- 0);
+ private void WmEraseBackground (ref Message m) {
+ // 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;
+ }
- HandleClick(mouse_clicks, me);
- OnMouseUp (me);
+ private void WmLButtonUp (ref Message m) {
+ MouseEventArgs me;
- if (InternalCapture) {
- InternalCapture = false;
- }
+ me = new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Left,
+ mouse_clicks,
+ LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
+ 0);
- if (mouse_clicks > 1) {
- mouse_clicks = 1;
- }
- return;
+ 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));
- return;
+ private void WmLButtonDown (ref Message m) {
+ if (CanSelect) {
+ Select (true, 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: {
- InternalCapture = true;
- mouse_clicks++;
- OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
- mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
- 0));
- return;
+ private void WmLButtonDblClick (ref Message m) {
+ InternalCapture = true;
+ mouse_clicks++;
+ OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
+ mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
+ 0));
+ }
+
+ private void WmMButtonUp (ref Message m) {
+ 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);
+
+ HandleClick(mouse_clicks, me);
+ OnMouseUp (me);
+ if (InternalCapture) {
+ InternalCapture = false;
}
+ if (mouse_clicks > 1) {
+ mouse_clicks = 1;
+ }
+ }
+
+ private void WmMButtonDown (ref Message m) {
+ 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_CONTEXTMENU: {
- if (context_menu != null) {
- Point pt;
+ private void WmMButtonDblClick (ref Message m) {
+ InternalCapture = true;
+ mouse_clicks++;
+ OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
+ mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
+ 0));
+ }
- pt = new Point(LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()));
+ private void WmRButtonUp (ref Message m) {
+ MouseEventArgs me;
+ Point pt;
- if (pt.X == -1 || pt.Y == -1) {
- pt.X = (this.Width / 2) + this.Left;
- pt.Y = (this.Height / 2) + this.Top;
- pt = this.PointToScreen (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)));
+
+ me = new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Right,
+ mouse_clicks,
+ LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
+ 0);
+
+ HandleClick(mouse_clicks, me);
+ OnMouseUp (me);
+
+ if (InternalCapture) {
+ InternalCapture = false;
+ }
+
+ if (mouse_clicks > 1) {
+ mouse_clicks = 1;
+ }
+ }
- context_menu.Show (this, PointToClient (pt));
- return;
+ private void WmRButtonDown (ref Message m) {
+ InternalCapture = true;
+ OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
+ mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
+ 0));
+ }
+
+ private void WmRButtonDblClick (ref Message m) {
+ InternalCapture = true;
+ mouse_clicks++;
+ OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
+ mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
+ 0));
+ }
+
+ private void WmContextMenu (ref Message m) {
+ if (context_menu != null) {
+ Point pt;
+
+ pt = new Point(LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()));
+
+ if (pt.X == -1 || pt.Y == -1) {
+ pt.X = (this.Width / 2) + this.Left;
+ pt.Y = (this.Height / 2) + this.Top;
+ pt = this.PointToScreen (pt);
}
+
+ context_menu.Show (this, PointToClient (pt));
+ return;
+ }
#if NET_2_0
// If there isn't a regular context menu, show the Strip version
return;
}
#endif
- DefWndProc(ref m);
- return;
- }
-
- case Msg.WM_MOUSEWHEEL: {
- DefWndProc(ref m);
- OnMouseWheel (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
- mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
- HighOrder(m.WParam.ToInt32())));
- return;
- }
+ DefWndProc(ref m);
+ }
+ private void WmCreate (ref Message m) {
+ OnHandleCreated(EventArgs.Empty);
+ }
- case Msg.WM_MOUSEMOVE: {
- OnMouseMove (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
- mouse_clicks,
- LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
- 0));
- return;
- }
+ private void WmMouseWheel (ref Message m) {
+ DefWndProc(ref m);
+ OnMouseWheel (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
+ mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
+ HighOrder(m.WParam.ToInt32())));
+ }
- case Msg.WM_MOUSE_ENTER: {
- if (is_entered) {
- return;
- }
- is_entered = true;
- OnMouseEnter(EventArgs.Empty);
- return;
- }
- case Msg.WM_MOUSE_LEAVE: {
- is_entered=false;
- OnMouseLeave(EventArgs.Empty);
- return;
- }
+ private void WmMouseMove (ref Message m) {
+ OnMouseMove (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
+ mouse_clicks,
+ LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
+ 0));
+ }
- case Msg.WM_MOUSEHOVER: {
- OnMouseHover(EventArgs.Empty);
+ private void WmMouseEnter (ref Message m) {
+ if (is_entered) {
return;
}
+ is_entered = true;
+ OnMouseEnter(EventArgs.Empty);
+ }
- case Msg.WM_SYSKEYUP: {
- if (ProcessKeyMessage(ref m)) {
- m.Result = IntPtr.Zero;
- return;
- }
+ private void WmMouseLeave (ref Message m) {
+ is_entered=false;
+ OnMouseLeave(EventArgs.Empty);
+ }
- if ((m.WParam.ToInt32() & (int)Keys.KeyCode) == (int)Keys.Menu) {
- Form form;
+ private void WmMouseHover (ref Message m) {
+ OnMouseHover(EventArgs.Empty);
+ }
- form = FindForm();
- if (form != null && form.ActiveMenu != null) {
- form.ActiveMenu.ProcessCmdKey(ref m, (Keys)m.WParam.ToInt32());
+ private void WmShowWindow (ref Message m) {
+ if (m.WParam.ToInt32() != 0) {
+ CreateControl ();
+ /* if we're being shown, make sure our child controls all have their handles created */
+ Control [] controls = child_controls.GetAllControls ();
+ for (int i=0; i<controls.Length; i++) {
+ if (controls [i].is_visible) {
+ controls [i].CreateControl ();
+ XplatUI.SetParent(controls[i].Handle, window.Handle);
}
}
-
- DefWndProc (ref m);
- return;
}
+ else {
+ if (parent != null && Focused) {
+ Control container;
- 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;
+ // Need to start at parent, GetContainerControl might return ourselves if we're a container
+ container = (Control)parent.GetContainerControl();
+ if (container != null) {
+ container.SelectNextControl(this, true, true, true, true);
+ }
}
- DefWndProc (ref m);
- return;
}
- case Msg.WM_HELP: {
- Point mouse_pos;
- if (m.LParam != IntPtr.Zero) {
- HELPINFO hi;
-
- hi = new HELPINFO();
+ if (is_toplevel || (this is Form && ((Form) this).IsMdiChild)) /* XXX make sure this works for mdi forms */
+ OnVisibleChanged(EventArgs.Empty);
+ }
- hi = (HELPINFO) Marshal.PtrToStructure (m.LParam, typeof (HELPINFO));
- mouse_pos = new Point(hi.MousePos.x, hi.MousePos.y);
- } else {
- mouse_pos = Control.MousePosition;
- }
- OnHelpRequested(new HelpEventArgs(mouse_pos));
- m.Result = (IntPtr)1;
+ private void WmSysKeyUp (ref Message m) {
+ if (ProcessKeyMessage(ref m)) {
+ m.Result = IntPtr.Zero;
return;
}
- case Msg.WM_KILLFOCUS: {
- this.has_focus = false;
- OnLostFocusInternal (EventArgs.Empty);
- return;
- }
+ if ((m.WParam.ToInt32() & (int)Keys.KeyCode) == (int)Keys.Menu) {
+ Form form;
- case Msg.WM_SETFOCUS: {
- if (!has_focus) {
- this.has_focus = true;
- if (this.Parent != null && this.Parent.ContainerSelected)
- return;
- OnGotFocusInternal (EventArgs.Empty);
+ form = FindForm();
+ if (form != null && form.ActiveMenu != null) {
+ form.ActiveMenu.ProcessCmdKey(ref m, (Keys)m.WParam.ToInt32());
}
- return;
}
-
- case Msg.WM_SYSCOLORCHANGE: {
- ThemeEngine.Current.ResetDefaults();
- OnSystemColorsChanged(EventArgs.Empty);
+
+ DefWndProc (ref m);
+ }
+
+ private void WmKeys (ref Message m) {
+ if (ProcessKeyMessage(ref m)) {
+ m.Result = IntPtr.Zero;
return;
}
+ DefWndProc (ref m);
+ }
- case Msg.WM_SETCURSOR: {
- if ((cursor == null) || ((HitTest)(m.LParam.ToInt32() & 0xffff) != HitTest.HTCLIENT)) {
- DefWndProc(ref m);
- return;
- }
+ private void WmHelp (ref Message m) {
+ Point mouse_pos;
+ if (m.LParam != IntPtr.Zero) {
+ HELPINFO hi;
- XplatUI.SetCursor(window.Handle, cursor.handle);
- m.Result = (IntPtr)1;
+ hi = new HELPINFO();
- return;
+ hi = (HELPINFO) Marshal.PtrToStructure (m.LParam, typeof (HELPINFO));
+ mouse_pos = new Point(hi.MousePos.x, hi.MousePos.y);
+ } else {
+ mouse_pos = Control.MousePosition;
}
+ OnHelpRequested(new HelpEventArgs(mouse_pos));
+ m.Result = (IntPtr)1;
+ }
- default:
+ private void WmKillFocus (ref Message m) {
+ this.has_focus = false;
+ OnLostFocus (EventArgs.Empty);
+ }
+
+ private void WmSetFocus (ref Message m) {
+ if (!has_focus) {
+ this.has_focus = true;
+ OnGotFocus (EventArgs.Empty);
+ }
+ }
+
+ private void WmSysColorChange (ref Message m) {
+ ThemeEngine.Current.ResetDefaults();
+ OnSystemColorsChanged(EventArgs.Empty);
+ }
+
+ private void WmSetCursor (ref Message m) {
+ if ((cursor == null) || ((HitTest)(m.LParam.ToInt32() & 0xffff) != HitTest.HTCLIENT)) {
DefWndProc(ref m);
return;
}
+
+ XplatUI.SetCursor(window.Handle, cursor.handle);
+ m.Result = (IntPtr)1;
}
- #endregion // Public Instance Methods
+
+ private void WmCaptureChanged (ref Message m) {
+ is_captured = false;
+ OnMouseCaptureChanged (EventArgs.Empty);
+ m.Result = (IntPtr) 0;
+ }
+
+
+ #endregion
#region OnXXX methods
- [EditorBrowsable(EditorBrowsableState.Advanced)]
+#if NET_2_0
+ protected virtual void OnAutoSizeChanged (EventArgs e)
+ {
+ EventHandler eh = (EventHandler)(Events[AutoSizeChangedEvent]);
+ if (eh != null)
+ eh (this, e);
+ }
+#endif
+
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
protected virtual void OnBackColorChanged(EventArgs e) {
EventHandler eh = (EventHandler)(Events [BackColorChangedEvent]);
if (eh != null)
for (int i=0; i<child_controls.Count; i++) child_controls[i].OnParentBackgroundImageChanged(e);
}
+#if NET_2_0
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+ protected virtual void OnBackgroundImageLayoutChanged (EventArgs e)
+ {
+ EventHandler eh = (EventHandler)(Events[BackgroundImageLayoutChangedEvent]);
+ if (eh != null)
+ eh (this, e);
+ }
+#endif
+
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnBindingContextChanged(EventArgs e) {
CheckDataBindings ();
eh (this, e);
}
+#if NET_2_0
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+ protected virtual void OnClientSizeChanged (EventArgs e)
+ {
+ EventHandler eh = (EventHandler)(Events[ClientSizeChangedEvent]);
+ if (eh != null)
+ eh (this, e);
+ }
+#endif
+
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnContextMenuChanged(EventArgs e) {
EventHandler eh = (EventHandler)(Events [ContextMenuChangedEvent]);
eh (this, e);
}
+ internal void RaiseHelpRequested (HelpEventArgs hevent) {
+ OnHelpRequested (hevent);
+ }
+
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnHelpRequested(HelpEventArgs hevent) {
HelpEventHandler eh = (HelpEventHandler)(Events [HelpRequestedEvent]);
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnInvalidated(InvalidateEventArgs e) {
- if (ThemeEngine.Current.DoubleBufferingSupported)
- if ((control_style & ControlStyles.DoubleBuffer) != 0) {
- // should this block be here? seems like it
- // would be more at home in
- // NotifyInvalidated..
- if (e.InvalidRect == ClientRectangle) {
- InvalidateBackBuffer ();
- }
- else {
- // we need this Inflate call here so
- // that the border of the rectangle is
- // considered Visible (the
- // invalid_region.IsVisible call) in
- // the WM_PAINT handling below.
- Rectangle r = Rectangle.Inflate(e.InvalidRect, 1,1);
- if (invalid_region == null)
- invalid_region = new Region (r);
- else
- invalid_region.Union (r);
- }
+ if (UseDoubleBuffering) {
+ // should this block be here? seems like it
+ // would be more at home in
+ // NotifyInvalidated..
+ if (e.InvalidRect == ClientRectangle) {
+ InvalidateBackBuffer ();
+ } else if (backbuffer != null){
+ // we need this Inflate call here so
+ // that the border of the rectangle is
+ // considered Visible (the
+ // invalid_region.IsVisible call) in
+ // the WM_PAINT handling below.
+ Rectangle r = Rectangle.Inflate(e.InvalidRect, 1,1);
+ backbuffer.InvalidRegion.Union (r);
}
+ }
InvalidateEventHandler eh = (InvalidateEventHandler)(Events [InvalidatedEvent]);
if (eh != null)
LayoutEventHandler eh = (LayoutEventHandler)(Events [LayoutEvent]);
if (eh != null)
eh (this, levent);
+
+ LayoutEngine.Layout (this, levent);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
}
#if NET_2_0
+ protected virtual void OnMarginChanged (EventArgs e)
+ {
+ EventHandler eh = (EventHandler)(Events[MarginChangedEvent]);
+ if (eh != null)
+ eh (this, e);
+ }
+#endif
[EditorBrowsable (EditorBrowsableState.Advanced)]
+#if NET_2_0
protected virtual void OnMouseCaptureChanged (EventArgs e)
+#else
+ internal virtual void OnMouseCaptureChanged (EventArgs e)
+#endif
{
EventHandler eh = (EventHandler)(Events [MouseCaptureChangedEvent]);
if (eh != null)
eh (this, e);
}
+#if NET_2_0
[EditorBrowsable (EditorBrowsableState.Advanced)]
protected virtual void OnMouseClick (MouseEventArgs e)
{
// Override me
}
- internal virtual void OnGotFocusInternal (EventArgs e)
- {
- OnGotFocus (e);
- }
-
- internal virtual void OnLostFocusInternal (EventArgs e)
- {
- OnLostFocus (e);
- }
-
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnPaintBackground(PaintEventArgs pevent) {
PaintControlBackground (pevent);
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnParentBackgroundImageChanged(EventArgs e) {
- if (background_color.IsEmpty && background_image==null) {
- Invalidate();
- OnBackgroundImageChanged(e);
- }
+ Invalidate();
+ OnBackgroundImageChanged(e);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
eh (this, e);
}
+#if NET_2_0
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+ protected virtual void OnRegionChanged (EventArgs e)
+ {
+ EventHandler eh = (EventHandler)(Events[RegionChangedEvent]);
+ if (eh != null)
+ eh (this, e);
+ }
+#endif
+
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnResize(EventArgs e) {
+ PerformLayout(this, "Bounds");
+
EventHandler eh = (EventHandler)(Events [ResizeEvent]);
if (eh != null)
eh (this, e);
-
- PerformLayout(this, "bounds");
-
- if (parent != null) {
- parent.PerformLayout();
- }
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnVisibleChanged(EventArgs e) {
- if ((parent != null) && !Created && Visible) {
- if (!is_disposed) {
- CreateControl();
- PerformLayout();
- }
- }
-
EventHandler eh = (EventHandler)(Events [VisibleChangedEvent]);
if (eh != null)
eh (this, e);
static object LostFocusEvent = new object ();
#if NET_2_0
static object MarginChangedEvent = new object ();
+#endif
static object MouseCaptureChangedEvent = new object ();
+#if NET_2_0
static object MouseClickEvent = new object ();
static object MouseDoubleClickEvent = new object ();
#endif
static object VisibleChangedEvent = new object ();
#if NET_2_0
+ [Browsable (false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
public event EventHandler AutoSizeChanged {
add { Events.AddHandler (AutoSizeChangedEvent, value);}
remove {Events.RemoveHandler (AutoSizeChangedEvent, value);}
add { Events.AddHandler (MarginChangedEvent, value); }
remove {Events.RemoveHandler (MarginChangedEvent, value); }
}
-
+#endif
+#if NET_2_0
public event EventHandler MouseCaptureChanged {
+#else
+ internal event EventHandler MouseCaptureChanged {
+#endif
add { Events.AddHandler (MouseCaptureChangedEvent, value); }
remove { Events.RemoveHandler (MouseCaptureChangedEvent, value); }
}
-
+#if NET_2_0
public event MouseEventHandler MouseClick
{
add { Events.AddHandler (MouseClickEvent, value); }
}
#if NET_2_0
- public event EventHandler PreviewKeyDown {
+ public event PreviewKeyDownEventHandler PreviewKeyDown {
add { Events.AddHandler (PreviewKeyDownEvent, value); }
remove { Events.RemoveHandler (PreviewKeyDownEvent, value); }
}