PageRenderTime 81ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs

https://bitbucket.org/danipen/mono
C# | 6728 lines | 5302 code | 1158 blank | 268 comment | 1215 complexity | 78e5bdf745b8d860b07ccbff92d06a4c MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2004-2006 Novell, Inc.
  21. //
  22. // Authors:
  23. // Peter Bartok pbartok@novell.com
  24. //
  25. // Partially based on work by:
  26. // Aleksey Ryabchuk ryabchuk@yahoo.com
  27. // Alexandre Pigolkine pigolkine@gmx.de
  28. // Dennis Hayes dennish@raytek.com
  29. // Jaak Simm jaaksimm@firm.ee
  30. // John Sohn jsohn@columbus.rr.com
  31. //
  32. #undef DebugRecreate
  33. #undef DebugFocus
  34. #undef DebugMessages
  35. using System;
  36. using System.ComponentModel;
  37. using System.ComponentModel.Design;
  38. using System.ComponentModel.Design.Serialization;
  39. using System.Collections;
  40. using System.Diagnostics;
  41. using System.Drawing;
  42. using System.Drawing.Drawing2D;
  43. using System.Reflection;
  44. using System.Runtime.InteropServices;
  45. using System.Security;
  46. using System.Threading;
  47. namespace System.Windows.Forms
  48. {
  49. [ComVisible(true)]
  50. [ClassInterface (ClassInterfaceType.AutoDispatch)]
  51. [Designer("System.Windows.Forms.Design.ControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
  52. [DefaultProperty("Text")]
  53. [DefaultEvent("Click")]
  54. [DesignerSerializer("System.Windows.Forms.Design.ControlCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
  55. [ToolboxItemFilter("System.Windows.Forms")]
  56. public class Control : Component, ISynchronizeInvoke, IWin32Window
  57. , IBindableComponent, IDropTarget, IBounds
  58. {
  59. #region Local Variables
  60. // Basic
  61. internal Rectangle bounds; // bounding rectangle for control (client area + decorations)
  62. Rectangle explicit_bounds; // explicitly set bounds
  63. internal object creator_thread; // thread that created the control
  64. internal ControlNativeWindow window; // object for native window handle
  65. private IWindowTarget window_target;
  66. string name; // for object naming
  67. // State
  68. bool is_created; // true if OnCreateControl has been sent
  69. internal bool has_focus; // true if control has focus
  70. internal bool is_visible; // true if control is visible
  71. internal bool is_entered; // is the mouse inside the control?
  72. internal bool is_enabled; // true if control is enabled (usable/not grayed out)
  73. bool is_accessible; // true if the control is visible to accessibility applications
  74. bool is_captured; // tracks if the control has captured the mouse
  75. internal bool is_toplevel; // tracks if the control is a toplevel window
  76. bool is_recreating; // tracks if the handle for the control is being recreated
  77. bool causes_validation; // tracks if validation is executed on changes
  78. bool is_focusing; // tracks if Focus has been called on the control and has not yet finished
  79. int tab_index; // position in tab order of siblings
  80. bool tab_stop; // is the control a tab stop?
  81. bool is_disposed; // has the window already been disposed?
  82. bool is_disposing; // is the window getting disposed?
  83. Size client_size; // size of the client area (window excluding decorations)
  84. Rectangle client_rect; // rectangle with the client area (window excluding decorations)
  85. ControlStyles control_style; // rather win32-specific, style bits for control
  86. ImeMode ime_mode;
  87. object control_tag; // object that contains data about our control
  88. internal int mouse_clicks; // Counter for mouse clicks
  89. Cursor cursor; // Cursor for the window
  90. internal bool allow_drop; // true if the control accepts droping objects on it
  91. Region clip_region; // User-specified clip region for the window
  92. // Visuals
  93. internal Color foreground_color; // foreground color for control
  94. internal Color background_color; // background color for control
  95. Image background_image; // background image for control
  96. internal Font font; // font for control
  97. string text; // window/title text for control
  98. internal BorderStyle border_style; // Border style of control
  99. bool show_keyboard_cues; // Current keyboard cues
  100. internal bool show_focus_cues; // Current focus cues
  101. internal bool force_double_buffer; // Always doublebuffer regardless of ControlStyle
  102. // Layout
  103. internal enum LayoutType {
  104. Anchor,
  105. Dock
  106. }
  107. Layout.LayoutEngine layout_engine;
  108. internal int layout_suspended;
  109. bool layout_pending; // true if our parent needs to re-layout us
  110. internal AnchorStyles anchor_style; // anchoring requirements for our control
  111. internal DockStyle dock_style; // docking requirements for our control
  112. LayoutType layout_type;
  113. private bool recalculate_distances = true; // Delay anchor calculations
  114. // Please leave the next 2 as internal until DefaultLayout (2.0) is rewritten
  115. internal int dist_right; // distance to the right border of the parent
  116. internal int dist_bottom; // distance to the bottom border of the parent
  117. // to be categorized...
  118. ControlCollection child_controls; // our children
  119. Control parent; // our parent control
  120. BindingContext binding_context;
  121. RightToLeft right_to_left; // drawing direction for control
  122. ContextMenu context_menu; // Context menu associated with the control
  123. internal bool use_compatible_text_rendering;
  124. private bool use_wait_cursor;
  125. //accessibility
  126. string accessible_name;
  127. string accessible_description;
  128. string accessible_default_action;
  129. AccessibleRole accessible_role = AccessibleRole.Default;
  130. AccessibleObject accessibility_object; // object that contains accessibility information about our control
  131. // double buffering
  132. DoubleBuffer backbuffer;
  133. ControlBindingsCollection data_bindings;
  134. static bool verify_thread_handle;
  135. Padding padding;
  136. ImageLayout backgroundimage_layout;
  137. Size maximum_size;
  138. Size minimum_size;
  139. Padding margin;
  140. private ContextMenuStrip context_menu_strip;
  141. private bool nested_layout = false;
  142. Point auto_scroll_offset;
  143. private AutoSizeMode auto_size_mode;
  144. private bool suppressing_key_press;
  145. #endregion // Local Variables
  146. #region Private Classes
  147. // This helper class allows us to dispatch messages to Control.WndProc
  148. internal class ControlNativeWindow : NativeWindow {
  149. private Control owner;
  150. public ControlNativeWindow(Control control) : base() {
  151. this.owner=control;
  152. }
  153. public Control Owner {
  154. get {
  155. return owner;
  156. }
  157. }
  158. protected override void OnHandleChange()
  159. {
  160. this.owner.WindowTarget.OnHandleChange(this.owner.Handle);
  161. }
  162. static internal Control ControlFromHandle(IntPtr hWnd) {
  163. ControlNativeWindow window;
  164. window = (ControlNativeWindow)NativeWindow.FromHandle (hWnd);
  165. if (window != null) {
  166. return window.owner;
  167. }
  168. return null;
  169. }
  170. static internal Control ControlFromChildHandle (IntPtr handle) {
  171. ControlNativeWindow window;
  172. Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
  173. while (hwnd != null) {
  174. window = (ControlNativeWindow)NativeWindow.FromHandle (handle);
  175. if (window != null) {
  176. return window.owner;
  177. }
  178. hwnd = hwnd.Parent;
  179. }
  180. return null;
  181. }
  182. protected override void WndProc(ref Message m) {
  183. owner.WindowTarget.OnMessage(ref m);
  184. }
  185. }
  186. private class ControlWindowTarget : IWindowTarget
  187. {
  188. private Control control;
  189. public ControlWindowTarget(Control control)
  190. {
  191. this.control = control;
  192. }
  193. public void OnHandleChange(IntPtr newHandle)
  194. {
  195. }
  196. public void OnMessage(ref Message m)
  197. {
  198. control.WndProc(ref m);
  199. }
  200. }
  201. #endregion
  202. #region Public Classes
  203. [ComVisible(true)]
  204. public class ControlAccessibleObject : AccessibleObject {
  205. IntPtr handle;
  206. #region ControlAccessibleObject Constructors
  207. public ControlAccessibleObject(Control ownerControl)
  208. : base (ownerControl)
  209. {
  210. if (ownerControl == null)
  211. throw new ArgumentNullException ("owner");
  212. handle = ownerControl.Handle;
  213. }
  214. #endregion // ControlAccessibleObject Constructors
  215. #region ControlAccessibleObject Public Instance Properties
  216. public override string DefaultAction {
  217. get {
  218. return base.DefaultAction;
  219. }
  220. }
  221. public override string Description {
  222. get {
  223. return base.Description;
  224. }
  225. }
  226. public IntPtr Handle {
  227. get {
  228. return handle;
  229. }
  230. set {
  231. // We don't want to let them set it
  232. }
  233. }
  234. public override string Help {
  235. get {
  236. return base.Help;
  237. }
  238. }
  239. public override string KeyboardShortcut {
  240. get {
  241. return base.KeyboardShortcut;
  242. }
  243. }
  244. public override string Name {
  245. get {
  246. return base.Name;
  247. }
  248. set {
  249. base.Name = value;
  250. }
  251. }
  252. public Control Owner {
  253. get {
  254. return base.owner;
  255. }
  256. }
  257. public override AccessibleObject Parent {
  258. get {
  259. return base.Parent;
  260. }
  261. }
  262. public override AccessibleRole Role {
  263. get {
  264. return base.Role;
  265. }
  266. }
  267. #endregion // ControlAccessibleObject Public Instance Properties
  268. #region ControlAccessibleObject Public Instance Methods
  269. public override int GetHelpTopic (out string fileName)
  270. {
  271. return base.GetHelpTopic (out fileName);
  272. }
  273. [MonoTODO ("Stub, does nothing")]
  274. public void NotifyClients (AccessibleEvents accEvent)
  275. {
  276. }
  277. [MonoTODO ("Stub, does nothing")]
  278. public void NotifyClients (AccessibleEvents accEvent, int childID)
  279. {
  280. }
  281. [MonoTODO ("Stub, does nothing")]
  282. public void NotifyClients (AccessibleEvents accEvent, int objectID, int childID)
  283. {
  284. }
  285. public override string ToString() {
  286. return "ControlAccessibleObject: Owner = " + owner.ToString() + ", Text: " + owner.text;
  287. }
  288. #endregion // ControlAccessibleObject Public Instance Methods
  289. }
  290. private class DoubleBuffer : IDisposable
  291. {
  292. public Region InvalidRegion;
  293. private Stack real_graphics;
  294. private object back_buffer;
  295. private Control parent;
  296. private bool pending_disposal;
  297. public DoubleBuffer (Control parent) {
  298. this.parent = parent;
  299. real_graphics = new Stack ();
  300. int width = parent.Width;
  301. int height = parent.Height;
  302. if (width < 1) width = 1;
  303. if (height < 1) height = 1;
  304. XplatUI.CreateOffscreenDrawable (parent.Handle, width, height, out back_buffer);
  305. Invalidate ();
  306. }
  307. public void Blit (PaintEventArgs pe) {
  308. Graphics buffered_graphics;
  309. buffered_graphics = XplatUI.GetOffscreenGraphics (back_buffer);
  310. XplatUI.BlitFromOffscreen (parent.Handle, pe.Graphics, back_buffer, buffered_graphics, pe.ClipRectangle);
  311. buffered_graphics.Dispose ();
  312. }
  313. public void Start (PaintEventArgs pe) {
  314. // We need to get the graphics for every paint.
  315. real_graphics.Push(pe.SetGraphics (XplatUI.GetOffscreenGraphics (back_buffer)));
  316. }
  317. public void End (PaintEventArgs pe) {
  318. Graphics buffered_graphics;
  319. buffered_graphics = pe.SetGraphics ((Graphics) real_graphics.Pop ());
  320. if (pending_disposal)
  321. Dispose ();
  322. else {
  323. XplatUI.BlitFromOffscreen (parent.Handle, pe.Graphics, back_buffer, buffered_graphics, pe.ClipRectangle);
  324. InvalidRegion.Exclude (pe.ClipRectangle);
  325. }
  326. buffered_graphics.Dispose ();
  327. }
  328. public void Invalidate ()
  329. {
  330. if (InvalidRegion != null)
  331. InvalidRegion.Dispose ();
  332. InvalidRegion = new Region (parent.ClientRectangle);
  333. }
  334. public void Dispose () {
  335. if (real_graphics.Count > 0) {
  336. pending_disposal = true;
  337. return;
  338. }
  339. XplatUI.DestroyOffscreenDrawable (back_buffer);
  340. if (InvalidRegion != null)
  341. InvalidRegion.Dispose ();
  342. InvalidRegion = null;
  343. back_buffer = null;
  344. GC.SuppressFinalize (this);
  345. }
  346. #region IDisposable Members
  347. void IDisposable.Dispose () {
  348. Dispose ();
  349. }
  350. #endregion
  351. ~DoubleBuffer () {
  352. Dispose ();
  353. }
  354. }
  355. [ListBindable (false)]
  356. [ComVisible (false)]
  357. public class ControlCollection : Layout.ArrangedElementCollection, IList, ICollection, ICloneable, IEnumerable {
  358. #region ControlCollection Local Variables
  359. ArrayList impl_list;
  360. Control [] all_controls;
  361. Control owner;
  362. #endregion // ControlCollection Local Variables
  363. #region ControlCollection Public Constructor
  364. public ControlCollection (Control owner)
  365. {
  366. this.owner = owner;
  367. }
  368. #endregion
  369. #region ControlCollection Public Instance Properties
  370. public Control Owner {
  371. get { return this.owner; }
  372. }
  373. public virtual Control this[string key] {
  374. get {
  375. int index = IndexOfKey (key);
  376. if (index >= 0)
  377. return this[index];
  378. return null;
  379. }
  380. }
  381. new public virtual Control this[int index] {
  382. get {
  383. if (index < 0 || index >= list.Count) {
  384. throw new ArgumentOutOfRangeException("index", index, "ControlCollection does not have that many controls");
  385. }
  386. return (Control)list[index];
  387. }
  388. }
  389. #endregion // ControlCollection Public Instance Properties
  390. #region ControlCollection Instance Methods
  391. public virtual void Add (Control value)
  392. {
  393. if (value == null)
  394. return;
  395. Form form_value = value as Form;
  396. Form form_owner = owner as Form;
  397. bool owner_permits_toplevels = (owner is MdiClient) || (form_owner != null && form_owner.IsMdiContainer);
  398. bool child_is_toplevel = value.GetTopLevel();
  399. bool child_is_mdichild = form_value != null && form_value.IsMdiChild;
  400. if (child_is_toplevel && !(owner_permits_toplevels && child_is_mdichild))
  401. throw new ArgumentException("Cannot add a top level control to a control.", "value");
  402. if (child_is_mdichild && form_value.MdiParent != null && form_value.MdiParent != owner && form_value.MdiParent != owner.Parent) {
  403. throw new ArgumentException ("Form cannot be added to the Controls collection that has a valid MDI parent.", "value");
  404. }
  405. value.recalculate_distances = true;
  406. if (Contains (value)) {
  407. owner.PerformLayout();
  408. return;
  409. }
  410. if (value.tab_index == -1) {
  411. int end;
  412. int index;
  413. int use;
  414. use = 0;
  415. end = owner.child_controls.Count;
  416. for (int i = 0; i < end; i++) {
  417. index = owner.child_controls[i].tab_index;
  418. if (index >= use) {
  419. use = index + 1;
  420. }
  421. }
  422. value.tab_index = use;
  423. }
  424. if (value.parent != null) {
  425. value.parent.Controls.Remove(value);
  426. }
  427. all_controls = null;
  428. list.Add (value);
  429. value.ChangeParent(owner);
  430. value.InitLayout();
  431. if (owner.Visible)
  432. owner.UpdateChildrenZOrder();
  433. owner.PerformLayout(value, "Parent");
  434. owner.OnControlAdded(new ControlEventArgs(value));
  435. }
  436. internal void AddToList (Control c)
  437. {
  438. all_controls = null;
  439. list.Add (c);
  440. }
  441. internal virtual void AddImplicit (Control control)
  442. {
  443. if (impl_list == null)
  444. impl_list = new ArrayList ();
  445. if (AllContains (control)) {
  446. owner.PerformLayout ();
  447. return;
  448. }
  449. if (control.parent != null) {
  450. control.parent.Controls.Remove(control);
  451. }
  452. all_controls = null;
  453. impl_list.Add (control);
  454. control.ChangeParent (owner);
  455. control.InitLayout ();
  456. if (owner.Visible)
  457. owner.UpdateChildrenZOrder ();
  458. // If we are adding a new control that isn't
  459. // visible, don't trigger a layout
  460. if (control.VisibleInternal)
  461. owner.PerformLayout (control, "Parent");
  462. }
  463. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  464. public virtual void AddRange (Control[] controls)
  465. {
  466. if (controls == null)
  467. throw new ArgumentNullException ("controls");
  468. owner.SuspendLayout ();
  469. try {
  470. for (int i = 0; i < controls.Length; i++)
  471. Add (controls[i]);
  472. } finally {
  473. owner.ResumeLayout ();
  474. }
  475. }
  476. internal virtual void AddRangeImplicit (Control [] controls)
  477. {
  478. if (controls == null)
  479. throw new ArgumentNullException ("controls");
  480. owner.SuspendLayout ();
  481. try {
  482. for (int i = 0; i < controls.Length; i++)
  483. AddImplicit (controls [i]);
  484. } finally {
  485. owner.ResumeLayout (false);
  486. }
  487. }
  488. new
  489. public virtual void Clear ()
  490. {
  491. all_controls = null;
  492. // MS sends remove events in reverse order
  493. while (list.Count > 0) {
  494. Remove((Control)list[list.Count - 1]);
  495. }
  496. }
  497. internal virtual void ClearImplicit ()
  498. {
  499. if (impl_list == null)
  500. return;
  501. all_controls = null;
  502. impl_list.Clear ();
  503. }
  504. public bool Contains (Control control)
  505. {
  506. return list.Contains (control);
  507. }
  508. internal bool ImplicitContains (Control value) {
  509. if (impl_list == null)
  510. return false;
  511. return impl_list.Contains (value);
  512. }
  513. internal bool AllContains (Control value) {
  514. return Contains (value) || ImplicitContains (value);
  515. }
  516. public virtual bool ContainsKey (string key)
  517. {
  518. return IndexOfKey (key) >= 0;
  519. }
  520. // LAMESPEC: MSDN says AE, MS implementation throws ANE
  521. public Control[] Find (string key, bool searchAllChildren)
  522. {
  523. if (string.IsNullOrEmpty (key))
  524. throw new ArgumentNullException ("key");
  525. ArrayList al = new ArrayList ();
  526. foreach (Control c in list) {
  527. if (c.Name.Equals (key, StringComparison.CurrentCultureIgnoreCase))
  528. al.Add (c);
  529. if (searchAllChildren)
  530. al.AddRange (c.Controls.Find (key, true));
  531. }
  532. return (Control[])al.ToArray (typeof (Control));
  533. }
  534. public int GetChildIndex(Control child) {
  535. return GetChildIndex(child, false);
  536. }
  537. public virtual int GetChildIndex(Control child, bool throwException) {
  538. int index;
  539. index=list.IndexOf(child);
  540. if (index==-1 && throwException) {
  541. throw new ArgumentException("Not a child control", "child");
  542. }
  543. return index;
  544. }
  545. public override IEnumerator
  546. GetEnumerator () {
  547. return new ControlCollectionEnumerator (list);
  548. }
  549. internal IEnumerator GetAllEnumerator () {
  550. Control [] res = GetAllControls ();
  551. return res.GetEnumerator ();
  552. }
  553. internal ArrayList ImplicitControls {
  554. get { return impl_list; }
  555. }
  556. internal Control [] GetAllControls () {
  557. if (all_controls != null)
  558. return all_controls;
  559. if (impl_list == null) {
  560. all_controls = (Control []) list.ToArray (typeof (Control));
  561. return all_controls;
  562. }
  563. all_controls = new Control [list.Count + impl_list.Count];
  564. impl_list.CopyTo (all_controls);
  565. list.CopyTo (all_controls, impl_list.Count);
  566. return all_controls;
  567. }
  568. public int IndexOf (Control control)
  569. {
  570. return list.IndexOf (control);
  571. }
  572. public virtual int IndexOfKey (string key)
  573. {
  574. if (string.IsNullOrEmpty (key))
  575. return -1;
  576. for (int i = 0; i < list.Count; i++)
  577. if (((Control)list[i]).Name.Equals (key, StringComparison.CurrentCultureIgnoreCase))
  578. return i;
  579. return -1;
  580. }
  581. public virtual void Remove (Control value)
  582. {
  583. if (value == null)
  584. return;
  585. all_controls = null;
  586. list.Remove(value);
  587. owner.PerformLayout(value, "Parent");
  588. owner.OnControlRemoved(new ControlEventArgs(value));
  589. ContainerControl container = owner.InternalGetContainerControl ();
  590. if (container != null) {
  591. // Inform any container controls about the loss of a child control
  592. // so that they can update their active control
  593. container.ChildControlRemoved (value);
  594. }
  595. value.ChangeParent(null);
  596. owner.UpdateChildrenZOrder();
  597. }
  598. internal virtual void RemoveImplicit (Control control)
  599. {
  600. if (impl_list != null) {
  601. all_controls = null;
  602. impl_list.Remove (control);
  603. owner.PerformLayout (control, "Parent");
  604. owner.OnControlRemoved (new ControlEventArgs (control));
  605. }
  606. control.ChangeParent (null);
  607. owner.UpdateChildrenZOrder ();
  608. }
  609. public void RemoveAt (int index)
  610. {
  611. if (index < 0 || index >= list.Count)
  612. throw new ArgumentOutOfRangeException("index", index, "ControlCollection does not have that many controls");
  613. Remove ((Control) list [index]);
  614. }
  615. public virtual void RemoveByKey (string key)
  616. {
  617. int index = IndexOfKey (key);
  618. if (index >= 0)
  619. RemoveAt (index);
  620. }
  621. public virtual void SetChildIndex(Control child, int newIndex)
  622. {
  623. if (child == null)
  624. throw new ArgumentNullException ("child");
  625. int old_index;
  626. old_index=list.IndexOf(child);
  627. if (old_index==-1) {
  628. throw new ArgumentException("Not a child control", "child");
  629. }
  630. if (old_index==newIndex) {
  631. return;
  632. }
  633. all_controls = null;
  634. list.RemoveAt(old_index);
  635. if (newIndex>list.Count) {
  636. list.Add(child);
  637. } else {
  638. list.Insert(newIndex, child);
  639. }
  640. child.UpdateZOrder();
  641. owner.PerformLayout();
  642. }
  643. #endregion // ControlCollection Private Instance Methods
  644. #region ControlCollection Interface Properties
  645. #endregion // ControlCollection Interface Properties
  646. #region ControlCollection Interface Methods
  647. int IList.Add (object control)
  648. {
  649. if (!(control is Control))
  650. throw new ArgumentException ("Object of type Control required", "control");
  651. if (control == null)
  652. throw new ArgumentException ("control", "Cannot add null controls");
  653. this.Add ((Control)control);
  654. return this.IndexOf ((Control)control);
  655. }
  656. void IList.Remove (object control)
  657. {
  658. if (!(control is Control))
  659. throw new ArgumentException ("Object of type Control required", "control");
  660. this.Remove ((Control)control);
  661. }
  662. Object ICloneable.Clone ()
  663. {
  664. ControlCollection clone = new ControlCollection (this.owner);
  665. clone.list = (ArrayList)list.Clone (); // FIXME: Do we need this?
  666. return clone;
  667. }
  668. #endregion // ControlCollection Interface Methods
  669. internal class ControlCollectionEnumerator : IEnumerator
  670. {
  671. private ArrayList list;
  672. int position = -1;
  673. public ControlCollectionEnumerator (ArrayList collection)
  674. {
  675. list = collection;
  676. }
  677. #region IEnumerator Members
  678. public object Current {
  679. get {
  680. try {
  681. return list[position];
  682. } catch (IndexOutOfRangeException) {
  683. throw new InvalidOperationException ();
  684. }
  685. }
  686. }
  687. public bool MoveNext ()
  688. {
  689. position++;
  690. return (position < list.Count);
  691. }
  692. public void Reset ()
  693. {
  694. position = -1;
  695. }
  696. #endregion
  697. }
  698. }
  699. #endregion // ControlCollection Class
  700. #region Public Constructors
  701. public Control ()
  702. {
  703. if (WindowsFormsSynchronizationContext.AutoInstall)
  704. if (!(SynchronizationContext.Current is WindowsFormsSynchronizationContext))
  705. SynchronizationContext.SetSynchronizationContext (new WindowsFormsSynchronizationContext ());
  706. layout_type = LayoutType.Anchor;
  707. anchor_style = AnchorStyles.Top | AnchorStyles.Left;
  708. is_created = false;
  709. is_visible = true;
  710. is_captured = false;
  711. is_disposed = false;
  712. is_enabled = true;
  713. is_entered = false;
  714. layout_pending = false;
  715. is_toplevel = false;
  716. causes_validation = true;
  717. has_focus = false;
  718. layout_suspended = 0;
  719. mouse_clicks = 1;
  720. tab_index = -1;
  721. cursor = null;
  722. right_to_left = RightToLeft.Inherit;
  723. border_style = BorderStyle.None;
  724. background_color = Color.Empty;
  725. dist_right = 0;
  726. dist_bottom = 0;
  727. tab_stop = true;
  728. ime_mode = ImeMode.Inherit;
  729. use_compatible_text_rendering = true;
  730. show_keyboard_cues = false;
  731. show_focus_cues = SystemInformation.MenuAccessKeysUnderlined;
  732. use_wait_cursor = false;
  733. backgroundimage_layout = ImageLayout.Tile;
  734. use_compatible_text_rendering = Application.use_compatible_text_rendering;
  735. padding = this.DefaultPadding;
  736. maximum_size = new Size();
  737. minimum_size = new Size();
  738. margin = this.DefaultMargin;
  739. auto_size_mode = AutoSizeMode.GrowOnly;
  740. control_style = ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint |
  741. ControlStyles.Selectable | ControlStyles.StandardClick |
  742. ControlStyles.StandardDoubleClick;
  743. control_style |= ControlStyles.UseTextForAccessibility;
  744. parent = null;
  745. background_image = null;
  746. text = string.Empty;
  747. name = string.Empty;
  748. window_target = new ControlWindowTarget(this);
  749. window = new ControlNativeWindow(this);
  750. child_controls = CreateControlsInstance();
  751. bounds.Size = DefaultSize;
  752. client_size = ClientSizeFromSize (bounds.Size);
  753. client_rect = new Rectangle (Point.Empty, client_size);
  754. explicit_bounds = bounds;
  755. }
  756. public Control (Control parent, string text) : this()
  757. {
  758. Text=text;
  759. Parent=parent;
  760. }
  761. public Control (Control parent, string text, int left, int top, int width, int height) : this()
  762. {
  763. Parent=parent;
  764. SetBounds(left, top, width, height, BoundsSpecified.All);
  765. Text=text;
  766. }
  767. public Control (string text) : this()
  768. {
  769. Text=text;
  770. }
  771. public Control (string text, int left, int top, int width, int height) : this()
  772. {
  773. SetBounds(left, top, width, height, BoundsSpecified.All);
  774. Text=text;
  775. }
  776. private delegate void RemoveDelegate(object c);
  777. protected override void Dispose (bool disposing)
  778. {
  779. if (!is_disposed && disposing) {
  780. is_disposing = true;
  781. Capture = false;
  782. DisposeBackBuffer ();
  783. if (this.InvokeRequired) {
  784. if (Application.MessageLoop && IsHandleCreated) {
  785. this.BeginInvokeInternal(new MethodInvoker(DestroyHandle), null);
  786. }
  787. } else {
  788. DestroyHandle();
  789. }
  790. if (parent != null)
  791. parent.Controls.Remove(this);
  792. Control [] children = child_controls.GetAllControls ();
  793. for (int i=0; i<children.Length; i++) {
  794. children[i].parent = null; // Need to set to null or our child will try and remove from ourselves and crash
  795. children[i].Dispose();
  796. }
  797. }
  798. is_disposed = true;
  799. base.Dispose(disposing);
  800. }
  801. #endregion // Public Constructors
  802. #region Internal Properties
  803. internal Rectangle PaddingClientRectangle
  804. {
  805. get {
  806. return new Rectangle (
  807. ClientRectangle.Left + padding.Left,
  808. ClientRectangle.Top + padding.Top,
  809. ClientRectangle.Width - padding.Horizontal,
  810. ClientRectangle.Height - padding.Vertical);
  811. }
  812. }
  813. private MenuTracker active_tracker;
  814. internal MenuTracker ActiveTracker {
  815. get { return active_tracker; }
  816. set {
  817. if (value == active_tracker)
  818. return;
  819. Capture = value != null;
  820. active_tracker = value;
  821. }
  822. }
  823. // Control is currently selected, like Focused, except maintains state
  824. // when Form loses focus
  825. internal bool InternalSelected {
  826. get {
  827. IContainerControl container;
  828. container = GetContainerControl();
  829. if (container != null && container.ActiveControl == this)
  830. return true;
  831. return false;
  832. }
  833. }
  834. // Looks for focus in child controls
  835. // and also in the implicit ones
  836. internal bool InternalContainsFocus {
  837. get {
  838. IntPtr focused_window;
  839. focused_window = XplatUI.GetFocus();
  840. if (IsHandleCreated) {
  841. if (focused_window == Handle)
  842. return true;
  843. foreach (Control child_control in child_controls.GetAllControls ())
  844. if (child_control.InternalContainsFocus)
  845. return true;
  846. }
  847. return false;
  848. }
  849. }
  850. // Mouse is currently within the control's bounds
  851. internal bool Entered {
  852. get { return this.is_entered; }
  853. }
  854. internal bool VisibleInternal {
  855. get { return is_visible; }
  856. }
  857. internal LayoutType ControlLayoutType {
  858. get { return layout_type; }
  859. }
  860. internal BorderStyle InternalBorderStyle {
  861. get {
  862. return border_style;
  863. }
  864. set {
  865. if (!Enum.IsDefined (typeof (BorderStyle), value))
  866. throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for BorderStyle", value));
  867. if (border_style != value) {
  868. border_style = value;
  869. if (IsHandleCreated) {
  870. XplatUI.SetBorderStyle (window.Handle, (FormBorderStyle)border_style);
  871. RecreateHandle ();
  872. Refresh ();
  873. } else
  874. client_size = ClientSizeFromSize (bounds.Size);
  875. }
  876. }
  877. }
  878. internal Size InternalClientSize { set { this.client_size = value; } }
  879. internal virtual bool ActivateOnShow { get { return true; } }
  880. internal Rectangle ExplicitBounds { get { return this.explicit_bounds; } set { this.explicit_bounds = value; } }
  881. internal bool ValidationFailed {
  882. get {
  883. ContainerControl c = InternalGetContainerControl ();
  884. if (c != null)
  885. return c.validation_failed;
  886. return false;
  887. }
  888. set {
  889. ContainerControl c = InternalGetContainerControl ();
  890. if (c != null)
  891. c.validation_failed = value;
  892. }
  893. }
  894. #endregion // Internal Properties
  895. #region Private & Internal Methods
  896. void IDropTarget.OnDragDrop (DragEventArgs drgEvent)
  897. {
  898. OnDragDrop (drgEvent);
  899. }
  900. void IDropTarget.OnDragEnter (DragEventArgs drgEvent)
  901. {
  902. OnDragEnter (drgEvent);
  903. }
  904. void IDropTarget.OnDragLeave (EventArgs e)
  905. {
  906. OnDragLeave (e);
  907. }
  908. void IDropTarget.OnDragOver (DragEventArgs drgEvent)
  909. {
  910. OnDragOver (drgEvent);
  911. }
  912. internal IAsyncResult BeginInvokeInternal (Delegate method, object [] args) {
  913. return BeginInvokeInternal (method, args, FindControlToInvokeOn ());
  914. }
  915. internal IAsyncResult BeginInvokeInternal (Delegate method, object [] args, Control control) {
  916. AsyncMethodResult result;
  917. AsyncMethodData data;
  918. result = new AsyncMethodResult ();
  919. data = new AsyncMethodData ();
  920. data.Handle = control.GetInvokableHandle ();
  921. data.Method = method;
  922. data.Args = args;
  923. data.Result = result;
  924. if (!ExecutionContext.IsFlowSuppressed ()) {
  925. data.Context = ExecutionContext.Capture ();
  926. }
  927. XplatUI.SendAsyncMethod (data);
  928. return result;
  929. }
  930. // The CheckForIllegalCrossThreadCalls in the #if 2.0 of
  931. // Control.Handle throws an exception when we are trying
  932. // to get the Handle to properly invoke on. This avoids that.
  933. private IntPtr GetInvokableHandle ()
  934. {
  935. if (!IsHandleCreated)
  936. CreateHandle ();
  937. return window.Handle;
  938. }
  939. internal void PointToClient (ref int x, ref int y) {
  940. XplatUI.ScreenToClient (Handle, ref x, ref y);
  941. }
  942. internal void PointToScreen (ref int x, ref int y) {
  943. XplatUI.ClientToScreen (Handle, ref x, ref y);
  944. }
  945. internal bool IsRecreating {
  946. get {
  947. return is_recreating;
  948. }
  949. }
  950. internal Graphics DeviceContext {
  951. get { return Hwnd.GraphicsContext; }
  952. }
  953. // An internal way to have a fixed height
  954. // Basically for DataTimePicker 2.0
  955. internal virtual int OverrideHeight (int height)
  956. {
  957. return height;
  958. }
  959. private void ProcessActiveTracker (ref Message m)
  960. {
  961. bool is_up = ((Msg) m.Msg == Msg.WM_LBUTTONUP) ||
  962. ((Msg) m.Msg == Msg.WM_RBUTTONUP);
  963. MouseButtons mb = FromParamToMouseButtons ((int) m.WParam.ToInt32 ());
  964. // We add in the button that was released (not sent in WParam)
  965. if (is_up) {
  966. switch ((Msg)m.Msg) {
  967. case Msg.WM_LBUTTONUP:
  968. mb |= MouseButtons.Left;
  969. break;
  970. case Msg.WM_RBUTTONUP:
  971. mb |= MouseButtons.Right;
  972. break;
  973. }
  974. }
  975. MouseEventArgs args = new MouseEventArgs (
  976. mb,
  977. mouse_clicks,
  978. Control.MousePosition.X,
  979. Control.MousePosition.Y,
  980. 0);
  981. if (is_up) {
  982. active_tracker.OnMouseUp (args);
  983. mouse_clicks = 1;
  984. } else {
  985. if (!active_tracker.OnMouseDown (args)) {
  986. Control control = GetRealChildAtPoint (Cursor.Position);
  987. if (control != null) {
  988. Point pt = control.PointToClient (Cursor.Position);
  989. XplatUI.SendMessage (control.Handle,
  990. (Msg)m.Msg,
  991. m.WParam,
  992. MakeParam (pt.X, pt.Y));
  993. }
  994. }
  995. }
  996. }
  997. private Control FindControlToInvokeOn ()
  998. {
  999. Control p = this;
  1000. do {
  1001. if (p.IsHandleCreated)
  1002. break;
  1003. p = p.parent;
  1004. } while (p != null);
  1005. if (p == null || !p.IsHandleCreated)
  1006. throw new InvalidOperationException ("Cannot call Invoke or BeginInvoke on a control until the window handle is created");
  1007. return p;
  1008. }
  1009. private void InvalidateBackBuffer () {
  1010. if (backbuffer != null)
  1011. backbuffer.Invalidate ();
  1012. }
  1013. private DoubleBuffer GetBackBuffer () {
  1014. if (backbuffer == null)
  1015. backbuffer = new DoubleBuffer (this);
  1016. return backbuffer;
  1017. }
  1018. private void DisposeBackBuffer () {
  1019. if (backbuffer != null) {
  1020. backbuffer.Dispose ();
  1021. backbuffer = null;
  1022. }
  1023. }
  1024. internal static void SetChildColor(Control parent) {
  1025. Control child;
  1026. for (int i=0; i < parent.child_controls.Count; i++) {
  1027. child=parent.child_controls[i];
  1028. if (child.child_controls.Count>0) {
  1029. SetChildColor(child);
  1030. }
  1031. }
  1032. }
  1033. internal bool Select(Control control) {
  1034. IContainerControl container;
  1035. if (control == null) {
  1036. return false;
  1037. }
  1038. container = GetContainerControl();
  1039. if (container != null && (Control)container != control) {
  1040. container.ActiveControl = control;
  1041. if (container.ActiveControl == control && !control.has_focus && control.IsHandleCreated)
  1042. XplatUI.SetFocus(control.window.Handle);
  1043. }
  1044. else if (control.IsHandleCreated) {
  1045. XplatUI.SetFocus(control.window.Handle);
  1046. }
  1047. return true;
  1048. }
  1049. internal virtual void DoDefaultAction() {
  1050. // Only here to be overriden by our actual controls; this is needed by the accessibility class
  1051. }
  1052. internal static IntPtr MakeParam (int low, int high){
  1053. return new IntPtr (high << 16 | low & 0xffff);
  1054. }
  1055. internal static int LowOrder (int param) {
  1056. return ((int)(short)(param & 0xffff));
  1057. }
  1058. internal static int HighOrder (long param) {
  1059. return ((int)(short)(param >> 16));
  1060. }
  1061. // This method exists so controls overriding OnPaintBackground can have default background painting done
  1062. internal virtual void PaintControlBackground (PaintEventArgs pevent) {
  1063. bool tbstyle_flat = ((CreateParams.Style & (int) ToolBarStyles.TBSTYLE_FLAT) != 0);
  1064. // If we have transparent background
  1065. if (((BackColor.A != 0xff) && GetStyle(ControlStyles.SupportsTransparentBackColor)) || tbstyle_flat) {
  1066. if (parent != null) {
  1067. PaintEventArgs parent_pe;
  1068. GraphicsState state;
  1069. parent_pe = new PaintEventArgs(pevent.Graphics, new Rectangle(pevent.ClipRectangle.X + Left, pevent.ClipRectangle.Y + Top, pevent.ClipRectangle.Width, pevent.ClipRectangle.Height));
  1070. state = parent_pe.Graphics.Save();
  1071. parent_pe.Graphics.TranslateTransform(-Left, -Top);
  1072. parent.OnPaintBackground(parent_pe);
  1073. parent_pe.Graphics.Restore(state);
  1074. state = parent_pe.Graphics.Save();
  1075. parent_pe.Graphics.TranslateTransform(-Left, -Top);
  1076. parent.OnPaint(parent_pe);
  1077. parent_pe.Graphics.Restore(state);
  1078. parent_pe.SetGraphics(null);
  1079. }
  1080. }
  1081. if ((clip_region != null) && (XplatUI.UserClipWontExposeParent)) {
  1082. if (parent != null) {
  1083. PaintEventArgs parent_pe;
  1084. Region region;
  1085. GraphicsState state;
  1086. Hwnd hwnd;
  1087. hwnd = Hwnd.ObjectFromHandle(Handle);
  1088. if (hwnd != null) {
  1089. parent_pe = new PaintEventArgs(pevent.Graphics, new Rectangle(pevent.ClipRectangle.X + Left, pevent.ClipRectangle.Y + Top, pevent.ClipRectangle.Width, pevent.ClipRectangle.Height));
  1090. region = new Region ();
  1091. region.MakeEmpty();
  1092. region.Union(ClientRectangle);
  1093. foreach (Rectangle r in hwnd.ClipRectangles) {
  1094. region.Union (r);
  1095. }
  1096. state = parent_pe.Graphics.Save();
  1097. parent_pe.Graphics.Clip = region;
  1098. parent_pe.Graphics.TranslateTransform(-Left, -Top);
  1099. parent.OnPaintBackground(parent_pe);
  1100. parent_pe.Graphics.Restore(state);
  1101. state = parent_pe.Graphics.Save();
  1102. parent_pe.Graphics.Clip = region;
  1103. parent_pe.Graphics.TranslateTransform(-Left, -Top);
  1104. parent.OnPaint(parent_pe);
  1105. parent_pe.Graphics.Restore(state);
  1106. parent_pe.SetGraphics(null);
  1107. region.Intersect(clip_region);
  1108. pevent.Graphics.Clip = region;
  1109. }
  1110. }
  1111. }
  1112. if (background_image == null) {
  1113. if (!tbstyle_flat) {
  1114. Rectangle paintRect = pevent.ClipRectangle;
  1115. Brush pen = ThemeEngine.Current.ResPool.GetSolidBrush(BackColor);
  1116. pevent.Graphics.FillRectangle(pen, paintRect);
  1117. }
  1118. return;
  1119. }
  1120. DrawBackgroundImage (pevent.Graphics);
  1121. }
  1122. void DrawBackgroundImage (Graphics g) {
  1123. Rectangle drawing_rectangle = new Rectangle ();
  1124. g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), ClientRectangle);
  1125. switch (backgroundimage_layout)
  1126. {
  1127. case ImageLayout.Tile:
  1128. using (TextureBrush b = new TextureBrush (background_image, WrapMode.Tile)) {
  1129. g.FillRectangle (b, ClientRectangle);
  1130. }
  1131. return;
  1132. case ImageLayout.Center:
  1133. drawing_rectangle.Location = new Point (ClientSize.Width / 2 - background_image.Width / 2, ClientSize.Height / 2 - background_image.Height / 2);
  1134. drawing_rectangle.Size = background_image.Size;
  1135. break;
  1136. case ImageLayout.None:
  1137. drawing_rectangle.Location = Point.Empty;
  1138. drawing_rectangle.Size = background_image.Size;
  1139. break;
  1140. case ImageLayout.Stretch:
  1141. drawing_rectangle = ClientRectangle;
  1142. break;
  1143. case ImageLayout.Zoom:
  1144. drawing_rectangle = ClientRectangle;
  1145. if ((float)background_image.Width / (float)background_image.Height < (float)drawing_rectangle.Width / (float) drawing_rectangle.Height) {
  1146. drawing_rectangle.Width = (int) (background_image.Width * ((float)drawing_rectangle.Height / (float)background_image.Height));
  1147. drawing_rectangle.X = (ClientRectangle.Width - drawing_rectangle.Width) / 2;
  1148. } else {
  1149. drawing_rectangle.Height = (int) (background_image.Height * ((float)drawing_rectangle.Width / (float)background_image.Width));
  1150. drawing_rectangle.Y = (ClientRectangle.Height - drawing_rectangle.Height) / 2;
  1151. }
  1152. break;
  1153. default:
  1154. return;
  1155. }
  1156. g.DrawImage (background_image, drawing_rectangle);
  1157. }
  1158. internal virtual void DndEnter (DragEventArgs e) {
  1159. try {
  1160. OnDragEnter (e);
  1161. } catch { }
  1162. }
  1163. internal virtual void DndOver (DragEventArgs e) {
  1164. try {
  1165. OnDragOver (e);
  1166. } catch { }
  1167. }
  1168. internal virtual void DndDrop (DragEventArgs e) {
  1169. try {
  1170. OnDragDrop (e);
  1171. } catch (Exception exc) {
  1172. Console.Error.WriteLine ("MWF: Exception while dropping:");
  1173. Console.Error.WriteLine (exc);
  1174. }
  1175. }
  1176. internal virtual void DndLeave (EventArgs e) {
  1177. try {
  1178. OnDragLeave (e);
  1179. } catch { }
  1180. }
  1181. internal virtual void DndFeedback(GiveFeedbackEventArgs e) {
  1182. try {
  1183. OnGiveFeedback(e);
  1184. } catch { }
  1185. }
  1186. internal virtual void DndContinueDrag(QueryContinueDragEventArgs e) {
  1187. try {
  1188. OnQueryContinueDrag(e);
  1189. } catch { }
  1190. }
  1191. internal static MouseButtons FromParamToMouseButtons (long param) {
  1192. MouseButtons buttons = MouseButtons.None;
  1193. if ((param & (long) MsgButtons.MK_LBUTTON) != 0)
  1194. buttons |= MouseButtons.Left;
  1195. if ((param & (long)MsgButtons.MK_MBUTTON) != 0)
  1196. buttons |= MouseButtons.Middle;
  1197. if ((param & (long)MsgButtons.MK_RBUTTON) != 0)
  1198. buttons |= MouseButtons.Right;
  1199. return buttons;
  1200. }
  1201. internal virtual void FireEnter () {
  1202. OnEnter (EventArgs.Empty);
  1203. }
  1204. internal virtual void FireLeave () {
  1205. OnLeave (EventArgs.Empty);
  1206. }
  1207. internal virtual void FireValidating (CancelEventArgs ce) {
  1208. OnValidating (ce);
  1209. }
  1210. internal virtual void FireValidated () {
  1211. OnValidated (EventArgs.Empty);
  1212. }
  1213. internal virtual bool ProcessControlMnemonic(char charCode) {
  1214. return ProcessMnemonic(charCode);
  1215. }
  1216. private static Control FindFlatForward(Control container, Control start) {
  1217. Control found;
  1218. int index;
  1219. int end;
  1220. bool hit;
  1221. found = null;
  1222. end = container.child_controls.Count;
  1223. hit = false;
  1224. if (start != null) {
  1225. index = start.tab_index;
  1226. } else {
  1227. index = -1;
  1228. }
  1229. for (int i = 0; i < end; i++) {
  1230. if (start == container.child_controls[i]) {
  1231. hit = true;
  1232. continue;
  1233. }
  1234. if (found == null || found.tab_index > container.child_controls[i].tab_index) {
  1235. if (container.child_controls[i].tab_index > index || (hit && container.child_controls[i].tab_index == index)) {
  1236. found = container.child_controls[i];
  1237. }
  1238. }
  1239. }
  1240. return found;
  1241. }
  1242. private static Control FindControlForward(Control container, Control start) {
  1243. Control found;
  1244. found = null;
  1245. if (start == null) {
  1246. return FindFlatForward(container, start);
  1247. }
  1248. if (start.child_controls != null && start.child_controls.Count > 0 &&
  1249. (start == container || !((start is IContainerControl) && start.GetStyle(ControlStyles.ContainerControl)))) {
  1250. return FindControlForward(start, null);
  1251. }
  1252. else {
  1253. while (start != container) {
  1254. found = FindFlatForward(start.parent, start);
  1255. if (found != null) {
  1256. return found;
  1257. }
  1258. start = start.parent;
  1259. }
  1260. }
  1261. return null;
  1262. }
  1263. private static Control FindFlatBackward(Control container, Control start) {
  1264. Control found;
  1265. int index;
  1266. int end;
  1267. bool hit;
  1268. found = null;
  1269. end = container.child_controls.Count;
  1270. hit = false;
  1271. if (start != null) {
  1272. index = start.tab_index;
  1273. } else {
  1274. index = int.MaxValue;
  1275. }
  1276. for (int i = end - 1; i >= 0; i--) {
  1277. if (start == container.child_controls[i]) {
  1278. hit = true;
  1279. continue;
  1280. }
  1281. if (found == null || found.tab_index < container.child_controls[i].tab_index) {
  1282. if (container.child_controls[i].tab_index < index || (hit && container.child_controls[i].tab_index == index))
  1283. found = container.child_controls[i];
  1284. }
  1285. }
  1286. return found;
  1287. }
  1288. private static Control FindControlBackward(Control container, Control start) {
  1289. Control found = null;
  1290. if (start == null) {
  1291. found = FindFlatBackward(container, start);
  1292. }
  1293. else if (start != container) {
  1294. if (start.parent != null) {
  1295. found = FindFlatBackward(start.parent, start);
  1296. if (found == null) {
  1297. if (start.parent != container)
  1298. return start.parent;
  1299. return null;
  1300. }
  1301. }
  1302. }
  1303. if (found == null || start.parent == null)
  1304. found = start;
  1305. while (found != null && (found == container || (!((found is IContainerControl) && found.GetStyle(ControlStyles.ContainerControl))) &&
  1306. found.child_controls != null && found.child_controls.Count > 0)) {
  1307. // while (ctl.child_controls != null && ctl.child_controls.Count > 0 &&
  1308. // (ctl == this || (!((ctl is IContainerControl) && ctl.GetStyle(ControlStyles.ContainerControl))))) {
  1309. found = FindFlatBackward(found, null);
  1310. }
  1311. return found;
  1312. /*
  1313. Control found;
  1314. found = null;
  1315. if (start != null) {
  1316. found = FindFlatBackward(start.parent, start);
  1317. if (found == null) {
  1318. if (start.parent != container) {
  1319. return start.parent;
  1320. }
  1321. }
  1322. }
  1323. if (found == null) {
  1324. found = FindFlatBackward(container, start);
  1325. }
  1326. if (container != start) {
  1327. while ((found != null) && (!found.Contains(start)) && found.child_controls != null && found.child_controls.Count > 0 && !(found is IContainerControl)) {// || found.GetStyle(ControlStyles.ContainerControl))) {
  1328. found = FindControlBackward(found, null);
  1329. if (found != null) {
  1330. return found;
  1331. }
  1332. }
  1333. }
  1334. return found;
  1335. */
  1336. }
  1337. internal virtual void HandleClick(int clicks, MouseEventArgs me) {
  1338. bool standardclick = GetStyle (ControlStyles.StandardClick);
  1339. bool standardclickclick = GetStyle (ControlStyles.StandardDoubleClick);
  1340. if ((clicks > 1) && standardclick && standardclickclick) {
  1341. OnDoubleClick (me);
  1342. OnMouseDoubleClick (me);
  1343. } else if (clicks == 1 && standardclick && !ValidationFailed) {
  1344. OnClick (me);
  1345. OnMouseClick (me);
  1346. }
  1347. }
  1348. internal void CaptureWithConfine (Control ConfineWindow) {
  1349. if (this.IsHandleCreated && !is_captured) {
  1350. is_captured = true;
  1351. XplatUI.GrabWindow (this.window.Handle, ConfineWindow.Handle);
  1352. }
  1353. }
  1354. private void CheckDataBindings () {
  1355. if (data_bindings == null)
  1356. return;
  1357. foreach (Binding binding in data_bindings) {
  1358. binding.Check ();
  1359. }
  1360. }
  1361. private void ChangeParent(Control new_parent) {
  1362. bool pre_enabled;
  1363. bool pre_visible;
  1364. Font pre_font;
  1365. Color pre_fore_color;
  1366. Color pre_back_color;
  1367. RightToLeft pre_rtl;
  1368. // These properties are inherited from our parent
  1369. // Get them pre parent-change and then send events
  1370. // if they are changed after we have our new parent
  1371. pre_enabled = Enabled;
  1372. pre_visible = Visible;
  1373. pre_font = Font;
  1374. pre_fore_color = ForeColor;
  1375. pre_back_color = BackColor;
  1376. pre_rtl = RightToLeft;
  1377. // MS doesn't seem to send a CursorChangedEvent
  1378. parent = new_parent;
  1379. Form frm = this as Form;
  1380. if (frm != null) {
  1381. frm.ChangingParent (new_parent);
  1382. } else if (IsHandleCreated) {
  1383. IntPtr parent_handle = IntPtr.Zero;
  1384. if (new_parent != null && new_parent.IsHandleCreated)
  1385. parent_handle = new_parent.Handle;
  1386. XplatUI.SetParent (Handle, parent_handle);
  1387. }
  1388. OnParentChanged(EventArgs.Empty);
  1389. if (pre_enabled != Enabled) {
  1390. OnEnabledChanged(EventArgs.Empty);
  1391. }
  1392. if (pre_visible != Visible) {
  1393. OnVisibleChanged(EventArgs.Empty);
  1394. }
  1395. if (pre_font != Font) {
  1396. OnFontChanged(EventArgs.Empty);
  1397. }
  1398. if (pre_fore_color != ForeColor) {
  1399. OnForeColorChanged(EventArgs.Empty);
  1400. }
  1401. if (pre_back_color != BackColor) {
  1402. OnBackColorChanged(EventArgs.Empty);
  1403. }
  1404. if (pre_rtl != RightToLeft) {
  1405. // MS sneaks a OnCreateControl and OnHandleCreated in here, I guess
  1406. // because when RTL changes they have to recreate the win32 control
  1407. // We don't really need that (until someone runs into compatibility issues)
  1408. OnRightToLeftChanged(EventArgs.Empty);
  1409. }
  1410. if ((new_parent != null) && new_parent.Created && is_visible && !Created) {
  1411. CreateControl();
  1412. }
  1413. if ((binding_context == null) && Created) {
  1414. OnBindingContextChanged(EventArgs.Empty);
  1415. }
  1416. }
  1417. // Sometimes we need to do this calculation without it being virtual (constructor)
  1418. internal Size InternalSizeFromClientSize (Size clientSize)
  1419. {
  1420. Rectangle ClientRect;
  1421. Rectangle WindowRect;
  1422. CreateParams cp;
  1423. ClientRect = new Rectangle (0, 0, clientSize.Width, clientSize.Height);
  1424. cp = this.CreateParams;
  1425. if (XplatUI.CalculateWindowRect (ref ClientRect, cp, null, out WindowRect))
  1426. return new Size (WindowRect.Width, WindowRect.Height);
  1427. return Size.Empty;
  1428. }
  1429. internal Size ClientSizeFromSize (Size size)
  1430. {
  1431. // Calling this gives us the difference in Size and ClientSize.
  1432. // We just have to apply that difference to our given size.
  1433. Size client_size = this.InternalSizeFromClientSize (size);
  1434. if (client_size == Size.Empty)
  1435. return Size.Empty;
  1436. return new Size (size.Width - (client_size.Width - size.Width), size.Height - (client_size.Height - size.Height));
  1437. }
  1438. internal CreateParams GetCreateParams ()
  1439. {
  1440. return CreateParams;
  1441. }
  1442. internal virtual Size GetPreferredSizeCore (Size proposedSize)
  1443. {
  1444. return this.explicit_bounds.Size;
  1445. }
  1446. private void UpdateDistances() {
  1447. if (parent != null) {
  1448. if (bounds.Width >= 0)
  1449. dist_right = parent.ClientSize.Width - bounds.X - bounds.Width;
  1450. if (bounds.Height >= 0)
  1451. dist_bottom = parent.ClientSize.Height - bounds.Y - bounds.Height;
  1452. recalculate_distances = false;
  1453. }
  1454. }
  1455. private Cursor GetAvailableCursor ()
  1456. {
  1457. if (Cursor != null && Enabled) {
  1458. return Cursor;
  1459. }
  1460. if (Parent != null) {
  1461. return Parent.GetAvailableCursor ();
  1462. }
  1463. return Cursors.Default;
  1464. }
  1465. private void UpdateCursor ()
  1466. {
  1467. if (!IsHandleCreated)
  1468. return;
  1469. if (!Enabled) {
  1470. XplatUI.SetCursor (window.Handle, GetAvailableCursor ().handle);
  1471. return;
  1472. }
  1473. Point pt = PointToClient (Cursor.Position);
  1474. if (!bounds.Contains (pt) && !Capture)
  1475. return;
  1476. if (cursor != null || use_wait_cursor) {
  1477. XplatUI.SetCursor (window.Handle, Cursor.handle);
  1478. } else {
  1479. XplatUI.SetCursor (window.Handle, GetAvailableCursor ().handle);
  1480. }
  1481. }
  1482. private bool UseDoubleBuffering {
  1483. get {
  1484. if (!ThemeEngine.Current.DoubleBufferingSupported)
  1485. return false;
  1486. // Since many of .Net's controls are unmanaged, they are doublebuffered
  1487. // even though their bits may not be set in managed land. This allows
  1488. // us to doublebuffer as well without affecting public style bits.
  1489. if (force_double_buffer)
  1490. return true;
  1491. if (DoubleBuffered)
  1492. return true;
  1493. return (control_style & ControlStyles.DoubleBuffer) != 0;
  1494. }
  1495. }
  1496. internal void OnSizeInitializedOrChanged ()
  1497. {
  1498. Form form = this as Form;
  1499. if (form != null && form.WindowManager != null)
  1500. ThemeEngine.Current.ManagedWindowOnSizeInitializedOrChanged (form);
  1501. }
  1502. #endregion // Private & Internal Methods
  1503. #region Public Static Properties
  1504. public static Color DefaultBackColor {
  1505. get {
  1506. return ThemeEngine.Current.DefaultControlBackColor;
  1507. }
  1508. }
  1509. public static Font DefaultFont {
  1510. get {
  1511. return ThemeEngine.Current.DefaultFont;
  1512. }
  1513. }
  1514. public static Color De

Large files files are truncated, but you can click here to view the full file