2 // System.Windows.Forms.Control.cs
5 // stubbed out by Jaak Simm (jaaksimm@firm.ee)
6 // Dennis Hayes (dennish@rayetk.com)
7 // WINELib implementation started by John Sohn (jsohn@columbus.rr.com)
8 // Alexandre Pigolkine (pigolkine@gmx.de)
9 // Aleksey Ryabchuk (ryabchuk@yahoo.com)
11 // (C) Ximian, Inc., 2002
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System
.ComponentModel
;
37 using System
.Collections
;
38 using System
.Threading
;
40 using System
.Runtime
.InteropServices
;
41 using System
.Collections
.Specialized
;
43 namespace System
.Windows
.Forms
45 public class Control
: Component
, ISynchronizeInvoke
, IWin32Window
,
46 UnsafeNativeMethods
.IOleControl
, UnsafeNativeMethods
.IOleObject
, UnsafeNativeMethods
.IOleInPlaceObject
,
47 UnsafeNativeMethods
.IOleInPlaceActiveObject
, UnsafeNativeMethods
.IOleWindow
, UnsafeNativeMethods
.IViewObject
,
48 UnsafeNativeMethods
.IViewObject2
, UnsafeNativeMethods
.IPersist
, UnsafeNativeMethods
.IPersistStreamInit
,
49 UnsafeNativeMethods
.IPersistPropertyBag
, UnsafeNativeMethods
.IPersistStorage
, UnsafeNativeMethods
.IQuickActivate
52 // Helper NativeWindow class to dispatch messages back
53 // to the Control class
55 internal class ControlNativeWindow
: NativeWindow
{
57 private Control control
;
59 public ControlNativeWindow (Control control
) : base ()
61 this.control
= control
;
64 protected override void WndProc (ref Message m
)
66 //Console.WriteLine ("Control WndProc Message HWnd {0}, Msg {1}", m.HWnd, m.Msg);
67 // Do not call default WndProc here
68 // let the control decide what to do
69 // base.WndProc (ref m);
70 //Console.WriteLine ("Control WndProc {0}", control.GetType().ToString());
72 if (m
.Msg
==(int) Msg
.WM_DRAWITEM
) {
76 control
.WndProc (ref m
);
78 control
.WndProc (ref m
);
82 // FIXME: not sure if dervied classes should have access
83 internal ControlNativeWindow window
;
84 private ControlCollection childControls
;
85 private Control parent
;
86 static private Hashtable controlsCollection
= new Hashtable ();
87 static private NativeWindow parkingWindow
= null;
88 private static bool classRegistered
= false;
93 // it seems these are stored in case the window is not created,
94 // corresponding properties (below) need to check if window
95 // is created or not and react accordingly
97 string accessibleDefaultActionDescription
;
98 string accessibleDescription
;
99 string accessibleName
;
100 AccessibleRole accessibleRole
;
103 internal Color backColor
;
104 Image backgroundImage
;
105 //BindingContext bindingContext;
109 bool causesValidation
;
110 ContextMenu contextMenu
;
114 internal Color foreColor
;
117 // Point location; // using bounds to store location
120 RightToLeft rightToLeft
;
122 internal string text
;
123 internal bool visible
;
124 internal ControlStyles controlStyles_
;
130 BitVector32 statuses
;
131 private static readonly int LAYOUT_SUSPENDED
= BitVector32
.CreateMask ();
132 private static readonly int LAYOUT_PENDING
= BitVector32
.CreateMask (LAYOUT_SUSPENDED
);
133 private static readonly int DISPOSED
= BitVector32
.CreateMask (LAYOUT_PENDING
);
134 private static readonly int RECREATING_HANDLE
= BitVector32
.CreateMask (DISPOSED
);
135 private static readonly int CREATED
= BitVector32
.CreateMask (RECREATING_HANDLE
);
136 private static readonly int DISPOSING
= BitVector32
.CreateMask (CREATED
);
137 private static readonly int TOPLEVEL
= BitVector32
.CreateMask (DISPOSING
);
139 internal enum CallWinControlProcMask
: uint {
140 MOUSE_MESSAGES
= 0x0001,
141 KEYBOARD_MESSAGES
= 0x0002
143 internal CallWinControlProcMask callWinControlProcMask
;
146 internal bool mouseIsInside_
;
148 // BeginInvoke () etc. helpers
149 static int InvokeMessage
= Win32
.RegisterWindowMessage ("mono_control_invoke_helper");
151 // CHECKME: This variable is used to determine whether current thread
152 // was used to create Control Handle. It take some space but saves a call
153 // to unmanaged code in ISynchronizeInvoke.IsInvokeRequired.
154 private int CreatorThreadId_
= 0;
156 private Queue InvokeQueue_
= new Queue ();
158 internal class ControlInvokeHelper
: IAsyncResult
{
159 private Delegate Method_
= null;
160 private object[] MethodArgs_
= null;
161 private object MethodResult_
= null;
162 private ManualResetEvent AsyncWaitHandle_
= new ManualResetEvent (false);
163 private bool CompletedSynchronously_
= false;
164 private bool IsCompleted_
= false;
166 public ControlInvokeHelper (Delegate method
, object[] args
) {
171 // IAsyncResult interface
172 object IAsyncResult
.AsyncState
{
174 if (MethodArgs_
!= null && MethodArgs_
.Length
!= 0)
175 return MethodArgs_
[MethodArgs_
.Length
- 1];
181 WaitHandle IAsyncResult
.AsyncWaitHandle
{
183 return AsyncWaitHandle_
;
187 bool IAsyncResult
.CompletedSynchronously
{
189 return CompletedSynchronously_
;
193 bool IAsyncResult
.IsCompleted
{
199 internal bool CompletedSynchronously
{
201 CompletedSynchronously_
= value;
205 internal object MethodResult
{
207 return MethodResult_
;
211 internal void ExecuteMethod () {
212 object result
= Method_
.DynamicInvoke (MethodArgs_
);
214 MethodResult_
= result
;
217 AsyncWaitHandle_
.Set ();
221 // --- Constructors ---
223 //Compact Framework //only Control ()
226 childControls
= CreateControlsInstance ();
228 statuses
= new BitVector32 ();
229 callWinControlProcMask
= CallWinControlProcMask
.MOUSE_MESSAGES
| CallWinControlProcMask
.KEYBOARD_MESSAGES
;
231 accessibleDefaultActionDescription
= null;
232 accessibleDescription
= null;
233 accessibleName
= null;
234 accessibleRole
= AccessibleRole
.Default
;
236 anchor
= AnchorStyles
.Top
| AnchorStyles
.Left
;
237 backColor
= Control
.DefaultBackColor
;
238 backgroundImage
= null;
239 bounds
= new Rectangle ();
240 oldBounds
= new Rectangle ();
241 // bindingContext = null;
242 causesValidation
= true;
244 dock
= DockStyle
.None
;
246 font
= Control
.DefaultFont
;
247 foreColor
= Control
.DefaultForeColor
;
248 imeMode
= ImeMode
.Inherit
;
249 isAccessible
= false;
250 // location = new Point (0,0); should be from OS
253 rightToLeft
= RightToLeft
.Inherit
;
260 oldBounds
.Width
= bounds
.Width
= DefaultSize
.Width
;
261 oldBounds
.Height
= bounds
.Height
= DefaultSize
.Height
;
262 clientWidth
= DefaultSize
.Width
;
263 clientHeight
= DefaultSize
.Height
;
265 mouseIsInside_
= false;
266 controlStyles_
= ControlStyles
.Selectable
| ControlStyles
.StandardClick
| ControlStyles
.StandardDoubleClick
;
267 // Do not create Handle here, only in CreateHandle
268 // CreateHandle ();//sets window handle. FIXME: No it does not
271 // according to docs, the constructors do not create
273 public Control (string text
) : this ()
276 // SetWindowTextA (Handle, text);
279 public Control (Control parent
, string text
) : this (text
)
282 // SetParent (Handle, parent.Handle);
285 public Control (string text
, int left
, int top
,
286 int width
, int height
) : this (text
)
292 //SetWindowPos (Handle, (IntPtr) 0, left, top,
293 // width, height, 0);
296 public Control (Control parent
,string text
,int left
, int top
,
297 int width
,int height
) : this (parent
, text
)
303 // SetWindowPos (Handle, (IntPtr) 0, left, top,
304 // width, height, 0);
307 // for internal use only, create a control class
308 // for an existing, created HWND
309 private Control (IntPtr existingHandle
)
311 window
= (ControlNativeWindow
) NativeWindow
.FromHandle (
315 // --- Properties ---
316 // Properties only supporting .NET framework, not stubbed out:
317 protected bool RenderRightToLeft
{
319 throw new NotImplementedException ();
322 public IWindowTarget WindowTarget
{
324 throw new NotImplementedException ();
330 public AccessibleObject AccessibilityObject
{
332 throw new NotImplementedException ();
336 public string AccessibleDefaultActionDescription
{
338 return accessibleDefaultActionDescription
;
341 accessibleDefaultActionDescription
= value;
345 public string AccessibleDescription
{
347 return accessibleDescription
;
350 accessibleDescription
=value;
354 public string AccessibleName
{
356 return accessibleName
;
359 accessibleName
=value;
363 public AccessibleRole AccessibleRole
{
365 return accessibleRole
;
368 accessibleRole
=value;
372 public virtual bool AllowDrop
{
381 public virtual AnchorStyles Anchor
{
386 if (anchor
!= value){
388 if (anchor
!= (AnchorStyles
.Left
| AnchorStyles
.Top
))
389 Dock
= DockStyle
.None
;
395 public virtual Color BackColor
{
400 if (backColor
!= value) {
402 OnBackColorChanged (new EventArgs ());
407 public virtual Image BackgroundImage
{
409 return backgroundImage
;
412 backgroundImage
= value;
413 // FIXME: force redraw
418 public virtual BindingContext BindingContext
{
420 //return bindingContext;
421 throw new NotImplementedException ();
424 //bindingContext=value;
425 throw new NotImplementedException ();
437 public Rectangle Bounds
{
442 SetBounds (value.Left
, value.Top
, value.Width
, value.Height
);
446 public bool CanFocus
{
448 if (IsHandleCreated
&& Visible
&& Enabled
)
455 public bool CanSelect
{
457 if (!GetStyle (ControlStyles
.Selectable
))
463 Control parent
= Parent
;
464 while (parent
!= null){
465 if (!parent
.Visible
|| !parent
.Enabled
)
467 parent
= parent
.Parent
;
475 public bool Capture
{
477 if (IsHandleCreated
) {
478 IntPtr captured
= Win32
.GetCapture ();
479 if (Handle
== captured
)
485 if (IsHandleCreated
) {
487 Win32
.SetCapture (Handle
);
489 IntPtr captured
= Win32
.GetCapture ();
491 // if this window is in capture state
493 if (Handle
== captured
)
494 Win32
.ReleaseCapture ();
500 public bool CausesValidation
{
502 return causesValidation
;
505 causesValidation
=value;
510 public Rectangle ClientRectangle
{
512 return new Rectangle (0, 0, ClientSize
.Width
, ClientSize
.Height
);
519 public Size ClientSize
{
521 return new Size (clientWidth
, clientHeight
);
524 SetClientSizeCore (value.Width
, value.Height
);
529 public string CompanyName
{
531 //Better than throwing an execption
532 return "Company Name";
536 public bool ContainsFocus
{
538 if (IsHandleCreated
) {
539 if (Focused
) return true;
540 foreach (Control ctr
in Controls
) {
541 if (ctr
.ContainsFocus
) return true;
550 public virtual ContextMenu ContextMenu
{
555 if (contextMenu
!= value){
557 OnContextMenuChanged (EventArgs
.Empty
);
562 public ControlCollection Controls
{
563 get { return childControls; }
566 public bool Created
{
567 get { return statuses[ CREATED ]; }
570 protected virtual CreateParams CreateParams
{
572 CreateParams createParams
= new CreateParams ();
573 createParams
.Caption
= Text
;
574 createParams
.X
= Left
;
575 createParams
.Y
= Top
;
576 createParams
.Width
= Width
;
577 createParams
.Height
= Height
;
578 createParams
.ClassStyle
= 0;
579 createParams
.ExStyle
= 0;
580 createParams
.Param
= 0;
583 createParams
.Parent
= parent
.Handle
;
585 createParams
.Parent
= ParkingWindowHandle
;
587 createParams
.Style
= (int) WindowStyles
.WS_OVERLAPPED
;
589 createParams
.Style
|= (int) WindowStyles
.WS_VISIBLE
;
596 internal protected IntPtr ControlRealWndProc
= IntPtr
.Zero
;
597 internal protected bool SubClassWndProc_
= false;
599 // This function lets Windows or/and default Windows control process message
600 // Classes have to call it if they do not handle message in WndProc or
601 // default handling is needed.
602 protected internal void CallControlWndProc (ref Message msg
) {
603 if (ControlRealWndProc
!= IntPtr
.Zero
) {
604 bool callControlProc
= true;
605 if ((callWinControlProcMask
& CallWinControlProcMask
.MOUSE_MESSAGES
) == 0 && msg
.IsMouseMessage
) {
606 callControlProc
= false;
608 if ((callWinControlProcMask
& CallWinControlProcMask
.KEYBOARD_MESSAGES
) == 0 && msg
.IsKeyboardMessage
) {
609 callControlProc
= false;
611 if (callControlProc
) {
612 //Console.WriteLine ("CallControl {0}", msg.Msg);
613 msg
.Result
= (IntPtr
)Win32
.CallWindowProc (ControlRealWndProc
, msg
.HWnd
, (int)msg
.Msg
, msg
.WParam
.ToInt32 (), msg
.LParam
.ToInt32 ());
617 DefWndProc (ref msg
);
621 // Subclass only native Windows controls. Those classes have to set SubClassWndProc_ to true in contructor
622 private void SubclassWindow () {
623 if (IsHandleCreated
&& SubClassWndProc_
) {
624 ControlRealWndProc
= Win32
.SetWindowLong (Handle
, GetWindowLongFlag
.GWL_WNDPROC
, NativeWindow
.GetWindowProc ());
628 private void UnsubclassWindow () {
629 if (IsHandleCreated
) {
630 Win32
.SetWindowLong (Handle
, GetWindowLongFlag
.GWL_WNDPROC
, ControlRealWndProc
.ToInt32 ());
634 protected internal virtual void OnWmCommand (ref Message m
) {
635 if (m
.LParam
.ToInt32 () != 0) {
636 if (m
.LParam
!= Handle
) {
637 // Control notification
638 //System.Console.WriteLine ("Control notification Code {0} Id = Hwnd {1}", m.HiWordWParam, m.LParam.ToInt32 ());
639 Control
.ReflectMessage (m
.LParam
, ref m
);
642 // Unhandled Control reflection
643 // Derived class didn't handle WM_COMMAND or called base.WndProc in WM_COMMAND handler
644 // CHECKME: Shall we notify user in debug build, throw an exception or just ignore this case ?
650 public virtual Cursor Cursor
{
653 return Cursors
.Default
;
656 set { cursor = value;}
661 // waiting for BindingContext; should be stubbed now
662 public ControlBindingsCollection DataBindings
{
664 throw new NotImplementedException ();
668 public static Color DefaultBackColor
{
670 // FIXME: use GetSystemMetrics?
671 return SystemColors
.Control
;
672 //throw new NotImplementedException ();
677 // FIXME: use GetSystemMetrics?
678 public static Font DefaultFont
{
679 // FIXME: get current system font from GenericSansSerif
680 // call ArgumentException not called
682 // throw new NotImplementedException ();
683 // return (FontFamily.GenericSansSerif);
684 return Font
.FromHfont (Win32
.GetStockObject (GSO_
.DEFAULT_GUI_FONT
));
688 public static Color DefaultForeColor
{
690 return SystemColors
.ControlText
;
694 protected virtual ImeMode DefaultImeMode
{
696 return ImeMode
.Inherit
;
700 protected virtual Size DefaultSize
{
702 //Default label size, this should be correct.
703 return new Size (100,23);
707 public virtual Rectangle DisplayRectangle
{
709 return ClientRectangle
;
713 public bool Disposing
{
714 get { return statuses [ DISPOSING ]; }
717 public virtual DockStyle Dock
{
724 if (dock
!= DockStyle
.None
)
725 Anchor
= (AnchorStyles
.Left
| AnchorStyles
.Top
);
726 OnDockChanged (EventArgs
.Empty
);
732 //public virtual bool Enabled {
733 public bool Enabled
{
736 //return Win32.IsWindowEnabled (Handle);
739 if (enabled
!= value) {
740 if (IsHandleCreated
) {
741 Win32
.EnableWindow (Handle
, value);
742 // FIXME: Disable/enable all children here
751 public virtual bool Focused
{
753 if (IsHandleCreated
) {
754 IntPtr focusedWindow
= Win32
.GetFocus ();
755 if (focusedWindow
== Handle
)
763 public virtual Font Font
{
766 if (result
== null) {
767 if (Parent
!= null) {
768 result
= Parent
.Font
;
770 if (result
== null) {
771 result
= Control
.DefaultFont
;
778 if (IsHandleCreated
) {
779 Win32
.SendMessage (Handle
, Msg
.WM_SETFONT
, Font
.ToHfont ().ToInt32 (), 1);
785 protected int FontHeight
{
787 throw new NotImplementedException ();
790 throw new NotImplementedException ();
795 public virtual Color ForeColor
{
804 public bool HasChildren
{
806 if (childControls
.Count
>0)
815 return bounds
.Height
;
818 SetBounds (bounds
.X
, bounds
.Y
, bounds
.Width
, value, BoundsSpecified
.Height
);
822 public ImeMode ImeMode
{
832 public bool IsAccessible
{
836 } // default is false
842 public bool IsDisposed
{
843 get { return statuses [ DISPOSED ]; }
846 public bool IsHandleCreated
{
847 get { return window != null && window.Handle != IntPtr.Zero; }
856 SetBounds (value, bounds
.Y
, bounds
.Width
, bounds
.Height
, BoundsSpecified
.X
);
861 public Point Location
{
864 return new Point (Top
, Left
);
867 SetBounds (value.X
, value.Y
, bounds
.Width
, bounds
.Height
, BoundsSpecified
.Location
);
871 public static Keys ModifierKeys
{
873 Keys keys
= Keys
.None
;
875 if ( (Win32
.GetKeyState ( (int) VirtualKeys
.VK_SHIFT
)& 0x8000)== 0x8000)
877 if ( (Win32
.GetKeyState ( (int) VirtualKeys
.VK_MENU
)& 0x8000) == 0x8000)
879 if ( (Win32
.GetKeyState ( (int) VirtualKeys
.VK_CONTROL
) & 0x8000) == 0x8000)
880 keys
|= Keys
.Control
;
887 public static MouseButtons MouseButtons
{
889 MouseButtons buttons
= MouseButtons
.None
;
891 if ( (Win32
.GetAsyncKeyState ( (int) VirtualKeys
.VK_LBUTTON
) & 0x8000)== 0x8000)
892 buttons
|= SystemInformation
.MouseButtonsSwapped
? MouseButtons
.Right
: MouseButtons
.Left
;
893 if ( (Win32
.GetAsyncKeyState ( (int) VirtualKeys
.VK_RBUTTON
) & 0x8000)== 0x8000)
894 buttons
|= SystemInformation
.MouseButtonsSwapped
? MouseButtons
.Left
: MouseButtons
.Right
;
896 if ( (Win32
.GetAsyncKeyState ( (int) VirtualKeys
.VK_MBUTTON
) & 0x8000)== 0x8000)
897 buttons
|= MouseButtons
.Middle
;
898 if ( (Win32
.GetAsyncKeyState ( (int) VirtualKeys
.VK_XBUTTON1
) & 0x8000)== 0x8000)
899 buttons
|= MouseButtons
.XButton1
;
900 if ( (Win32
.GetAsyncKeyState ( (int) VirtualKeys
.VK_XBUTTON2
) & 0x8000)== 0x8000)
901 buttons
|= MouseButtons
.XButton2
;
908 public static Point MousePosition
{
910 POINT point
= new POINT ();
911 Win32
.GetCursorPos (ref point
);
912 return new Point ( (int) point
.x
, (int) point
.y
);
927 public Control Parent
{
930 //IntPtr parent = GetParent (Handle);
931 //return FromHandle (parent);
934 if (parent
!= value) {
937 // add ourself to the parents control
938 if (!parent
.Controls
.Contains (this))
939 parent
.Controls
.Add (this);
941 // FIXME: Is this logic correct ?
942 if (BackColor
== DefaultBackColor
) {
943 if (parent
.BackColor
!= BackColor
)
944 OnParentBackColorChanged (new EventArgs ());
947 if (IsHandleCreated
) {
948 Win32
.SetParent (Handle
, value.Handle
);
951 else if (parent.IsHandleCreated){
952 // CHECKME: Now control is responsible for creating his window
953 // when added to Form, may be things must be reversed.
961 protected internal static IntPtr ParkingWindowHandle
{
963 if (parkingWindow
== null)
964 parkingWindow
= new NativeWindow ();
966 if (parkingWindow
.Handle
== IntPtr
.Zero
){
967 CreateParams pars
= new CreateParams ();
968 pars
.ClassName
= "mono_native_window";
969 pars
.Style
= (int) WindowStyles
.WS_OVERLAPPED
;
970 parkingWindow
.CreateHandle (pars
);
973 return parkingWindow
.Handle
;
977 protected internal static void RegisterDefaultWindowClass ()
979 if (!classRegistered
){
980 WNDCLASS wndClass
= new WNDCLASS ();
982 wndClass
.style
= (int) (CS_
.CS_OWNDC
);
983 wndClass
.lpfnWndProc
= NativeWindow
.GetWindowProc ();
984 wndClass
.cbClsExtra
= 0;
985 wndClass
.cbWndExtra
= 0;
986 wndClass
.hInstance
= (IntPtr
)0;
987 wndClass
.hIcon
= (IntPtr
)0;
988 wndClass
.hCursor
= Win32
.LoadCursor ( (IntPtr
)0, LC_
.IDC_ARROW
);
989 wndClass
.hbrBackground
= (IntPtr
) ( (int)GetSysColorIndex
.COLOR_BTNFACE
+ 1);
990 wndClass
.lpszMenuName
= "";
991 wndClass
.lpszClassName
= Win32
.DEFAULT_WINDOW_CLASS
;
993 if (Win32
.RegisterClass (ref wndClass
) != 0)
994 classRegistered
= true;
999 public string ProductName
{
1002 return "Product Name";
1007 public string ProductVersion
{
1010 return "Product Version";
1015 public bool RecreatingHandle
{
1017 return statuses
[ RECREATING_HANDLE
] ;
1021 public Region Region
{
1031 protected bool ResizeRedraw
{
1032 get { return GetStyle (ControlStyles.ResizeRedraw); }
1033 set { SetStyle (ControlStyles.ResizeRedraw, value); }
1039 return Left
+ Width
;
1044 public virtual RightToLeft RightToLeft
{
1055 protected virtual bool ShowFocusCues
{
1057 throw new NotImplementedException ();
1062 protected bool ShowKeyboardCues
{
1064 throw new NotImplementedException ();
1069 public override ISite Site
{
1071 throw new NotImplementedException ();
1074 throw new NotImplementedException ();
1081 return new Size (Width
, Height
);
1084 SetBounds (bounds
.X
, bounds
.Y
, value.Width
, value.Height
, BoundsSpecified
.Size
);
1088 internal int tabindex
;//for debug/test only. remove
1090 public int TabIndex
{
1099 public bool TabStop
{
1120 public virtual string Text
{
1122 if (!GetStyle(ControlStyles
.CacheText
) && IsHandleCreated
){
1123 int len
= Win32
.GetWindowTextLengthA(Handle
);
1124 StringBuilder sb
= new StringBuilder(len
+1);
1125 Win32
.GetWindowTextA(Handle
, sb
, sb
.Capacity
);
1126 text
= sb
.ToString ();
1131 /* We must update text first, it might have been changed
1132 in the UI by the user */
1133 if (!GetStyle(ControlStyles
.CacheText
) && IsHandleCreated
){
1134 int len
= Win32
.GetWindowTextLengthA(Handle
);
1135 StringBuilder sb
= new StringBuilder(len
+1);
1136 Win32
.GetWindowTextA(Handle
, sb
, sb
.Capacity
);
1137 text
= sb
.ToString ();
1143 if (IsHandleCreated
)
1144 Win32
.SetWindowTextA (Handle
, value);
1146 OnTextChanged (EventArgs
.Empty
);
1157 SetBounds (bounds
.X
, value, bounds
.Width
, bounds
.Height
, BoundsSpecified
.Y
);
1162 public Control TopLevelControl
{
1164 throw new NotImplementedException ();
1168 public bool Visible
{
1169 get { return visible; }
1171 SetVisibleCore (value);
1178 return bounds
.Width
;
1181 SetBounds (bounds
.X
, bounds
.Y
, value, bounds
.Height
, BoundsSpecified
.Width
);
1186 /// internal .NET framework supporting methods, not stubbed out:
1187 protected virtual void NotifyInvalidate (Rectangle invalidatedArea
)
1191 protected void RaiseDragEvent (object key
,DragEventArgs e
)
1195 protected void RaiseKeyEvent (object key
,KeyEventArgs e
)
1199 protected void RaiseMouseEvent (object key
,MouseEventArgs e
)
1203 protected void RaisePaintEvent (object key
,PaintEventArgs e
)
1207 protected void ResetMouseEventArgs ()
1212 protected void AccessibilityNotifyClients (
1213 AccessibleEvents accEvent
,int childID
)
1215 throw new NotImplementedException ();
1219 public void BringToFront ()
1221 if (IsHandleCreated
)
1222 Win32
.SetWindowPos (Handle
, SetWindowPosZOrder
.HWND_TOP
, 0, 0, 0, 0,
1223 SetWindowPosFlags
.SWP_NOMOVE
| SetWindowPosFlags
.SWP_NOSIZE
);
1226 public bool Contains (Control ctl
)
1228 return childControls
.Contains (ctl
);
1231 public void CreateControl ()
1236 statuses
[ CREATED
] = true;
1241 protected virtual AccessibleObject
CreateAccessibilityInstance () {
1242 throw new NotImplementedException ();
1245 protected virtual ControlCollection
CreateControlsInstance ()
1247 return new ControlCollection (this);
1252 public Graphics
CreateGraphics ()
1254 return Graphics
.FromHwnd (Handle
);
1257 protected virtual void CreateHandle ()
1260 throw new ObjectDisposedException (Name
);
1262 if (IsHandleCreated
)
1266 window
= new ControlNativeWindow (this);
1268 CreateParams createParams
= CreateParams
;
1270 createParams
.Style
|= (int)WindowStyles
.WS_DISABLED
;
1272 window
.CreateHandle (createParams
);
1274 if (window
.Handle
!= IntPtr
.Zero
) {
1275 if (!controlsCollection
.Contains (window
.Handle
))
1276 controlsCollection
.Add (window
.Handle
, this);
1280 CreatorThreadId_
= Win32
.GetCurrentThreadId ();
1282 OnHandleCreated (EventArgs
.Empty
);
1286 protected virtual void DefWndProc (ref Message m
)
1288 window
.DefWndProc (ref m
);
1291 protected virtual void DestroyHandle ()
1293 if (IsHandleCreated
){
1294 if (Handle
!= IntPtr
.Zero
) {
1295 controlsCollection
.Remove (Handle
);
1297 if (window
!= null) {
1298 window
.DestroyHandle ();
1303 protected override void Dispose (bool disposing
)
1306 statuses
[ DISPOSING
] = true;
1311 // close/free unmanaged resources
1314 base.Dispose (disposing
);
1316 statuses
[ DISPOSED
] = true;
1321 public DragDropEffects
DoDragDrop (
1322 object data
, DragDropEffects allowedEffects
)
1324 throw new NotImplementedException ();
1327 //public object EndInvoke (IAsyncResult asyncResult):
1328 //look under ISynchronizeInvoke methods
1331 public Form
FindForm ()
1333 throw new NotImplementedException ();
1337 public bool Focus ()
1339 if (Win32
.SetFocus (Handle
) != (IntPtr
) 0)
1345 public static Control
FromChildHandle (IntPtr handle
)
1347 Control control
= null;
1348 IntPtr controlHwnd
= handle
;
1349 while (controlHwnd
!= IntPtr
.Zero
) {
1350 control
= controlsCollection
[controlHwnd
] as Control
;
1351 if (control
!= null) break;
1352 controlHwnd
= Win32
.GetParent (controlHwnd
);
1357 public static Control
FromHandle (IntPtr handle
)
1359 // FIXME: Here we have to check, whether control already exists
1360 //Control control = new Control (handle);
1361 Control control
= controlsCollection
[handle
] as Control
;
1366 public Control
GetChildAtPoint (Point pt
)
1368 throw new NotImplementedException ();
1372 public IContainerControl
GetContainerControl ()
1374 throw new NotImplementedException ();
1377 internal Control
getNextFocusedControlCore (Control parent
, Control ctl
, bool forward
)
1379 while (parent
.Parent
!= null)
1380 parent
= parent
.Parent
;
1382 Control next
= parent
.GetNextControl (ctl
, forward
);
1383 while (next
!= null){
1384 if (next
.TabStop
&& next
.CanFocus
)
1386 next
= parent
.GetNextControl (next
, forward
);
1391 internal Control
getNextFocusedControl (Control parent
, bool forward
)
1393 Control next
= getNextFocusedControlCore (parent
, FocusedControl
, forward
);
1395 next
= getNextFocusedControlCore (parent
, null, forward
);
1400 public Control
GetNextControl (Control ctl
, bool forward
)
1402 Control next
= null;
1405 next
= Controls
.GetFirstControl (forward
);
1408 next
= getNextControlForward (ctl
);
1410 next
= getNextControlBackward (ctl
);
1415 private Control
getNextControlForward (Control ctl
)
1417 if (ctl
.Controls
.Count
!= 0)
1418 return ctl
.Controls
.GetFirstControl (true);
1420 Control parent
= ctl
.Parent
;
1421 if (parent
!= null){
1422 while (parent
!= null){
1423 Control next
= parent
.Controls
.GetNextControl (ctl
, true);
1427 parent
= parent
.Parent
;
1432 return Controls
.GetFirstControl (true);
1435 private Control
getNextControlBackward (Control ctl
)
1437 Control parent
= ctl
.Parent
;
1438 if (parent
!= null){
1439 Control next
= parent
.Controls
.GetNextControl (ctl
, false);
1441 if (next
.Controls
.Count
> 0)
1442 return next
.Controls
.GetFirstControl (false);
1449 return Controls
.GetFirstControl (false);
1453 protected bool GetStyle (ControlStyles flag
)
1455 return (controlStyles_
& flag
) != 0;
1459 protected bool GetTopLevel ()
1461 return statuses
[ TOPLEVEL
];
1470 protected virtual void InitLayout ()
1476 public void Invalidate ()
1478 if (IsHandleCreated
) {
1479 Win32
.InvalidateRect (Handle
, IntPtr
.Zero
, 1);
1483 public void Invalidate (bool invalidateChildren
)
1486 if (invalidateChildren
){
1487 foreach (Control child
in Controls
)
1488 child
.Invalidate (invalidateChildren
);
1492 // tries to find appropriate owner for modal form
1493 internal static Control
getOwnerWindow (Control skip
)
1495 // temporary solution
1496 IEnumerator cw
= controlsCollection
.GetEnumerator ();
1498 while (cw
.MoveNext ()){
1499 Control c
= ( (DictionaryEntry
) cw
.Current
).Value
as Control
;
1500 if (c
!= null && c
!= skip
){
1501 IntPtr parent
= Win32
.GetParent (c
.Handle
);
1502 IntPtr owner
= Win32
.GetWindow (c
.Handle
, (uint) GetWindowConstants
.GW_OWNER
);
1503 if (parent
== IntPtr
.Zero
&& owner
== IntPtr
.Zero
)
1511 public void Invalidate (Rectangle rc
)
1513 if (IsHandleCreated
) {
1514 RECT rect
= new RECT ();
1515 rect
.left
= rc
.Left
;
1517 rect
.right
= rc
.Right
;
1518 rect
.bottom
= rc
.Bottom
;
1519 Win32
.InvalidateRect (Handle
, ref rect
, true);
1524 public void Invalidate (Region region
)
1530 public void Invalidate (Rectangle rc
, bool invalidateChildren
)
1536 public void Invalidate (Region region
,bool invalidateChildren
)
1542 protected void InvokeGotFocus (Control toInvoke
, EventArgs e
)
1548 protected void InvokeLostFocus (Control toInvoke
, EventArgs e
)
1554 protected void InvokeOnClick (Control toInvoke
, EventArgs e
)
1560 protected void InvokePaint (Control c
, PaintEventArgs e
)
1566 protected void InvokePaintBackground (
1567 Control c
,PaintEventArgs e
)
1573 protected virtual bool IsInputChar (char charCode
)
1579 protected virtual bool IsInputKey (Keys keyData
)
1584 public static bool IsMnemonic (char charCode
, string text
)
1588 return text
.IndexOf ("&" + charCode
)> 0;
1592 // methods used with events:
1593 protected virtual void OnBackColorChanged (EventArgs e
)
1595 if (BackColorChanged
!= null)
1596 BackColorChanged (this, e
);
1598 foreach (Control ctl
in Controls
) {
1599 ctl
.OnParentBackColorChanged (e
);
1603 protected virtual void OnBackgroundImageChanged (EventArgs e
)
1605 if (BackgroundImageChanged
!= null)
1606 BackgroundImageChanged (this, e
);
1609 protected virtual void OnBindingContextChanged (EventArgs e
)
1611 if (BindingContextChanged
!= null)
1612 BindingContextChanged (this, e
);
1615 protected virtual void OnCausesValidationChanged (EventArgs e
)
1617 if (CausesValidationChanged
!= null)
1618 CausesValidationChanged (this, e
);
1621 protected virtual void OnChangeUICues (UICuesEventArgs e
)
1623 if (ChangeUICues
!= null)
1624 ChangeUICues (this, e
);
1628 protected virtual void OnClick (EventArgs e
)
1635 protected virtual void OnContextMenuChanged (EventArgs e
)
1637 if (ContextMenuChanged
!= null)
1638 ContextMenuChanged (this, e
);
1641 protected virtual void OnControlAdded (ControlEventArgs e
)
1644 e
.Control
.CreateControl ();
1646 e
.Control
.Visible
= Visible
;
1648 if (ControlAdded
!= null)
1649 ControlAdded (this, e
);
1652 protected virtual void OnControlRemoved (ControlEventArgs e
)
1654 if (ControlRemoved
!= null)
1655 ControlRemoved (this, e
);
1658 protected virtual void OnCreateControl ()
1661 // create all child windows
1662 IEnumerator cw
= childControls
.GetEnumerator ();
1664 while (cw
.MoveNext ()) {
1665 Control control
= (Control
) cw
.Current
;
1666 control
.CreateControl ();
1671 protected virtual void OnCursorChanged (EventArgs e
)
1673 if (CursorChanged
!= null)
1674 CursorChanged (this, e
);
1677 protected virtual void OnDockChanged (EventArgs e
)
1679 // changing this property does not affect the control directly
1680 // so have its parent to calculate new layout
1682 Parent
.PerformLayout (this, "Dock");
1683 if (DockChanged
!= null)
1684 DockChanged (this, e
);
1687 protected virtual void OnDoubleClick (EventArgs e
)
1689 if (DoubleClick
!= null)
1690 DoubleClick (this, e
);
1693 protected virtual void OnDragDrop (DragEventArgs drgevent
)
1695 if (DragDrop
!= null)
1696 DragDrop (this, drgevent
);
1699 protected virtual void OnDragEnter (DragEventArgs drgevent
)
1701 if (DragEnter
!= null)
1702 DragEnter (this, drgevent
);
1705 protected virtual void OnDragLeave (EventArgs e
)
1707 if (DragLeave
!= null)
1708 DragLeave (this, e
);
1711 protected virtual void OnDragOver (DragEventArgs drgevent
)
1713 if (DragOver
!= null)
1714 DragOver (this, drgevent
);
1718 protected virtual void OnEnabledChanged (EventArgs e
)
1720 if (EnabledChanged
!= null)
1721 EnabledChanged (this, e
);
1724 protected virtual void OnEnter (EventArgs e
)
1730 protected virtual void OnFontChanged (EventArgs e
)
1732 if (FontChanged
!= null)
1733 FontChanged (this, e
);
1736 protected virtual void OnForeColorChanged (EventArgs e
)
1738 if (ForeColorChanged
!= null)
1739 ForeColorChanged (this, e
);
1742 protected virtual void OnGiveFeedback (GiveFeedbackEventArgs gfbevent
)
1744 if (GiveFeedback
!= null)
1745 GiveFeedback (this, gfbevent
);
1749 protected virtual void OnGotFocus (EventArgs e
)
1751 if (GotFocus
!= null)
1755 protected virtual void OnHandleCreated (EventArgs e
)
1758 Win32
.SendMessage (Handle
, Msg
.WM_SETFONT
, font
.ToHfont ().ToInt32 (), 0);
1760 Win32
.SendMessage (Handle
, Msg
.WM_SETFONT
, Font
.ToHfont ().ToInt32 (), 0);
1762 Win32
.SetWindowText (Handle
, text
);
1764 if (HandleCreated
!= null)
1765 HandleCreated (this, e
);
1769 protected virtual void OnHandleDestroyed (EventArgs e
)
1771 if (Handle
!= IntPtr
.Zero
) {
1772 controlsCollection
.Remove (Handle
);
1775 if (HandleDestroyed
!= null) {
1776 HandleDestroyed (this, e
);
1780 protected virtual void OnHelpRequested (HelpEventArgs hevent
)
1782 if (HelpRequested
!= null)
1783 HelpRequested (this, hevent
);
1786 protected virtual void OnImeModeChanged (EventArgs e
)
1788 if (ImeModeChanged
!= null)
1789 ImeModeChanged (this, e
);
1792 protected virtual void OnInvalidated (InvalidateEventArgs e
)
1794 if (Invalidated
!= null)
1795 Invalidated (this, e
);
1799 protected virtual void OnKeyDown (KeyEventArgs e
)
1801 if (KeyDown
!= null)
1806 protected virtual void OnKeyPress (KeyPressEventArgs e
)
1808 if (KeyPress
!= null)
1813 protected virtual void OnKeyUp (KeyEventArgs e
)
1820 protected virtual void OnLayout (LayoutEventArgs levent
)
1822 DoDockAndAnchorLayout (levent
);
1824 Layout (this, levent
);
1827 protected virtual void OnLeave (EventArgs e
)
1833 protected virtual void OnLocationChanged (EventArgs e
)
1835 if (LocationChanged
!= null)
1836 LocationChanged (this, e
);
1840 protected virtual void OnLostFocus (EventArgs e
)
1842 if (LostFocus
!= null)
1843 LostFocus (this, e
);
1847 protected virtual void OnMouseDown (MouseEventArgs e
)
1849 if (MouseDown
!= null)
1850 MouseDown (this, e
);
1853 protected virtual void OnMouseEnter (EventArgs e
)
1855 //System.Console.WriteLine ("OnMouseEnter");
1856 if (MouseEnter
!= null)
1857 MouseEnter (this, e
);
1860 protected virtual void OnMouseHover (EventArgs e
)
1862 if (MouseHover
!= null)
1863 MouseHover (this, e
);
1866 protected virtual void OnMouseLeave (EventArgs e
)
1868 //System.Console.WriteLine ("OnMouseLeave");
1870 mouseIsInside_
= false;
1871 if (MouseLeave
!= null)
1872 MouseLeave (this, e
);
1876 protected virtual void OnMouseMove (MouseEventArgs e
)
1878 // If enter and mouse pressed - do not process
1879 if ( ( (e
.Button
& MouseButtons
.Left
) != 0) && !mouseIsInside_
) return;
1881 if (!mouseIsInside_
) {
1882 TRACKMOUSEEVENT tme
= new TRACKMOUSEEVENT ();
1885 tme
.dwFlags
= (int)TrackerEventFlags
.TME_LEAVE
;
1886 tme
.dwHoverTime
= 0;
1888 bool result
= Win32
.TrackMouseEvent (ref tme
);
1890 System
.Console
.WriteLine ("{0}",Win32
.FormatMessage (Win32
.GetLastError ()));
1894 POINT pt
= new POINT ();
1897 Win32
.ClientToScreen (Handle
, ref pt
);
1898 IntPtr wndUnderMouse
= Win32
.WindowFromPoint (pt
);
1900 if (wndUnderMouse
!= Handle
) {
1901 // we are outside of the window
1902 if (mouseIsInside_
) {
1903 OnMouseLeave (new EventArgs ());
1904 mouseIsInside_
= false;
1908 if (!mouseIsInside_
) {
1909 mouseIsInside_
= true;
1910 OnMouseEnter (new EventArgs ());
1913 if (MouseMove
!= null)
1914 MouseMove (this, e
);
1918 protected virtual void OnMouseUp (MouseEventArgs e
)
1920 if (MouseUp
!= null)
1924 protected virtual void OnMouseWheel (MouseEventArgs e
)
1926 if (MouseWheel
!= null)
1927 MouseWheel (this, e
);
1930 protected virtual void OnMove (EventArgs e
)
1936 protected virtual void OnNotifyMessage (Message m
)
1942 protected virtual void OnPaint (PaintEventArgs e
)
1949 protected virtual void OnPaintBackground (PaintEventArgs pevent
)
1951 if (GetStyle (ControlStyles
.UserPaint
)) {
1952 Brush br
= new SolidBrush (BackColor
);
1953 pevent
.Graphics
.FillRectangle (br
, pevent
.ClipRectangle
);
1958 protected virtual void OnParentBackColorChanged (EventArgs e
)
1960 BackColor
= Parent
.BackColor
;
1961 // FIXME: setting BackColor fires the BackColorChanged event,
1962 // so we do not need to call this here
1964 if (BackColorChanged != null)
1965 BackColorChanged (this, e);
1969 protected virtual void OnParentBackgroundImageChanged (
1972 if (BackgroundImageChanged
!= null)
1973 BackgroundImageChanged (this, e
);
1976 protected virtual void OnParentBindingContextChanged (
1979 if (BindingContextChanged
!= null)
1980 BindingContextChanged (this, e
);
1984 protected virtual void OnParentChanged (EventArgs e
)
1986 if (ParentChanged
!= null)
1987 ParentChanged (this, e
);
1990 protected virtual void OnParentEnabledChanged (EventArgs e
)
1992 if (EnabledChanged
!= null)
1993 EnabledChanged (this, e
);
1996 protected virtual void OnParentFontChanged (EventArgs e
)
1998 if (FontChanged
!= null)
1999 FontChanged (this, e
);
2002 protected virtual void OnParentForeColorChanged (EventArgs e
)
2004 if (ForeColorChanged
!= null)
2005 ForeColorChanged (this, e
);
2008 protected virtual void OnParentRightToLeftChanged (
2011 if (RightToLeftChanged
!= null)
2012 RightToLeftChanged (this, e
);
2015 protected virtual void OnParentVisibleChanged (EventArgs e
)
2017 if (VisibleChanged
!= null)
2018 VisibleChanged (this, e
);
2021 protected virtual void OnQueryContinueDrag (
2022 QueryContinueDragEventArgs qcdevent
)
2024 if (QueryContinueDrag
!= null)
2025 QueryContinueDrag (this, qcdevent
);
2029 protected virtual void OnResize (EventArgs e
)
2034 PerformLayout (this, "Bounds");
2037 protected virtual void OnRightToLeftChanged (EventArgs e
)
2039 if (RightToLeftChanged
!= null)
2040 RightToLeftChanged (this, e
);
2043 protected virtual void OnSizeChanged (EventArgs e
)
2046 if (SizeChanged
!= null)
2047 SizeChanged (this, e
);
2050 protected virtual void OnStyleChanged (EventArgs e
)
2052 if (StyleChanged
!= null)
2053 StyleChanged (this, e
);
2056 protected virtual void OnSystemColorsChanged (EventArgs e
)
2058 if (SystemColorsChanged
!= null)
2059 SystemColorsChanged (this, e
);
2062 protected virtual void OnTabIndexChanged (EventArgs e
)
2064 if (TabIndexChanged
!= null)
2065 TabIndexChanged (this, e
);
2068 protected virtual void OnTabStopChanged (EventArgs e
)
2070 if (TabStopChanged
!= null)
2071 TabStopChanged (this, e
);
2075 protected virtual void OnTextChanged (EventArgs e
)
2077 if (TextChanged
!= null)
2078 TextChanged (this, e
);
2081 //[MonoTODO] // this doesn't seem to be documented
2082 // protected virtual void OnTextAlignChanged (EventArgs e) {
2083 // TextAlignChanged (this, e);
2086 protected virtual void OnValidated (EventArgs e
)
2088 if (Validated
!= null)
2089 Validated (this, e
);
2093 // CancelEventArgs not ready
2094 protected virtual void OnValidating (CancelEventArgs e
)
2096 throw new NotImplementedException ();
2100 protected virtual void OnVisibleChanged (EventArgs e
)
2102 if (VisibleChanged
!= null)
2103 VisibleChanged (this, e
);
2107 // --- end of methods for events ---
2111 public void PerformLayout ()
2113 PerformLayout (null, null);
2117 public void PerformLayout (Control affectedControl
,
2118 string affectedProperty
)
2120 if (!statuses
[ LAYOUT_SUSPENDED
])
2121 OnLayout (new LayoutEventArgs (affectedControl
, affectedProperty
));
2123 statuses
[ LAYOUT_PENDING
] = true;
2127 public Point
PointToClient ( Point p
)
2129 POINT pt
= new POINT();
2132 Win32
.ScreenToClient( Handle
, ref pt
);
2133 return new Point ( pt
.x
, pt
.y
);
2137 public Point
PointToScreen ( Point p
)
2139 POINT pt
= new POINT();
2142 Win32
.ClientToScreen ( Handle
, ref pt
);
2143 return new Point ( pt
.x
, pt
.y
);
2147 public virtual bool PreProcessMessage (ref Message msg
)
2149 if ((uint)msg
.Msg
== (uint)Msg
.WM_KEYDOWN
){
2150 Keys keyData
= (Keys
)msg
.WParam
.ToInt32 ();
2151 if (!ProcessCmdKey (ref msg
, keyData
)) {
2152 if (IsInputKey (keyData
))
2155 return ProcessDialogKey (keyData
);
2159 else if ((uint)msg
.Msg
== (uint) Msg
.WM_CHAR
){
2160 if (IsInputChar ( (char) msg
.WParam
))
2163 return ProcessDialogChar ( (char) msg
.WParam
);
2170 protected virtual bool ProcessCmdKey (ref Message msg
,
2173 // do something with context menu
2176 return Parent
.ProcessCmdKey (ref msg
, keyData
);
2181 protected virtual bool ProcessDialogChar (char charCode
)
2184 return Parent
.ProcessDialogChar (charCode
);
2189 protected virtual bool ProcessDialogKey (Keys keyData
)
2192 return Parent
.ProcessDialogKey (keyData
);
2197 protected virtual bool ProcessKeyEventArgs (ref Message m
)
2199 bool handled
= false;
2201 switch ((Msg
) m
.Msg
) {
2202 case Msg
.WM_KEYDOWN
:
2203 KeyEventArgs args_down
= new KeyEventArgs ( (Keys
)m
.WParam
.ToInt32 ());
2204 OnKeyDown (args_down
);
2205 handled
= args_down
.Handled
;
2208 KeyPressEventArgs args_press
= new KeyPressEventArgs ( (char) m
.WParam
);
2209 OnKeyPress (args_press
);
2210 handled
= args_press
.Handled
;
2213 KeyEventArgs args_up
= new KeyEventArgs ( (Keys
)m
.WParam
.ToInt32 ());
2215 handled
= args_up
.Handled
;
2223 protected internal virtual bool ProcessKeyMessage (ref Message m
)
2225 if (Parent
!= null){
2226 if (!Parent
.ProcessKeyPreview (ref m
))
2227 return ProcessKeyEventArgs (ref m
);
2233 protected virtual bool ProcessKeyPreview (ref Message m
)
2236 return Parent
.ProcessKeyPreview (ref m
);
2240 // This default implementation of the ProcessMnemonic method simply
2241 // returns false to indicate that the control has no mnemonic.
2242 protected virtual bool ProcessMnemonic (char charCode
)
2247 // used when properties/values of Control
2248 // are big enough to warrant recreating the HWND
2249 protected void RecreateHandle ()
2251 statuses
[RECREATING_HANDLE
] = true;
2252 if (IsHandleCreated
) {
2258 IEnumerator cw
= childControls
.GetEnumerator ();
2259 while (cw
.MoveNext ())
2260 ( (Control
)cw
.Current
).RecreateHandle ();
2263 statuses
[ RECREATING_HANDLE
] = false;
2267 public Rectangle
RectangleToClient (Rectangle r
)
2269 RECT rect
= new RECT ();
2272 rect
.right
= r
.Right
;
2273 rect
.bottom
= r
.Bottom
;
2274 Win32
.ScreenToClient (Handle
,ref rect
);
2275 return new Rectangle (rect
.left
, rect
.top
, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
);
2279 public Rectangle
RectangleToScreen (Rectangle r
)
2281 RECT rect
= new RECT ();
2284 rect
.right
= r
.Right
;
2285 rect
.bottom
= r
.Bottom
;
2286 Win32
.ClientToScreen (Handle
,ref rect
);
2287 return new Rectangle (rect
.left
, rect
.top
, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
);
2291 protected static bool ReflectMessage (IntPtr hWnd
, ref Message m
) {
2292 bool result
= false;
2293 Control cntrl
= Control
.FromHandle (hWnd
);
2294 if (cntrl
!= null) {
2295 cntrl
.WndProc (ref m
);
2301 public virtual void Refresh ()
2303 Win32
.UpdateWindow (Handle
);
2307 public virtual void ResetBackColor ()
2313 public void ResetBindings ()
2319 public virtual void ResetFont ()
2325 public virtual void ResetForeColor ()
2331 public void ResetImeMode ()
2335 public virtual void ResetCursor(){
2339 public virtual void ResetRightToLeft ()
2345 public virtual void ResetText ()
2351 public void ResumeLayout ()
2353 statuses
[ LAYOUT_SUSPENDED
] = false;
2354 if (statuses
[ LAYOUT_PENDING
]){
2356 statuses
[ LAYOUT_PENDING
] = false;
2361 public void ResumeLayout (bool performLayout
)
2363 statuses
[ LAYOUT_SUSPENDED
] = false;
2364 if (performLayout
&& statuses
[ LAYOUT_PENDING
]){
2366 statuses
[ LAYOUT_PENDING
] = false;
2371 protected ContentAlignment
RtlTranslateAlignment (
2372 ContentAlignment align
)
2374 throw new NotImplementedException ();
2378 protected HorizontalAlignment
RtlTranslateAlignment (
2379 HorizontalAlignment align
)
2381 throw new NotImplementedException ();
2385 protected LeftRightAlignment
RtlTranslateAlignment (
2386 LeftRightAlignment align
)
2388 throw new NotImplementedException ();
2392 protected ContentAlignment
RtlTranslateContent (
2393 ContentAlignment align
)
2395 throw new NotImplementedException ();
2399 protected HorizontalAlignment
RtlTranslateHorizontal (
2400 HorizontalAlignment align
)
2402 throw new NotImplementedException ();
2406 protected LeftRightAlignment
RtlTranslateLeftRight (
2407 LeftRightAlignment align
)
2409 throw new NotImplementedException ();
2412 public void Scale (float ratio
)
2414 Scale (ratio
, ratio
);
2418 public void Scale (float dx
,float dy
)
2422 IEnumerator cw
= childControls
.GetEnumerator ();
2423 while (cw
.MoveNext ()){
2424 Control control
= (Control
) cw
.Current
;
2425 control
.Scale (dx
, dy
);
2431 protected virtual void ScaleCore (float dx
, float dy
)
2433 Location
= new Point ( (int) (Left
* dx
), (int) (Top
* dy
));
2434 ClientSize
= new Size ( (int) (ClientSize
.Width
* dx
),
2435 (int) (ClientSize
.Height
* dy
));
2439 public void Select ()
2445 protected virtual void Select (bool directed
,bool forward
)
2451 public bool SelectNextControl (Control ctl
, bool forward
,
2453 bool nested
, bool wrap
)
2455 throw new NotImplementedException ();
2460 public void SendToBack ()
2466 public void SetBounds (int x
, int y
, int width
, int height
)
2468 SetBounds (x
, y
, width
, height
, BoundsSpecified
.All
);
2472 public void SetBounds (int x
, int y
, int width
, int height
, BoundsSpecified specified
)
2474 SetBoundsCore (x
, y
, width
, height
, specified
);
2478 protected virtual void SetBoundsCore (int x
, int y
, int width
, int height
, BoundsSpecified specified
)
2480 if ( (specified
& BoundsSpecified
.X
) == 0) x
= Left
;
2481 if ( (specified
& BoundsSpecified
.Y
) == 0) y
= Top
;
2482 if ( (specified
& BoundsSpecified
.Width
) == 0) width
= Width
;
2483 if ( (specified
& BoundsSpecified
.Height
) == 0) height
= Height
;
2485 if (IsHandleCreated
){
2486 SetWindowPosFlags flags
= SetWindowPosFlags
.SWP_NOZORDER
| SetWindowPosFlags
.SWP_FRAMECHANGED
| SetWindowPosFlags
.SWP_DRAWFRAME
;
2487 Win32
.SetWindowPos (Handle
, SetWindowPosZOrder
.HWND_NOTOPMOST
, x
, y
, width
, height
, flags
);
2490 UpdateBounds (x
, y
, width
, height
);
2493 protected internal virtual bool MenuPresent
{
2494 get { return false; }
2498 protected virtual void SetClientSizeCore (int x
, int y
)
2500 RECT rc
= new RECT ();
2504 CreateParams pars
= CreateParams
;
2505 Win32
.AdjustWindowRectEx (ref rc
, pars
.Style
, MenuPresent
? 1 : 0, pars
.ExStyle
);
2507 Size
= new Size (rc
.right
- rc
.left
, rc
.bottom
- rc
.top
);
2511 protected void SetStyle (ControlStyles flag
, bool value)
2514 controlStyles_
|= flag
;
2517 controlStyles_
&= ~flag
;
2521 protected void SetTopLevel (bool value)
2524 // FIXME: verify on whether this is supposed
2525 // to activate/deactive the window
2526 Win32.SetWindowPos (Handle,
2527 SetWindowPosZOrder.HWND_NOTOPMOST,
2530 // FIXME: this does not make sense but
2531 // the docs say the window is hidden
2532 Win32.ShowWindow (Handle, ShowWindowStyles.SW_HIDE);
2534 if (GetTopLevel () != value && Parent
!= null)
2535 throw new ArgumentException ();
2537 statuses
[ TOPLEVEL
] = value;
2541 protected virtual void SetVisibleCore (bool value)
2543 bool visibleChanged
= (visible
!= value);
2548 OnVisibleChanged (EventArgs
.Empty
);
2550 if (IsHandleCreated
){
2551 SetWindowPosFlags flags
= value ? SetWindowPosFlags
.SWP_SHOWWINDOW
: SetWindowPosFlags
.SWP_HIDEWINDOW
;
2552 flags
|= SetWindowPosFlags
.SWP_NOZORDER
| SetWindowPosFlags
.SWP_NOMOVE
| SetWindowPosFlags
.SWP_NOSIZE
;
2553 Win32
.SetWindowPos (Handle
, 0, 0, 0, 0, 0, flags
);
2556 foreach (Control c
in Controls
)
2562 if (!IsHandleCreated
)
2568 public void SuspendLayout ()
2570 statuses
[ LAYOUT_SUSPENDED
] = true;
2574 public void Update ()
2576 Win32
.UpdateWindow (Handle
);
2580 protected void UpdateBounds ()
2581 { // update control bounds with current size and position
2583 // currently, this function is called in responce to
2584 // window events, so I assume that all window handles
2586 RECT rect
= new RECT ();
2587 Win32
.GetWindowRect (Handle
, ref rect
);
2589 IntPtr parent
= Win32
.GetParent (Handle
);
2590 if (parent
!= IntPtr
.Zero
){
2591 Win32
.ScreenToClient (parent
, ref rect
);
2594 UpdateBounds (rect
.left
, rect
.top
, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
);
2598 protected void UpdateBounds (int x
, int y
, int width
, int height
)
2600 int clWidth
= width
;
2601 int clHeight
= height
;
2603 CreateParams pars
= CreateParams
;
2605 RECT rc
= new RECT ();
2609 Win32
.AdjustWindowRectEx (ref rc
, pars
.Style
, MenuPresent
? 1 : 0, pars
.ExStyle
);
2611 clWidth
-= ( (rc
.right
- rc
.left
)- clWidth
);
2612 clHeight
-= ( (rc
.bottom
- rc
.top
)- clHeight
);
2614 UpdateBounds (x
, y
, width
, height
, clWidth
, clHeight
);
2618 protected void UpdateBounds (
2619 int x
, int y
, int width
, int height
, int clientWidth
,
2622 oldBounds
.X
= bounds
.X
;
2623 oldBounds
.Y
= bounds
.Y
;
2624 oldBounds
.Width
= bounds
.Width
;
2625 oldBounds
.Height
= bounds
.Height
;
2627 bool bLocationChanged
= (bounds
.X
!= x
)|| (bounds
.Y
!= y
);
2631 bool bSizeChanged
= (bounds
.Width
!= width
)|| (bounds
.Height
!= height
);
2632 bounds
.Width
= width
;
2633 bounds
.Height
= height
;
2635 this.clientWidth
= clientWidth
;
2636 this.clientHeight
= clientHeight
;
2638 // FIXME: not sure whether this is correct
2639 if (statuses
[ LAYOUT_SUSPENDED
]) {
2640 oldBounds
.X
= bounds
.X
;
2641 oldBounds
.Y
= bounds
.Y
;
2642 oldBounds
.Width
= bounds
.Width
;
2643 oldBounds
.Height
= bounds
.Height
;
2646 if (bLocationChanged
)
2647 OnLocationChanged (EventArgs
.Empty
);
2649 OnSizeChanged (EventArgs
.Empty
);
2653 protected void UpdateStyles ()
2659 protected void UpdateZOrder ()
2661 if (!IsHandleCreated
|| Parent
== null)
2664 int position
= Parent
.Controls
.GetChildIndex (this , false);
2669 // not in collection for some reason
2673 Control prev
= Parent
.Controls
[ position
- 1 ];
2674 if (prev
.IsHandleCreated
)
2675 Win32
.SetWindowPos (Handle
, prev
.Handle
, 0, 0, 0, 0, SetWindowPosFlags
.SWP_NOMOVE
| SetWindowPosFlags
.SWP_NOSIZE
);
2681 internal MouseEventArgs
Msg2MouseEventArgs (ref Message msg
) {
2682 MouseButtons mb
= MouseButtons
.None
;
2683 KeyStatusFlags keyIndicator
= (KeyStatusFlags
)msg
.WParam
.ToInt32 ();
2684 if ( (keyIndicator
& KeyStatusFlags
.MK_LBUTTON
) != 0) {
2685 mb
|= MouseButtons
.Left
;
2687 if ( (keyIndicator
& KeyStatusFlags
.MK_RBUTTON
) != 0) {
2688 mb
|= MouseButtons
.Right
;
2690 if ( (keyIndicator
& KeyStatusFlags
.MK_MBUTTON
) != 0) {
2691 mb
|= MouseButtons
.Middle
;
2693 if ( (keyIndicator
& KeyStatusFlags
.MK_XBUTTON1
) != 0) {
2694 mb
|= MouseButtons
.XButton1
;
2696 if ( (keyIndicator
& KeyStatusFlags
.MK_XBUTTON2
) != 0) {
2697 mb
|= MouseButtons
.XButton2
;
2700 return new MouseEventArgs (mb
, (mb
!= MouseButtons
.None
) ? 1: 0, msg
.LoWordLParam
, msg
.HiWordLParam
, 0);
2703 // WndProc - calls appriate On... function for the give
2706 // These On... functions do not appear to be called by
2709 // background color/image handled by WinForms
2710 // OnBackColorChanged
2711 // OnBackgroundImageChanged
2712 // OnForeColorChanged
2713 // OnPaintBackground
2715 // controls are added/removed by WinForms
2720 // OnBindingContextChanged
2721 // OnCausesValidationChanged
2723 // OnContextMenuChanged
2724 // OnRightToLeftChanged
2729 // OnTextAlignChanged
2732 // OnTabIndexChanged
2734 // OnLocationChanged
2736 // FIXME: may be one of the WM_IME_ messages
2739 // InvalidateRect is called by no Invalidate message exists
2742 // these messages ARE not called by WNDPROC according to docs
2743 // OnParentBackColorChanged
2744 // OnParentBackgroundImageChanged
2745 // OnParentBindingContextChanged
2747 // OnParentEnabledChanged
2748 // OnParentFontChanged
2749 // OnParentForeColorChanged
2750 // OnParentRightToLeftChanged
2751 // OnParentVisibleChanged
2753 protected virtual void WndProc (ref Message m
)
2755 EventArgs eventArgs
= new EventArgs ();
2756 // FIXME: paintEventArgs is not being created properly
2757 // FIXME: Graphics does not have a public constructor, you must get one from .NET
2758 //PaintEventArgs paintEventArgs = new PaintEventArgs (
2759 // new Graphics (), new Rectangle ());
2761 if ( (uint)m
.Msg
== Control
.InvokeMessage
) {
2762 ControlInvokeHelper helper
= null;
2763 lock (InvokeQueue_
.SyncRoot
) {
2764 if (InvokeQueue_
.Count
> 0) {
2765 helper
= (ControlInvokeHelper
)InvokeQueue_
.Dequeue ();
2768 if (helper
!= null) {
2769 helper
.ExecuteMethod ();
2773 else if ((uint)m
.Msg
== (uint) Msg
.WM_COMMAND
) {
2775 m
.Result
= (IntPtr
)1;
2776 OnWmCommand (ref m
);
2777 if (m
.Result
!= IntPtr
.Zero
) {
2778 CallControlWndProc (ref m
);
2783 switch ((Msg
) m
.Msg
) {
2785 Console
.WriteLine("WM_CREATE");
2786 OnHandleCreated (eventArgs
);
2788 case Msg
.WM_LBUTTONDBLCLK
:
2789 OnDoubleClick (eventArgs
);
2790 CallControlWndProc (ref m
);
2796 // OnQueryContinueDrag
2798 OnEnabledChanged (eventArgs
);
2799 CallControlWndProc (ref m
);
2801 case Msg
.WM_SETFOCUS
:
2802 OnEnter (eventArgs
);
2803 OnGotFocus (eventArgs
);
2804 CallControlWndProc (ref m
);
2806 case Msg
.WM_FONTCHANGE
:
2807 OnFontChanged (eventArgs
);
2808 CallControlWndProc (ref m
);
2810 case Msg
.WM_DESTROY
:
2811 OnHandleDestroyed (eventArgs
);
2812 CallControlWndProc (ref m
);
2816 //OnHelpRequested (eventArgs);
2817 CallControlWndProc (ref m
);
2819 case Msg
.WM_KEYDOWN
:
2820 if (!ProcessKeyMessage (ref m
))
2821 CallControlWndProc (ref m
);
2824 if (!ProcessKeyMessage (ref m
))
2825 CallControlWndProc (ref m
);
2828 if (!ProcessKeyMessage (ref m
))
2829 CallControlWndProc (ref m
);
2831 case Msg
.WM_KILLFOCUS
:
2832 OnLeave (eventArgs
);
2833 OnLostFocus (eventArgs
);
2834 CallControlWndProc (ref m
);
2836 case Msg
.WM_MOUSEACTIVATE
:
2837 //OnMouseEnter (eventArgs);
2838 CallControlWndProc (ref m
);
2840 case Msg
.WM_MOUSEHOVER
: // called by TrackMouseEvent
2841 OnMouseHover (eventArgs
);
2842 CallControlWndProc (ref m
);
2844 case Msg
.WM_MOUSELEAVE
: // called by TrackMouseEvent
2845 OnMouseLeave (eventArgs
);
2846 CallControlWndProc (ref m
);
2848 case Msg
.WM_MOUSEMOVE
:
2850 OnMouseMove (Msg2MouseEventArgs (ref m
));
2851 CallControlWndProc (ref m
);
2853 case Msg
.WM_LBUTTONDOWN
:
2855 OnMouseDown (Msg2MouseEventArgs(ref m
));
2856 CallControlWndProc (ref m
);
2858 case Msg
.WM_LBUTTONUP
:
2860 OnMouseUp (Msg2MouseEventArgs(ref m
));
2861 CallControlWndProc (ref m
);
2863 case Msg
.WM_MOUSEWHEEL
:
2865 //OnMouseWheel (eventArgs);
2866 CallControlWndProc (ref m
);
2871 CallControlWndProc (ref m
);
2873 case Msg
.WM_CTLCOLOREDIT
:
2874 if ( !Control
.ReflectMessage ( m
.LParam
, ref m
) )
2875 CallControlWndProc ( ref m
);
2877 //case Msg.WM_CTLCOLORSTATIC:
2878 // if ( !Control.ReflectMessage ( m.LParam, ref m ) )
2879 // CallControlWndProc ( ref m );
2882 NMHDR nmhdr
= (NMHDR
)Marshal
.PtrToStructure (m
.LParam
,
2884 if (!Control
.ReflectMessage (nmhdr
.hwndFrom
, ref m
))
2885 CallControlWndProc (ref m
);
2887 // FIXME: get NM_CLICKED msg from pnmh
2888 // OnClick (eventArgs);
2889 //OnNotifyMessage (eventArgs);
2891 case Msg
.WM_ERASEBKGND
:
2892 if (GetStyle (ControlStyles
.UserPaint
)){
2893 if (!GetStyle (ControlStyles
.AllPaintingInWmPaint
)) {
2894 PaintEventArgs eraseEventArgs
= new PaintEventArgs (Graphics
.FromHdc (m
.WParam
), new Rectangle (new Point (0,0),Size
));
2895 OnPaintBackground (eraseEventArgs
);
2896 eraseEventArgs
.Dispose ();
2898 m
.Result
= (IntPtr
)1;
2901 CallControlWndProc (ref m
);
2905 if (!GetStyle (ControlStyles
.UserPaint
)) {
2906 CallControlWndProc (ref m
);
2909 Rectangle rc
= new Rectangle ();
2910 bool beginPaint
= false;
2911 IntPtr hdc
= IntPtr
.Zero
;
2912 RECT updateRect
= new RECT();
2913 PAINTSTRUCT ps
= new PAINTSTRUCT ();
2915 if (Win32
.GetUpdateRect (Handle
, ref updateRect
, false)) {
2916 hdc
= Win32
.BeginPaint (Handle
, ref ps
);
2917 rc
.X
= ps
.rcPaint
.left
;
2918 rc
.Y
= ps
.rcPaint
.top
;
2919 rc
.Width
= ps
.rcPaint
.right
- ps
.rcPaint
.left
;
2920 rc
.Height
= ps
.rcPaint
.bottom
- ps
.rcPaint
.top
;
2923 hdc
= Win32
.GetDC (Handle
);
2924 rc
.X
= updateRect
.left
;
2925 rc
.Y
= updateRect
.top
;
2926 rc
.Width
= updateRect
.right
- updateRect
.left
;
2927 rc
.Height
= updateRect
.bottom
- updateRect
.top
;
2930 PaintEventArgs paintEventArgs
= new PaintEventArgs (Graphics
.FromHdc (hdc
), rc
);
2931 if (GetStyle (ControlStyles
.AllPaintingInWmPaint
)) {
2932 OnPaintBackground (paintEventArgs
);
2934 OnPaint (paintEventArgs
);
2935 paintEventArgs
.Dispose ();
2938 Win32
.EndPaint (Handle
, ref ps
);
2940 Win32
.ReleaseDC (Handle
, hdc
);
2944 if (GetStyle (ControlStyles
.ResizeRedraw
)) {
2947 CallControlWndProc (ref m
);
2949 case Msg
.WM_WINDOWPOSCHANGED
:
2951 CallControlWndProc (ref m
);
2953 case Msg
.WM_STYLECHANGED
:
2954 OnStyleChanged (eventArgs
);
2955 CallControlWndProc (ref m
);
2957 case Msg
.WM_SYSCOLORCHANGE
:
2958 OnSystemColorsChanged (eventArgs
);
2959 CallControlWndProc (ref m
);
2961 case Msg
.WM_SETTEXT
:
2962 //OnTextChanged (eventArgs);
2963 CallControlWndProc (ref m
);
2965 case Msg
.WM_SETFONT
:
2966 //OnTextChanged (eventArgs);
2967 CallControlWndProc (ref m
);
2969 case Msg
.WM_SHOWWINDOW
:
2970 OnVisibleChanged (eventArgs
);
2971 CallControlWndProc (ref m
);
2973 case Msg
.WM_CTLCOLORLISTBOX
:
2974 Win32
.SetTextColor (m
.WParam
, Win32
.RGB (ForeColor
));
2975 //Win32.SetBkColor (m.WParam, 0x00FF00);
2976 //m.Result = Win32.GetStockObject (GSO_.LTGRAY_BRUSH);
2978 case Msg
.WM_MEASUREITEM
:
2979 ReflectMessage (m
.WParam
, ref m
);
2981 case Msg
.WM_DRAWITEM
:
2982 Control
.ReflectMessage (m
.WParam
, ref m
);
2984 case Msg
.WM_HSCROLL
:
2985 case Msg
.WM_VSCROLL
:
2986 if (!Control
.ReflectMessage (m
.LParam
, ref m
)) {
2987 CallControlWndProc (ref m
);
2990 case Msg
.WM_SETCURSOR
:
2991 if (cursor
!= null && cursor
.Handle
!= IntPtr
.Zero
){
2992 Win32
.SetCursor (cursor
.Handle
);
2993 m
.Result
= (IntPtr
)1;
2995 CallControlWndProc (ref m
);
2997 case Msg
.WM_RBUTTONDOWN
:
2998 if (contextMenu
!= null){
2999 contextMenu
.Show (this,
3000 new Point (Win32
.LOW_ORDER (m
.LParam
.ToInt32 ()),
3001 Win32
.HIGH_ORDER (m
.LParam
.ToInt32 ())));
3003 OnMouseDown ( Msg2MouseEventArgs( ref m
) );
3004 CallControlWndProc (ref m
);
3007 CallControlWndProc (ref m
);
3009 if (ControlRealWndProc != IntPtr.Zero) {
3010 CallControlWndProc (ref m);
3020 private void DoAnchor (Control ctrl
)
3022 // the default, no actions are needed
3023 if (ctrl
.Anchor
== (AnchorStyles
.Left
| AnchorStyles
.Top
))
3026 int deltaWidth
= Bounds
.Width
- oldBounds
.Width
;
3027 int deltaHeight
= Bounds
.Height
- oldBounds
.Height
;
3029 double x_change
= 0;
3030 double y_change
= 0;
3032 double halfDeltaWidth
= (double)deltaWidth
/ 2.0;
3033 double halfDeltaHeight
= (double)deltaHeight
/ 2.0;
3035 Rectangle controlBounds
= ctrl
.Bounds
;
3037 if ( (ctrl
.Anchor
& AnchorStyles
.Left
) == 0) {
3038 x_change
+= halfDeltaWidth
;
3040 if ( (ctrl
.Anchor
& AnchorStyles
.Top
) == 0) {
3041 y_change
+= halfDeltaHeight
;
3043 if ( (ctrl
.Anchor
& AnchorStyles
.Right
) == AnchorStyles
.Right
) {
3044 if ( (ctrl
.Anchor
& AnchorStyles
.Left
) == AnchorStyles
.Left
) {
3045 if ( !ctrl
.GetStyle ( ControlStyles
.FixedWidth
) )
3046 controlBounds
.Width
+= deltaWidth
;
3049 x_change
+= halfDeltaWidth
;
3052 if ( (ctrl
.Anchor
& AnchorStyles
.Bottom
) == AnchorStyles
.Bottom
) {
3053 if ( (ctrl
.Anchor
& AnchorStyles
.Top
) == AnchorStyles
.Top
) {
3054 if ( !ctrl
.GetStyle ( ControlStyles
.FixedHeight
) )
3055 controlBounds
.Height
+= deltaHeight
;
3058 y_change
+= halfDeltaHeight
;
3062 controlBounds
.X
+= (int) Math
.Round( x_change
);
3063 controlBounds
.Y
+= (int) Math
.Round( y_change
);
3065 ctrl
.Bounds
= controlBounds
;
3068 private void DoDockAndAnchorLayout (LayoutEventArgs e
)
3070 Rectangle area
= DisplayRectangle
;
3072 for (int i
= childControls
.Count
- 1; i
>= 0; i
--){
3073 Control control
= childControls
[i
];
3075 switch (control
.Dock
){
3076 case DockStyle
.Bottom
:
3077 control
.SetBounds (area
.Left
, area
.Bottom
- control
.Height
,
3078 area
.Width
, control
.Height
);
3079 area
.Height
-= control
.Height
;
3082 control
.SetBounds (area
.Left
, area
.Y
, area
.Width
, control
.Height
);
3083 area
.Y
+= control
.Height
;
3084 area
.Height
-= control
.Height
;
3086 case DockStyle
.Right
:
3087 control
.SetBounds (area
.Right
- control
.Width
, area
.Top
,
3088 control
.Width
, area
.Height
);
3089 area
.Width
-= control
.Width
;
3091 case DockStyle
.Left
:
3092 control
.SetBounds (area
.Left
, area
.Y
, control
.Width
, area
.Height
);
3093 area
.X
+= control
.Width
;
3094 area
.Width
-= control
.Width
;
3096 case DockStyle
.None
:
3102 for (int i
= childControls
.Count
- 1; i
>= 0; i
--){
3103 Control control
= childControls
[i
];
3105 if (control
.Dock
== DockStyle
.Fill
){
3106 control
.SetBounds (area
.X
, area
.Y
, area
.Width
, area
.Height
);
3111 internal static Control FocusedControl
{
3113 IEnumerator cw
= controlsCollection
.GetEnumerator ();
3115 while (cw
.MoveNext ()){
3116 Control c
= ( (DictionaryEntry
) cw
.Current
).Value
as Control
;
3118 if (c
.Focused
)return c
;
3125 internal Control
getParentForm ()
3127 Control parent
= this.Parent
;
3128 while (parent
!= null){
3131 parent
= parent
.Parent
;
3136 /// --- Control: events ---
3137 public event EventHandler BackColorChanged
;
3138 public event EventHandler BackgroundImageChanged
;
3139 public event EventHandler BindingContextChanged
;
3140 public event EventHandler CausesValidationChanged
;
3141 public event UICuesEventHandler ChangeUICues
;
3144 public event EventHandler Click
;
3146 public event EventHandler ContextMenuChanged
;
3147 public event ControlEventHandler ControlAdded
;
3148 public event ControlEventHandler ControlRemoved
;
3149 public event EventHandler CursorChanged
;
3150 public event EventHandler DockChanged
;
3151 public event EventHandler DoubleClick
;
3152 public event DragEventHandler DragDrop
;
3153 public event DragEventHandler DragEnter
;
3154 public event EventHandler DragLeave
;
3155 public event DragEventHandler DragOver
;
3158 public event EventHandler EnabledChanged
;
3160 public event EventHandler Enter
;
3161 public event EventHandler FontChanged
;
3162 public event EventHandler ForeColorChanged
;
3163 public event GiveFeedbackEventHandler GiveFeedback
;
3166 public event EventHandler GotFocus
;
3168 public event EventHandler HandleCreated
;
3169 public event EventHandler HandleDestroyed
;
3170 public event HelpEventHandler HelpRequested
;
3171 public event EventHandler ImeModeChanged
;
3172 public event InvalidateEventHandler Invalidated
;
3175 public event KeyEventHandler KeyDown
;
3178 public event KeyPressEventHandler KeyPress
;
3181 public event KeyEventHandler KeyUp
;
3183 public event LayoutEventHandler Layout
;
3184 public event EventHandler Leave
;
3185 public event EventHandler LocationChanged
;
3188 public event EventHandler LostFocus
;
3191 public event MouseEventHandler MouseDown
;
3193 public event EventHandler MouseEnter
;
3194 public event EventHandler MouseHover
;
3195 public event EventHandler MouseLeave
;
3198 public event MouseEventHandler MouseMove
;
3201 public event MouseEventHandler MouseUp
;
3203 public event MouseEventHandler MouseWheel
;
3204 public event EventHandler Move
;
3207 public event PaintEventHandler Paint
;
3210 public event EventHandler ParentChanged
;
3212 public event QueryAccessibilityHelpEventHandler QueryAccessibilityHelp
;
3213 public event QueryContinueDragEventHandler QueryContinueDrag
;
3216 public event EventHandler Resize
;
3218 public event EventHandler RightToLeftChanged
;
3219 public event EventHandler SizeChanged
;
3220 public event EventHandler StyleChanged
;
3221 public event EventHandler SystemColorsChanged
;
3222 public event EventHandler TabIndexChanged
;
3223 public event EventHandler TabStopChanged
;
3226 public event EventHandler TextChanged
;
3228 public event EventHandler Validated
;
3230 // CancelEventHandler not yet defined
3231 public event CancelEventHandler Validating
;
3233 public event EventHandler VisibleChanged
;
3235 /// --- IWin32Window properties
3236 public IntPtr Handle
{
3238 // If the handle has not yet been created,
3239 // referencing this property will force the
3240 // handle to be created. (MSDN)
3242 if (!IsHandleCreated
)
3245 return window
.Handle
;
3249 /// --- ISynchronizeInvoke properties ---
3251 public bool InvokeRequired
{
3253 return CreatorThreadId_
!= Win32
.GetCurrentThreadId ();
3257 private IAsyncResult
DoInvoke (Delegate method
, object[] args
) {
3258 IAsyncResult result
= null;
3259 ControlInvokeHelper helper
= new ControlInvokeHelper (method
, args
);
3260 if (InvokeRequired
) {
3262 lock (InvokeQueue_
.SyncRoot
) {
3263 InvokeQueue_
.Enqueue (helper
);
3265 Win32
.PostMessage (Handle
, Control
.InvokeMessage
, 0, 0);
3270 helper
.CompletedSynchronously
= true;
3271 helper
.ExecuteMethod ();
3277 /// --- ISynchronizeInvoke methods ---
3279 public IAsyncResult
BeginInvoke (Delegate method
)
3281 return DoInvoke (method
, null);
3285 public IAsyncResult
BeginInvoke (Delegate method
, object[] args
)
3287 return DoInvoke (method
, args
);
3291 public object EndInvoke (IAsyncResult asyncResult
)
3293 object result
= null;
3294 ControlInvokeHelper helper
= asyncResult
as ControlInvokeHelper
;
3295 if (helper
!= null) {
3296 if (!asyncResult
.CompletedSynchronously
) {
3297 asyncResult
.AsyncWaitHandle
.WaitOne ();
3299 result
= helper
.MethodResult
;
3306 public object Invoke (Delegate method
)
3308 return Invoke (method
, null);
3312 public object Invoke (Delegate method
, object[] args
)
3314 IAsyncResult result
= BeginInvoke (method
, args
);
3315 return EndInvoke (result
);
3318 /// sub-class: Control.ControlAccessibleObject
3320 /// Provides information about a control that can be used by an accessibility application.
3322 public class ControlAccessibleObject
: AccessibleObject
{
3323 /// --- ControlAccessibleObject.constructor ---
3325 public ControlAccessibleObject (Control ownerControl
)
3327 throw new NotImplementedException ();
3331 /// --- ControlAccessibleObject Properties ---
3333 public override string DefaultAction
{
3336 return base.DefaultAction
;
3341 public override string Description
{
3344 return base.Description
;
3349 public IntPtr Handle
{
3351 throw new NotImplementedException ();
3359 public override string Help
{
3367 public override string KeyboardShortcut
{
3370 return base.KeyboardShortcut
;
3375 public override string Name
{
3387 public Control Owner
{
3389 throw new NotImplementedException ();
3394 public override AccessibleRole Role
{
3401 /// --- ControlAccessibleObject Methods ---
3403 public override int GetHelpTopic (out string fileName
)
3406 return base.GetHelpTopic (out fileName
);
3410 public void NotifyClients (AccessibleEvents accEvent
)
3416 public void NotifyClients (AccessibleEvents accEvent
,
3423 public override string ToString ()
3426 return base.ToString ();
3430 /// sub-class: Control.ControlCollection
3432 /// Represents a collection of Control objects
3434 public class ControlCollection
: IList
, ICollection
, IEnumerable
, ICloneable
{
3436 class ControlComparer
: IComparer
{
3438 int IComparer
.Compare (object x
, object y
)
3440 int tx
= ( (Control
)x
).TabIndex
;
3441 int ty
= ( (Control
)y
).TabIndex
;
3452 private ArrayList collection
= new ArrayList ();
3453 protected Control owner
;
3455 /// --- ControlCollection.constructor ---
3456 public ControlCollection (Control owner
)
3461 /// --- ControlCollection Properties ---
3464 return collection
.Count
;
3468 public bool IsReadOnly
{
3470 return collection
.IsReadOnly
;
3474 public virtual Control
this [int index
] {
3476 return (Control
) collection
[index
];
3480 public virtual void Add (Control
value)
3482 if (!Contains (value)) {
3483 collection
.Add (value);
3484 value.Parent
= owner
;
3485 owner
.OnControlAdded (new ControlEventArgs (value));
3489 public virtual void AddRange (Control
[] controls
)
3491 for (int i
= 0; i
< controls
.Length
; i
++) {
3496 public virtual void Clear ()
3498 collection
.Clear ();
3501 public bool Contains (Control control
)
3503 return collection
.Contains (control
);
3506 public void CopyTo (Array dest
,int index
)
3508 collection
.CopyTo (dest
, index
);
3512 public override bool Equals (object obj
)
3515 return base.Equals (obj
);
3518 public int GetChildIndex (Control child
)
3520 return GetChildIndex (child
, true);
3523 public int GetChildIndex (Control child
, bool throwException
)
3525 int index
= collection
.IndexOf (child
);
3526 if (index
== -1 && throwException
)
3527 throw new ArgumentException ("'child' is not a child control of this parent.");
3531 public IEnumerator
GetEnumerator ()
3533 return collection
.GetEnumerator ();
3537 public override int GetHashCode ()
3540 return base.GetHashCode ();
3543 public int IndexOf (Control control
)
3545 return collection
.IndexOf (control
);
3548 public virtual void Remove (Control
value)
3550 collection
.Remove (value);
3553 public void RemoveAt (int index
)
3555 Remove (this [ index
]);
3556 // have to give a chance to handle this situation in derived class
3557 //collection.RemoveAt (index);
3560 public void SetChildIndex (Control child
, int newIndex
)
3562 int oldIndex
= collection
.IndexOf (child
);
3564 throw new ArgumentException ("'child' is not a child control of this parent.");
3566 if (oldIndex
!= newIndex
){
3567 collection
.Remove (child
);
3569 if (newIndex
>= collection
.Count
)
3570 collection
.Add (child
);
3572 collection
.Insert (newIndex
, child
);
3576 internal Control
GetFirstControl (bool direction
)
3578 if (collection
.Count
== 0)
3581 ArrayList copy
= collection
.Clone () as ArrayList
;
3582 copy
.Sort (new ControlComparer ());
3585 return copy
[0] as Control
;
3587 Control last
= copy
[ collection
.Count
- 1 ] as Control
;
3588 if (last
.Controls
.Count
== 0)
3591 return last
.Controls
.GetFirstControl (false);
3596 internal Control
GetNextControl (Control ctl
, bool forward
)
3598 if (collection
.Count
== 0)
3601 ArrayList copy
= collection
.Clone () as ArrayList
;
3602 copy
.Sort (new ControlComparer ());
3604 int index
= copy
.IndexOf (ctl
)+ (forward
? 1 : -1);
3606 if ( (forward
&& index
< copy
.Count
)|| (!forward
&& index
>= 0))
3607 return copy
[index
] as Control
;
3612 /// --- ControlCollection.IClonable methods ---
3614 object ICloneable
.Clone ()
3616 throw new NotImplementedException ();
3619 /// --- ControlCollection.IList properties ---
3620 bool IList
.IsFixedSize
{
3622 return collection
.IsFixedSize
;
3626 object IList
.this [int index
] {
3628 return collection
[index
];
3631 collection
[index
] = value;
3635 object ICollection
.SyncRoot
{
3637 return collection
.SyncRoot
;
3641 bool ICollection
.IsSynchronized
{
3643 return collection
.IsSynchronized
;
3647 /// --- ControlCollection.IList methods ---
3648 int IList
.Add (object control
)
3650 return collection
.Add (control
);
3653 bool IList
.Contains (object control
)
3655 return collection
.Contains (control
);
3658 int IList
.IndexOf (object control
)
3660 return collection
.IndexOf (control
);
3663 void IList
.Insert (int index
,object value)
3665 collection
.Insert (index
, value);
3668 void IList
.Remove (object control
)
3670 collection
.Remove (control
);
3672 } // --- end of Control.ControlCollection ---