Add this for backwards compatibility
[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 - 2005 Novell, Inc.
21 //
22 // Authors:
23 //      Peter Bartok    pbartok@novell.com
24 //
25
26 // COMPLETE
27
28 using Microsoft.Win32;
29 using System;
30 using System.Drawing;
31 using System.ComponentModel;
32 using System.Collections;
33 using System.Diagnostics;
34 using System.Globalization;
35 using System.IO;
36 using System.Reflection;
37 using System.Runtime.InteropServices;
38 using System.Threading;
39
40 namespace System.Windows.Forms {
41         public sealed class Application {
42                 private static bool                     browser_embedded        = false;
43                 private static bool                     exiting                 = false;
44                 private static InputLanguage            input_language          = InputLanguage.CurrentInputLanguage;
45                 private static bool                     messageloop_started     = false;
46                 private static string                   safe_caption_format     = "{1} - {0} - {2}";
47                 private static ArrayList                message_filters         = new ArrayList();
48                 private static ApplicationContext       app_context             = null;
49
50                 private Application () {
51                 }
52
53                 #region Private and Internal Methods
54                 internal static void ModalRun(Form form) {
55                         MSG     msg = new MSG();
56                         Queue   toplevels = new Queue();
57                         IEnumerator control = Control.controls.GetEnumerator();
58
59                         if (form == null) {
60                                 return;
61                         }
62
63                         // Both calls are needed, one is for the WM, the other for our focus logic
64                         XplatUI.Activate(form.window.Handle);
65                         form.Activate();
66
67                         while (control.MoveNext()) {
68                                 if ((((Control)control.Current).parent == null) && (((Control)control.Current).is_visible) && (((Control)control.Current).is_enabled)) {
69                                         if ((control.Current is Form)  && (((Form)control.Current)!=form)) {
70                                                 XplatUI.EnableWindow(((Control)control.Current).window.Handle, false);
71                                                 toplevels.Enqueue((Control)control.Current);
72                                         }
73                                 }
74                         }
75
76                         form.CreateControl();
77
78                         while (!exiting && !form.end_modal && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
79                                 if ((message_filters != null) && (message_filters.Count > 0)) {
80                                         Message m;
81                                         bool    drop;
82
83                                         drop = false;
84                                         m = new Message();
85                                         m.Msg = (int)msg.message;
86                                         m.HWnd = msg.hwnd;
87                                         m.LParam = msg.lParam;
88                                         m.WParam = msg.wParam;
89                                         for (int i = 0; i < message_filters.Count; i++) {
90                                                 if (((IMessageFilter)message_filters[i]).PreFilterMessage(ref m)) {
91                                                         // we're dropping the message
92                                                         drop = true;
93                                                         break;
94                                                 }
95                                         }
96                                         if (drop) {
97                                                 continue;
98                                         }
99                                 }
100
101                                 XplatUI.TranslateMessage(ref msg);
102                                 XplatUI.DispatchMessage(ref msg);
103
104                                 // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
105                                 if (form.closing) {
106                                         form.end_modal = true;
107                                 }
108                         }
109
110                         while (toplevels.Count>0) {
111                                 XplatUI.EnableWindow(((Control)toplevels.Dequeue()).window.Handle, true);
112                         }
113                 }
114                 #endregion      // Private and Internal Methods
115
116                 #region Public Static Properties
117                 public static bool AllowQuit {
118                         get {
119                                 return browser_embedded;
120                         }
121                 }
122
123                 public static string CommonAppDataPath {
124                         get {
125                                 return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
126                         }
127                 }
128
129                 public static RegistryKey CommonAppDataRegistry {
130                         get {
131                                 RegistryKey     key;
132
133                                 key = Registry.LocalMachine.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
134
135                                 return key;
136                         }
137                 }
138
139                 public static string CompanyName {
140                         get {
141                                 AssemblyCompanyAttribute[] attrs = (AssemblyCompanyAttribute[]) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), true);
142                                 
143                                 if ((attrs != null) && attrs.Length>0) {
144                                         return attrs[0].Company;
145                                 }
146
147                                 return Assembly.GetEntryAssembly().GetName().Name;
148                         }
149                 }
150
151                 public static CultureInfo CurrentCulture {
152                         get {
153                                 return Thread.CurrentThread.CurrentUICulture;
154                         }
155
156                         set {
157                                 
158                                 Thread.CurrentThread.CurrentUICulture=value;
159                         }
160                 }
161
162                 public static InputLanguage CurrentInputLanguage {
163                         get {
164                                 return input_language;
165                         }
166
167                         set {
168                                 input_language=value;
169                         }
170                 }
171
172                 public static string ExecutablePath {
173                         get {
174                                 return Assembly.GetEntryAssembly().Location;
175                         }
176                 }
177
178                 public static string LocalUserAppDataPath {
179                         get {
180                                 return Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), CompanyName), ProductName), ProductVersion);
181                         }
182                 }
183
184                 public static bool MessageLoop {
185                         get {
186                                 return messageloop_started;
187                         }
188                 }
189
190                 public static string ProductName {
191                         get {
192                                 AssemblyProductAttribute[] attrs = (AssemblyProductAttribute[]) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true);
193                                 
194                                 if ((attrs != null) && attrs.Length>0) {
195                                         return attrs[0].Product;
196                                 }
197
198                                 return Assembly.GetEntryAssembly().GetName().Name;
199                         }
200                 }
201
202                 public static string ProductVersion {
203                         get {
204                                 String version;
205
206                                 version = Assembly.GetEntryAssembly().GetName().Version.ToString();
207
208                                 if (version.StartsWith("0.")) {
209                                         version="1." + version.Substring(2);
210                                 }
211                                 return version;
212                         }
213                 }
214
215                 public static string SafeTopLevelCaptionFormat {
216                         get {
217                                 return safe_caption_format;
218                         }
219
220                         set {
221                                 safe_caption_format=value;
222                         }
223                 }
224
225                 public static string StartupPath {
226                         get {
227                                 return Path.GetDirectoryName(Application.ExecutablePath);
228                         }
229                 }
230
231                 public static string UserAppDataPath {
232                         get {
233                                 return Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), CompanyName), ProductName), ProductVersion);
234                         }
235                 }
236
237                 public static RegistryKey UserAppDataRegistry {
238                         get {
239                                 RegistryKey     key;
240
241                                 key = Registry.CurrentUser.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
242
243                                 return key;
244                         }
245                 }
246                 #endregion
247
248                 #region Public Static Methods
249                 public static void AddMessageFilter(IMessageFilter value) {
250                         message_filters.Add(value);
251                 }
252
253                 public static void DoEvents() {
254                         XplatUI.DoEvents();
255                 }
256
257                 public static void EnableVisualStyles() {
258                         XplatUI.EnableThemes();
259                 }
260
261 #if NET_2_0
262                 public static void EnableRTLMirroring () 
263                 {
264                 }
265 #endif
266
267                 public static void Exit() {
268                         XplatUI.PostQuitMessage(0);
269                 }
270
271                 public static void ExitThread() {
272                         exiting=true;
273                 }
274
275                 private static void InternalExit(object sender, EventArgs e) {
276                         Application.Exit();
277                 }
278
279                 public static ApartmentState OleRequired() {
280                         //throw new NotImplementedException("OLE Not supported by this System.Windows.Forms implementation");
281                         return ApartmentState.Unknown;
282                 }
283
284                 public static void OnThreadException(Exception t) {
285                         if (Application.ThreadException != null) {
286                                 Application.ThreadException(null, new ThreadExceptionEventArgs(t));
287                                 return;
288                         }
289
290                         if (SystemInformation.UserInteractive) {
291                                 Form form = new ThreadExceptionDialog (t);
292                                 form.ShowDialog ();
293                         } else {
294                                 Console.WriteLine (t.ToString ());
295                         }
296                 }
297
298                 public static void RemoveMessageFilter(IMessageFilter filter) {
299                         message_filters.Remove(filter);
300                 }
301
302                 public static void Run() {
303                         MSG     msg = new MSG();
304                         Form    form = null;
305
306                         if (app_context != null) {
307                                 form = app_context.MainForm;
308                                 form.context = app_context;
309                         }
310
311                         if (form != null) {
312                                 // Both calls are needed, one is for the WM, the other for our focus logic
313                                 XplatUI.Activate(form.window.Handle);
314                                 form.Activate();
315                         }
316
317                         messageloop_started = true;
318
319                         while (!exiting && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
320                                 if ((message_filters != null) && (message_filters.Count > 0)) {
321                                         Message m;
322                                         bool    drop;
323
324                                         drop = false;
325                                         m = new Message();
326                                         m.Msg = (int)msg.message;
327                                         m.HWnd = msg.hwnd;
328                                         m.LParam = msg.lParam;
329                                         m.WParam = msg.wParam;
330                                         for (int i = 0; i < message_filters.Count; i++) {
331                                                 if (((IMessageFilter)message_filters[i]).PreFilterMessage(ref m)) {
332                                                         // we're dropping the message
333                                                         drop = true;
334                                                         break;
335                                                 }
336                                         }
337                                         if (drop) {
338                                                 continue;
339                                         }
340                                 }
341
342                                 XplatUI.TranslateMessage(ref msg);
343                                 XplatUI.DispatchMessage(ref msg);
344
345                                 // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
346                                 if ((form != null) && form.closing) {
347                                         exiting = true;
348                                 }
349                         }
350
351                         messageloop_started = false;
352
353                         if (form != null) {
354                                 form.context = null;
355                         }
356
357                         if (ThreadExit != null) {
358                                 ThreadExit(null, EventArgs.Empty);
359                         }
360
361                         if (ApplicationExit != null) {
362                                 ApplicationExit(null, EventArgs.Empty);
363                         }
364
365                         if (app_context != null) {
366                                 app_context.ExitThread();
367                         }
368                 }
369
370                 public static void Run(Form mainForm) {
371                         mainForm.CreateControl();
372                         Run(new ApplicationContext(mainForm));
373                 }
374
375                 public static void Run(ApplicationContext context) {
376                         app_context=context;
377                         if (app_context.MainForm!=null) {
378                                 app_context.MainForm.Show();
379                                 app_context.MainForm.PerformLayout();
380                                 app_context.ThreadExit += new EventHandler(InternalExit);
381                         }
382                         Run();
383                 }
384                 #endregion      // Public Static Methods
385
386                 #region Events
387                 public static event EventHandler        ApplicationExit;
388
389                 public static event EventHandler        Idle {
390                         add {
391                                 XplatUI.Idle += value;
392                         }
393                         remove {
394                                 XplatUI.Idle -= value;
395                         }
396                 }
397
398                 public static event EventHandler        ThreadExit;
399                 public static event ThreadExceptionEventHandler ThreadException;
400                 #endregion      // Events
401         }
402 }