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; }
public bool HandlingException {
get { return handling_exception; }
set { handling_exception = value; }
-
}
public static int LoopCount {
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
}
}
}
+
#endregion // Private methods
#region Public Static Properties
+
public static bool AllowQuit {
get {
return !browser_embedded;
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;
}
}
get {
return Thread.CurrentThread.CurrentUICulture;
}
-
set {
-
- Thread.CurrentThread.CurrentUICulture=value;
+ Thread.CurrentThread.CurrentUICulture = value;
}
}
get {
return input_language;
}
-
set {
input_language=value;
}
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));
}
}
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;
}
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;
}
}
}
-
+
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 DoEvents ()
+ {
+ XplatUI.DoEvents ();
}
- public static void EnableVisualStyles() {
- XplatUI.EnableThemes();
+ public static void EnableVisualStyles ()
+ {
+ visual_styles_enabled = true;
+ XplatUI.EnableThemes ();
}
-#if NET_2_0
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+ public static bool FilterMessage (ref Message message)
+ {
+ 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 true, it uses GDI+, performance reasons were quoted
//
return forms;
}
}
+
+ [MonoNotSupported ("Only applies when Winforms is being hosted by an unmanaged app.")]
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+ public static void RegisterMessageLoop (MessageLoopCallback callback)
+ {
+ }
+
+ [MonoNotSupported ("Empty stub.")]
+ public static bool SetSuspendState (PowerState state, bool force, bool disableWakeEvent)
+ {
+ return false;
+ }
[MonoNotSupported ("Empty stub.")]
public static void SetUnhandledExceptionMode (UnhandledExceptionMode mode)
//FIXME: a stub to fill
}
+ [MonoNotSupported ("Empty stub.")]
+ public static void SetUnhandledExceptionMode (UnhandledExceptionMode mode, bool threadScope)
+ {
+ //FIXME: a stub to fill
+ }
+
+ [MonoNotSupported ("Only applies when Winforms is being hosted by an unmanaged app.")]
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+ public static void UnregisterMessageLoop ()
+ {
+ }
+
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
public static void RaiseIdle (EventArgs e)
{
XplatUI.RaiseIdle (e);
Application.Exit ();
Process.Start (procInfo);
}
-#endif
- public static void Exit() {
- XplatUI.PostQuitMessage(0);
- CloseForms(null);
+ public static void Exit ()
+ {
+ Exit (new CancelEventArgs ());
+ }
+
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+ public static void Exit (CancelEventArgs e)
+ {
+ ArrayList forms_to_close;
+
+ lock (forms) {
+ forms_to_close = new ArrayList (forms);
+
+ foreach (Form f in forms_to_close) {
+ // Give each form a chance to cancel the Application.Exit
+ e.Cancel = f.FireClosingEvents (CloseReason.ApplicationExitCall, false);
+
+ if (e.Cancel)
+ return;
+
+ f.suppress_closing_events = true;
+ f.Close ();
+ f.Dispose ();
+ }
+ }
+
+ XplatUI.PostQuitMessage (0);
}
- 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
}
}
- 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)
+ {
+ Run (new ApplicationContext (mainForm));
}
- public static void Run(Form mainForm) {
- RunLoop(false, 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)
// 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);
{
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;
msg = new MSG();
- if (context == null) {
+ if (context == null)
context = new ApplicationContext();
- }
previous_thread_context = thread.Context;
thread.Context = context;
bool quit = false;
while (!quit && XplatUI.GetMessage(queue_id, ref msg, IntPtr.Zero, 0, 0)) {
- lock (message_filters) {
- if (message_filters.Count > 0) {
- Message m;
- bool drop;
-
- drop = false;
- m = Message.Create(msg.hwnd, (int)msg.message, msg.wParam, msg.lParam);
- for (int i = 0; i < message_filters.Count; i++) {
- if (((IMessageFilter)message_filters[i]).PreFilterMessage(ref m)) {
- // we're dropping the message
- drop = true;
- break;
- }
- }
- if (drop) {
- continue;
- }
- }
- }
-
+ Message m = Message.Create(msg.hwnd, (int)msg.message, msg.wParam, msg.lParam);
+
+ if (Application.FilterMessage (ref m))
+ continue;
+
switch((Msg)msg.message) {
case Msg.WM_KEYDOWN:
case Msg.WM_SYSKEYDOWN:
case Msg.WM_SYSCHAR:
case Msg.WM_KEYUP:
case Msg.WM_SYSKEYUP:
- Message m;
- m = Message.Create(msg.hwnd, (int)msg.message, msg.wParam, msg.lParam);
-
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;
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;
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;
}
}
}
- 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)
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
}
}