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 - 2005 Novell, Inc.
23 // Peter Bartok pbartok@novell.com
28 using Microsoft.Win32;
31 using System.ComponentModel;
32 using System.Collections;
33 using System.Diagnostics;
34 using System.Globalization;
36 using System.Reflection;
37 using System.Runtime.InteropServices;
38 using System.Threading;
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;
50 private Application () {
53 #region Private and Internal Methods
54 internal static void ModalRun(Form form) {
56 Queue toplevels = new Queue();
57 IEnumerator control = Control.controls.GetEnumerator();
63 // Both calls are needed, one is for the WM, the other for our focus logic
64 XplatUI.Activate(form.window.Handle);
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);
78 while (!exiting && !form.end_modal && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
79 if ((message_filters != null) && (message_filters.Count > 0)) {
85 m.Msg = (int)msg.message;
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
101 XplatUI.TranslateMessage(ref msg);
102 XplatUI.DispatchMessage(ref msg);
104 // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
106 form.end_modal = true;
110 while (toplevels.Count>0) {
111 XplatUI.EnableWindow(((Control)toplevels.Dequeue()).window.Handle, true);
114 #endregion // Private and Internal Methods
116 #region Public Static Properties
117 public static bool AllowQuit {
119 return browser_embedded;
123 public static string CommonAppDataPath {
125 return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
129 public static RegistryKey CommonAppDataRegistry {
133 key = Registry.LocalMachine.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
139 public static string CompanyName {
141 AssemblyCompanyAttribute[] attrs = (AssemblyCompanyAttribute[]) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), true);
143 if ((attrs != null) && attrs.Length>0) {
144 return attrs[0].Company;
147 return Assembly.GetEntryAssembly().GetName().Name;
151 public static CultureInfo CurrentCulture {
153 return Thread.CurrentThread.CurrentUICulture;
158 Thread.CurrentThread.CurrentUICulture=value;
162 public static InputLanguage CurrentInputLanguage {
164 return input_language;
168 input_language=value;
172 public static string ExecutablePath {
174 return Assembly.GetEntryAssembly().Location;
178 public static string LocalUserAppDataPath {
180 return Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), CompanyName), ProductName), ProductVersion);
184 public static bool MessageLoop {
186 return messageloop_started;
190 public static string ProductName {
192 AssemblyProductAttribute[] attrs = (AssemblyProductAttribute[]) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true);
194 if ((attrs != null) && attrs.Length>0) {
195 return attrs[0].Product;
198 return Assembly.GetEntryAssembly().GetName().Name;
202 public static string ProductVersion {
206 version = Assembly.GetEntryAssembly().GetName().Version.ToString();
208 if (version.StartsWith("0.")) {
209 version="1." + version.Substring(2);
215 public static string SafeTopLevelCaptionFormat {
217 return safe_caption_format;
221 safe_caption_format=value;
225 public static string StartupPath {
227 return Path.GetDirectoryName(Application.ExecutablePath);
231 public static string UserAppDataPath {
233 return Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), CompanyName), ProductName), ProductVersion);
237 public static RegistryKey UserAppDataRegistry {
241 key = Registry.CurrentUser.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
248 #region Public Static Methods
249 public static void AddMessageFilter(IMessageFilter value) {
250 message_filters.Add(value);
253 public static void DoEvents() {
257 public static void EnableVisualStyles() {
258 XplatUI.EnableThemes();
262 public static void EnableRTLMirroring ()
267 public static void Exit() {
268 XplatUI.PostQuitMessage(0);
271 public static void ExitThread() {
275 private static void InternalExit(object sender, EventArgs e) {
279 public static ApartmentState OleRequired() {
280 //throw new NotImplementedException("OLE Not supported by this System.Windows.Forms implementation");
281 return ApartmentState.Unknown;
284 public static void OnThreadException(Exception t) {
285 if (Application.ThreadException != null) {
286 Application.ThreadException(null, new ThreadExceptionEventArgs(t));
290 if (SystemInformation.UserInteractive) {
291 Form form = new ThreadExceptionDialog (t);
294 Console.WriteLine (t.ToString ());
298 public static void RemoveMessageFilter(IMessageFilter filter) {
299 message_filters.Remove(filter);
302 public static void Run() {
306 if (app_context != null) {
307 form = app_context.MainForm;
308 form.context = app_context;
312 // Both calls are needed, one is for the WM, the other for our focus logic
313 XplatUI.Activate(form.window.Handle);
317 messageloop_started = true;
319 while (!exiting && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
320 if ((message_filters != null) && (message_filters.Count > 0)) {
326 m.Msg = (int)msg.message;
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
342 XplatUI.TranslateMessage(ref msg);
343 XplatUI.DispatchMessage(ref msg);
345 // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
346 if ((form != null) && form.closing) {
351 messageloop_started = false;
357 if (ThreadExit != null) {
358 ThreadExit(null, EventArgs.Empty);
361 if (ApplicationExit != null) {
362 ApplicationExit(null, EventArgs.Empty);
365 if (app_context != null) {
366 app_context.ExitThread();
370 public static void Run(Form mainForm) {
371 mainForm.CreateControl();
372 Run(new ApplicationContext(mainForm));
375 public static void Run(ApplicationContext context) {
377 if (app_context.MainForm!=null) {
378 app_context.MainForm.Show();
379 app_context.MainForm.PerformLayout();
380 app_context.ThreadExit += new EventHandler(InternalExit);
384 #endregion // Public Static Methods
387 public static event EventHandler ApplicationExit;
389 public static event EventHandler Idle {
391 XplatUI.Idle += value;
394 XplatUI.Idle -= value;
398 public static event EventHandler ThreadExit;
399 public static event ThreadExceptionEventHandler ThreadException;