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
29 using Microsoft.Win32;
32 using System.ComponentModel;
33 using System.Collections;
34 using System.Diagnostics;
35 using System.Globalization;
37 using System.Reflection;
38 using System.Runtime.InteropServices;
39 using System.Threading;
41 namespace System.Windows.Forms {
42 public sealed class Application {
43 private static bool browser_embedded = false;
44 private static bool exiting = false;
45 private static InputLanguage input_language = InputLanguage.CurrentInputLanguage;
46 private static bool messageloop_started = false;
47 private static string safe_caption_format = "{1} - {0} - {2}";
48 private static ArrayList message_filters = new ArrayList();
49 private static ApplicationContext app_context = null;
51 private Application () {
54 #region Private and Internal Methods
55 internal static void ModalRun(Form form) {
57 Queue toplevels = new Queue();
58 IEnumerator control = Control.controls.GetEnumerator();
64 // Both calls are needed, one is for the WM, the other for our focus logic
65 XplatUI.Activate(form.window.Handle);
68 while (control.MoveNext()) {
69 if ((((Control)control.Current).parent == null) && (((Control)control.Current).is_visible) && (((Control)control.Current).is_enabled)) {
70 if ((control.Current is Form) && (((Form)control.Current)!=form)) {
71 XplatUI.EnableWindow(((Control)control.Current).window.Handle, false);
72 toplevels.Enqueue((Control)control.Current);
79 while (!exiting && !form.end_modal && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
80 if ((message_filters != null) && (message_filters.Count > 0)) {
86 m.Msg = (int)msg.message;
88 m.LParam = msg.lParam;
89 m.WParam = msg.wParam;
90 for (int i = 0; i < message_filters.Count; i++) {
91 if (((IMessageFilter)message_filters[i]).PreFilterMessage(ref m)) {
92 // we're dropping the message
102 XplatUI.TranslateMessage(ref msg);
103 XplatUI.DispatchMessage(ref msg);
105 // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
107 form.end_modal = true;
111 while (toplevels.Count>0) {
112 XplatUI.EnableWindow(((Control)toplevels.Dequeue()).window.Handle, true);
115 #endregion // Private and Internal Methods
117 #region Public Static Properties
118 public static bool AllowQuit {
120 return browser_embedded;
124 public static string CommonAppDataPath {
126 return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
130 public static RegistryKey CommonAppDataRegistry {
134 key = Registry.LocalMachine.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
140 public static string CompanyName {
142 AssemblyCompanyAttribute[] attrs = (AssemblyCompanyAttribute[]) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), true);
144 if ((attrs != null) && attrs.Length>0) {
145 return attrs[0].Company;
148 return Assembly.GetEntryAssembly().GetName().Name;
152 public static CultureInfo CurrentCulture {
154 return Thread.CurrentThread.CurrentUICulture;
159 Thread.CurrentThread.CurrentUICulture=value;
163 public static InputLanguage CurrentInputLanguage {
165 return input_language;
169 input_language=value;
173 public static string ExecutablePath {
175 return Assembly.GetEntryAssembly().Location;
179 public static string LocalUserAppDataPath {
181 return Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), CompanyName), ProductName), ProductVersion);
185 public static bool MessageLoop {
187 return messageloop_started;
191 public static string ProductName {
193 AssemblyProductAttribute[] attrs = (AssemblyProductAttribute[]) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true);
195 if ((attrs != null) && attrs.Length>0) {
196 return attrs[0].Product;
199 return Assembly.GetEntryAssembly().GetName().Name;
203 public static string ProductVersion {
207 version = Assembly.GetEntryAssembly().GetName().Version.ToString();
209 if (version.StartsWith("0.")) {
210 version="1." + version.Substring(2);
216 public static string SafeTopLevelCaptionFormat {
218 return safe_caption_format;
222 safe_caption_format=value;
226 public static string StartupPath {
228 return Path.GetDirectoryName(Application.ExecutablePath);
232 public static string UserAppDataPath {
234 return Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), CompanyName), ProductName), ProductVersion);
238 public static RegistryKey UserAppDataRegistry {
242 key = Registry.CurrentUser.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
249 #region Public Static Methods
250 public static void AddMessageFilter(IMessageFilter value) {
251 message_filters.Add(value);
254 public static void DoEvents() {
258 public static void EnableVisualStyles() {
259 XplatUI.EnableThemes();
263 public static void EnableRTLMirroring ()
268 public static void Exit() {
272 public static void ExitThread() {
276 private static void InternalExit(object sender, EventArgs e) {
280 public static ApartmentState OleRequired() {
281 //throw new NotImplementedException("OLE Not supported by this System.Windows.Forms implementation");
282 return ApartmentState.Unknown;
285 public static void OnThreadException(Exception t) {
286 if (Application.ThreadException != null) {
287 Application.ThreadException(null, new ThreadExceptionEventArgs(t));
292 XplatUI.HandleException(t);
295 // TODO: Missing implementation
296 //if (SystemInformation.UserInteractive)
298 Form form = new ThreadExceptionDialog (t);
302 Console.WriteLine (t.ToString ());
306 public static void RemoveMessageFilter(IMessageFilter filter) {
307 message_filters.Remove(filter);
310 public static void Run() {
314 if (app_context != null) {
315 form = app_context.MainForm;
319 // Both calls are needed, one is for the WM, the other for our focus logic
320 XplatUI.Activate(form.window.Handle);
324 messageloop_started = true;
326 while (!exiting && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
327 if ((message_filters != null) && (message_filters.Count > 0)) {
333 m.Msg = (int)msg.message;
335 m.LParam = msg.lParam;
336 m.WParam = msg.wParam;
337 for (int i = 0; i < message_filters.Count; i++) {
338 if (((IMessageFilter)message_filters[i]).PreFilterMessage(ref m)) {
339 // we're dropping the message
349 XplatUI.TranslateMessage(ref msg);
350 XplatUI.DispatchMessage(ref msg);
352 // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
353 if ((form != null) && form.closing) {
358 messageloop_started = false;
360 if (ThreadExit != null) {
361 ThreadExit(null, EventArgs.Empty);
364 if (ApplicationExit != null) {
365 ApplicationExit(null, EventArgs.Empty);
369 public static void Run(Form mainForm) {
370 mainForm.CreateControl();
371 Run(new ApplicationContext(mainForm));
374 public static void Run(ApplicationContext context) {
376 if (app_context.MainForm!=null) {
377 app_context.MainForm.Show();
378 app_context.MainForm.PerformLayout();
379 app_context.ThreadExit += new EventHandler(InternalExit);
383 #endregion // Public Static Methods
386 public static event EventHandler ApplicationExit;
388 public static event EventHandler Idle {
390 XplatUI.Idle += value;
393 XplatUI.Idle -= value;
397 public static event EventHandler ThreadExit;
398 public static event ThreadExceptionEventHandler ThreadException;