X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FManaged.Windows.Forms%2FSystem.Windows.Forms%2FApplication.cs;h=2c2d5bf931d3f08343f4a39947239bc0adacce93;hb=2f9c820c7ee1063d9fabcb2410b57843c17cb926;hp=301bab4c61b0bbd614f808cb0be2420e27cd6c78;hpb=fd7e719ede262cce5bae53252ed8eafc70f908d3;p=mono.git diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Application.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Application.cs index 301bab4c61b..2c2d5bf931d 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Application.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Application.cs @@ -39,29 +39,36 @@ using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; -#if NET_2_0 using System.Text; using System.Windows.Forms.VisualStyles; -#endif -namespace System.Windows.Forms { - public sealed class Application { - internal class MWFThread { +namespace System.Windows.Forms +{ + public sealed class Application + { + internal class MWFThread + { #region Fields - private ApplicationContext context; - private bool messageloop_started; - private bool handling_exception; - private int thread_id; - private static Hashtable threads = new Hashtable(); + private ApplicationContext context; + private bool messageloop_started; + private bool handling_exception; + private int thread_id; + + private static readonly Hashtable threads = new Hashtable(); + #endregion // Fields #region Constructors - private MWFThread() { + + private MWFThread() + { } + #endregion // Constructors #region Properties + public ApplicationContext Context { get { return context; } set { context = value; } @@ -75,7 +82,6 @@ namespace System.Windows.Forms { public bool HandlingException { get { return handling_exception; } set { handling_exception = value; } - } public static int LoopCount { @@ -95,62 +101,110 @@ namespace System.Windows.Forms { public static MWFThread Current { get { - MWFThread thread; + MWFThread thread = null; - thread = null; lock (threads) { - thread = (MWFThread)threads[Thread.CurrentThread.GetHashCode()]; + thread = (MWFThread) threads [Thread.CurrentThread.GetHashCode ()]; if (thread == null) { thread = new MWFThread(); - thread.thread_id = Thread.CurrentThread.GetHashCode(); - threads[thread.thread_id] = thread; + thread.thread_id = Thread.CurrentThread.GetHashCode (); + threads [thread.thread_id] = thread; } } return thread; } } + #endregion // Properties #region Methods - public void Exit() { - if (context != null) { + + public void Exit () + { + if (context != null) context.ExitThread(); - } context = null; - if (Application.ThreadExit != null) { + if (Application.ThreadExit != null) Application.ThreadExit(null, EventArgs.Empty); - } if (LoopCount == 0) { - if (Application.ApplicationExit != null) { - Application.ApplicationExit(null, EventArgs.Empty); - } + if (Application.ApplicationExit != null) + Application.ApplicationExit (null, EventArgs.Empty); } - ((MWFThread)threads[thread_id]).MessageLoop = false; + ((MWFThread) threads [thread_id]).MessageLoop = false; } + #endregion // Methods } - private static bool browser_embedded = false; - private static InputLanguage input_language = InputLanguage.CurrentInputLanguage; - private static string safe_caption_format = "{1} - {0} - {2}"; - private static ArrayList message_filters = new ArrayList(); - private static FormCollection forms = new FormCollection (); + private static bool browser_embedded; + private static InputLanguage input_language = InputLanguage.CurrentInputLanguage; + private static string safe_caption_format = "{1} - {0} - {2}"; + private static readonly ArrayList message_filters = new ArrayList(); + private static readonly FormCollection forms = new FormCollection (); -#if NET_2_0 - private static bool use_wait_cursor = false; + private static bool use_wait_cursor; private static ToolStrip keyboard_capture; private static VisualStyleState visual_style_state = VisualStyleState.ClientAndNonClientAreasEnabled; -#endif + static bool visual_styles_enabled; + + private Application () + { + browser_embedded = false; + } - private Application () { + static Application () + { + // Attempt to load UIA support for winforms + // UIA support requires .NET 2.0 + InitializeUIAutomation (); } #region Private Methods - internal static void CloseForms(Thread thread) { + + private static void InitializeUIAutomation () + { + // Initialize the UIAutomationWinforms Global class, + // which create some listeners which subscribe to internal + // MWF events so that it can provide a11y support for MWF + const string UIA_WINFORMS_ASSEMBLY = + "UIAutomationWinforms, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f4ceacb585d99812"; + MethodInfo init_method; + Assembly mwf_providers = null; + try { + mwf_providers = Assembly.Load (UIA_WINFORMS_ASSEMBLY); + } catch { } + + if (mwf_providers == null) + return; + + const string UIA_WINFORMS_TYPE = "Mono.UIAutomation.Winforms.Global"; + const string UIA_WINFORMS_METHOD = "Initialize"; + try { + Type global_type = mwf_providers.GetType (UIA_WINFORMS_TYPE, false); + if (global_type != null) { + init_method = global_type.GetMethod (UIA_WINFORMS_METHOD, + BindingFlags.Static | + BindingFlags.Public); + if (init_method != null) + init_method.Invoke (null, new object [] {}); + else + throw new Exception (String.Format ("Method {0} not found in type {1}.", + UIA_WINFORMS_METHOD, UIA_WINFORMS_TYPE)); + } + else + throw new Exception (String.Format ("Type {0} not found in assembly {1}.", + UIA_WINFORMS_TYPE, UIA_WINFORMS_ASSEMBLY)); + } catch (Exception ex) { + Console.Error.WriteLine ("Error setting up UIA: " + ex); + } + } + + internal static void CloseForms (Thread thread) + { #if DebugRunLoop Console.WriteLine(" CloseForms({0}) called", thread); #endif @@ -171,9 +225,11 @@ namespace System.Windows.Forms { } } } + #endregion // Private methods #region Public Static Properties + public static bool AllowQuit { get { return !browser_embedded; @@ -182,35 +238,51 @@ namespace System.Windows.Forms { public static string CommonAppDataPath { get { - return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); + return CreateDataPath (Environment.GetFolderPath (Environment.SpecialFolder.CommonApplicationData)); } } public static RegistryKey CommonAppDataRegistry { get { - RegistryKey key; + string key = string.Format ("Software\\{0}\\{1}\\{2}", CompanyName, ProductName, ProductVersion); - key = Registry.LocalMachine.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true); - - return key; + return Registry.LocalMachine.CreateSubKey (key); } } public static string CompanyName { get { + string company = string.Empty; + Assembly assembly = Assembly.GetEntryAssembly (); + if (assembly == null) assembly = Assembly.GetCallingAssembly (); - if (assembly == null) - return string.Empty; - - AssemblyCompanyAttribute[] attrs = (AssemblyCompanyAttribute[]) assembly.GetCustomAttributes(typeof(AssemblyCompanyAttribute), true); - - if ((attrs != null) && attrs.Length>0) { - return attrs[0].Company; - } - return assembly.GetName().Name; + AssemblyCompanyAttribute[] attrs = (AssemblyCompanyAttribute[]) + assembly.GetCustomAttributes (typeof(AssemblyCompanyAttribute), true); + if (attrs != null && attrs.Length > 0) + company = attrs [0].Company; + + // If there is no [AssemblyCompany], return the outermost namespace + // on Main () + if (company == null || company.Length == 0) + if (assembly.EntryPoint != null) { + company = assembly.EntryPoint.DeclaringType.Namespace; + + if (company != null) { + int firstDot = company.IndexOf ('.'); + if (firstDot >= 0) + company = company.Substring (0, firstDot); + } + } + + // If that doesn't work, return the name of class containing Main () + if (company == null || company.Length == 0) + if (assembly.EntryPoint != null) + company = assembly.EntryPoint.DeclaringType.FullName; + + return company; } } @@ -218,10 +290,8 @@ namespace System.Windows.Forms { get { return Thread.CurrentThread.CurrentUICulture; } - set { - - Thread.CurrentThread.CurrentUICulture=value; + Thread.CurrentThread.CurrentUICulture = value; } } @@ -229,7 +299,6 @@ namespace System.Windows.Forms { get { return input_language; } - set { input_language=value; } @@ -237,13 +306,13 @@ namespace System.Windows.Forms { public static string ExecutablePath { get { - return Assembly.GetEntryAssembly().Location; + return Path.GetFullPath (Environment.GetCommandLineArgs ()[0]); } } public static string LocalUserAppDataPath { get { - return Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), CompanyName), ProductName), ProductVersion); + return CreateDataPath (Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData)); } } @@ -255,33 +324,73 @@ namespace System.Windows.Forms { public static string ProductName { get { + string name = string.Empty; + Assembly assembly = Assembly.GetEntryAssembly (); + if (assembly == null) assembly = Assembly.GetCallingAssembly (); - if (assembly == null) - return string.Empty; - - AssemblyProductAttribute[] attrs = (AssemblyProductAttribute[]) assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), true); - - if ((attrs != null) && attrs.Length>0) { - return attrs[0].Product; - } - return assembly.GetName ().Name; + AssemblyProductAttribute[] attrs = (AssemblyProductAttribute[]) + assembly.GetCustomAttributes (typeof(AssemblyProductAttribute), true); + + if (attrs != null && attrs.Length > 0) + name = attrs [0].Product; + + // If there is no [AssemblyProduct], .NET returns the name of + // the innermost namespace and if that fails, resorts to the + // name of the class containing Main () + if (name == null || name.Length == 0) + if (assembly.EntryPoint != null) { + name = assembly.EntryPoint.DeclaringType.Namespace; + + if (name != null) { + int lastDot = name.LastIndexOf ('.'); + if (lastDot >= 0 && lastDot < name.Length - 1) + name = name.Substring (lastDot + 1); + } + + if (name == null || name.Length == 0) + name = assembly.EntryPoint.DeclaringType.FullName; + } + + return name; } } public static string ProductVersion { get { - String version; + String version = string.Empty; Assembly assembly = Assembly.GetEntryAssembly (); + if (assembly == null) assembly = Assembly.GetCallingAssembly (); - if (assembly == null) - return string.Empty; - version = assembly.GetName ().Version.ToString (); + AssemblyInformationalVersionAttribute infoVersion = + Attribute.GetCustomAttribute (assembly, + typeof (AssemblyInformationalVersionAttribute)) + as AssemblyInformationalVersionAttribute; + + if (infoVersion != null) + version = infoVersion.InformationalVersion; + + // If [AssemblyFileVersion] is present it is used + // before resorting to assembly version + if (version == null || version.Length == 0) { + AssemblyFileVersionAttribute fileVersion = + Attribute.GetCustomAttribute (assembly, + typeof (AssemblyFileVersionAttribute)) + as AssemblyFileVersionAttribute; + if (fileVersion != null) + version = fileVersion.Version; + } + + // If neither [AssemblyInformationalVersionAttribute] + // nor [AssemblyFileVersion] are present, then use + // the assembly version + if (version == null || version.Length == 0) + version = assembly.GetName ().Version.ToString (); return version; } @@ -291,36 +400,31 @@ namespace System.Windows.Forms { get { return safe_caption_format; } - set { - safe_caption_format=value; + safe_caption_format = value; } } public static string StartupPath { get { - return Path.GetDirectoryName(Application.ExecutablePath); + return Path.GetDirectoryName (Application.ExecutablePath); } } public static string UserAppDataPath { get { - return Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), CompanyName), ProductName), ProductVersion); + return CreateDataPath (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData)); } } public static RegistryKey UserAppDataRegistry { get { - RegistryKey key; - - key = Registry.CurrentUser.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true); - - return key; + string key = string.Format ("Software\\{0}\\{1}\\{2}", CompanyName, ProductName, ProductVersion); + + return Registry.CurrentUser.CreateSubKey (key); } } -#if NET_2_0 - public static bool UseWaitCursor { get { return use_wait_cursor; @@ -334,66 +438,68 @@ namespace System.Windows.Forms { } } } - + public static bool RenderWithVisualStyles { - get { - if (VisualStyleInformation.IsSupportedByOS) - { + get { + if (VisualStyleInformation.IsSupportedByOS) { if (!VisualStyleInformation.IsEnabledByUser) return false; - if (!XplatUI.ThemesEnabled) return false; - if (Application.VisualStyleState == VisualStyleState.ClientAndNonClientAreasEnabled) return true; - if (Application.VisualStyleState == VisualStyleState.ClientAreaEnabled) - return true; + return true; } - return false; - } + } } public static VisualStyleState VisualStyleState { get { return Application.visual_style_state; } set { Application.visual_style_state = value; } } -#endif #endregion #region Public Static Methods - public static void AddMessageFilter(IMessageFilter value) { + + public static void AddMessageFilter (IMessageFilter value) + { lock (message_filters) { - message_filters.Add(value); + message_filters.Add (value); } } - public static void DoEvents() { - XplatUI.DoEvents(); + internal static void AddKeyFilter (IKeyFilter value) + { + XplatUI.AddKeyFilter (value); } - public static void EnableVisualStyles() { - XplatUI.EnableThemes(); + public static void DoEvents () + { + XplatUI.DoEvents (); + } + + public static void EnableVisualStyles () + { + visual_styles_enabled = true; + XplatUI.EnableThemes (); } -#if NET_2_0 [EditorBrowsable (EditorBrowsableState.Advanced)] - public -#endif - static bool FilterMessage (ref Message message) + public static bool FilterMessage (ref Message message) { - lock (message_filters) - foreach (IMessageFilter filter in message_filters) + lock (message_filters) { + for (int i = 0; i < message_filters.Count; i++) { + IMessageFilter filter = (IMessageFilter) message_filters[i]; if (filter.PreFilterMessage (ref message)) return true; - + } + } return false; } -#if NET_2_0 // // If true, it uses GDI+, performance reasons were quoted // @@ -508,14 +614,12 @@ namespace System.Windows.Forms { Application.Exit (); Process.Start (procInfo); } -#endif - public static void Exit() { - XplatUI.PostQuitMessage(0); - CloseForms(null); + public static void Exit () + { + Exit (new CancelEventArgs ()); } -#if NET_2_0 [EditorBrowsable (EditorBrowsableState.Advanced)] public static void Exit (CancelEventArgs e) { @@ -526,11 +630,12 @@ namespace System.Windows.Forms { foreach (Form f in forms_to_close) { // Give each form a chance to cancel the Application.Exit - e.Cancel = f.FireClosingEvents (CloseReason.ApplicationExitCall); + e.Cancel = f.FireClosingEvents (CloseReason.ApplicationExitCall, false); if (e.Cancel) return; + f.suppress_closing_events = true; f.Close (); f.Dispose (); } @@ -538,20 +643,22 @@ namespace System.Windows.Forms { XplatUI.PostQuitMessage (0); } -#endif - public static void ExitThread() { + public static void ExitThread() + { CloseForms(Thread.CurrentThread); // this might not be right - need to investigate (somehow) if a WM_QUIT message is generated here XplatUI.PostQuitMessage(0); } - public static ApartmentState OleRequired() { + public static ApartmentState OleRequired () + { //throw new NotImplementedException("OLE Not supported by this System.Windows.Forms implementation"); return ApartmentState.Unknown; } - public static void OnThreadException(Exception t) { + public static void OnThreadException (Exception t) + { if (MWFThread.Current.HandlingException) { /* we're already handling an exception and we got another one? print it out and exit, this means @@ -583,22 +690,42 @@ namespace System.Windows.Forms { } } - public static void RemoveMessageFilter(IMessageFilter filter) { + public static void RemoveMessageFilter (IMessageFilter value) + { lock (message_filters) { - message_filters.Remove(filter); + message_filters.Remove (value); } } - public static void Run() { - RunLoop(false, new ApplicationContext()); + public static void Run () + { + Run (new ApplicationContext ()); } - public static void Run(Form mainForm) { - RunLoop(false, new ApplicationContext(mainForm)); + public static void Run (Form mainForm) + { + Run (new ApplicationContext (mainForm)); + } + + internal static void FirePreRun () + { + EventHandler handler = PreRun; + if (handler != null) + handler (null, EventArgs.Empty); } - public static void Run(ApplicationContext context) { - RunLoop(false, context); + public static void Run (ApplicationContext context) + { + // If a sync context hasn't been created by now, create + // a default one + if (SynchronizationContext.Current == null) + SynchronizationContext.SetSynchronizationContext (new SynchronizationContext ()); + + RunLoop (false, context); + + // Reset the sync context back to the default + if (SynchronizationContext.Current is WindowsFormsSynchronizationContext) + WindowsFormsSynchronizationContext.Uninstall (); } private static void DisableFormsForModalLoop (Queue toplevels, ApplicationContext context) @@ -635,7 +762,7 @@ namespace System.Windows.Forms { // Disable the rest if (f.IsHandleCreated && XplatUI.IsEnabled (f.Handle)) { #if DebugRunLoop - Console.WriteLine(" Disabling form {0}", f); + Console.WriteLine(" Disabling form {0}", f); #endif XplatUI.EnableWindow (f.Handle, false); toplevels.Enqueue (f); @@ -650,20 +777,21 @@ namespace System.Windows.Forms { { while (toplevels.Count > 0) { #if DebugRunLoop - Console.WriteLine(" Re-Enabling form form {0}", toplevels.Peek()); + Console.WriteLine(" Re-Enabling form form {0}", toplevels.Peek()); #endif - Form c = (Form)toplevels.Dequeue (); + Form c = (Form) toplevels.Dequeue (); if (c.IsHandleCreated) { XplatUI.EnableWindow (c.window.Handle, true); context.MainForm = c; } } #if DebugRunLoop - Console.WriteLine(" Done with the re-enable"); + Console.WriteLine(" Done with the re-enable"); #endif } - internal static void RunLoop(bool Modal, ApplicationContext context) { + internal static void RunLoop (bool Modal, ApplicationContext context) + { Queue toplevels; MSG msg; Object queue_id; @@ -682,9 +810,8 @@ namespace System.Windows.Forms { msg = new MSG(); - if (context == null) { + if (context == null) context = new ApplicationContext(); - } previous_thread_context = thread.Context; thread.Context = context; @@ -738,76 +865,102 @@ namespace System.Windows.Forms { Control c; c = Control.FromHandle(msg.hwnd); -#if NET_2_0 // If we have a control with keyboard capture (usually a *Strip) // give it the message, and then drop the message if (keyboard_capture != null) { // WM_SYSKEYUP does not make it into ProcessCmdKey, so do it here - if ((Msg)m.Msg == Msg.WM_SYSKEYUP) + if ((Msg)m.Msg == Msg.WM_SYSKEYDOWN) if (m.WParam.ToInt32() == (int)Keys.Menu) { keyboard_capture.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.Keyboard); continue; } m.HWnd = keyboard_capture.Handle; - - if (keyboard_capture.PreProcessControlMessageInternal (ref m) != PreProcessControlState.MessageProcessed && (m.Msg == (int)Msg.WM_KEYDOWN && !keyboard_capture.ProcessControlMnemonic ((char)m.WParam))) { - if (c == null || c.Parent == null || !(c.Parent is ToolStrip)) + + switch (keyboard_capture.PreProcessControlMessageInternal (ref m)) { + case PreProcessControlState.MessageProcessed: continue; - else - m.HWnd = msg.hwnd; - } else - continue; + case PreProcessControlState.MessageNeeded: + case PreProcessControlState.MessageNotNeeded: + if (((m.Msg == (int)Msg.WM_KEYDOWN || m.Msg == (int)Msg.WM_CHAR) && !keyboard_capture.ProcessControlMnemonic ((char)m.WParam))) { + if (c == null || !ControlOnToolStrip (c)) + continue; + else + m.HWnd = msg.hwnd; + } else + continue; + + break; + } } -#endif - if ((c != null) && c.PreProcessControlMessageInternal (ref m) != PreProcessControlState.MessageProcessed) { + if (((c != null) && c.PreProcessControlMessageInternal (ref m) != PreProcessControlState.MessageProcessed) || + (c == null)) { goto default; - } + } break; -#if NET_2_0 + case Msg.WM_LBUTTONDOWN: case Msg.WM_MBUTTONDOWN: case Msg.WM_RBUTTONDOWN: if (keyboard_capture != null) { Control c2 = Control.FromHandle (msg.hwnd); - + + // the target is not a winforms control (an embedded control, perhaps), so + // release everything + if (c2 == null) { + ToolStripManager.FireAppClicked (); + goto default; + } + // If we clicked a ToolStrip, we have to make sure it isn't // the one we are on, or any of its parents or children // If we clicked off the dropped down menu, release everything if (c2 is ToolStrip) { if ((c2 as ToolStrip).GetTopLevelToolStrip () != keyboard_capture.GetTopLevelToolStrip ()) ToolStripManager.FireAppClicked (); - } else + } else { + if (c2.Parent != null) + if (c2.Parent is ToolStripDropDownMenu) + if ((c2.Parent as ToolStripDropDownMenu).GetTopLevelToolStrip () == keyboard_capture.GetTopLevelToolStrip ()) + goto default; + if (c2.TopLevelControl == null) + goto default; + ToolStripManager.FireAppClicked (); + } } goto default; -#endif + case Msg.WM_QUIT: quit = true; // make sure we exit break; default: - XplatUI.TranslateMessage(ref msg); - XplatUI.DispatchMessage(ref msg); + XplatUI.TranslateMessage (ref msg); + XplatUI.DispatchMessage (ref msg); break; } - // Handle exit, Form might have received WM_CLOSE and set 'closing' in response + // If our Form doesn't have a handle anymore, it means it was destroyed and we need to *wait* for WM_QUIT. + if ((context.MainForm != null) && (!context.MainForm.IsHandleCreated)) + continue; + + // Handle exit, Form might have received WM_CLOSE and set 'closing' in response. if ((context.MainForm != null) && (context.MainForm.closing || (Modal && !context.MainForm.Visible))) { if (!Modal) { - XplatUI.PostQuitMessage(0); + XplatUI.PostQuitMessage (0); } else { break; } } } #if DebugRunLoop - Console.WriteLine(" RunLoop loop left"); + Console.WriteLine (" RunLoop loop left"); #endif thread.MessageLoop = false; - XplatUI.EndLoop(Thread.CurrentThread); + XplatUI.EndLoop (Thread.CurrentThread); if (Modal) { Form old = context.MainForm; @@ -817,18 +970,19 @@ namespace System.Windows.Forms { EnableFormsForModalLoop (toplevels, context); if (context.MainForm != null && context.MainForm.IsHandleCreated) { - XplatUI.SetModal(context.MainForm.Handle, false); + XplatUI.SetModal (context.MainForm.Handle, false); } #if DebugRunLoop - Console.WriteLine(" Done with the SetModal"); + Console.WriteLine (" Done with the SetModal"); #endif - old.RaiseCloseEvents (true); + old.RaiseCloseEvents (true, false); old.is_modal = false; } #if DebugRunLoop - Console.WriteLine("Leaving RunLoop(Modal={0}, Form={1})", Modal, context.MainForm != null ? context.MainForm.ToString() : "NULL"); + Console.WriteLine ("Leaving RunLoop(Modal={0}, Form={1})", Modal, context.MainForm != null ? context.MainForm.ToString() : "NULL"); #endif + if (context.MainForm != null) { context.MainForm.context = null; context.MainForm = null; @@ -836,17 +990,17 @@ namespace System.Windows.Forms { thread.Context = previous_thread_context; - if (!Modal) { + if (!Modal) thread.Exit(); - } } #endregion // Public Static Methods #region Events - public static event EventHandler ApplicationExit; - public static event EventHandler Idle { + public static event EventHandler ApplicationExit; + + public static event EventHandler Idle { add { XplatUI.Idle += value; } @@ -855,39 +1009,56 @@ namespace System.Windows.Forms { } } - public static event EventHandler ThreadExit; - public static event ThreadExceptionEventHandler ThreadException; + public static event EventHandler ThreadExit; + public static event ThreadExceptionEventHandler ThreadException; + + // These are used externally by the UIA framework + internal static event EventHandler FormAdded; + internal static event EventHandler PreRun; -#if NET_2_0 +#pragma warning disable 0067 + [MonoTODO] [EditorBrowsable (EditorBrowsableState.Advanced)] public static event EventHandler EnterThreadModal; + [MonoTODO] [EditorBrowsable (EditorBrowsableState.Advanced)] public static event EventHandler LeaveThreadModal; -#endif +#pragma warning restore 0067 + #endregion // Events #region Public Delegates -#if NET_2_0 + [EditorBrowsable (EditorBrowsableState.Advanced)] public delegate bool MessageLoopCallback (); -#endif + #endregion #region Internal Properties -#if NET_2_0 internal static ToolStrip KeyboardCapture { get { return keyboard_capture; } set { keyboard_capture = value; } } -#endif + + internal static bool VisualStylesEnabled { + get { return visual_styles_enabled; } + } #endregion #region Internal Methods + internal static void AddForm (Form f) { lock (forms) forms.Add (f); + // Signal that a Form has been added to this + // Application. Used by UIA to detect new Forms that + // need a11y support. This event may be fired even if + // the form has already been added, so clients should + // account for that when handling this signal. + if (FormAdded != null) + FormAdded (f, null); } internal static void RemoveForm (Form f) @@ -895,6 +1066,36 @@ namespace System.Windows.Forms { lock (forms) forms.Remove (f); } + + private static bool ControlOnToolStrip (Control c) + { + Control p = c.Parent; + + while (p != null) { + if (p is ToolStrip) + return true; + + p = p.Parent; + } + + return false; + } + + // Takes a starting path, appends company name, product name, and + // product version. If the directory doesn't exist, create it + private static string CreateDataPath (string basePath) + { + string path; + + path = Path.Combine (basePath, CompanyName); + path = Path.Combine (path, ProductName); + path = Path.Combine (path, ProductVersion); + + if (!Directory.Exists (path)) + Directory.CreateDirectory (path); + + return path; + } #endregion } }