X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Windows.Forms%2FSystem.Windows.Forms%2FControl.cs;h=eef0b0ee10805851740f5f8bfcc6ed2ea78ccc1d;hb=07d8828f508128adabe8c9ed0e69f4fb7635c270;hp=d598e1776549e4b6278f6773d9e19270cb5a5639;hpb=242d710a1e316d12758cde47345a9b85f31f8ab5;p=mono.git diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs index d598e177654..eef0b0ee108 100644 --- a/mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs +++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs @@ -54,6 +54,7 @@ private Control parent; static private Hashtable controlsCollection = new Hashtable (); static private NativeWindow parkingWindow = null; + private static bool classRegistered = false; // private fields // it seems these are stored in case the window is not created, @@ -65,18 +66,18 @@ AccessibleRole accessibleRole; bool allowDrop; AnchorStyles anchor; - Color backColor; + protected Color backColor; Image backgroundImage; //BindingContext bindingContext; Rectangle bounds; Rectangle oldBounds; bool causesValidation; - //ContextMenu contextMenu; + ContextMenu contextMenu; DockStyle dock; bool enabled; Font font; - Color foreColor; + protected Color foreColor; ImeMode imeMode; bool isAccessible; // Point location; // using bounds to store location @@ -85,8 +86,9 @@ RightToLeft rightToLeft; bool tabStop; protected string text; - bool visible; + protected bool visible; protected ControlStyles controlStyles_; + Cursor cursor; int clientWidth; int clientHeight; @@ -97,6 +99,7 @@ private static readonly int DISPOSED = BitVector32.CreateMask( LAYOUT_PENDING ); private static readonly int RECREATING_HANDLE= BitVector32.CreateMask( DISPOSED ); private static readonly int CREATED = BitVector32.CreateMask( RECREATING_HANDLE ); + private static readonly int DISPOSING = BitVector32.CreateMask( CREATED ); object tag; protected bool mouseIsInside_; @@ -195,7 +198,7 @@ oldBounds = new Rectangle(); // bindingContext = null; causesValidation = true; - // contextMenu = null; + contextMenu = null; dock = DockStyle.None; enabled = true; // font = Control.DefaultFont; @@ -206,10 +209,11 @@ name = ""; region = null; rightToLeft = RightToLeft.Inherit; - tabStop = false; + tabStop = true; text = ""; visible = true; parent = null; + cursor = null; oldBounds.Width = bounds.Width = DefaultSize.Width; oldBounds.Height = bounds.Height= DefaultSize.Height; @@ -398,15 +402,20 @@ [MonoTODO] public bool CanSelect { get { - // if (ControlStyles.Selectable && - // isContainedInAnotherControl && - // parentIsVisiable && isVisialbe && - // parentIsEnabled && isEnabled) { - // return true; - // } - // return false; - - throw new NotImplementedException (); + if ( !GetStyle ( ControlStyles.Selectable ) ) + return false; + + if ( Parent == null ) + return false; + + Control parent = Parent; + while ( parent != null ) { + if ( !parent.Visible || !parent.Enabled ) + return false; + parent = parent.Parent; + } + + return true; } } @@ -472,34 +481,13 @@ } } - internal void SetClientSize(Size value, int styleIfNoWindow, bool menuIfNoWindow) { - RECT rc = new RECT(); - rc.left = rc.top = 0; - rc.right = value.Width; - rc.bottom = value.Height; - - if( IsHandleCreated ){ - int style = Win32.GetWindowLong( Handle, GetWindowLongFlag.GWL_STYLE).ToInt32(); - int menuExists = 0; - if( (style & (int)WindowStyles.WS_CHILD) == 0 ){ - menuExists = Win32.GetMenu(Handle) != IntPtr.Zero ? 1 : 0; - } - Win32.AdjustWindowRect( ref rc, style, menuExists); - Win32.SetWindowPos( Handle, SetWindowPosZOrder.HWND_TOP, 0, 0, rc.right - rc.left, rc.bottom - rc.top, - SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOZORDER); - } - else { - Win32.AdjustWindowRect( ref rc, styleIfNoWindow, menuIfNoWindow ? 1 : 0); - } - Size = new Size(rc.right - rc.left, rc.bottom - rc.top); - } - public bool ContainsFocus { get { if (IsHandleCreated) { - IntPtr focusedWindow = Win32.GetFocus(); - if (focusedWindow == Handle) - return true; + if (Focused) return true; + foreach (Control ctr in Controls) { + if (ctr.ContainsFocus) return true; + } } return false; } @@ -509,12 +497,13 @@ [MonoTODO] public virtual ContextMenu ContextMenu { get { - //return contextMenu; - throw new NotImplementedException (); + return contextMenu; } set { - //contextMenu=value; - throw new NotImplementedException (); + if ( contextMenu != value ) { + contextMenu = value; + OnContextMenuChanged ( EventArgs.Empty ); + } } } @@ -543,7 +532,10 @@ else createParams.Parent = ParkingWindowHandle; - createParams.Style = (int) WindowStyles.WS_OVERLAPPEDWINDOW; + createParams.Style = (int) WindowStyles.WS_OVERLAPPED; + if( visible) { + createParams.Style |= (int) WindowStyles.WS_VISIBLE; + } return createParams; } @@ -594,12 +586,12 @@ [MonoTODO] public virtual Cursor Cursor { - get { - throw new NotImplementedException (); - } - set { - throw new NotImplementedException (); - } + get { + if ( cursor == null ) + return Cursors.Default; + return cursor; + } + set { cursor = value;} } //Compact Framework @@ -656,11 +648,8 @@ } } - [MonoTODO] public bool Disposing { - get { - throw new NotImplementedException (); - } + get { return statuses [ DISPOSING ]; } } public virtual DockStyle Dock { @@ -696,8 +685,13 @@ //Compact Framework public virtual bool Focused { get { - return ContainsFocus; - } + if (IsHandleCreated) { + IntPtr focusedWindow = Win32.GetFocus(); + if (focusedWindow == Handle) + return true; + } + return false; + } } //Compact Framework @@ -785,12 +779,7 @@ } public bool IsHandleCreated { - get { - return window != null && window.Handle != IntPtr.Zero; - //if (Handle != (IntPtr) 0) - // return true; - //return false; - } + get { return window != null && window.Handle != IntPtr.Zero; } } //Compact Framework @@ -814,10 +803,18 @@ } } - [MonoTODO] public static Keys ModifierKeys { get { - throw new NotImplementedException (); + Keys keys = Keys.None; + + if ( ( Win32.GetKeyState( (int) VirtualKeys.VK_SHIFT ) & 0x8000 ) == 0x8000 ) + keys |= Keys.Shift; + if ( ( Win32.GetKeyState( (int) VirtualKeys.VK_MENU ) & 0x8000 ) == 0x8000 ) + keys |= Keys.Alt; + if ( ( Win32.GetKeyState( (int) VirtualKeys.VK_CONTROL) & 0x8000) == 0x8000 ) + keys |= Keys.Control; + + return keys; } } @@ -888,7 +885,7 @@ } } - private static IntPtr ParkingWindowHandle { + protected static IntPtr ParkingWindowHandle { get { if ( parkingWindow == null ) parkingWindow = new NativeWindow ( ); @@ -904,6 +901,27 @@ } } + protected static void RegisterDefaultWindowClass ( ) + { + if ( !classRegistered ) { + WNDCLASS wndClass = new WNDCLASS(); + + wndClass.style = (int) (CS_.CS_OWNDC); + wndClass.lpfnWndProc = NativeWindow.GetWindowProc(); + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = 0; + wndClass.hInstance = (IntPtr)0; + wndClass.hIcon = (IntPtr)0; + wndClass.hCursor = Win32.LoadCursor( (IntPtr)0, LC_.IDC_ARROW); + wndClass.hbrBackground = (IntPtr)((int)GetSysColorIndex.COLOR_BTNFACE + 1); + wndClass.lpszMenuName = ""; + wndClass.lpszClassName = Win32.DEFAULT_WINDOW_CLASS; + + if (Win32.RegisterClass(ref wndClass) != 0) + classRegistered = true; + } + } + [MonoTODO] public string ProductName { get { @@ -937,14 +955,9 @@ } } - [MonoTODO] protected bool ResizeRedraw { - get { - throw new NotImplementedException (); - } - set { - throw new NotImplementedException (); - } + get { return GetStyle ( ControlStyles.ResizeRedraw ); } + set { SetStyle ( ControlStyles.ResizeRedraw, value ); } } //Compact Framework @@ -1035,23 +1048,25 @@ get { // CHECKME: if we really need to provide back current text of real window // or just our copy in text member. - if (IsHandleCreated) { - int len = Win32.GetWindowTextLengthA (Handle); - // FIXME: len is doubled due to some strange behaviour.(of GetWindowText function ?) - // instead of 10 characters we can get only 9, even if sb.Capacity is 10. - StringBuilder sb = new StringBuilder(len * 2 /*Win32.GetWindowTextLengthA (Handle)*/); + if ( IsHandleCreated ) { + int len = Win32.GetWindowTextLengthA (Handle); + // FIXME: len is doubled due to some strange behaviour.(of GetWindowText function ?) + // instead of 10 characters we can get only 9, even if sb.Capacity is 10. + StringBuilder sb = new StringBuilder(len * 2 /*Win32.GetWindowTextLengthA (Handle)*/); Win32.GetWindowText (Handle, sb, sb.Capacity); - return sb.ToString(); + text = sb.ToString(); } - else{ - return text; - } + return text; } set { - text = value; - - if (IsHandleCreated) - Win32.SetWindowTextA (Handle, value); + if ( text != value ) { + text = value; + + if (IsHandleCreated) + Win32.SetWindowTextA (Handle, value); + + OnTextChanged ( EventArgs.Empty ); + } } } @@ -1072,16 +1087,10 @@ } } - //Compact Framework public bool Visible { - get { - return visible; - } + get { return visible; } set { - visible = value; - if ( visible ) - Show(); - else Hide (); + SetVisibleCore ( value ); } } @@ -1111,12 +1120,13 @@ throw new NotImplementedException (); } - //Compact Framework [MonoTODO] public void BringToFront () { - //FIXME: - } + if ( IsHandleCreated ) + Win32.SetWindowPos ( Handle, SetWindowPosZOrder.HWND_TOP, 0, 0, 0, 0, + SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE ); + } public bool Contains (Control ctl) { @@ -1195,11 +1205,21 @@ } } - protected override void Dispose (bool disposing) + protected override void Dispose ( bool disposing ) { - statuses [ DISPOSED ] = true; - //FIXME: - base.Dispose(disposing); + lock ( this ) { + statuses [ DISPOSING ] = true; + try { + if ( disposing ) { + DestroyHandle ( ); + } + // close/free unmanaged resources + } + finally { + base.Dispose( disposing ); + } + statuses [ DISPOSED ] = true; + } } [MonoTODO] @@ -1258,13 +1278,82 @@ //{ // throw new NotImplementedException (); //} + + internal Control getNextFocusedControlCore ( Control parent, Control ctl, bool forward ) + { + while ( parent.Parent != null ) + parent = parent.Parent; + + Control next = parent.GetNextControl ( ctl, forward ); + while ( next != null ) { + if ( next.TabStop && next.CanFocus ) + return next; + next = parent.GetNextControl ( next, forward ); + } + return null; + } + + internal Control getNextFocusedControl ( Control parent, bool forward ) + { + Control next = getNextFocusedControlCore ( parent, FocusedControl, forward ); + if ( next == null ) + next = getNextFocusedControlCore ( parent, null, forward ); + return next; + } [MonoTODO] - public Control GetNextControl (Control ctl, bool forward) + public Control GetNextControl ( Control ctl, bool forward ) { - throw new NotImplementedException (); - } - + Control next = null; + + if ( ctl == null ) + next = Controls.GetFirstControl ( forward ); + else { + if ( forward ) + next = getNextControlForward ( ctl ); + else + next = getNextControlBackward ( ctl ); + } + return next; + } + + private Control getNextControlForward ( Control ctl ) + { + if ( ctl.Controls.Count != 0 ) + return ctl.Controls.GetFirstControl ( true ); + + Control parent = ctl.Parent; + if ( parent != null ) { + while ( parent != null ) { + Control next = parent.Controls.GetNextControl ( ctl, true ); + if ( next != null ) + return next; + ctl = parent; + parent = parent.Parent; + } + return null; + } + else + return Controls.GetFirstControl ( true ); + } + + private Control getNextControlBackward ( Control ctl ) + { + Control parent = ctl.Parent; + if ( parent != null ) { + Control next = parent.Controls.GetNextControl ( ctl, false ); + if ( next != null ) { + if ( next.Controls.Count > 0 ) + return next.Controls.GetFirstControl ( false ); + else + return next; + } + return parent; + } + else + return Controls.GetFirstControl ( false ); + } + [MonoTODO] protected bool GetStyle (ControlStyles flag) { @@ -1277,12 +1366,9 @@ throw new NotImplementedException (); } - //Compact Framework public void Hide () { - visible = false; - if (IsHandleCreated) - Win32.ShowWindow (Handle, ShowWindowStyles.SW_HIDE); + Visible = false; } [MonoTODO] @@ -1299,11 +1385,14 @@ } } - [MonoTODO] - public void Invalidate (bool invalidateChildren) + public void Invalidate ( bool invalidateChildren ) { - //FIXME: - } + Invalidate ( ) ; + if ( invalidateChildren ) { + foreach ( Control child in Controls ) + child.Invalidate ( invalidateChildren ); + } + } // tries to find appropriate owner for modal form internal static Control getOwnerWindow ( Control skip ) @@ -1388,19 +1477,21 @@ [MonoTODO] protected virtual bool IsInputChar (char charCode) { - throw new NotImplementedException (); + return true; } [MonoTODO] protected virtual bool IsInputKey (Keys keyData) { - throw new NotImplementedException (); + return false; } - [MonoTODO] - public static bool IsMnemonic (char charCode,string text) + public static bool IsMnemonic (char charCode, string text) { - throw new NotImplementedException (); + if ( text == null ) + return false; + return text.IndexOf ( "&" + charCode ) > 0; + } // methods used with events: @@ -1456,8 +1547,8 @@ { if ( Created ) { e.Control.CreateControl ( ); - e.Control.Visible = parent.Visible; } + e.Control.Visible = Visible; if (ControlAdded != null) ControlAdded (this, e); @@ -1491,7 +1582,10 @@ protected virtual void OnDockChanged (EventArgs e) { - PerformLayout ( this, "Dock" ); + // changing this property does not affect the control directly + // so have its parent to calculate new layout + if ( Parent != null ) + Parent.PerformLayout ( this, "Dock" ); if (DockChanged != null) DockChanged (this, e); } @@ -1645,7 +1739,6 @@ protected virtual void OnLocationChanged (EventArgs e) { - PerformLayout ( this, "Location" ); if (LocationChanged != null) LocationChanged (this, e); } @@ -1845,7 +1938,7 @@ if (Resize != null) Resize (this, e); - PerformLayout ( ); + PerformLayout ( this, "Bounds" ); } protected virtual void OnRightToLeftChanged (EventArgs e) @@ -1857,7 +1950,6 @@ protected virtual void OnSizeChanged (EventArgs e) { OnResize ( e ); - PerformLayout ( this, "Size" ); if (SizeChanged != null) SizeChanged (this, e); } @@ -1955,51 +2047,102 @@ [MonoTODO] public virtual bool PreProcessMessage (ref Message msg) { - throw new NotImplementedException (); + if ( msg.Msg == Msg.WM_KEYDOWN ) { + Keys keyData = (Keys)msg.WParam.ToInt32( ); + if ( !ProcessCmdKey ( ref msg, keyData ) ) { + if ( IsInputKey ( keyData ) ) + return false; + + return ProcessDialogKey ( keyData ); + } + return true; + } + else if ( msg.Msg == Msg.WM_CHAR ) { + if ( IsInputChar ( (char) msg.WParam ) ) + return false; + + return ProcessDialogChar ( (char) msg.WParam ); + } + + return false; } [MonoTODO] protected virtual bool ProcessCmdKey (ref Message msg, Keys keyData) { - throw new NotImplementedException (); + // do something with context menu + + if ( Parent != null ) + return Parent.ProcessCmdKey ( ref msg, keyData ); + return false; } [MonoTODO] protected virtual bool ProcessDialogChar (char charCode) { - throw new NotImplementedException (); + if ( Parent != null ) + return Parent.ProcessDialogChar ( charCode ); + return false; } [MonoTODO] protected virtual bool ProcessDialogKey (Keys keyData) { - throw new NotImplementedException (); + if ( Parent != null ) + return Parent.ProcessDialogKey ( keyData ); + return false; } [MonoTODO] protected virtual bool ProcessKeyEventArgs (ref Message m) { - throw new NotImplementedException (); + bool handled = false; + + switch ( m.Msg ) { + case Msg.WM_KEYDOWN: + KeyEventArgs args_down = new KeyEventArgs ( (Keys)m.WParam.ToInt32() ); + OnKeyDown ( args_down ); + handled = args_down.Handled; + break; + case Msg.WM_CHAR: + KeyPressEventArgs args_press = new KeyPressEventArgs ( (char) m.WParam ); + OnKeyPress ( args_press ); + handled = args_press.Handled; + break; + case Msg.WM_KEYUP: + KeyEventArgs args_up = new KeyEventArgs ( (Keys)m.WParam.ToInt32() ); + OnKeyUp ( args_up ); + handled = args_up.Handled; + break; + } + + return handled; } [MonoTODO] - protected internal virtual bool ProcessKeyMessage ( - ref Message m) + protected internal virtual bool ProcessKeyMessage ( ref Message m) { - throw new NotImplementedException (); + if ( Parent != null ) { + if ( !Parent.ProcessKeyPreview ( ref m ) ) + return ProcessKeyEventArgs ( ref m ); + } + return false; } [MonoTODO] protected virtual bool ProcessKeyPreview (ref Message m) { - throw new NotImplementedException (); + if ( Parent != null ) + return Parent.ProcessKeyPreview ( ref m ); + return false; } - [MonoTODO] + // This default implementation of the ProcessMnemonic method simply + // returns false to indicate that the control has no mnemonic. protected virtual bool ProcessMnemonic (char charCode) { - throw new NotImplementedException (); + return false; } // used when properties/values of Control @@ -2011,6 +2154,8 @@ DestroyHandle (); CreateHandle (); + UpdateZOrder ( ); + IEnumerator cw = childControls.GetEnumerator(); while ( cw.MoveNext() ) (( Control )cw.Current).RecreateHandle ( ); @@ -2295,17 +2440,28 @@ } [MonoTODO] - protected virtual void SetVisibleCore (bool value) + protected virtual void SetVisibleCore ( bool value ) { - //FIXME: + bool visibleChanged = ( visible != value ); + + visible = value; + + if ( visibleChanged ) + OnVisibleChanged ( EventArgs.Empty ); + + if ( IsHandleCreated ) { + SetWindowPosFlags flags = value ? SetWindowPosFlags.SWP_SHOWWINDOW : SetWindowPosFlags.SWP_HIDEWINDOW; + flags |= SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE; + Win32.SetWindowPos( Handle, 0, 0, 0, 0, 0, flags ); } + + foreach ( Control c in Controls ) + c.Visible = value ; + } - //Compact Framework public void Show () { - visible = true; - if (IsHandleCreated) - Win32.ShowWindow (Handle, ShowWindowStyles.SW_SHOW); + Visible = true; } public void SuspendLayout () @@ -2396,8 +2552,24 @@ [MonoTODO] protected void UpdateZOrder () { - //FIXME: + if ( !IsHandleCreated || Parent == null ) + return; + + int position = Parent.Controls.GetChildIndex ( this , false ); + switch ( position ) { + case 0: + BringToFront(); + break; + // not in collection for some reason + case -1: + break; + default: + Control prev = Parent.Controls [ position - 1 ]; + if ( prev.IsHandleCreated ) + Win32.SetWindowPos( Handle, prev.Handle, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE ); + break; } + } internal MouseEventArgs Msg2MouseEventArgs( ref Message msg) { @@ -2539,20 +2711,17 @@ CallControlWndProc(ref m); break; case Msg.WM_KEYDOWN: - // FIXME: - // OnKeyDown (eventArgs); - CallControlWndProc(ref m); - break; + if ( !ProcessKeyMessage ( ref m ) ) + CallControlWndProc( ref m ); + break; case Msg.WM_CHAR: - // FIXME: - // OnKeyPress (eventArgs); - CallControlWndProc(ref m); - break; + if ( !ProcessKeyMessage ( ref m ) ) + CallControlWndProc( ref m ); + break; case Msg.WM_KEYUP: - // FIXME: - OnKeyUp ( new KeyEventArgs ( (Keys)m.WParam.ToInt32() ) ); - CallControlWndProc(ref m); - break; + if ( !ProcessKeyMessage ( ref m ) ) + CallControlWndProc( ref m ); + break; case Msg.WM_KILLFOCUS: OnLeave (eventArgs); OnLostFocus (eventArgs); @@ -2640,8 +2809,6 @@ } break; case Msg.WM_SIZE: - OnResize (eventArgs); - UpdateBounds ( ); if( GetStyle(ControlStyles.ResizeRedraw)) { Invalidate(); } @@ -2660,7 +2827,7 @@ CallControlWndProc(ref m); break; case Msg.WM_SETTEXT: - OnTextChanged (eventArgs); + //OnTextChanged (eventArgs); CallControlWndProc(ref m); break; case Msg.WM_SETFONT: @@ -2688,6 +2855,21 @@ CallControlWndProc(ref m); } break; + case Msg.WM_SETCURSOR: + if ( cursor != null && cursor.Handle != IntPtr.Zero ) { + Win32.SetCursor ( cursor.Handle ); + m.Result = (IntPtr)1; + } else + CallControlWndProc( ref m ); + break; + case Msg.WM_RBUTTONDOWN: + if ( contextMenu != null ) { + contextMenu.Show ( this, + new Point ( Win32.HIGH_ORDER ( m.LParam.ToInt32() ), + Win32.LOW_ORDER ( m.LParam.ToInt32() ) ) ); + } + CallControlWndProc( ref m ); + break; default: CallControlWndProc(ref m); /* @@ -2702,6 +2884,37 @@ } } + private void DoAnchor(Control ctrl) { + int deltaWidth = Bounds.Width - oldBounds.Width; + int deltaHeight = Bounds.Height - oldBounds.Height; + int halfDeltaWidth = deltaWidth / 2; + int halfDeltaHeight = deltaHeight / 2; + Rectangle controlBounds = ctrl.Bounds; + if ((ctrl.Anchor & AnchorStyles.Left) == 0) { + controlBounds.X += halfDeltaWidth; + } + if ((ctrl.Anchor & AnchorStyles.Top) == 0) { + controlBounds.Y += halfDeltaHeight; + } + if ((ctrl.Anchor & AnchorStyles.Right) == AnchorStyles.Right) { + if ((ctrl.Anchor & AnchorStyles.Left) == AnchorStyles.Left) { + controlBounds.Width += deltaWidth; + } + else { + controlBounds.X += halfDeltaWidth; + } + } + if ((ctrl.Anchor & AnchorStyles.Bottom) == AnchorStyles.Bottom) { + if ((ctrl.Anchor & AnchorStyles.Top) == AnchorStyles.Top) { + controlBounds.Height += deltaHeight; + } + else { + controlBounds.Y += halfDeltaHeight; + } + } + ctrl.Bounds = controlBounds; + } + private void DoDockAndAnchorLayout ( LayoutEventArgs e ) { Rectangle area = DisplayRectangle; @@ -2729,6 +2942,9 @@ area.X += control.Width; area.Width -= control.Width; break; + case DockStyle.None: + DoAnchor(control); + break; } } @@ -2741,6 +2957,31 @@ } } + internal static Control FocusedControl { + get { + IEnumerator cw = controlsCollection.GetEnumerator ( ); + + while ( cw.MoveNext ( ) ) { + Control c = ( (DictionaryEntry) cw.Current).Value as Control; + + if ( c.Focused ) return c; + } + + return null; + } + } + + internal Control getParentForm ( ) + { + Control parent = this.Parent; + while ( parent != null ) { + if ( parent is Form ) + return parent; + parent = parent.Parent; + } + return null; + } + /// --- Control: events --- public event EventHandler BackColorChanged; public event EventHandler BackgroundImageChanged; @@ -3033,7 +3274,7 @@ { //FIXME: return base.ToString(); - } + } } /// sub-class: Control.ControlCollection @@ -3042,6 +3283,22 @@ /// public class ControlCollection : IList, ICollection, IEnumerable, ICloneable { + class ControlComparer : IComparer { + + int IComparer.Compare( object x, object y ) + { + int tx = ( ( Control )x ).TabIndex; + int ty = ( ( Control )y ).TabIndex; + + if ( tx > ty ) + return 1; + else if ( tx < ty ) + return -1; + else + return 0; + } + } + private ArrayList collection = new ArrayList (); protected Control owner; @@ -3106,14 +3363,21 @@ { //FIXME: return base.Equals(obj); - } + } + + public int GetChildIndex ( Control child ) + { + return GetChildIndex ( child, true ); + } + + public int GetChildIndex ( Control child, bool throwException ) + { + int index = collection.IndexOf ( child ); + if ( index == -1 && throwException ) + throw new ArgumentException( "'child' is not a child control of this parent."); + return index; + } - [MonoTODO] - public int GetChildIndex (Control child) - { - throw new NotImplementedException (); - } - public IEnumerator GetEnumerator () { return collection.GetEnumerator (); @@ -3122,9 +3386,9 @@ [MonoTODO] public override int GetHashCode () { - //FIXME: - return base.GetHashCode(); - } + //FIXME: + return base.GetHashCode(); + } public int IndexOf (Control control) { @@ -3143,12 +3407,58 @@ //collection.RemoveAt (index); } - [MonoTODO] - public void SetChildIndex (Control child,int newIndex) + public void SetChildIndex ( Control child, int newIndex ) { - //FIXME: + int oldIndex = collection.IndexOf ( child ); + if ( oldIndex == -1 ) + throw new ArgumentException( "'child' is not a child control of this parent."); + + if ( oldIndex != newIndex ) { + collection.Remove ( child ); + + if ( newIndex >= collection.Count ) + collection.Add ( child ); + else + collection.Insert ( newIndex, child ); + } } - + + internal Control GetFirstControl ( bool direction ) + { + if ( collection.Count == 0 ) + return null; + + ArrayList copy = collection.Clone ( ) as ArrayList; + copy.Sort ( new ControlComparer ( ) ); + + if ( direction ) + return copy [0] as Control; + else { + Control last = copy[ collection.Count - 1 ] as Control; + if ( last.Controls.Count == 0 ) + return last; + else + return last.Controls.GetFirstControl ( false ); + } + } + + + internal Control GetNextControl ( Control ctl, bool forward ) + { + if ( collection.Count == 0 ) + return null; + + ArrayList copy = collection.Clone ( ) as ArrayList; + copy.Sort ( new ControlComparer ( ) ); + + int index = copy.IndexOf ( ctl ) + ( forward ? 1 : -1 ); + + if ( ( forward && index < copy.Count ) || ( !forward && index >= 0 ) ) + return copy[index] as Control; + + return null; + } + /// --- ControlCollection.IClonable methods --- [MonoTODO] object ICloneable.Clone () @@ -3211,4 +3521,4 @@ } } // --- end of Control.ControlCollection --- } - } + } \ No newline at end of file