- Added code to simulate modal dialogs on Win32
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Application.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 // $Revision: 1.7 $
27 // $Modtime: $
28 // $Log: Application.cs,v $
29 // Revision 1.7  2004/10/18 04:14:14  pbartok
30 // - Added code to simulate modal dialogs on Win32
31 //
32 // Revision 1.6  2004/09/22 20:05:41  pbartok
33 // - Added message loop for modal dialogs
34 //
35 // Revision 1.5  2004/09/21 00:54:15  jackson
36 // New message loop that uses poll so we don't get a busy loop
37 //
38 // Revision 1.4  2004/08/23 22:45:19  pbartok
39 // - Removed debug output
40 // - Simplifications
41 //
42 // Revision 1.3  2004/08/23 22:09:29  pbartok
43 // - Added handling of Idle event
44 // - Added handling of form closing
45 // - Fixed reporting of MessageLoop property
46 // - Removed some unneeded code, should provide a bit of a speedup
47 //
48 // Revision 1.2  2004/08/11 22:16:50  pbartok
49 // - Fixed Signature
50 // - Added .Net 1.1 method
51 //
52 // Revision 1.1  2004/07/09 05:21:25  pbartok
53 // - Initial check-in
54 //
55 //
56
57 // COMPLETE
58
59 using Microsoft.Win32;
60 using System;
61 using System.Drawing;
62 using System.ComponentModel;
63 using System.Collections;
64 using System.Diagnostics;
65 using System.Globalization;
66 using System.IO;
67 using System.Reflection;
68 using System.Runtime.InteropServices;
69 using System.Threading;
70
71 namespace System.Windows.Forms {
72         public sealed class Application {
73                 private static bool                     browser_embedded;
74                 private static bool                     exiting;
75                 private static InputLanguage            input_language;
76                 private static bool                     messageloop_started;
77                 private static string                   safe_caption_format;
78                 private static ArrayList                message_filters;
79                 private static ApplicationContext       app_context;
80                 private static Form                     main_form;
81
82                 private Application () {
83                         input_language  = InputLanguage.CurrentInputLanguage;
84                         message_filters = new ArrayList();
85                         app_context     = null;
86                         browser_embedded= false;
87                         exiting         = false;
88                         messageloop_started = false;
89                         safe_caption_format = "{1} - {0} - {2}";
90                 }
91
92                 #region Private and Internal Methods
93                 internal static void ModalRun(Form form) {
94                         MSG     msg = new MSG();
95                         Queue   toplevels = new Queue();
96                         IEnumerator control = Control.controls.GetEnumerator();
97
98                         if (form == null) {
99                                 return;
100                         }
101
102                         while (control.MoveNext()) {
103                                 if ((((Control)control.Current).parent == null) && (((Control)control.Current).is_visible) && (((Control)control.Current).is_enabled) && (((Form)control.Current)!=form)) {
104                                         XplatUI.EnableWindow(((Control)control.Current).window.Handle, false);
105                                         toplevels.Enqueue((Control)control.Current);
106                                 }
107                         }
108
109                         while (!exiting && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
110                                 if (form.end_modal) {
111                                         break;
112                                 }
113
114                                 XplatUI.TranslateMessage(ref msg);
115                                 XplatUI.DispatchMessage(ref msg);
116
117                                 // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
118                                 if (form.closing) {
119                                         form.end_modal = true;
120                                 }
121                         }
122
123                         while (toplevels.Count>0) {
124                                 XplatUI.EnableWindow(((Control)toplevels.Dequeue()).window.Handle, true);
125                         }
126                 }
127                 #endregion      // Private and Internal Methods
128
129                 #region Public Static Properties
130                 public static bool AllowQuit {
131                         get {
132                                 return browser_embedded;
133                         }
134                 }
135
136                 public static string CommonAppDataPath {
137                         get {
138                                 return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
139                         }
140                 }
141
142                 public static RegistryKey CommonAppDataRegistry {
143                         get {
144                                 RegistryKey     key;
145
146                                 key = Registry.LocalMachine.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
147
148                                 return key;
149                         }
150                 }
151
152                 public static string CompanyName {
153                         get {
154                                 StackTrace      st;
155
156                                 if (Environment.OSVersion.Platform != (PlatformID)128) {
157                                         RegistryKey     key;
158                                         String          ret;
159
160                                         key=Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion", false);
161                                         ret=(String)key.GetValue("RegisteredOrganization");
162
163                                         return ret;
164                                         
165                                 }
166
167                                 st=new StackTrace();
168                                 return st.GetFrame(st.FrameCount-1).GetMethod().DeclaringType.Namespace;
169                         }
170                 }
171
172                 public static CultureInfo CurrentCulture {
173                         get {
174                                 return Thread.CurrentThread.CurrentUICulture;
175                         }
176
177                         set {
178                                 
179                                 Thread.CurrentThread.CurrentUICulture=value;
180                         }
181                 }
182
183                 public static InputLanguage CurrentInputLanguage {
184                         get {
185                                 return input_language;
186                         }
187
188                         set {
189                                 input_language=value;
190                         }
191                 }
192
193                 public static string ExecutablePath {
194                         get {
195                                 return Assembly.GetEntryAssembly().Location;
196                         }
197                 }
198
199                 public static string LocalUserAppDataPath {
200                         get {
201                                 return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
202                         }
203                 }
204
205                 public static bool MessageLoop {
206                         get {
207                                 return messageloop_started;
208                         }
209                 }
210
211                 public static string ProductName {
212                         get {
213                                 AssemblyProductAttribute[] attrs = (AssemblyProductAttribute[]) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true);
214                                 
215                                 if ((attrs != null) && attrs.Length>0) {
216                                         return attrs[0].Product;
217                                 }
218
219                                 return Assembly.GetEntryAssembly().GetName().Name;
220                         }
221                 }
222
223                 public static string ProductVersion {
224                         get {
225                                 String version;
226
227                                 version = Assembly.GetEntryAssembly().GetName().Version.ToString();
228
229                                 if (version.StartsWith("0.")) {
230                                         version="1." + version.Substring(2);
231                                 }
232                                 return version;
233                         }
234                 }
235
236                 public static string SafeTopLevelCaptionFormat {
237                         get {
238                                 return safe_caption_format;
239                         }
240
241                         set {
242                                 safe_caption_format=value;
243                         }
244                 }
245
246                 public static string StartupPath {
247                         get {
248                                 return Path.GetDirectoryName(Application.ExecutablePath);
249                         }
250                 }
251
252                 public static string UserAppDataPath {
253                         get {
254                                 return Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
255                         }
256                 }
257
258                 public static RegistryKey UserAppDataRegistry {
259                         get {
260                                 RegistryKey     key;
261
262                                 key = Registry.CurrentUser.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
263
264                                 return key;
265                         }
266                 }
267                 #endregion
268
269                 #region Public Static Methods
270                 public static void AddMessageFilter(IMessageFilter value) {
271                         message_filters.Add(value);
272                 }
273
274                 public static void DoEvents() {
275                         XplatUI.DoEvents();
276                 }
277
278                 public static void EnableVisualStyles() {
279                         XplatUI.EnableThemes();
280                 }
281
282                 public static void Exit() {
283                         XplatUI.Exit();
284                 }
285
286                 public static void ExitThread() {
287                         exiting=true;
288                 }
289
290                 private static void InternalExit(object sender, EventArgs e) {
291                         Application.Exit();
292                 }
293
294                 public static ApartmentState OleRequired() {
295                         //throw new NotImplementedException("OLE Not supported by this System.Windows.Forms implementation");
296                         return ApartmentState.Unknown;
297                 }
298
299                 public static void OnThreadException(Exception t) {
300                         if (Application.ThreadException != null) {
301                                 Application.ThreadException(null, new ThreadExceptionEventArgs(t));
302                         } else {
303                                 XplatUI.HandleException(t);
304                         }
305                 }
306
307                 public static void RemoveMessageFilter(IMessageFilter filter) {
308                         message_filters.Remove(filter);
309                 }
310
311                 public static void Run() {
312                         MSG     msg = new MSG();
313                         Form    form = null;
314
315                         if (app_context != null) {
316                                 form = app_context.MainForm;
317                         }
318
319                         messageloop_started = true;
320
321                         while (!exiting && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
322                                 XplatUI.TranslateMessage(ref msg);
323                                 XplatUI.DispatchMessage(ref msg);
324
325                                 // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
326                                 if ((form != null) && form.closing) {
327                                         exiting = true;
328                                 }
329                         }
330
331                         messageloop_started = false;
332
333                         if (ApplicationExit != null) {
334                                 ApplicationExit(null, EventArgs.Empty);
335                         }
336                 }
337
338                 public static void Run(Form mainForm) {
339                         mainForm.CreateControl();
340                         Run(new ApplicationContext(mainForm));
341                 }
342
343                 public static void Run(ApplicationContext context) {
344                         app_context=context;
345                         if (app_context.MainForm!=null) {
346                                 app_context.MainForm.Show();
347                                 app_context.ThreadExit += new EventHandler(InternalExit);
348                         }
349                         Run();
350                 }
351                 #endregion      // Public Static Methods
352
353                 #region Events
354                 public static event EventHandler        ApplicationExit;
355
356                 public static event EventHandler        Idle {
357                         add {
358                                 XplatUI.Idle += value;
359                         }
360                         remove {
361                                 XplatUI.Idle -= value;
362                         }
363                 }
364
365                 public static event EventHandler        ThreadExit;
366                 public static event ThreadExceptionEventHandler ThreadException;
367                 #endregion      // Events
368         }
369 }