2005-05-19 Marek Safar <marek.safar@seznam.cz>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Form.cs
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 Novell, Inc.
21 //
22 // Authors:
23 //      Peter Bartok    pbartok@novell.com
24 //
25
26 // NOT COMPLETE
27
28 using System;
29 using System.Drawing;
30 using System.ComponentModel;
31 using System.ComponentModel.Design;
32 using System.ComponentModel.Design.Serialization;
33 using System.Collections;
34 using System.Runtime.InteropServices;
35 using System.Threading;
36
37 namespace System.Windows.Forms {
38         [DesignerCategory("Form")]
39         [DesignTimeVisible(false)]
40         [Designer("System.Windows.Forms.Design.FormDocumentDesigner, " + Consts.AssemblySystem_Design, typeof(IRootDesigner))]
41         [DefaultEvent("Load")]
42         [ToolboxItem(false)]
43         public class Form : ContainerControl {
44                 #region Local Variables
45                 internal static Form            active_form;
46                 internal bool                   closing;
47                 FormBorderStyle                 formBorderStyle;
48                 private static bool             autoscale;
49                 private static Size             autoscale_base_size;
50                 internal bool                   is_modal;
51                 internal bool                   end_modal;                      // This var is being monitored by the application modal loop
52                 private bool                    control_box;
53                 private bool                    minimize_box;
54                 private bool                    maximize_box;
55                 private bool                    help_button;
56                 private bool                    show_in_taskbar;
57                 private bool                    topmost;
58                 private IButtonControl          accept_button;
59                 private IButtonControl          cancel_button;
60                 private DialogResult            dialog_result;
61                 private FormStartPosition       start_position;
62                 private Form                    owner;
63                 private Form.ControlCollection  owned_forms;
64                 private MdiClient               mdi_container;
65                 private Form                    mdi_parent;
66                 private bool                    key_preview;
67                 private MainMenu                menu;
68                 private Icon                    icon;
69                 private Size                    maximum_size;
70                 private Size                    minimum_size;
71                 private SizeGripStyle           size_grip_style;
72                 private Rectangle               maximized_bounds;
73                 private Rectangle               default_maximized_bounds;
74                 Color                           transparency_key;\r
75
76                 #endregion      // Local Variables
77
78                 #region Private & Internal Methods
79                 #endregion      // Private & Internal Methods
80
81                 #region Public Classes
82                 public new class ControlCollection : Control.ControlCollection {
83                         Form    form_owner;
84
85                         public ControlCollection(Form owner) : base(owner) {
86                                 this.form_owner = owner;
87                         }
88
89                         public override void Add(Control value) {
90                                 for (int i=0; i<list.Count; i++) {
91                                         if (list[i]==value) {
92                                                 // Do we need to do anything here?
93                                                 return;
94                                         }
95                                 }
96                                 list.Add(value);
97                                 ((Form)value).owner=(Form)owner;
98                         }
99
100                         public override void Remove(Control value) {
101                                 ((Form)value).owner = null;
102                                 base.Remove (value);
103                         }
104                 }
105                 #endregion      // Public Classes
106
107                 #region Public Constructor & Destructor
108                 public Form() {
109                         closing = false;
110                         is_modal = false;
111                         end_modal = false;
112                         dialog_result = DialogResult.None;
113                         start_position = FormStartPosition.WindowsDefaultLocation;
114                         formBorderStyle = FormBorderStyle.Sizable;
115                         key_preview = false;
116                         menu = null;
117                         icon = null;
118                         minimum_size = new Size(0, 0);
119                         maximum_size = new Size(0, 0);
120                         control_box = true;
121                         minimize_box = true;
122                         maximize_box = true;
123                         help_button = false;
124                         show_in_taskbar = true;
125                         ime_mode = ImeMode.NoControl;
126                         is_visible = false;
127                         is_toplevel = true;
128                         size_grip_style = SizeGripStyle.Auto;
129                         maximized_bounds = Rectangle.Empty;
130                         default_maximized_bounds = Rectangle.Empty;
131                         owned_forms = new Form.ControlCollection(this);
132                         transparency_key = Color.Empty;
133                 }
134                 #endregion      // Public Constructor & Destructor
135
136                 #region Public Static Properties
137
138                 public static Form ActiveForm {
139                         get {
140                                 Control active;
141
142                                 active = FromHandle(XplatUI.GetActive());
143
144                                 if (active != null) {
145                                         if ( !(active is Form)) {
146                                                 Control parent;
147
148                                                 parent = active.Parent;
149                                                 while (parent != null) {
150                                                         if (parent is Form) {
151                                                                 return (Form)parent;
152                                                         }
153                                                         parent = parent.Parent;
154                                                 }
155                                         } else {
156                                                 return (Form)active;
157                                         }
158                                 }
159                                 return null;
160                         }
161                 }
162
163                 #endregion      // Public Static Properties
164
165                 #region Public Instance Properties
166                 [DefaultValue(null)]
167                 public IButtonControl AcceptButton {
168                         get {
169                                 return accept_button;
170                         }
171
172                         set {
173                                 accept_button = value;
174                         }
175                 }
176
177                 [MonoTODO("Figure out a way for transparency support in windows")]
178                 [Browsable(false)]
179                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
180                 public bool AllowTransparency {
181                         get {
182                                 return false;
183                         }
184
185                         set {
186                         }
187                 }
188                         
189                 [DefaultValue(true)]
190                 public bool AutoScale {
191                         get {
192                                 return autoscale;
193                         }
194
195                         set {
196                                 autoscale=value;
197                         }
198                 }
199
200                 [Localizable(true)]
201                 [Browsable(false)]
202                 [EditorBrowsable(EditorBrowsableState.Advanced)]
203                 public virtual Size AutoScaleBaseSize {
204                         get {
205                                 return autoscale_base_size;
206                         }
207
208                         set {
209                                 autoscale_base_size=value;
210                         }
211                 }
212
213                 [Localizable(true)]
214                 public override bool AutoScroll {
215                         get {
216                                 return base.AutoScroll;
217                         }
218                         set {
219                                 base.AutoScroll = value;
220                         }
221                 }
222
223                 public override Color BackColor {
224                         get {
225                                 return base.BackColor;
226                         }
227                         set {
228                                 base.BackColor = value;
229                         }
230                 }
231
232                 [DefaultValue(null)]
233                 public IButtonControl CancelButton {
234                         get {
235                                 return cancel_button;
236                         }
237
238                         set {
239                                 cancel_button = value;
240                         }
241                 }
242
243                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
244                 [Localizable(true)]
245                 public Size ClientSize {
246                         get {
247                                 return base.ClientSize;
248                         }
249
250                         set {
251                                 base.ClientSize = value;
252                         }
253                 }
254
255                 [DefaultValue(true)]
256                 public bool ControlBox {
257                         get {
258                                 return control_box;
259                         }
260
261                         set {
262                                 if (control_box != value) {
263                                         control_box = value;
264                                         UpdateStyles();
265                                 }
266                         }
267                 }
268
269                 [Browsable(false)]
270                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
271                 public Rectangle DesktopBounds {
272                         get {
273                                 return new Rectangle(Location, Size);
274                         }
275
276                         set {
277                                 Bounds = value;
278                         }
279                 }
280
281                 [Browsable(false)]
282                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
283                 public Point DesktopLocation {
284                         get {
285                                 return Location;
286                         }
287
288                         set {
289                                 Location = value;
290                         }
291                 }
292
293                 [Browsable(false)]
294                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
295                 public DialogResult DialogResult {
296                         get {
297                                 return dialog_result;
298                         }
299
300                         set {
301                                 dialog_result = value;
302
303                                 if (is_modal && (dialog_result != DialogResult.None)) {
304                                         end_modal = true;
305                                 }
306                         }
307                 }
308
309                 [DefaultValue(FormBorderStyle.Sizable)]
310                 [DispId(-504)]
311                 public FormBorderStyle FormBorderStyle {
312                         get {
313                                 return formBorderStyle;
314                         }
315                         set {
316                                 formBorderStyle = value;
317                                 UpdateStyles();
318                         }
319                 }
320
321                 [DefaultValue(false)]
322                 public bool HelpButton {
323                         get {
324                                 return help_button;
325                         }
326
327                         set {
328                                 if (help_button != value) {
329                                         help_button = value;
330                                         UpdateStyles();
331                                 }
332                         }
333                 }
334
335                 [Localizable(true)]
336                 [AmbientValue(null)]
337                 public Icon Icon {
338                         get {
339                                 return icon;
340                         }
341
342                         set {
343                                 if (icon != value) {
344                                         icon = value;
345
346                                         XplatUI.SetIcon(Handle, icon);
347                                 }
348                         }
349                 }
350
351                 [Browsable(false)]
352                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
353                 public bool IsMdiChild {
354                         get {
355                                 return mdi_parent != null;
356                         }
357                 }
358
359                 [DefaultValue(false)]
360                 public bool IsMdiContainer {
361                         get {
362                                 return mdi_container != null;
363                         }
364
365                         set {
366                                 if (value && mdi_container == null) {
367                                         mdi_container = new MdiClient();
368                                         Controls.Add(mdi_container);
369                                 } else if (!value && mdi_container != null) {
370                                         Controls.Remove(mdi_container);
371                                         mdi_container.Dispose();
372                                 }
373                         }
374                 }
375
376                 [Browsable(false)]
377                 [EditorBrowsable(EditorBrowsableState.Advanced)]
378                 public bool IsRestrictedWindow {
379                         get {
380                                 return false;
381                         }
382                 }
383
384                 [DefaultValue(false)]
385                 public bool KeyPreview {
386                         get {
387                                 return key_preview;
388                         }
389
390                         set {
391                                 key_preview = value;
392                         }
393                 }
394
395                 [DefaultValue(true)]
396                 public bool MaximizeBox {
397                         get {
398                                 return maximize_box;
399                         }
400                         set {
401                                 if (maximize_box != value) {
402                                         maximize_box = value;
403                                         UpdateStyles();
404                                 }
405                         }
406                 }
407
408                 [DefaultValue(typeof(Size), "{Width=0, Height=0}")]
409                 [Localizable(true)]
410                 [RefreshProperties(RefreshProperties.Repaint)]
411                 public Size MaximumSize {
412                         get {
413                                 return maximum_size;
414                         }
415
416                         set {
417                                 if (maximum_size != value) {
418                                         maximum_size = value;
419                                         OnMaximumSizeChanged(EventArgs.Empty);
420                                 }
421                         }
422                 }
423
424                 [Browsable(false)]
425                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
426                 public Form[] MdiChildren {
427                         get {
428                                 if (mdi_container != null) {
429                                         Form[] form_list;
430
431                                         form_list = new Form[mdi_container.Controls.Count];
432                                         for (int i = 0; i < mdi_container.Controls.Count; i++) {
433                                                 form_list[i] = (Form)mdi_container.Controls[i];
434                                         }
435                                         return form_list;
436                                 } else {
437                                         return new Form[0];
438                                 }
439                         }
440                 }
441
442                 [MonoTODO("Finish setter")]
443                 [Browsable(false)]
444                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
445                 public Form MdiParent {
446                         get {
447                                 return mdi_parent;
448                         }
449
450                         set {
451                                 if (mdi_parent != null) {
452                                         mdi_parent.Controls.Remove(this);
453                                 }
454
455                                 mdi_parent = value;
456                                 if (mdi_parent != null) {
457                                         mdi_parent.Controls.Add(this);
458                                 }
459                         }
460                 }
461
462                 [DefaultValue(null)]
463                 public MainMenu Menu {
464                         get {
465                                 return menu;
466                         }
467
468                         set {                           
469                                 if (menu != value) {                                    
470                                         menu = value;
471
472                                         menu.SetForm (this);
473                                         MenuAPI.SetMenuBarWindow (menu.Handle, this);
474                                 
475                                         if (IsHandleCreated && menu != null) {  
476                                                 XplatUI.SetMenu(window.Handle, menu.Handle);
477                                         }
478
479                                         // FIXME - Do we still need this?
480                                         this.SetBoundsCore(0, 0, 0, 0, BoundsSpecified.None);
481
482                                         ThemeEngine.Current.CalcMenuBarSize (DeviceContext, menu.Handle, ClientSize.Width);
483                                 }
484                         }
485                 }
486
487                 [DefaultValue(true)]
488                 public bool MinimizeBox {
489                         get {
490                                 return minimize_box;
491                         }
492                         set {
493                                 if (minimize_box != value) {
494                                         minimize_box = value;
495                                         UpdateStyles();
496                                 }
497                         }
498                 }
499
500                 [DefaultValue(typeof(Size), "{Width=0, Height=0}")]
501                 [Localizable(true)]
502                 [RefreshProperties(RefreshProperties.Repaint)]
503                 public Size MinimumSize {
504                         get {
505                                 return minimum_size;
506                         }
507
508                         set {
509                                 if (minimum_size != value) {
510                                         minimum_size = value;
511                                         OnMinimumSizeChanged(EventArgs.Empty);
512                                 }
513                         }
514                 }
515
516                 [Browsable(false)]
517                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
518                 public bool Modal  {
519                         get {
520                                 return is_modal;
521                         }
522                 }
523
524                 [Browsable(false)]
525                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
526                 public Form[] OwnedForms {
527                         get {
528                                 Form[] form_list;
529
530                                 form_list = new Form[owned_forms.Count];
531
532                                 for (int i=0; i<owned_forms.Count; i++) {
533                                         form_list[i] = (Form)owned_forms[i];
534                                 }
535
536                                 return form_list;
537                         }
538                 }
539
540                 [Browsable(false)]
541                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
542                 public Form Owner {
543                         get {
544                                 return owner;
545                         }
546
547                         set {
548                                 if (owner != value) {
549                                         if (owner != null) {
550                                                 owner.RemoveOwnedForm(this);
551                                         }
552                                         owner = value;
553                                         owner.AddOwnedForm(this);
554                                         if (owner != null) {
555                                                 XplatUI.SetTopmost(this.window.Handle, owner.window.Handle, true);
556                                         } else {
557                                                 XplatUI.SetTopmost(this.window.Handle, IntPtr.Zero, false);
558                                         }
559                                 }
560                         }
561                 }
562
563                 [DefaultValue(true)]
564                 public bool ShowInTaskbar {
565                         get {
566                                 return show_in_taskbar;
567                         }
568                         set {
569                                 if (show_in_taskbar != value) {
570                                         show_in_taskbar = value;
571                                         UpdateStyles();
572                                 }
573                         }
574                 }
575
576                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
577                 [Localizable(false)]
578                 public Size Size {
579                         get {
580                                 return base.Size;
581                         }
582
583                         set {
584                                 base.Size = value;
585                         }
586                 }
587
588                 [MonoTODO("Trigger something when GripStyle is set")]
589                 [DefaultValue(SizeGripStyle.Auto)]
590                 public SizeGripStyle SizeGripStyle {
591                         get {
592                                 return size_grip_style;
593                         }
594
595                         set {
596                                 size_grip_style = value;
597                         }
598                 }
599
600                 [DefaultValue(FormStartPosition.WindowsDefaultLocation)]
601                 [Localizable(true)]
602                 public FormStartPosition StartPosition {
603                         get {
604                                 return start_position;
605                         }
606
607                         set {
608                                 if (start_position == FormStartPosition.WindowsDefaultLocation) {               // Only do this if it's not set yet
609                                         start_position = value;
610                                         if (IsHandleCreated) {
611                                                 switch(start_position) {
612                                                         case FormStartPosition.CenterParent: {
613                                                                 CenterToParent();
614                                                                 break;
615                                                         }
616
617                                                         case FormStartPosition.CenterScreen: {
618                                                                 CenterToScreen();
619                                                                 break;
620                                                         }
621
622                                                         default: {
623                                                                 break;
624                                                         }
625                                                 }
626                                         }
627                                 }
628                         }
629                 }
630
631                 [Browsable(false)]
632                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
633                 [EditorBrowsable(EditorBrowsableState.Never)]
634                 public int TabIndex {
635                         get {
636                                 return base.TabIndex;
637                         }
638
639                         set {
640                                 base.TabIndex = value;
641                         }
642                 }
643
644                 [Browsable(false)]
645                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
646                 [EditorBrowsable(EditorBrowsableState.Advanced)]
647                 public bool TopLevel {
648                         get {
649                                 return GetTopLevel();
650                         }
651
652                         set {
653                                 SetTopLevel(value);
654                         }
655                 }
656
657                 [DefaultValue(false)]
658                 public bool TopMost {
659                         get {
660                                 return topmost;
661                         }
662
663                         set {
664                                 if (topmost != value) {
665                                         topmost = value;
666                                         XplatUI.SetTopmost(window.Handle, owner != null ? owner.window.Handle : IntPtr.Zero, value);
667                                 }
668                         }
669                 }
670
671                 public Color TransparencyKey {\r
672                         get {\r
673                                 return transparency_key;\r
674                         }\r
675 \r
676                         set {\r
677                                 AllowTransparency = true;\r
678                                 transparency_key = value;\r
679                                 // TODO: change window attributes; a new driver call\r
680                         }\r
681                 }\r
682
683                 [DefaultValue(FormWindowState.Normal)]
684                 public FormWindowState WindowState {
685                         get {
686                                 return XplatUI.GetWindowState(window.Handle);
687                         }
688
689                         set {
690                                 XplatUI.SetWindowState(window.Handle, value);
691                         }
692                 }
693
694                 #endregion      // Public Instance Properties
695
696                 #region Protected Instance Properties
697                 [MonoTODO("Need to add MDI support")]
698                 protected override CreateParams CreateParams {
699                         get {
700                                 CreateParams cp;
701
702                                 cp = new CreateParams();
703
704                                 cp.Caption = "FormWindow";
705                                 cp.ClassName = XplatUI.DefaultClassName;
706                                 cp.ClassStyle = 0;
707                                 cp.ExStyle = 0;
708                                 cp.Param = 0;
709                                 cp.Parent = IntPtr.Zero;
710 //                              if (start_position == FormStartPosition.WindowsDefaultLocation) {
711                                         cp.X = unchecked((int)0x80000000);
712                                         cp.Y = unchecked((int)0x80000000);
713 //                              } else {
714 //                                      cp.X = Left;
715 //                                      cp.Y = Top;
716 //                              }
717                                 cp.Width = Width;
718                                 cp.Height = Height;
719                                 
720                                 cp.Style = (int)(WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN);
721
722                                 switch (FormBorderStyle) {
723                                         case FormBorderStyle.Fixed3D: {
724                                                 cp.Style |= (int)WindowStyles.WS_CAPTION;
725                                                 cp.ExStyle |= (int)WindowStyles.WS_EX_OVERLAPPEDWINDOW;
726                                                 break;
727                                         }
728
729                                         case FormBorderStyle.FixedDialog: {
730                                                 cp.Style |= (int)WindowStyles.WS_CAPTION;
731                                                 cp.ExStyle |= (int)(WindowStyles.WS_EX_DLGMODALFRAME | WindowStyles.WS_EX_WINDOWEDGE);
732                                                 break;
733                                         }
734
735                                         case FormBorderStyle.FixedSingle: {
736                                                 cp.Style |= (int)WindowStyles.WS_CAPTION;
737                                                 cp.ExStyle |= (int)(WindowStyles.WS_EX_WINDOWEDGE);
738                                                 break;
739                                         }
740
741                                         case FormBorderStyle.FixedToolWindow: {
742                                                 cp.Style |= (int)WindowStyles.WS_CAPTION;
743                                                 cp.ExStyle |= (int)(WindowStyles.WS_EX_WINDOWEDGE | WindowStyles.WS_EX_TOOLWINDOW);
744                                                 break;
745                                         }
746
747                                         case FormBorderStyle.Sizable: {
748                                                 cp.Style |= (int)WindowStyles.WS_OVERLAPPEDWINDOW;
749                                                 cp.ExStyle |= (int)(WindowStyles.WS_EX_WINDOWEDGE);
750                                                 break;
751                                         }
752
753                                         case FormBorderStyle.SizableToolWindow: {
754                                                 cp.Style |= (int)WindowStyles.WS_OVERLAPPEDWINDOW;
755                                                 cp.ExStyle |= (int)(WindowStyles.WS_EX_WINDOWEDGE | WindowStyles.WS_EX_TOOLWINDOW);
756                                                 break;
757                                         }
758                                 }
759
760                                 if (ShowInTaskbar) {
761                                         cp.ExStyle |= (int)WindowStyles.WS_EX_APPWINDOW;
762                                 }
763
764                                 if (MaximizeBox) {
765                                         cp.Style |= (int)WindowStyles.WS_MAXIMIZEBOX;
766                                 }
767
768                                 if (MinimizeBox) {
769                                         cp.Style |= (int)WindowStyles.WS_MINIMIZEBOX;
770                                 }
771
772                                 if (ControlBox) {
773                                         cp.Style |= (int)WindowStyles.WS_SYSMENU;
774                                 }
775
776                                 if (HelpButton) {
777                                         cp.ExStyle |= (int)WindowStyles.WS_EX_CONTEXTHELP;
778                                 }
779                                 return cp;
780                         }
781                 }
782
783                 protected override ImeMode DefaultImeMode {
784                         get {
785                                 return ImeMode.NoControl;
786                         }
787                 }
788
789                 protected override Size DefaultSize {
790                         get {
791                                 return new Size (250, 250);
792                         }
793                 }               
794
795                 protected Rectangle MaximizedBounds {
796                         get {
797                                 if (maximized_bounds != Rectangle.Empty) {
798                                         return maximized_bounds;
799                                 }
800                                 return default_maximized_bounds;
801                         }
802
803                         set {
804                                 maximized_bounds = value;
805                                 OnMaximizedBoundsChanged(EventArgs.Empty);
806                         }
807                 }
808                 #endregion      // Protected Instance Properties
809
810                 #region Public Static Methods
811                 [MonoTODO("Figure out the math")]
812                 [EditorBrowsable(EditorBrowsableState.Advanced)]
813                 public static SizeF GetAutoScaleSize(Font font) {
814                         SizeF   result;
815
816                         result = new SizeF(250, 250);
817                         result.Width *= font.SizeInPoints / 12;
818                         result.Height *= font.SizeInPoints / 12;
819                         return result;
820                 }
821                 #endregion      // Public Static Methods
822
823                 #region Public Instance Methods
824                 public void Activate() {
825                         Form    active;
826
827                         // The docs say activate only activates if our app is already active
828                         active = ActiveForm;
829                         if ((active != null) && (this != active)) {
830                                 XplatUI.Activate(window.Handle);
831                         }
832                 }
833
834                 public void AddOwnedForm(Form ownedForm) {
835                         owned_forms.Add(ownedForm);
836                 }
837
838                 public void Close () {
839                         CancelEventArgs args = new CancelEventArgs ();
840                         OnClosing (args);
841                         if (!args.Cancel) {
842                                 OnClosed (EventArgs.Empty);
843                                 closing = true;
844                                 return;
845                         }
846                 }
847
848                 public void LayoutMdi(MdiLayout value) {
849                         if (mdi_container != null) {
850                                 mdi_container.LayoutMdi(value);
851                         }
852                 }
853
854                 public void RemoveOwnedForm(Form ownedForm) {
855                         owned_forms.Remove(ownedForm);
856                 }
857
858                 public void SetDesktopBounds(int x, int y, int width, int height) {
859                         DesktopBounds = new Rectangle(x, y, width, height);
860                 }
861
862                 public void SetDesktopLocation(int x, int y) {
863                         DesktopLocation = new Point(x, y);
864                 }
865
866                 public DialogResult ShowDialog() {
867                         return ShowDialog(null);
868                 }
869
870                 public DialogResult ShowDialog(IWin32Window ownerWin32) {
871                         Form            previous;
872
873                         #if broken
874                         Control         owner = null;
875
876                         if (ownerWin32 != null) {
877                                 owner = Control.FromHandle(ownerWin32.Handle);
878                         }
879                         #endif
880
881                         if (is_modal) {
882                                 return DialogResult.None;
883                         }
884
885                         if (Visible) {
886                                 throw new InvalidOperationException("Already visible forms cannot be displayed as a modal dialog. Set the Visible property to 'false' prior to calling Form.ShowDialog.");
887                         }
888
889                         #if broken
890                         // Can't do this, will screw us in the modal loop
891                         form_parent_window.Parent = owner;
892                         #endif
893
894                         previous = Form.ActiveForm;
895
896                         if (!IsHandleCreated) {
897                                 CreateControl();
898                         }
899
900                         XplatUI.SetModal(window.Handle, true);
901
902                         Show();
903                         PerformLayout();
904
905                         is_modal = true;
906                         Application.ModalRun(this);
907                         is_modal = false;
908                         Hide();
909
910                         XplatUI.SetModal(window.Handle, false);
911
912                         if (previous != null) {
913                                 // Cannot use Activate(), it has a check for the current active window...
914                                 XplatUI.Activate(previous.window.Handle);
915                         }
916
917                         return DialogResult;
918                 }
919
920                 public override string ToString() {
921                         return GetType().FullName.ToString() + ", Text: " + Text;
922                 }
923                 #endregion      // Public Instance Methods
924
925                 #region Protected Instance Methods
926                 [MonoTODO("Finish when MDI is more complete")]
927                 protected void ActivateMdiChild(Form form) {
928                         OnMdiChildActivate(EventArgs.Empty);
929                         throw new NotImplementedException();
930                 }
931
932                 [EditorBrowsable(EditorBrowsableState.Advanced)]
933                 protected override void AdjustFormScrollbars(bool displayScrollbars) {
934                         base.AdjustFormScrollbars (displayScrollbars);
935                 }
936
937                 [EditorBrowsable(EditorBrowsableState.Advanced)]
938                 protected void ApplyAutoScaling() {
939                         // Hm, not sure what this does
940                 }
941
942                 protected void CenterToParent() {
943                         Control ctl;
944                         int     w;
945                         int     h;
946
947                         if (Width > 0) {
948                                 w = Width;
949                         } else {
950                                 w = DefaultSize.Width;
951                         }
952
953                         if (Height > 0) {
954                                 h = Height;
955                         } else {
956                                 h = DefaultSize.Height;
957                         }
958
959                         ctl = null;
960                         if (parent != null) {
961                                 ctl = parent;
962                         } else if (owner != null) {
963                                 ctl = owner;
964                         }
965
966                         if (owner != null) {
967                                 this.Location = new Point(ctl.Left + ctl.Width / 2 - w /2, ctl.Top + ctl.Height / 2 - h / 2);
968                         }
969                 }
970
971                 protected void CenterToScreen() {
972                         Size    DisplaySize;
973                         int     w;
974                         int     h;
975
976                         if (Width > 0) {
977                                 w = Width;
978                         } else {
979                                 w = DefaultSize.Width;
980                         }
981
982                         if (Height > 0) {
983                                 h = Height;
984                         } else {
985                                 h = DefaultSize.Height;
986                         }
987
988                         XplatUI.GetDisplaySize(out DisplaySize);
989                         this.Location = new Point(DisplaySize.Width / 2 - w / 2, DisplaySize.Height / 2 - h / 2);
990                 }
991
992                 [EditorBrowsable(EditorBrowsableState.Advanced)]
993                 protected override Control.ControlCollection CreateControlsInstance() {
994                         return base.CreateControlsInstance ();
995                 }
996
997                 [EditorBrowsable(EditorBrowsableState.Advanced)]
998                 protected override void CreateHandle() {
999                         base.CreateHandle ();
1000                 }
1001
1002                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1003                 protected override void DefWndProc(ref Message m) {
1004                         base.DefWndProc (ref m);
1005                 }
1006
1007                 protected override void Dispose(bool disposing) {
1008                         base.Dispose (disposing);
1009                 }
1010
1011                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1012                 protected virtual void OnActivated(EventArgs e) {
1013                         if (Activated != null) {
1014                                 Activated(this, e);
1015                         }
1016                 }
1017
1018                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1019                 protected virtual void OnClosed(EventArgs e) {
1020                         if (Closed != null) {
1021                                 Closed(this, e);
1022                         }
1023                 }
1024
1025                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1026                 protected virtual void OnClosing(System.ComponentModel.CancelEventArgs e) {
1027                         if (Closing != null) {
1028                                 Closing(this, e);
1029                         }
1030                 }
1031
1032                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1033                 protected override void OnCreateControl() {
1034                         base.OnCreateControl ();
1035                         if (this.ActiveControl == null) {
1036                                 bool visible;
1037
1038                                 // This visible hack is to work around CanSelect always being false if one of the parents
1039                                 // is not visible; and we by default create Form invisible...
1040                                 visible = this.is_visible;
1041                                 this.is_visible = true;
1042
1043                                 if (SelectNextControl(this, true, true, true, true) == false) {
1044                                         Select(this);
1045                                 }
1046
1047                                 this.is_visible = visible;
1048                         }
1049                         
1050                         if (menu != null) {
1051                                 XplatUI.SetMenu(window.Handle, menu.Handle);
1052                         }
1053                         
1054                         OnLoad(EventArgs.Empty);
1055
1056                         // Send initial location
1057                         OnLocationChanged(EventArgs.Empty);
1058                 }
1059
1060                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1061                 protected virtual void OnDeactivate(EventArgs e) {
1062                         if (Deactivate != null) {
1063                                 Deactivate(this, e);
1064                         }
1065                 }
1066
1067                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1068                 protected override void OnFontChanged(EventArgs e) {
1069                         base.OnFontChanged (e);
1070                 }
1071
1072                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1073                 protected override void OnHandleCreated(EventArgs e) {
1074                         base.OnHandleCreated (e);
1075                 }
1076
1077                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1078                 protected override void OnHandleDestroyed(EventArgs e) {
1079                         base.OnHandleDestroyed (e);
1080                 }
1081
1082                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1083                 protected virtual void OnInputLanguageChanged(InputLanguageChangedEventArgs e) {
1084                         if (InputLanguageChanged!=null) {
1085                                 InputLanguageChanged(this, e);
1086                         }
1087                 }
1088
1089                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1090                 protected virtual void OnInputLanguageChanging(InputLanguageChangingEventArgs e) {
1091                         if (InputLanguageChanging!=null) {
1092                                 InputLanguageChanging(this, e);
1093                         }
1094                 }
1095
1096                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1097                 protected virtual void OnLoad(EventArgs e) {
1098                         if (Load != null) {
1099                                 Load(this, e);
1100                         }
1101                 }
1102
1103                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1104                 protected virtual void OnMaximizedBoundsChanged(EventArgs e) {
1105                         if (MaximizedBoundsChanged != null) {
1106                                 MaximizedBoundsChanged(this, e);
1107                         }
1108                 }
1109
1110                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1111                 protected virtual void OnMaximumSizeChanged(EventArgs e) {
1112                         if (MaximumSizeChanged != null) {
1113                                 MaximumSizeChanged(this, e);
1114                         }
1115                 }
1116
1117                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1118                 protected virtual void OnMdiChildActivate(EventArgs e) {
1119                         if (MdiChildActivate != null) {
1120                                 MdiChildActivate(this, e);
1121                         }
1122                 }
1123
1124                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1125                 protected virtual void OnMenuComplete(EventArgs e) {
1126                         if (MenuComplete != null) {
1127                                 MenuComplete(this, e);
1128                         }
1129                 }
1130
1131                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1132                 protected virtual void OnMenuStart(EventArgs e) {
1133                         if (MenuStart != null) {
1134                                 MenuStart(this, e);
1135                         }
1136                 }
1137
1138                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1139                 protected virtual void OnMinimumSizeChanged(EventArgs e) {
1140                         if (MinimumSizeChanged != null) {
1141                                 MinimumSizeChanged(this, e);
1142                         }
1143                 }
1144
1145                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1146                 protected override void OnPaint (PaintEventArgs pevent) {
1147                         base.OnPaint (pevent);
1148                 }               
1149                 
1150                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1151                 protected override void OnResize(EventArgs e) {
1152                         base.OnResize(e);
1153                 }
1154
1155                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1156                 protected override void OnStyleChanged(EventArgs e) {
1157                         base.OnStyleChanged (e);
1158                 }
1159
1160                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1161                 protected override void OnTextChanged(EventArgs e) {
1162                         base.OnTextChanged (e);
1163                 }
1164
1165                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1166                 protected override void OnVisibleChanged(EventArgs e) {
1167                         base.OnVisibleChanged (e);
1168                 }
1169
1170                 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
1171                         if (base.ProcessCmdKey (ref msg, keyData)) {
1172                                 return true;
1173                         }
1174
1175                         // Give our menu a shot
1176                         if (menu != null) {
1177                                 return menu.ProcessCmdKey(ref msg, keyData);
1178                         }
1179
1180                         return false;
1181                 }
1182
1183                 // LAMESPEC - Not documented that Form overrides ProcessDialogChar; class-status showed
1184                 [EditorBrowsable (EditorBrowsableState.Advanced)]
1185                 protected override bool ProcessDialogChar(char charCode) {
1186                         return base.ProcessDialogChar (charCode);
1187                 }
1188
1189                 protected override bool ProcessDialogKey(Keys keyData) {
1190                         if ((keyData & Keys.Modifiers) == 0) {
1191                                 if (keyData == Keys.Enter && accept_button != null) {
1192                                         accept_button.PerformClick();
1193                                         return true;
1194                                 } else if (keyData == Keys.Escape && cancel_button != null) {
1195                                         cancel_button.PerformClick();
1196                                         return true;
1197                                 }
1198                         }
1199                         return base.ProcessDialogKey(keyData);
1200                 }
1201
1202                 protected override bool ProcessKeyPreview(ref Message msg) {
1203                         if (key_preview) {
1204                                 if (ProcessKeyEventArgs(ref msg)) {
1205                                         return true;
1206                                 }
1207                         }
1208                         return base.ProcessKeyPreview (ref msg);
1209                 }
1210
1211                 protected override bool ProcessTabKey(bool forward) {
1212                         return SelectNextControl(ActiveControl, forward, true, true, true);
1213                 }
1214
1215                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1216                 protected override void ScaleCore(float dx, float dy) {
1217                         base.ScaleCore (dx, dy);
1218                 }
1219
1220                 protected override void Select(bool directed, bool forward) {
1221                         Form    parent;
1222
1223                         if (directed) {
1224                                 base.SelectNextControl(null, forward, true, true, true);
1225                         }
1226
1227                         parent = this.ParentForm;
1228                         if (parent != null) {
1229                                 parent.ActiveControl = this;
1230                         }
1231
1232                         Activate();
1233                 }
1234
1235                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1236                 protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {
1237                         base.SetBoundsCore (x, y, width, height, specified);
1238                 }
1239
1240                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1241                 protected override void SetClientSizeCore(int x, int y) {
1242                         if ((minimum_size.Width != 0) && (x < minimum_size.Width)) {
1243                                 x = minimum_size.Width;
1244                         } else if ((maximum_size.Width != 0) && (x > maximum_size.Width)) {
1245                                 x = maximum_size.Width;
1246                         }
1247
1248                         if ((minimum_size.Height != 0) && (y < minimum_size.Height)) {
1249                                 y = minimum_size.Height;
1250                         } else if ((maximum_size.Height != 0) && (y > maximum_size.Height)) {
1251                                 y = maximum_size.Height;
1252                         }
1253
1254                         base.SetClientSizeCore (x, y);
1255                 }
1256
1257                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1258                 protected override void SetVisibleCore(bool value) {
1259                         base.SetVisibleCore (value);
1260                 }
1261
1262                 protected override void UpdateDefaultButton() {
1263                         base.UpdateDefaultButton ();
1264                 }
1265
1266                 [EditorBrowsable(EditorBrowsableState.Advanced)]
1267                 protected override void WndProc(ref Message m) {
1268                         switch((Msg)m.Msg) {
1269                                 case Msg.WM_CLOSE: {
1270                                         CancelEventArgs args = new CancelEventArgs();
1271
1272                                         OnClosing(args);
1273
1274                                         if (!args.Cancel) {
1275                                                 OnClosed(EventArgs.Empty);
1276                                                 closing = true;
1277                                                 base.WndProc(ref m);
1278                                                 break;
1279                                         }
1280                                         break;
1281                                 }
1282
1283                                 case Msg.WM_ACTIVATE: {
1284                                         if (m.WParam != (IntPtr)WindowActiveFlags.WA_INACTIVE) {
1285                                                 OnActivated(EventArgs.Empty);
1286                                         } else {
1287                                                 OnDeactivate(EventArgs.Empty);
1288                                         }
1289                                         return;
1290                                 }
1291
1292                                 case Msg.WM_KILLFOCUS: {
1293                                         base.WndProc(ref m);
1294                                         return;
1295                                 }
1296
1297                                 case Msg.WM_SETFOCUS: {
1298 #if not
1299                                         if (this.ActiveControl != null) {
1300                                                 ActiveControl.Focus();
1301                                         }
1302 #endif
1303                                         base.WndProc(ref m);
1304                                         return;
1305                                 }
1306
1307                                 // Menu drawing
1308                                 case Msg.WM_NCLBUTTONDOWN: {
1309                                         if (this.menu != null) {
1310                                                 int x = LowOrder ((int) m.LParam.ToInt32 ()) ;
1311                                                 int y = HighOrder ((int) m.LParam.ToInt32 ());                                          
1312                                                 menu.OnMouseDown(this, new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), mouse_clicks, x, y, 0));
1313                                         }
1314                                         base.WndProc(ref m);
1315                                         return;
1316                                 }
1317
1318                                 case Msg.WM_NCMOUSEMOVE: {
1319                                         if (this.menu != null) {
1320                                                 menu.OnMouseMove(this, new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
1321                                                         mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 0));
1322                                         }
1323                                         base.WndProc(ref m);
1324                                         return;
1325                                 }
1326
1327                                 case Msg.WM_NCPAINT: {
1328                                         if (this.menu != null) {
1329                                                 Point pnt = XplatUI.GetMenuOrigin(window.Handle);
1330                                                 MenuAPI.DrawMenuBar (menu.Handle, new Rectangle (pnt.X, pnt.Y, ClientSize.Width, 0));
1331                                         }
1332
1333                                         base.WndProc(ref m);
1334                                         return;
1335                                 }
1336
1337                                 // This message is only received under Win32
1338                                 case Msg.WM_NCCALCSIZE: {
1339                                         XplatUIWin32.NCCALCSIZE_PARAMS  ncp;
1340
1341                                         if ((menu != null) && (m.WParam == (IntPtr)1)) {
1342                                                 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
1343
1344                                                 // Adjust for menu
1345                                                 ncp.rgrc1.top += ThemeEngine.Current.CalcMenuBarSize (DeviceContext, menu.menu_handle, ClientSize.Width);
1346                                                 Marshal.StructureToPtr(ncp, m.LParam, true);
1347                                         }
1348                                         DefWndProc(ref m);
1349                                         break;
1350                                 }
1351
1352                                 case Msg.WM_GETMINMAXINFO: {
1353                                         XplatUIWin32.MINMAXINFO mmi;
1354
1355                                         if (m.LParam != IntPtr.Zero) {
1356                                                 mmi = (XplatUIWin32.MINMAXINFO)Marshal.PtrToStructure(m.LParam, typeof(XplatUIWin32.MINMAXINFO));
1357                                                 default_maximized_bounds = new Rectangle(mmi.ptMaxPosition.x, mmi.ptMaxPosition.y, mmi.ptMaxSize.x, mmi.ptMaxSize.y);
1358                                                 if (maximized_bounds != Rectangle.Empty) {
1359                                                         mmi.ptMaxSize.x = maximized_bounds.Width;
1360                                                         mmi.ptMaxSize.y = maximized_bounds.Height;
1361                                                 }
1362
1363                                                 Marshal.StructureToPtr(mmi, m.LParam, false);
1364                                         }
1365                                         break;
1366                                 }
1367
1368                                 default: {
1369                                         base.WndProc (ref m);
1370                                         break;
1371                                 }
1372                         }
1373                 }
1374                 #endregion      // Protected Instance Methods
1375
1376                 #region Events
1377                 public event EventHandler Activated;
1378                 public event EventHandler Closed;
1379                 public event CancelEventHandler Closing;
1380                 public event EventHandler Deactivate;
1381                 public event InputLanguageChangedEventHandler InputLanguageChanged;
1382                 public event InputLanguageChangingEventHandler InputLanguageChanging;
1383                 public event EventHandler Load;
1384                 public event EventHandler MaximizedBoundsChanged;
1385                 public event EventHandler MaximumSizeChanged;
1386                 public event EventHandler MdiChildActivate;
1387                 public event EventHandler MenuComplete;
1388                 public event EventHandler MenuStart;
1389                 public event EventHandler MinimumSizeChanged;
1390
1391                 [Browsable(false)]
1392                 [EditorBrowsable(EditorBrowsableState.Never)]
1393                 public new event EventHandler TabIndexChanged;
1394                 #endregion      // Events
1395         }
1396 }