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