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:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
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.
20 // Copyright (c) 2004 Novell, Inc.
23 // Peter Bartok pbartok@novell.com
28 // $Log: Application.cs,v $
29 // Revision 1.8 2004/10/20 03:33:33 pbartok
30 // - Fixed to deal with new Form subclasses for menus
32 // Revision 1.7 2004/10/18 04:14:14 pbartok
33 // - Added code to simulate modal dialogs on Win32
35 // Revision 1.6 2004/09/22 20:05:41 pbartok
36 // - Added message loop for modal dialogs
38 // Revision 1.5 2004/09/21 00:54:15 jackson
39 // New message loop that uses poll so we don't get a busy loop
41 // Revision 1.4 2004/08/23 22:45:19 pbartok
42 // - Removed debug output
45 // Revision 1.3 2004/08/23 22:09:29 pbartok
46 // - Added handling of Idle event
47 // - Added handling of form closing
48 // - Fixed reporting of MessageLoop property
49 // - Removed some unneeded code, should provide a bit of a speedup
51 // Revision 1.2 2004/08/11 22:16:50 pbartok
53 // - Added .Net 1.1 method
55 // Revision 1.1 2004/07/09 05:21:25 pbartok
62 using Microsoft.Win32;
65 using System.ComponentModel;
66 using System.Collections;
67 using System.Diagnostics;
68 using System.Globalization;
70 using System.Reflection;
71 using System.Runtime.InteropServices;
72 using System.Threading;
74 namespace System.Windows.Forms {
75 public sealed class Application {
76 private static bool browser_embedded;
77 private static bool exiting;
78 private static InputLanguage input_language;
79 private static bool messageloop_started;
80 private static string safe_caption_format;
81 private static ArrayList message_filters;
82 private static ApplicationContext app_context;
83 private static Form main_form;
85 private Application () {
86 input_language = InputLanguage.CurrentInputLanguage;
87 message_filters = new ArrayList();
89 browser_embedded= false;
91 messageloop_started = false;
92 safe_caption_format = "{1} - {0} - {2}";
95 #region Private and Internal Methods
96 internal static void ModalRun(Form form) {
98 Queue toplevels = new Queue();
99 IEnumerator control = Control.controls.GetEnumerator();
105 while (control.MoveNext()) {
106 if ((((Control)control.Current).parent == null) && (((Control)control.Current).is_visible) && (((Control)control.Current).is_enabled)) {
107 if ((control.Current is Form.FormParentWindow) && (((Form.FormParentWindow)control.Current)!=form.form_parent_window)) {
108 XplatUI.EnableWindow(((Control)control.Current).window.Handle, false);
109 toplevels.Enqueue((Control)control.Current);
114 while (!exiting && !form.end_modal && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
115 XplatUI.TranslateMessage(ref msg);
116 XplatUI.DispatchMessage(ref msg);
118 // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
120 form.end_modal = true;
124 while (toplevels.Count>0) {
125 XplatUI.EnableWindow(((Control)toplevels.Dequeue()).window.Handle, true);
128 #endregion // Private and Internal Methods
130 #region Public Static Properties
131 public static bool AllowQuit {
133 return browser_embedded;
137 public static string CommonAppDataPath {
139 return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
143 public static RegistryKey CommonAppDataRegistry {
147 key = Registry.LocalMachine.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
153 public static string CompanyName {
157 if (Environment.OSVersion.Platform != (PlatformID)128) {
161 key=Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion", false);
162 ret=(String)key.GetValue("RegisteredOrganization");
169 return st.GetFrame(st.FrameCount-1).GetMethod().DeclaringType.Namespace;
173 public static CultureInfo CurrentCulture {
175 return Thread.CurrentThread.CurrentUICulture;
180 Thread.CurrentThread.CurrentUICulture=value;
184 public static InputLanguage CurrentInputLanguage {
186 return input_language;
190 input_language=value;
194 public static string ExecutablePath {
196 return Assembly.GetEntryAssembly().Location;
200 public static string LocalUserAppDataPath {
202 return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
206 public static bool MessageLoop {
208 return messageloop_started;
212 public static string ProductName {
214 AssemblyProductAttribute[] attrs = (AssemblyProductAttribute[]) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true);
216 if ((attrs != null) && attrs.Length>0) {
217 return attrs[0].Product;
220 return Assembly.GetEntryAssembly().GetName().Name;
224 public static string ProductVersion {
228 version = Assembly.GetEntryAssembly().GetName().Version.ToString();
230 if (version.StartsWith("0.")) {
231 version="1." + version.Substring(2);
237 public static string SafeTopLevelCaptionFormat {
239 return safe_caption_format;
243 safe_caption_format=value;
247 public static string StartupPath {
249 return Path.GetDirectoryName(Application.ExecutablePath);
253 public static string UserAppDataPath {
255 return Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
259 public static RegistryKey UserAppDataRegistry {
263 key = Registry.CurrentUser.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
270 #region Public Static Methods
271 public static void AddMessageFilter(IMessageFilter value) {
272 message_filters.Add(value);
275 public static void DoEvents() {
279 public static void EnableVisualStyles() {
280 XplatUI.EnableThemes();
283 public static void Exit() {
287 public static void ExitThread() {
291 private static void InternalExit(object sender, EventArgs e) {
295 public static ApartmentState OleRequired() {
296 //throw new NotImplementedException("OLE Not supported by this System.Windows.Forms implementation");
297 return ApartmentState.Unknown;
300 public static void OnThreadException(Exception t) {
301 if (Application.ThreadException != null) {
302 Application.ThreadException(null, new ThreadExceptionEventArgs(t));
307 XplatUI.HandleException(t);
310 // TODO: Missing implementation
311 //if (SystemInformation.UserInteractive)
313 Form form = new ThreadExceptionDialog (t);
317 Console.WriteLine (t.ToString ());
321 public static void RemoveMessageFilter(IMessageFilter filter) {
322 message_filters.Remove(filter);
325 public static void Run() {
329 if (app_context != null) {
330 form = app_context.MainForm;
333 messageloop_started = true;
335 while (!exiting && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
336 XplatUI.TranslateMessage(ref msg);
337 XplatUI.DispatchMessage(ref msg);
339 // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
340 if ((form != null) && form.closing) {
345 messageloop_started = false;
347 if (ApplicationExit != null) {
348 ApplicationExit(null, EventArgs.Empty);
352 public static void Run(Form mainForm) {
353 mainForm.CreateControl();
354 Run(new ApplicationContext(mainForm));
357 public static void Run(ApplicationContext context) {
359 if (app_context.MainForm!=null) {
360 app_context.MainForm.Show();
361 app_context.ThreadExit += new EventHandler(InternalExit);
365 #endregion // Public Static Methods
368 public static event EventHandler ApplicationExit;
370 public static event EventHandler Idle {
372 XplatUI.Idle += value;
375 XplatUI.Idle -= value;
379 public static event EventHandler ThreadExit;
380 public static event ThreadExceptionEventHandler ThreadException;