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;
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;
51 private Application () {
52 input_language = InputLanguage.CurrentInputLanguage;
53 message_filters = new ArrayList();
55 browser_embedded= false;
57 messageloop_started = false;
58 safe_caption_format = "{1} - {0} - {2}";
61 #region Private and Internal Methods
62 internal static void ModalRun(Form form) {
64 Queue toplevels = new Queue();
65 IEnumerator control = Control.controls.GetEnumerator();
71 // Both calls are needed, one is for the WM, the other for our focus logic
72 XplatUI.Activate(form.window.Handle);
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);
86 while (!exiting && !form.end_modal && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
87 if ((message_filters != null) && (message_filters.Count > 0)) {
93 m.Msg = (int)msg.message;
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
109 XplatUI.TranslateMessage(ref msg);
110 XplatUI.DispatchMessage(ref msg);
112 // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
114 form.end_modal = true;
118 while (toplevels.Count>0) {
119 XplatUI.EnableWindow(((Control)toplevels.Dequeue()).window.Handle, true);
122 #endregion // Private and Internal Methods
124 #region Public Static Properties
125 public static bool AllowQuit {
127 return browser_embedded;
131 public static string CommonAppDataPath {
133 return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
137 public static RegistryKey CommonAppDataRegistry {
141 key = Registry.LocalMachine.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
147 public static string CompanyName {
151 if (Environment.OSVersion.Platform != (PlatformID)128) {
155 key=Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion", false);
156 ret=(String)key.GetValue("RegisteredOrganization");
163 return st.GetFrame(st.FrameCount-1).GetMethod().DeclaringType.Namespace;
167 public static CultureInfo CurrentCulture {
169 return Thread.CurrentThread.CurrentUICulture;
174 Thread.CurrentThread.CurrentUICulture=value;
178 public static InputLanguage CurrentInputLanguage {
180 return input_language;
184 input_language=value;
188 public static string ExecutablePath {
190 return Assembly.GetEntryAssembly().Location;
194 public static string LocalUserAppDataPath {
196 return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
200 public static bool MessageLoop {
202 return messageloop_started;
206 public static string ProductName {
208 AssemblyProductAttribute[] attrs = (AssemblyProductAttribute[]) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true);
210 if ((attrs != null) && attrs.Length>0) {
211 return attrs[0].Product;
214 return Assembly.GetEntryAssembly().GetName().Name;
218 public static string ProductVersion {
222 version = Assembly.GetEntryAssembly().GetName().Version.ToString();
224 if (version.StartsWith("0.")) {
225 version="1." + version.Substring(2);
231 public static string SafeTopLevelCaptionFormat {
233 return safe_caption_format;
237 safe_caption_format=value;
241 public static string StartupPath {
243 return Path.GetDirectoryName(Application.ExecutablePath);
247 public static string UserAppDataPath {
249 return Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
253 public static RegistryKey UserAppDataRegistry {
257 key = Registry.CurrentUser.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
264 #region Public Static Methods
265 public static void AddMessageFilter(IMessageFilter value) {
266 message_filters.Add(value);
269 public static void DoEvents() {
273 public static void EnableVisualStyles() {
274 XplatUI.EnableThemes();
277 public static void Exit() {
281 public static void ExitThread() {
285 private static void InternalExit(object sender, EventArgs e) {
289 public static ApartmentState OleRequired() {
290 //throw new NotImplementedException("OLE Not supported by this System.Windows.Forms implementation");
291 return ApartmentState.Unknown;
294 public static void OnThreadException(Exception t) {
295 if (Application.ThreadException != null) {
296 Application.ThreadException(null, new ThreadExceptionEventArgs(t));
301 XplatUI.HandleException(t);
304 // TODO: Missing implementation
305 //if (SystemInformation.UserInteractive)
307 Form form = new ThreadExceptionDialog (t);
311 Console.WriteLine (t.ToString ());
315 public static void RemoveMessageFilter(IMessageFilter filter) {
316 message_filters.Remove(filter);
319 public static void Run() {
323 if (app_context != null) {
324 form = app_context.MainForm;
328 // Both calls are needed, one is for the WM, the other for our focus logic
329 XplatUI.Activate(form.window.Handle);
333 messageloop_started = true;
335 while (!exiting && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
336 if ((message_filters != null) && (message_filters.Count > 0)) {
342 m.Msg = (int)msg.message;
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
358 XplatUI.TranslateMessage(ref msg);
359 XplatUI.DispatchMessage(ref msg);
361 // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
362 if ((form != null) && form.closing) {
367 messageloop_started = false;
369 if (ThreadExit != null) {
370 ThreadExit(null, EventArgs.Empty);
373 if (ApplicationExit != null) {
374 ApplicationExit(null, EventArgs.Empty);
378 public static void Run(Form mainForm) {
379 mainForm.CreateControl();
380 Run(new ApplicationContext(mainForm));
383 public static void Run(ApplicationContext context) {
385 if (app_context.MainForm!=null) {
386 app_context.MainForm.Show();
387 app_context.MainForm.PerformLayout();
388 app_context.ThreadExit += new EventHandler(InternalExit);
392 #endregion // Public Static Methods
395 public static event EventHandler ApplicationExit;
397 public static event EventHandler Idle {
399 XplatUI.Idle += value;
402 XplatUI.Idle -= value;
406 public static event EventHandler ThreadExit;
407 public static event ThreadExceptionEventHandler ThreadException;