**** Merged from MCS ****
[mono-project.git] / mcs / class / System.Windows.Forms / System.Windows.Forms / Control.cs
blob588047dcdeec0ffa1a0efadf5aa9984db2f92a35
1 //
2 // System.Windows.Forms.Control.cs
3 //
4 // Author:
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:
22 //
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 //
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;
36 using System.Drawing;
37 using System.Collections;
38 using System.Threading;
39 using System.Text;
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());
71 #if FilterDrawItem
72 if (m.Msg ==(int) Msg.WM_DRAWITEM) {
73 m.Result = (IntPtr)1;
75 else
76 control.WndProc (ref m);
77 #endif
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;
91 // private fields
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;
101 bool allowDrop;
102 AnchorStyles anchor;
103 internal Color backColor;
104 Image backgroundImage;
105 //BindingContext bindingContext;
106 Rectangle bounds;
107 Rectangle oldBounds;
109 bool causesValidation;
110 ContextMenu contextMenu;
111 DockStyle dock;
112 bool enabled;
113 Font font;
114 internal Color foreColor;
115 ImeMode imeMode;
116 bool isAccessible;
117 // Point location; // using bounds to store location
118 string name;
119 Region region;
120 RightToLeft rightToLeft;
121 bool tabStop;
122 internal string text;
123 internal bool visible;
124 internal ControlStyles controlStyles_;
125 Cursor cursor;
127 int clientWidth;
128 int clientHeight;
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;
145 object tag;
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) {
167 Method_ = method;
168 MethodArgs_ = args;
171 // IAsyncResult interface
172 object IAsyncResult.AsyncState {
173 get {
174 if (MethodArgs_ != null && MethodArgs_.Length != 0)
175 return MethodArgs_[MethodArgs_.Length - 1];
177 return null;
181 WaitHandle IAsyncResult.AsyncWaitHandle {
182 get {
183 return AsyncWaitHandle_;
187 bool IAsyncResult.CompletedSynchronously {
188 get {
189 return CompletedSynchronously_;
193 bool IAsyncResult.IsCompleted {
194 get {
195 return IsCompleted_;
199 internal bool CompletedSynchronously {
200 set {
201 CompletedSynchronously_ = value;
205 internal object MethodResult {
206 get {
207 return MethodResult_;
211 internal void ExecuteMethod () {
212 object result = Method_.DynamicInvoke (MethodArgs_);
213 lock (this) {
214 MethodResult_ = result;
215 IsCompleted_ = true;
217 AsyncWaitHandle_.Set ();
221 // --- Constructors ---
223 //Compact Framework //only Control ()
224 public 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;
235 allowDrop = false;
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;
243 contextMenu = null;
244 dock = DockStyle.None;
245 enabled = true;
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
251 name = "";
252 region = null;
253 rightToLeft = RightToLeft.Inherit;
254 tabStop = true;
255 text = "";
256 visible = true;
257 parent = null;
258 cursor = null;
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
272 // the (HWND) window
273 public Control (string text) : this ()
275 Text = text;
276 // SetWindowTextA (Handle, text);
279 public Control (Control parent, string text) : this (text)
281 Parent = parent;
282 // SetParent (Handle, parent.Handle);
285 public Control (string text, int left, int top,
286 int width, int height) : this (text)
288 Left = left;
289 Top = top;
290 Width = width;
291 Height = height;
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)
299 Left = left;
300 Top = top;
301 Width = width;
302 Height = height;
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 (
312 existingHandle);
315 // --- Properties ---
316 // Properties only supporting .NET framework, not stubbed out:
317 protected bool RenderRightToLeft {
318 get{
319 throw new NotImplementedException ();
322 public IWindowTarget WindowTarget {
323 get {
324 throw new NotImplementedException ();
326 set {
329 [MonoTODO]
330 public AccessibleObject AccessibilityObject {
331 get {
332 throw new NotImplementedException ();
336 public string AccessibleDefaultActionDescription {
337 get {
338 return accessibleDefaultActionDescription;
340 set {
341 accessibleDefaultActionDescription = value;
345 public string AccessibleDescription {
346 get {
347 return accessibleDescription;
349 set {
350 accessibleDescription=value;
354 public string AccessibleName {
355 get {
356 return accessibleName;
358 set {
359 accessibleName=value;
363 public AccessibleRole AccessibleRole {
364 get {
365 return accessibleRole;
367 set {
368 accessibleRole=value;
372 public virtual bool AllowDrop {
373 get {
374 return allowDrop;
376 set {
377 allowDrop=value;
381 public virtual AnchorStyles Anchor {
382 get {
383 return anchor;
385 set {
386 if (anchor != value){
387 anchor = value;
388 if (anchor != (AnchorStyles.Left | AnchorStyles.Top))
389 Dock = DockStyle.None;
394 //Compact Framework
395 public virtual Color BackColor {
396 get {
397 return backColor;
399 set {
400 if (backColor != value) {
401 backColor = value;
402 OnBackColorChanged (new EventArgs ());
407 public virtual Image BackgroundImage {
408 get {
409 return backgroundImage;
411 set {
412 backgroundImage = value;
413 // FIXME: force redraw
414 Invalidate ();
418 public virtual BindingContext BindingContext {
419 get {
420 //return bindingContext;
421 throw new NotImplementedException ();
423 set {
424 //bindingContext=value;
425 throw new NotImplementedException ();
429 //Compact Framework
430 public int Bottom {
431 get {
432 return Top + Height;
436 //Compact Framework
437 public Rectangle Bounds {
438 get {
439 return bounds;
441 set {
442 SetBounds (value.Left, value.Top, value.Width, value.Height);
446 public bool CanFocus {
447 get {
448 if (IsHandleCreated && Visible && Enabled)
449 return true;
450 return false;
454 [MonoTODO]
455 public bool CanSelect {
456 get {
457 if (!GetStyle (ControlStyles.Selectable))
458 return false;
460 if (Parent == null)
461 return false;
463 Control parent = Parent;
464 while (parent != null){
465 if (!parent.Visible || !parent.Enabled)
466 return false;
467 parent = parent.Parent;
470 return true;
474 //Compact Framework
475 public bool Capture {
476 get {
477 if (IsHandleCreated) {
478 IntPtr captured = Win32.GetCapture ();
479 if (Handle == captured)
480 return true;
482 return false;
484 set {
485 if (IsHandleCreated) {
486 if (value)
487 Win32.SetCapture (Handle);
488 else {
489 IntPtr captured = Win32.GetCapture ();
491 // if this window is in capture state
492 // release it
493 if (Handle == captured)
494 Win32.ReleaseCapture ();
500 public bool CausesValidation {
501 get {
502 return causesValidation;
504 set {
505 causesValidation=value;
509 //Compact Framework
510 public Rectangle ClientRectangle {
511 get {
512 return new Rectangle (0, 0, ClientSize.Width, ClientSize.Height);
517 //Compact Framework
518 [MonoTODO]
519 public Size ClientSize {
520 get {
521 return new Size (clientWidth, clientHeight);
523 set {
524 SetClientSizeCore (value.Width, value.Height);
528 [MonoTODO]
529 public string CompanyName {
530 get {
531 //Better than throwing an execption
532 return "Company Name";
536 public bool ContainsFocus {
537 get {
538 if (IsHandleCreated) {
539 if (Focused) return true;
540 foreach (Control ctr in Controls) {
541 if (ctr.ContainsFocus) return true;
544 return false;
548 //Compact Framework
549 [MonoTODO]
550 public virtual ContextMenu ContextMenu {
551 get {
552 return contextMenu;
554 set {
555 if (contextMenu != value){
556 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 {
571 get {
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;
582 if (parent != null)
583 createParams.Parent = parent.Handle;
584 else
585 createParams.Parent = ParkingWindowHandle;
587 createParams.Style = (int) WindowStyles.WS_OVERLAPPED;
588 if (visible) {
589 createParams.Style |= (int) WindowStyles.WS_VISIBLE;
592 return createParams;
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 ());
616 else {
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);
641 else {
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 ?
649 [MonoTODO]
650 public virtual Cursor Cursor {
651 get {
652 if (cursor == null)
653 return Cursors.Default;
654 return cursor;
656 set { cursor = value;}
659 //Compact Framework
660 [MonoTODO]
661 // waiting for BindingContext; should be stubbed now
662 public ControlBindingsCollection DataBindings {
663 get {
664 throw new NotImplementedException ();
668 public static Color DefaultBackColor {
669 get {
670 // FIXME: use GetSystemMetrics?
671 return SystemColors.Control;
672 //throw new NotImplementedException ();
676 //[MonoTODO]
677 // FIXME: use GetSystemMetrics?
678 public static Font DefaultFont {
679 // FIXME: get current system font from GenericSansSerif
680 // call ArgumentException not called
681 get {
682 // throw new NotImplementedException ();
683 // return (FontFamily.GenericSansSerif);
684 return Font.FromHfont (Win32.GetStockObject (GSO_.DEFAULT_GUI_FONT));
688 public static Color DefaultForeColor {
689 get {
690 return SystemColors.ControlText;
694 protected virtual ImeMode DefaultImeMode {
695 get {
696 return ImeMode.Inherit;
700 protected virtual Size DefaultSize {
701 get {
702 //Default label size, this should be correct.
703 return new Size (100,23);
707 public virtual Rectangle DisplayRectangle {
708 get {
709 return ClientRectangle;
713 public bool Disposing {
714 get { return statuses [ DISPOSING ]; }
717 public virtual DockStyle Dock {
718 get {
719 return dock;
721 set {
722 if (dock != value){
723 dock = value;
724 if (dock != DockStyle.None)
725 Anchor = (AnchorStyles.Left | AnchorStyles.Top);
726 OnDockChanged (EventArgs.Empty);
731 //Compact Framework
732 //public virtual bool Enabled {
733 public bool Enabled {
734 get {
735 return enabled;
736 //return Win32.IsWindowEnabled (Handle);
738 set {
739 if (enabled != value) {
740 if (IsHandleCreated) {
741 Win32.EnableWindow (Handle, value);
742 // FIXME: Disable/enable all children here
743 Invalidate ();
745 enabled = value;
750 //Compact Framework
751 public virtual bool Focused {
752 get {
753 if (IsHandleCreated) {
754 IntPtr focusedWindow = Win32.GetFocus ();
755 if (focusedWindow == Handle)
756 return true;
758 return false;
762 //Compact Framework
763 public virtual Font Font {
764 get {
765 Font result = font;
766 if (result == null) {
767 if (Parent != null) {
768 result = Parent.Font;
770 if (result == null) {
771 result = Control.DefaultFont;
774 return result;
776 set {
777 font = value;
778 if (IsHandleCreated) {
779 Win32.SendMessage (Handle, Msg.WM_SETFONT, Font.ToHfont ().ToInt32 (), 1);
784 [MonoTODO]
785 protected int FontHeight {
786 get {
787 throw new NotImplementedException ();
789 set {
790 throw new NotImplementedException ();
794 //Compact Framework
795 public virtual Color ForeColor {
796 get {
797 return foreColor;
799 set {
800 foreColor = value;
804 public bool HasChildren {
805 get {
806 if (childControls.Count >0)
807 return true;
808 return false;
812 //Compact Framework
813 public int Height {
814 get {
815 return bounds.Height;
817 set {
818 SetBounds (bounds.X, bounds.Y, bounds.Width, value, BoundsSpecified.Height);
822 public ImeMode ImeMode {
823 // CHECKME:
824 get {
825 return imeMode;
827 set {
828 imeMode=value;
832 public bool IsAccessible {
833 // CHECKME:
834 get {
835 return isAccessible;
836 } // default is false
837 set {
838 isAccessible=value;
842 public bool IsDisposed {
843 get { return statuses [ DISPOSED ]; }
846 public bool IsHandleCreated {
847 get { return window != null && window.Handle != IntPtr.Zero; }
850 //Compact Framework
851 public int Left {
852 get {
853 return bounds.X;
855 set {
856 SetBounds (value, bounds.Y, bounds.Width, bounds.Height, BoundsSpecified.X);
860 //Compact Framework
861 public Point Location {
862 // CHECKME:
863 get {
864 return new Point (Top, Left);
866 set {
867 SetBounds (value.X, value.Y, bounds.Width, bounds.Height, BoundsSpecified.Location);
871 public static Keys ModifierKeys {
872 get {
873 Keys keys = Keys.None;
875 if ( (Win32.GetKeyState ( (int) VirtualKeys.VK_SHIFT)& 0x8000)== 0x8000)
876 keys |= Keys.Shift;
877 if ( (Win32.GetKeyState ( (int) VirtualKeys.VK_MENU)& 0x8000) == 0x8000)
878 keys |= Keys.Alt;
879 if ( (Win32.GetKeyState ( (int) VirtualKeys.VK_CONTROL) & 0x8000) == 0x8000)
880 keys |= Keys.Control;
882 return keys;
886 //Compact Framework
887 public static MouseButtons MouseButtons {
888 get {
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;
903 return buttons;
907 //Compact Framework
908 public static Point MousePosition {
909 get {
910 POINT point = new POINT ();
911 Win32.GetCursorPos (ref point);
912 return new Point ( (int) point.x, (int) point.y);
916 public string Name {
917 // CHECKME:
918 get {
919 return name;
921 set {
922 name = value;
926 //Compact Framework
927 public Control Parent {
928 get {
929 return parent;
930 //IntPtr parent = GetParent (Handle);
931 //return FromHandle (parent);
933 set {
934 if (parent != value) {
935 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.
954 CreateControl ();
961 protected internal static IntPtr ParkingWindowHandle {
962 get {
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;
998 [MonoTODO]
999 public string ProductName {
1000 get {
1001 //FIXME:
1002 return "Product Name";
1006 [MonoTODO]
1007 public string ProductVersion {
1008 get {
1009 //FIXME:
1010 return "Product Version";
1014 [MonoTODO]
1015 public bool RecreatingHandle {
1016 get {
1017 return statuses [ RECREATING_HANDLE ] ;
1021 public Region Region {
1022 // CHECKME:
1023 get {
1024 return region;
1026 set {
1027 region = value;
1031 protected bool ResizeRedraw {
1032 get { return GetStyle (ControlStyles.ResizeRedraw); }
1033 set { SetStyle (ControlStyles.ResizeRedraw, value); }
1036 //Compact Framework
1037 public int Right {
1038 get {
1039 return Left + Width;
1043 [MonoTODO]
1044 public virtual RightToLeft RightToLeft {
1045 // CHECKME:
1046 get {
1047 return rightToLeft;
1049 set {
1050 rightToLeft=value;
1054 [MonoTODO]
1055 protected virtual bool ShowFocusCues {
1056 get {
1057 throw new NotImplementedException ();
1061 [MonoTODO]
1062 protected bool ShowKeyboardCues {
1063 get {
1064 throw new NotImplementedException ();
1068 [MonoTODO]
1069 public override ISite Site {
1070 get {
1071 throw new NotImplementedException ();
1073 set {
1074 throw new NotImplementedException ();
1078 //Compact Framework
1079 public Size Size {
1080 get {
1081 return new Size (Width, Height);
1083 set {
1084 SetBounds (bounds.X, bounds.Y, value.Width, value.Height, BoundsSpecified.Size);
1088 internal int tabindex;//for debug/test only. remove
1089 [MonoTODO]
1090 public int TabIndex {
1091 get {
1092 return tabindex;
1094 set {
1095 tabindex = value;
1099 public bool TabStop {
1100 // CHECKME:
1101 get {
1102 return tabStop;
1104 set {
1105 tabStop = value;
1109 [MonoTODO]
1110 public object Tag {
1111 get {
1112 return tag;
1114 set {
1115 tag = value;
1119 //Compact Framework
1120 public virtual string Text {
1121 get {
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 ();
1128 return text;
1130 set {
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 ();
1140 if (text != value){
1141 text = value;
1143 if (IsHandleCreated)
1144 Win32.SetWindowTextA (Handle, value);
1146 OnTextChanged (EventArgs.Empty);
1151 //Compact Framework
1152 public int Top {
1153 get {
1154 return bounds.Top;
1156 set {
1157 SetBounds (bounds.X, value, bounds.Width, bounds.Height, BoundsSpecified.Y);
1161 [MonoTODO]
1162 public Control TopLevelControl {
1163 get {
1164 throw new NotImplementedException ();
1168 public bool Visible {
1169 get { return visible; }
1170 set {
1171 SetVisibleCore (value);
1175 //Compact Framework
1176 public int Width {
1177 get {
1178 return bounds.Width;
1180 set {
1181 SetBounds (bounds.X, bounds.Y, value, bounds.Height, BoundsSpecified.Width);
1185 /// --- methods ---
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 ()
1211 [MonoTODO]
1212 protected void AccessibilityNotifyClients (
1213 AccessibleEvents accEvent,int childID)
1215 throw new NotImplementedException ();
1218 [MonoTODO]
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 ()
1233 if (!Created) {
1234 CreateHandle ();
1235 OnCreateControl ();
1236 statuses [ CREATED ] = true;
1240 [MonoTODO]
1241 protected virtual AccessibleObject CreateAccessibilityInstance () {
1242 throw new NotImplementedException ();
1245 protected virtual ControlCollection CreateControlsInstance ()
1247 return new ControlCollection (this);
1250 //Compact Framework
1251 [MonoTODO]
1252 public Graphics CreateGraphics ()
1254 return Graphics.FromHwnd (Handle);
1257 protected virtual void CreateHandle ()
1259 if (IsDisposed)
1260 throw new ObjectDisposedException (Name);
1262 if (IsHandleCreated)
1263 return;
1265 if (window == null)
1266 window = new ControlNativeWindow (this);
1268 CreateParams createParams = CreateParams;
1269 if (!Enabled) {
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);
1278 SubclassWindow ();
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)
1305 lock (this){
1306 statuses [ DISPOSING ] = true;
1307 try {
1308 if (disposing){
1309 DestroyHandle ();
1311 // close/free unmanaged resources
1313 finally {
1314 base.Dispose (disposing);
1316 statuses [ DISPOSED ] = true;
1320 [MonoTODO]
1321 public DragDropEffects DoDragDrop (
1322 object data, DragDropEffects allowedEffects)
1324 throw new NotImplementedException ();
1327 //public object EndInvoke (IAsyncResult asyncResult):
1328 //look under ISynchronizeInvoke methods
1330 [MonoTODO]
1331 public Form FindForm ()
1333 throw new NotImplementedException ();
1336 //Compact Framework
1337 public bool Focus ()
1339 if (Win32.SetFocus (Handle) != (IntPtr) 0)
1340 return true;
1341 return false;
1344 [MonoTODO]
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);
1354 return control;
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;
1362 return control;
1365 [MonoTODO]
1366 public Control GetChildAtPoint (Point pt)
1368 throw new NotImplementedException ();
1371 [MonoTODO]
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)
1385 return next;
1386 next = parent.GetNextControl (next, forward);
1388 return null;
1391 internal Control getNextFocusedControl (Control parent, bool forward)
1393 Control next = getNextFocusedControlCore (parent, FocusedControl, forward);
1394 if (next == null)
1395 next = getNextFocusedControlCore (parent, null, forward);
1396 return next;
1399 [MonoTODO]
1400 public Control GetNextControl (Control ctl, bool forward)
1402 Control next = null;
1404 if (ctl == null)
1405 next = Controls.GetFirstControl (forward);
1406 else {
1407 if (forward)
1408 next = getNextControlForward (ctl);
1409 else
1410 next = getNextControlBackward (ctl);
1412 return next;
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);
1424 if (next != null)
1425 return next;
1426 ctl = parent;
1427 parent = parent.Parent;
1429 return null;
1431 else
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);
1440 if (next != null){
1441 if (next.Controls.Count > 0)
1442 return next.Controls.GetFirstControl (false);
1443 else
1444 return next;
1446 return parent;
1448 else
1449 return Controls.GetFirstControl (false);
1452 [MonoTODO]
1453 protected bool GetStyle (ControlStyles flag)
1455 return (controlStyles_ & flag) != 0;
1458 [MonoTODO]
1459 protected bool GetTopLevel ()
1461 return statuses [ TOPLEVEL ];
1464 public void Hide ()
1466 Visible = false;
1469 [MonoTODO]
1470 protected virtual void InitLayout ()
1472 //FIXME:
1475 //Compact Framework
1476 public void Invalidate ()
1478 if (IsHandleCreated) {
1479 Win32.InvalidateRect (Handle, IntPtr.Zero, 1);
1483 public void Invalidate (bool invalidateChildren)
1485 Invalidate () ;
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)
1504 return c;
1507 return null;
1510 //Compact Framework
1511 public void Invalidate (Rectangle rc)
1513 if (IsHandleCreated) {
1514 RECT rect = new RECT ();
1515 rect.left = rc.Left;
1516 rect.top = rc.Top;
1517 rect.right = rc.Right;
1518 rect.bottom = rc.Bottom;
1519 Win32.InvalidateRect (Handle, ref rect, true);
1523 [MonoTODO]
1524 public void Invalidate (Region region)
1526 //FIXME:
1529 [MonoTODO]
1530 public void Invalidate (Rectangle rc, bool invalidateChildren)
1532 //FIXME:
1535 [MonoTODO]
1536 public void Invalidate (Region region,bool invalidateChildren)
1538 //FIXME:
1541 [MonoTODO]
1542 protected void InvokeGotFocus (Control toInvoke, EventArgs e)
1544 //FIXME:
1547 [MonoTODO]
1548 protected void InvokeLostFocus (Control toInvoke, EventArgs e)
1550 //FIXME:
1553 [MonoTODO]
1554 protected void InvokeOnClick (Control toInvoke, EventArgs e)
1556 //FIXME:
1559 [MonoTODO]
1560 protected void InvokePaint (Control c, PaintEventArgs e)
1562 //FIXME:
1565 [MonoTODO]
1566 protected void InvokePaintBackground (
1567 Control c,PaintEventArgs e)
1569 //FIXME:
1572 [MonoTODO]
1573 protected virtual bool IsInputChar (char charCode)
1575 return true;
1578 [MonoTODO]
1579 protected virtual bool IsInputKey (Keys keyData)
1581 return false;
1584 public static bool IsMnemonic (char charCode, string text)
1586 if (text == null)
1587 return false;
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);
1627 //Compact Framework
1628 protected virtual void OnClick (EventArgs e)
1630 if (Click != null)
1631 Click (this, e);
1635 protected virtual void OnContextMenuChanged (EventArgs e)
1637 if (ContextMenuChanged != null)
1638 ContextMenuChanged (this, e);
1641 protected virtual void OnControlAdded (ControlEventArgs e)
1643 if (Created){
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 ()
1660 //FIXME:
1661 // create all child windows
1662 IEnumerator cw = childControls.GetEnumerator ();
1664 while (cw.MoveNext ()) {
1665 Control control = (Control) cw.Current;
1666 control.CreateControl ();
1667 control.Show ();
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
1681 if (Parent != null)
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);
1717 //Compact Framework
1718 protected virtual void OnEnabledChanged (EventArgs e)
1720 if (EnabledChanged != null)
1721 EnabledChanged (this, e);
1724 protected virtual void OnEnter (EventArgs e)
1726 if (Enter != null)
1727 Enter (this, 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);
1748 //Compact Framework
1749 protected virtual void OnGotFocus (EventArgs e)
1751 if (GotFocus != null)
1752 GotFocus (this, e);
1755 protected virtual void OnHandleCreated (EventArgs e)
1757 if (font != null) {
1758 Win32.SendMessage (Handle, Msg.WM_SETFONT, font.ToHfont ().ToInt32 (), 0);
1759 } else {
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);
1798 //Compact Framework
1799 protected virtual void OnKeyDown (KeyEventArgs e)
1801 if (KeyDown != null)
1802 KeyDown (this, e);
1805 //Compact Framework
1806 protected virtual void OnKeyPress (KeyPressEventArgs e)
1808 if (KeyPress != null)
1809 KeyPress (this, e);
1812 //Compact Framework
1813 protected virtual void OnKeyUp (KeyEventArgs e)
1815 if (KeyUp != null)
1816 KeyUp (this, e);
1820 protected virtual void OnLayout (LayoutEventArgs levent)
1822 DoDockAndAnchorLayout (levent);
1823 if (Layout != null)
1824 Layout (this, levent);
1827 protected virtual void OnLeave (EventArgs e)
1829 if (Leave != null)
1830 Leave (this, e);
1833 protected virtual void OnLocationChanged (EventArgs e)
1835 if (LocationChanged != null)
1836 LocationChanged (this, e);
1839 //Compact Framework
1840 protected virtual void OnLostFocus (EventArgs e)
1842 if (LostFocus != null)
1843 LostFocus (this, e);
1846 //Compact Framework
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);
1875 //Compact Framework
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 ();
1883 tme.cbSize = 16;
1884 tme.hWnd = Handle;
1885 tme.dwFlags = (int)TrackerEventFlags.TME_LEAVE;
1886 tme.dwHoverTime = 0;
1888 bool result = Win32.TrackMouseEvent (ref tme);
1889 if (!result) {
1890 System.Console.WriteLine ("{0}",Win32.FormatMessage (Win32.GetLastError ()));
1894 POINT pt = new POINT ();
1895 pt.x = e.X;
1896 pt.y = e.Y;
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;
1907 else {
1908 if (!mouseIsInside_) {
1909 mouseIsInside_ = true;
1910 OnMouseEnter (new EventArgs ());
1913 if (MouseMove != null)
1914 MouseMove (this, e);
1917 //Compact Framework
1918 protected virtual void OnMouseUp (MouseEventArgs e)
1920 if (MouseUp != null)
1921 MouseUp (this, e);
1924 protected virtual void OnMouseWheel (MouseEventArgs e)
1926 if (MouseWheel != null)
1927 MouseWheel (this, e);
1930 protected virtual void OnMove (EventArgs e)
1932 if (Move != null)
1933 Move (this, e);
1936 protected virtual void OnNotifyMessage (Message m)
1938 //FIXME:
1941 //Compact Framework
1942 protected virtual void OnPaint (PaintEventArgs e)
1944 if (Paint != null)
1945 Paint (this, e);
1948 //Compact Framework
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);
1954 br.Dispose ();
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 (
1970 EventArgs e)
1972 if (BackgroundImageChanged != null)
1973 BackgroundImageChanged (this, e);
1976 protected virtual void OnParentBindingContextChanged (
1977 EventArgs e)
1979 if (BindingContextChanged != null)
1980 BindingContextChanged (this, e);
1983 //Compact Framework
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 (
2009 EventArgs e)
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);
2028 //Compact Framework
2029 protected virtual void OnResize (EventArgs e)
2031 if (Resize != null)
2032 Resize (this, 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)
2045 OnResize (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);
2074 //Compact Framework
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);
2084 // }
2086 protected virtual void OnValidated (EventArgs e)
2088 if (Validated != null)
2089 Validated (this, e);
2092 [MonoTODO]
2093 // CancelEventArgs not ready
2094 protected virtual void OnValidating (CancelEventArgs e)
2096 throw new NotImplementedException ();
2099 [MonoTODO]
2100 protected virtual void OnVisibleChanged (EventArgs e)
2102 if (VisibleChanged != null)
2103 VisibleChanged (this, e);
2105 PerformLayout ();
2107 // --- end of methods for events ---
2110 [MonoTODO]
2111 public void PerformLayout ()
2113 PerformLayout (null, null);
2116 [MonoTODO]
2117 public void PerformLayout (Control affectedControl,
2118 string affectedProperty)
2120 if (!statuses [ LAYOUT_SUSPENDED ])
2121 OnLayout (new LayoutEventArgs (affectedControl, affectedProperty));
2122 else
2123 statuses [ LAYOUT_PENDING ] = true;
2126 //Compact Framework
2127 public Point PointToClient ( Point p )
2129 POINT pt = new POINT();
2130 pt.x = p.X;
2131 pt.y = p.Y;
2132 Win32.ScreenToClient( Handle, ref pt);
2133 return new Point ( pt.x, pt.y );
2136 //Compact Framework
2137 public Point PointToScreen ( Point p )
2139 POINT pt = new POINT();
2140 pt.x = p.X;
2141 pt.y = p.Y;
2142 Win32.ClientToScreen ( Handle, ref pt);
2143 return new Point ( pt.x, pt.y );
2146 [MonoTODO]
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))
2153 return false;
2155 return ProcessDialogKey (keyData);
2157 return true;
2159 else if ((uint)msg.Msg == (uint) Msg.WM_CHAR){
2160 if (IsInputChar ( (char) msg.WParam))
2161 return false;
2163 return ProcessDialogChar ( (char) msg.WParam);
2166 return false;
2169 [MonoTODO]
2170 protected virtual bool ProcessCmdKey (ref Message msg,
2171 Keys keyData)
2173 // do something with context menu
2175 if (Parent != null)
2176 return Parent.ProcessCmdKey (ref msg, keyData);
2177 return false;
2180 [MonoTODO]
2181 protected virtual bool ProcessDialogChar (char charCode)
2183 if (Parent != null)
2184 return Parent.ProcessDialogChar (charCode);
2185 return false;
2188 [MonoTODO]
2189 protected virtual bool ProcessDialogKey (Keys keyData)
2191 if (Parent != null)
2192 return Parent.ProcessDialogKey (keyData);
2193 return false;
2196 [MonoTODO]
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;
2206 break;
2207 case Msg.WM_CHAR:
2208 KeyPressEventArgs args_press = new KeyPressEventArgs ( (char) m.WParam);
2209 OnKeyPress (args_press);
2210 handled = args_press.Handled;
2211 break;
2212 case Msg.WM_KEYUP:
2213 KeyEventArgs args_up = new KeyEventArgs ( (Keys)m.WParam.ToInt32 ());
2214 OnKeyUp (args_up);
2215 handled = args_up.Handled;
2216 break;
2219 return handled;
2222 [MonoTODO]
2223 protected internal virtual bool ProcessKeyMessage (ref Message m)
2225 if (Parent != null){
2226 if (!Parent.ProcessKeyPreview (ref m))
2227 return ProcessKeyEventArgs (ref m);
2229 return false;
2232 [MonoTODO]
2233 protected virtual bool ProcessKeyPreview (ref Message m)
2235 if (Parent != null)
2236 return Parent.ProcessKeyPreview (ref m);
2237 return false;
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)
2244 return false;
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) {
2253 DestroyHandle ();
2254 CreateHandle ();
2256 UpdateZOrder ();
2258 IEnumerator cw = childControls.GetEnumerator ();
2259 while (cw.MoveNext ())
2260 ( (Control)cw.Current).RecreateHandle ();
2263 statuses [ RECREATING_HANDLE ] = false;
2266 //Compact Framework
2267 public Rectangle RectangleToClient (Rectangle r)
2269 RECT rect = new RECT ();
2270 rect.left = r.Left;
2271 rect.top = r.Top;
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);
2278 //Compact Framework
2279 public Rectangle RectangleToScreen (Rectangle r)
2281 RECT rect = new RECT ();
2282 rect.left = r.Left;
2283 rect.top = r.Top;
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);
2290 [MonoTODO]
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);
2296 result = true;
2298 return result;
2301 public virtual void Refresh ()
2303 Win32.UpdateWindow (Handle);
2306 [MonoTODO]
2307 public virtual void ResetBackColor ()
2309 //FIXME:
2312 [MonoTODO]
2313 public void ResetBindings ()
2315 //FIXME:
2318 [MonoTODO]
2319 public virtual void ResetFont ()
2321 //FIXME:
2324 [MonoTODO]
2325 public virtual void ResetForeColor ()
2327 //FIXME:
2330 [MonoTODO]
2331 public void ResetImeMode ()
2333 //FIXME:
2335 public virtual void ResetCursor(){
2338 [MonoTODO]
2339 public virtual void ResetRightToLeft ()
2341 //FIXME:
2344 [MonoTODO]
2345 public virtual void ResetText ()
2347 //FIXME:
2350 [MonoTODO]
2351 public void ResumeLayout ()
2353 statuses [ LAYOUT_SUSPENDED ] = false;
2354 if (statuses [ LAYOUT_PENDING ]){
2355 PerformLayout ();
2356 statuses [ LAYOUT_PENDING ] = false;
2360 [MonoTODO]
2361 public void ResumeLayout (bool performLayout)
2363 statuses [ LAYOUT_SUSPENDED ] = false;
2364 if (performLayout && statuses [ LAYOUT_PENDING ]){
2365 PerformLayout ();
2366 statuses [ LAYOUT_PENDING ] = false;
2370 [MonoTODO]
2371 protected ContentAlignment RtlTranslateAlignment (
2372 ContentAlignment align)
2374 throw new NotImplementedException ();
2377 [MonoTODO]
2378 protected HorizontalAlignment RtlTranslateAlignment (
2379 HorizontalAlignment align)
2381 throw new NotImplementedException ();
2384 [MonoTODO]
2385 protected LeftRightAlignment RtlTranslateAlignment (
2386 LeftRightAlignment align)
2388 throw new NotImplementedException ();
2391 [MonoTODO]
2392 protected ContentAlignment RtlTranslateContent (
2393 ContentAlignment align)
2395 throw new NotImplementedException ();
2398 [MonoTODO]
2399 protected HorizontalAlignment RtlTranslateHorizontal (
2400 HorizontalAlignment align)
2402 throw new NotImplementedException ();
2405 [MonoTODO]
2406 protected LeftRightAlignment RtlTranslateLeftRight (
2407 LeftRightAlignment align)
2409 throw new NotImplementedException ();
2412 public void Scale (float ratio)
2414 Scale (ratio, ratio);
2417 [MonoTODO]
2418 public void Scale (float dx,float dy)
2420 SuspendLayout ();
2421 ScaleCore (dx, dy);
2422 IEnumerator cw = childControls.GetEnumerator ();
2423 while (cw.MoveNext ()){
2424 Control control = (Control) cw.Current;
2425 control.Scale (dx, dy);
2427 ResumeLayout ();
2430 [MonoTODO]
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));
2438 [MonoTODO]
2439 public void Select ()
2441 //FIXME:
2444 [MonoTODO]
2445 protected virtual void Select (bool directed,bool forward)
2447 //FIXME:
2450 [MonoTODO]
2451 public bool SelectNextControl (Control ctl, bool forward,
2452 bool tabStopOnly,
2453 bool nested, bool wrap)
2455 throw new NotImplementedException ();
2458 //Compact Framework
2459 [MonoTODO]
2460 public void SendToBack ()
2462 //FIXME:
2465 [MonoTODO]
2466 public void SetBounds (int x, int y, int width, int height)
2468 SetBounds (x, y, width, height, BoundsSpecified.All);
2471 [MonoTODO]
2472 public void SetBounds (int x, int y, int width, int height, BoundsSpecified specified)
2474 SetBoundsCore (x, y, width, height, specified);
2477 [MonoTODO]
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; }
2497 [MonoTODO]
2498 protected virtual void SetClientSizeCore (int x, int y)
2500 RECT rc = new RECT ();
2501 rc.right = x;
2502 rc.bottom = y;
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);
2510 [MonoTODO]
2511 protected void SetStyle (ControlStyles flag, bool value)
2513 if (value) {
2514 controlStyles_ |= flag;
2516 else {
2517 controlStyles_ &= ~flag;
2521 protected void SetTopLevel (bool value)
2523 if (value)
2524 // FIXME: verify on whether this is supposed
2525 // to activate/deactive the window
2526 Win32.SetWindowPos (Handle,
2527 SetWindowPosZOrder.HWND_NOTOPMOST,
2528 0, 0, 0, 0, 0);
2529 else
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;
2540 [MonoTODO]
2541 protected virtual void SetVisibleCore (bool value)
2543 bool visibleChanged = (visible != value);
2545 visible = value;
2547 if (visibleChanged)
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)
2557 c.Visible = value ;
2560 public void Show ()
2562 if (!IsHandleCreated)
2563 CreateHandle ();
2565 Visible = true;
2568 public void SuspendLayout ()
2570 statuses [ LAYOUT_SUSPENDED ] = true;
2573 //Compact Framework
2574 public void Update ()
2576 Win32.UpdateWindow (Handle);
2579 [MonoTODO]
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
2585 // are created
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);
2597 [MonoTODO]
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 ();
2606 rc.right = width;
2607 rc.bottom = height;
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);
2617 [MonoTODO]
2618 protected void UpdateBounds (
2619 int x, int y, int width, int height, int clientWidth,
2620 int clientHeight)
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);
2628 bounds.X = x;
2629 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);
2648 if (bSizeChanged)
2649 OnSizeChanged (EventArgs.Empty);
2652 [MonoTODO]
2653 protected void UpdateStyles ()
2655 //FIXME:
2658 [MonoTODO]
2659 protected void UpdateZOrder ()
2661 if (!IsHandleCreated || Parent == null)
2662 return;
2664 int position = Parent.Controls.GetChildIndex (this , false);
2665 switch (position){
2666 case 0:
2667 BringToFront ();
2668 break;
2669 // not in collection for some reason
2670 case -1:
2671 break;
2672 default:
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);
2676 break;
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
2704 // message
2706 // These On... functions do not appear to be called by
2707 // WndProc:
2709 // background color/image handled by WinForms
2710 // OnBackColorChanged
2711 // OnBackgroundImageChanged
2712 // OnForeColorChanged
2713 // OnPaintBackground
2715 // controls are added/removed by WinForms
2716 // OnControlAdded
2717 // OnControlRemoved
2718 // OnCreateControl
2720 // OnBindingContextChanged
2721 // OnCausesValidationChanged
2722 // OnChangeUICues
2723 // OnContextMenuChanged
2724 // OnRightToLeftChanged
2725 // OnGiveFeedback
2726 // OnLayout
2727 // OnDockChanged
2728 // OnCursorChanged
2729 // OnTextAlignChanged
2730 // OnValidated
2731 // OnValidating
2732 // OnTabIndexChanged
2733 // OnTabStopChanged
2734 // OnLocationChanged
2736 // FIXME: may be one of the WM_IME_ messages
2737 // OnImeModeChanged
2739 // InvalidateRect is called by no Invalidate message exists
2740 // OnInvalidated
2742 // these messages ARE not called by WNDPROC according to docs
2743 // OnParentBackColorChanged
2744 // OnParentBackgroundImageChanged
2745 // OnParentBindingContextChanged
2746 // OnParentChanged
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 ();
2771 return;
2773 else if ((uint)m.Msg == (uint) Msg.WM_COMMAND) {
2774 // Notification
2775 m.Result = (IntPtr)1;
2776 OnWmCommand (ref m);
2777 if (m.Result != IntPtr.Zero) {
2778 CallControlWndProc (ref m);
2780 return;
2783 switch ((Msg) m.Msg) {
2784 case Msg.WM_CREATE:
2785 Console.WriteLine("WM_CREATE");
2786 OnHandleCreated (eventArgs);
2787 break;
2788 case Msg.WM_LBUTTONDBLCLK:
2789 OnDoubleClick (eventArgs);
2790 CallControlWndProc (ref m);
2791 break;
2792 // OnDragDrop
2793 // OnDragEnter
2794 // OnDragLeave
2795 // OnDragOver
2796 // OnQueryContinueDrag
2797 case Msg.WM_ENABLE:
2798 OnEnabledChanged (eventArgs);
2799 CallControlWndProc (ref m);
2800 break;
2801 case Msg.WM_SETFOCUS:
2802 OnEnter (eventArgs);
2803 OnGotFocus (eventArgs);
2804 CallControlWndProc (ref m);
2805 break;
2806 case Msg.WM_FONTCHANGE:
2807 OnFontChanged (eventArgs);
2808 CallControlWndProc (ref m);
2809 break;
2810 case Msg.WM_DESTROY:
2811 OnHandleDestroyed (eventArgs);
2812 CallControlWndProc (ref m);
2813 break;
2814 case Msg.WM_HELP:
2815 // FIXME:
2816 //OnHelpRequested (eventArgs);
2817 CallControlWndProc (ref m);
2818 break;
2819 case Msg.WM_KEYDOWN:
2820 if (!ProcessKeyMessage (ref m))
2821 CallControlWndProc (ref m);
2822 break;
2823 case Msg.WM_CHAR:
2824 if (!ProcessKeyMessage (ref m))
2825 CallControlWndProc (ref m);
2826 break;
2827 case Msg.WM_KEYUP:
2828 if (!ProcessKeyMessage (ref m))
2829 CallControlWndProc (ref m);
2830 break;
2831 case Msg.WM_KILLFOCUS:
2832 OnLeave (eventArgs);
2833 OnLostFocus (eventArgs);
2834 CallControlWndProc (ref m);
2835 break;
2836 case Msg.WM_MOUSEACTIVATE:
2837 //OnMouseEnter (eventArgs);
2838 CallControlWndProc (ref m);
2839 break;
2840 case Msg.WM_MOUSEHOVER: // called by TrackMouseEvent
2841 OnMouseHover (eventArgs);
2842 CallControlWndProc (ref m);
2843 break;
2844 case Msg.WM_MOUSELEAVE: // called by TrackMouseEvent
2845 OnMouseLeave (eventArgs);
2846 CallControlWndProc (ref m);
2847 break;
2848 case Msg.WM_MOUSEMOVE:
2849 // FIXME:
2850 OnMouseMove (Msg2MouseEventArgs (ref m));
2851 CallControlWndProc (ref m);
2852 break;
2853 case Msg.WM_LBUTTONDOWN:
2854 // FIXME:
2855 OnMouseDown (Msg2MouseEventArgs(ref m));
2856 CallControlWndProc (ref m);
2857 break;
2858 case Msg.WM_LBUTTONUP:
2859 // FIXME:
2860 OnMouseUp (Msg2MouseEventArgs(ref m));
2861 CallControlWndProc (ref m);
2862 break;
2863 case Msg.WM_MOUSEWHEEL:
2864 // FIXME:
2865 //OnMouseWheel (eventArgs);
2866 CallControlWndProc (ref m);
2867 break;
2868 case Msg.WM_MOVE:
2869 OnMove (eventArgs);
2870 UpdateBounds ();
2871 CallControlWndProc (ref m);
2872 break;
2873 case Msg.WM_CTLCOLOREDIT :
2874 if ( !Control.ReflectMessage ( m.LParam, ref m ) )
2875 CallControlWndProc ( ref m );
2876 break;
2877 //case Msg.WM_CTLCOLORSTATIC:
2878 // if ( !Control.ReflectMessage ( m.LParam, ref m ) )
2879 // CallControlWndProc ( ref m );
2880 //break;
2881 case Msg.WM_NOTIFY:
2882 NMHDR nmhdr = (NMHDR)Marshal.PtrToStructure (m.LParam,
2883 typeof (NMHDR));
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);
2890 break;
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;
2900 else {
2901 CallControlWndProc (ref m);
2903 break;
2904 case Msg.WM_PAINT:
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;
2921 beginPaint = true;
2922 } else {
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 ();
2937 if(beginPaint)
2938 Win32.EndPaint (Handle, ref ps);
2939 else
2940 Win32.ReleaseDC (Handle, hdc);
2942 break;
2943 case Msg.WM_SIZE:
2944 if (GetStyle (ControlStyles.ResizeRedraw)) {
2945 Invalidate ();
2947 CallControlWndProc (ref m);
2948 break;
2949 case Msg.WM_WINDOWPOSCHANGED:
2950 UpdateBounds ();
2951 CallControlWndProc (ref m);
2952 break;
2953 case Msg.WM_STYLECHANGED:
2954 OnStyleChanged (eventArgs);
2955 CallControlWndProc (ref m);
2956 break;
2957 case Msg.WM_SYSCOLORCHANGE:
2958 OnSystemColorsChanged (eventArgs);
2959 CallControlWndProc (ref m);
2960 break;
2961 case Msg.WM_SETTEXT:
2962 //OnTextChanged (eventArgs);
2963 CallControlWndProc (ref m);
2964 break;
2965 case Msg.WM_SETFONT:
2966 //OnTextChanged (eventArgs);
2967 CallControlWndProc (ref m);
2968 break;
2969 case Msg.WM_SHOWWINDOW:
2970 OnVisibleChanged (eventArgs);
2971 CallControlWndProc (ref m);
2972 break;
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);
2977 break;
2978 case Msg.WM_MEASUREITEM:
2979 ReflectMessage (m.WParam, ref m);
2980 break;
2981 case Msg.WM_DRAWITEM:
2982 Control.ReflectMessage (m.WParam, ref m);
2983 break;
2984 case Msg.WM_HSCROLL:
2985 case Msg.WM_VSCROLL:
2986 if (!Control.ReflectMessage (m.LParam, ref m)) {
2987 CallControlWndProc (ref m);
2989 break;
2990 case Msg.WM_SETCURSOR:
2991 if (cursor != null && cursor.Handle != IntPtr.Zero){
2992 Win32.SetCursor (cursor.Handle);
2993 m.Result = (IntPtr)1;
2994 } else
2995 CallControlWndProc (ref m);
2996 break;
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);
3005 break;
3006 default:
3007 CallControlWndProc (ref m);
3009 if (ControlRealWndProc != IntPtr.Zero) {
3010 CallControlWndProc (ref m);
3012 else {
3013 DefWndProc (ref m);
3016 break;
3020 private void DoAnchor (Control ctrl)
3022 // the default, no actions are needed
3023 if (ctrl.Anchor == (AnchorStyles.Left | AnchorStyles.Top))
3024 return;
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;
3048 else {
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;
3057 else {
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;
3080 break;
3081 case DockStyle.Top:
3082 control.SetBounds (area.Left, area.Y, area.Width, control.Height);
3083 area.Y += control.Height;
3084 area.Height -= control.Height;
3085 break;
3086 case DockStyle.Right:
3087 control.SetBounds (area.Right - control.Width, area.Top,
3088 control.Width, area.Height);
3089 area.Width -= control.Width;
3090 break;
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;
3095 break;
3096 case DockStyle.None:
3097 DoAnchor (control);
3098 break;
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 {
3112 get {
3113 IEnumerator cw = controlsCollection.GetEnumerator ();
3115 while (cw.MoveNext ()){
3116 Control c = ( (DictionaryEntry) cw.Current).Value as Control;
3118 if (c.Focused)return c;
3121 return null;
3125 internal Control getParentForm ()
3127 Control parent = this.Parent;
3128 while (parent != null){
3129 if (parent is Form)
3130 return parent;
3131 parent = parent.Parent;
3133 return null;
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;
3143 //Compact Framework
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;
3157 //Compact Framework
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;
3165 //Compact Framework
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;
3174 //Compact Framework
3175 public event KeyEventHandler KeyDown;
3177 //Compact Framework
3178 public event KeyPressEventHandler KeyPress;
3180 //Compact Framework
3181 public event KeyEventHandler KeyUp;
3183 public event LayoutEventHandler Layout;
3184 public event EventHandler Leave;
3185 public event EventHandler LocationChanged;
3187 //Compact Framework
3188 public event EventHandler LostFocus;
3190 //Compact Framework
3191 public event MouseEventHandler MouseDown;
3193 public event EventHandler MouseEnter;
3194 public event EventHandler MouseHover;
3195 public event EventHandler MouseLeave;
3197 //Compact Framework
3198 public event MouseEventHandler MouseMove;
3200 //Compact Framework
3201 public event MouseEventHandler MouseUp;
3203 public event MouseEventHandler MouseWheel;
3204 public event EventHandler Move;
3206 //Compact Framework
3207 public event PaintEventHandler Paint;
3209 //Compact Framework
3210 public event EventHandler ParentChanged;
3212 public event QueryAccessibilityHelpEventHandler QueryAccessibilityHelp;
3213 public event QueryContinueDragEventHandler QueryContinueDrag;
3215 //Compact Framework
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;
3225 //Compact Framework
3226 public event EventHandler TextChanged;
3228 public event EventHandler Validated;
3229 //[MonoTODO]
3230 // CancelEventHandler not yet defined
3231 public event CancelEventHandler Validating;
3233 public event EventHandler VisibleChanged;
3235 /// --- IWin32Window properties
3236 public IntPtr Handle {
3237 get {
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)
3243 CreateHandle ();
3245 return window.Handle;
3249 /// --- ISynchronizeInvoke properties ---
3250 [MonoTODO]
3251 public bool InvokeRequired {
3252 get {
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) {
3261 lock (this) {
3262 lock (InvokeQueue_.SyncRoot) {
3263 InvokeQueue_.Enqueue (helper);
3265 Win32.PostMessage (Handle, Control.InvokeMessage, 0, 0);
3266 result = helper;
3269 else {
3270 helper.CompletedSynchronously = true;
3271 helper.ExecuteMethod ();
3272 result = helper;
3274 return result;
3277 /// --- ISynchronizeInvoke methods ---
3278 [MonoTODO]
3279 public IAsyncResult BeginInvoke (Delegate method)
3281 return DoInvoke (method, null);
3284 [MonoTODO]
3285 public IAsyncResult BeginInvoke (Delegate method, object[] args)
3287 return DoInvoke (method, args);
3290 [MonoTODO]
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;
3301 return result;
3304 //Compact Framework
3305 [MonoTODO]
3306 public object Invoke (Delegate method)
3308 return Invoke (method, null);
3311 //[MonoTODO]
3312 public object Invoke (Delegate method, object[] args)
3314 IAsyncResult result = BeginInvoke (method, args);
3315 return EndInvoke (result);
3318 /// sub-class: Control.ControlAccessibleObject
3319 /// <summary>
3320 /// Provides information about a control that can be used by an accessibility application.
3321 /// </summary>
3322 public class ControlAccessibleObject : AccessibleObject {
3323 /// --- ControlAccessibleObject.constructor ---
3324 [MonoTODO]
3325 public ControlAccessibleObject (Control ownerControl)
3327 throw new NotImplementedException ();
3331 /// --- ControlAccessibleObject Properties ---
3332 [MonoTODO]
3333 public override string DefaultAction {
3334 get {
3335 //FIXME:
3336 return base.DefaultAction;
3340 [MonoTODO]
3341 public override string Description {
3342 get {
3343 //FIXME:
3344 return base.Description;
3348 [MonoTODO]
3349 public IntPtr Handle {
3350 get {
3351 throw new NotImplementedException ();
3353 set {
3354 //FIXME:
3358 [MonoTODO]
3359 public override string Help {
3360 get {
3361 //FIXME:
3362 return base.Help;
3366 [MonoTODO]
3367 public override string KeyboardShortcut {
3368 get {
3369 //FIXME:
3370 return base.KeyboardShortcut;
3374 [MonoTODO]
3375 public override string Name {
3376 get {
3377 //FIXME:
3378 return base.Name;
3380 set {
3381 //FIXME:
3382 base.Name = value;
3386 [MonoTODO]
3387 public Control Owner {
3388 get {
3389 throw new NotImplementedException ();
3393 [MonoTODO]
3394 public override AccessibleRole Role {
3395 get {
3396 //FIXME:
3397 return base.Role;
3401 /// --- ControlAccessibleObject Methods ---
3402 [MonoTODO]
3403 public override int GetHelpTopic (out string fileName)
3405 //FIXME:
3406 return base.GetHelpTopic (out fileName);
3409 [MonoTODO]
3410 public void NotifyClients (AccessibleEvents accEvent)
3412 //FIXME:
3415 [MonoTODO]
3416 public void NotifyClients (AccessibleEvents accEvent,
3417 int childID)
3419 //FIXME:
3422 [MonoTODO]
3423 public override string ToString ()
3425 //FIXME:
3426 return base.ToString ();
3430 /// sub-class: Control.ControlCollection
3431 /// <summary>
3432 /// Represents a collection of Control objects
3433 /// </summary>
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;
3443 if (tx > ty)
3444 return 1;
3445 else if (tx < ty)
3446 return -1;
3447 else
3448 return 0;
3452 private ArrayList collection = new ArrayList ();
3453 protected Control owner;
3455 /// --- ControlCollection.constructor ---
3456 public ControlCollection (Control owner)
3458 this.owner = owner;
3461 /// --- ControlCollection Properties ---
3462 public int Count {
3463 get {
3464 return collection.Count;
3468 public bool IsReadOnly {
3469 get {
3470 return collection.IsReadOnly;
3474 public virtual Control this [int index] {
3475 get {
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++) {
3492 Add (controls[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);
3511 [MonoTODO]
3512 public override bool Equals (object obj)
3514 //FIXME:
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.");
3528 return index;
3531 public IEnumerator GetEnumerator ()
3533 return collection.GetEnumerator ();
3536 [MonoTODO]
3537 public override int GetHashCode ()
3539 //FIXME:
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);
3563 if (oldIndex == -1)
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);
3571 else
3572 collection.Insert (newIndex, child);
3576 internal Control GetFirstControl (bool direction)
3578 if (collection.Count == 0)
3579 return null;
3581 ArrayList copy = collection.Clone () as ArrayList;
3582 copy.Sort (new ControlComparer ());
3584 if (direction)
3585 return copy [0] as Control;
3586 else {
3587 Control last = copy[ collection.Count - 1 ] as Control;
3588 if (last.Controls.Count == 0)
3589 return last;
3590 else
3591 return last.Controls.GetFirstControl (false);
3596 internal Control GetNextControl (Control ctl, bool forward)
3598 if (collection.Count == 0)
3599 return null;
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;
3609 return null;
3612 /// --- ControlCollection.IClonable methods ---
3613 [MonoTODO]
3614 object ICloneable.Clone ()
3616 throw new NotImplementedException ();
3619 /// --- ControlCollection.IList properties ---
3620 bool IList.IsFixedSize {
3621 get {
3622 return collection.IsFixedSize;
3626 object IList.this [int index] {
3627 get {
3628 return collection[index];
3630 set {
3631 collection[index] = value;
3635 object ICollection.SyncRoot {
3636 get {
3637 return collection.SyncRoot;
3641 bool ICollection.IsSynchronized {
3642 get {
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 ---