Application.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  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:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  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.
  19. //
  20. // Copyright (c) 2004 Novell, Inc.
  21. //
  22. // Authors:
  23. // Peter Bartok [email protected]
  24. //
  25. //
  26. // $Revision: 1.8 $
  27. // $Modtime: $
  28. // $Log: Application.cs,v $
  29. // Revision 1.8 2004/10/20 03:33:33 pbartok
  30. // - Fixed to deal with new Form subclasses for menus
  31. //
  32. // Revision 1.7 2004/10/18 04:14:14 pbartok
  33. // - Added code to simulate modal dialogs on Win32
  34. //
  35. // Revision 1.6 2004/09/22 20:05:41 pbartok
  36. // - Added message loop for modal dialogs
  37. //
  38. // Revision 1.5 2004/09/21 00:54:15 jackson
  39. // New message loop that uses poll so we don't get a busy loop
  40. //
  41. // Revision 1.4 2004/08/23 22:45:19 pbartok
  42. // - Removed debug output
  43. // - Simplifications
  44. //
  45. // Revision 1.3 2004/08/23 22:09:29 pbartok
  46. // - Added handling of Idle event
  47. // - Added handling of form closing
  48. // - Fixed reporting of MessageLoop property
  49. // - Removed some unneeded code, should provide a bit of a speedup
  50. //
  51. // Revision 1.2 2004/08/11 22:16:50 pbartok
  52. // - Fixed Signature
  53. // - Added .Net 1.1 method
  54. //
  55. // Revision 1.1 2004/07/09 05:21:25 pbartok
  56. // - Initial check-in
  57. //
  58. //
  59. // COMPLETE
  60. using Microsoft.Win32;
  61. using System;
  62. using System.Drawing;
  63. using System.ComponentModel;
  64. using System.Collections;
  65. using System.Diagnostics;
  66. using System.Globalization;
  67. using System.IO;
  68. using System.Reflection;
  69. using System.Runtime.InteropServices;
  70. using System.Threading;
  71. namespace System.Windows.Forms {
  72. public sealed class Application {
  73. private static bool browser_embedded;
  74. private static bool exiting;
  75. private static InputLanguage input_language;
  76. private static bool messageloop_started;
  77. private static string safe_caption_format;
  78. private static ArrayList message_filters;
  79. private static ApplicationContext app_context;
  80. private static Form main_form;
  81. private Application () {
  82. input_language = InputLanguage.CurrentInputLanguage;
  83. message_filters = new ArrayList();
  84. app_context = null;
  85. browser_embedded= false;
  86. exiting = false;
  87. messageloop_started = false;
  88. safe_caption_format = "{1} - {0} - {2}";
  89. }
  90. #region Private and Internal Methods
  91. internal static void ModalRun(Form form) {
  92. MSG msg = new MSG();
  93. Queue toplevels = new Queue();
  94. IEnumerator control = Control.controls.GetEnumerator();
  95. if (form == null) {
  96. return;
  97. }
  98. while (control.MoveNext()) {
  99. if ((((Control)control.Current).parent == null) && (((Control)control.Current).is_visible) && (((Control)control.Current).is_enabled)) {
  100. if ((control.Current is Form.FormParentWindow) && (((Form.FormParentWindow)control.Current)!=form.form_parent_window)) {
  101. XplatUI.EnableWindow(((Control)control.Current).window.Handle, false);
  102. toplevels.Enqueue((Control)control.Current);
  103. }
  104. }
  105. }
  106. while (!exiting && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
  107. if (form.end_modal) {
  108. break;
  109. }
  110. XplatUI.TranslateMessage(ref msg);
  111. XplatUI.DispatchMessage(ref msg);
  112. // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
  113. if (form.closing) {
  114. form.end_modal = true;
  115. }
  116. }
  117. while (toplevels.Count>0) {
  118. XplatUI.EnableWindow(((Control)toplevels.Dequeue()).window.Handle, true);
  119. }
  120. }
  121. #endregion // Private and Internal Methods
  122. #region Public Static Properties
  123. public static bool AllowQuit {
  124. get {
  125. return browser_embedded;
  126. }
  127. }
  128. public static string CommonAppDataPath {
  129. get {
  130. return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
  131. }
  132. }
  133. public static RegistryKey CommonAppDataRegistry {
  134. get {
  135. RegistryKey key;
  136. key = Registry.LocalMachine.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
  137. return key;
  138. }
  139. }
  140. public static string CompanyName {
  141. get {
  142. StackTrace st;
  143. if (Environment.OSVersion.Platform != (PlatformID)128) {
  144. RegistryKey key;
  145. String ret;
  146. key=Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion", false);
  147. ret=(String)key.GetValue("RegisteredOrganization");
  148. return ret;
  149. }
  150. st=new StackTrace();
  151. return st.GetFrame(st.FrameCount-1).GetMethod().DeclaringType.Namespace;
  152. }
  153. }
  154. public static CultureInfo CurrentCulture {
  155. get {
  156. return Thread.CurrentThread.CurrentUICulture;
  157. }
  158. set {
  159. Thread.CurrentThread.CurrentUICulture=value;
  160. }
  161. }
  162. public static InputLanguage CurrentInputLanguage {
  163. get {
  164. return input_language;
  165. }
  166. set {
  167. input_language=value;
  168. }
  169. }
  170. public static string ExecutablePath {
  171. get {
  172. return Assembly.GetEntryAssembly().Location;
  173. }
  174. }
  175. public static string LocalUserAppDataPath {
  176. get {
  177. return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
  178. }
  179. }
  180. public static bool MessageLoop {
  181. get {
  182. return messageloop_started;
  183. }
  184. }
  185. public static string ProductName {
  186. get {
  187. AssemblyProductAttribute[] attrs = (AssemblyProductAttribute[]) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true);
  188. if ((attrs != null) && attrs.Length>0) {
  189. return attrs[0].Product;
  190. }
  191. return Assembly.GetEntryAssembly().GetName().Name;
  192. }
  193. }
  194. public static string ProductVersion {
  195. get {
  196. String version;
  197. version = Assembly.GetEntryAssembly().GetName().Version.ToString();
  198. if (version.StartsWith("0.")) {
  199. version="1." + version.Substring(2);
  200. }
  201. return version;
  202. }
  203. }
  204. public static string SafeTopLevelCaptionFormat {
  205. get {
  206. return safe_caption_format;
  207. }
  208. set {
  209. safe_caption_format=value;
  210. }
  211. }
  212. public static string StartupPath {
  213. get {
  214. return Path.GetDirectoryName(Application.ExecutablePath);
  215. }
  216. }
  217. public static string UserAppDataPath {
  218. get {
  219. return Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
  220. }
  221. }
  222. public static RegistryKey UserAppDataRegistry {
  223. get {
  224. RegistryKey key;
  225. key = Registry.CurrentUser.OpenSubKey("Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion, true);
  226. return key;
  227. }
  228. }
  229. #endregion
  230. #region Public Static Methods
  231. public static void AddMessageFilter(IMessageFilter value) {
  232. message_filters.Add(value);
  233. }
  234. public static void DoEvents() {
  235. XplatUI.DoEvents();
  236. }
  237. public static void EnableVisualStyles() {
  238. XplatUI.EnableThemes();
  239. }
  240. public static void Exit() {
  241. XplatUI.Exit();
  242. }
  243. public static void ExitThread() {
  244. exiting=true;
  245. }
  246. private static void InternalExit(object sender, EventArgs e) {
  247. Application.Exit();
  248. }
  249. public static ApartmentState OleRequired() {
  250. //throw new NotImplementedException("OLE Not supported by this System.Windows.Forms implementation");
  251. return ApartmentState.Unknown;
  252. }
  253. public static void OnThreadException(Exception t) {
  254. if (Application.ThreadException != null) {
  255. Application.ThreadException(null, new ThreadExceptionEventArgs(t));
  256. } else {
  257. XplatUI.HandleException(t);
  258. }
  259. }
  260. public static void RemoveMessageFilter(IMessageFilter filter) {
  261. message_filters.Remove(filter);
  262. }
  263. public static void Run() {
  264. MSG msg = new MSG();
  265. Form form = null;
  266. if (app_context != null) {
  267. form = app_context.MainForm;
  268. }
  269. messageloop_started = true;
  270. while (!exiting && XplatUI.GetMessage(ref msg, IntPtr.Zero, 0, 0)) {
  271. XplatUI.TranslateMessage(ref msg);
  272. XplatUI.DispatchMessage(ref msg);
  273. // Handle exit, Form might have received WM_CLOSE and set 'closing' in response
  274. if ((form != null) && form.closing) {
  275. exiting = true;
  276. }
  277. }
  278. messageloop_started = false;
  279. if (ApplicationExit != null) {
  280. ApplicationExit(null, EventArgs.Empty);
  281. }
  282. }
  283. public static void Run(Form mainForm) {
  284. mainForm.CreateControl();
  285. Run(new ApplicationContext(mainForm));
  286. }
  287. public static void Run(ApplicationContext context) {
  288. app_context=context;
  289. if (app_context.MainForm!=null) {
  290. app_context.MainForm.Show();
  291. app_context.ThreadExit += new EventHandler(InternalExit);
  292. }
  293. Run();
  294. }
  295. #endregion // Public Static Methods
  296. #region Events
  297. public static event EventHandler ApplicationExit;
  298. public static event EventHandler Idle {
  299. add {
  300. XplatUI.Idle += value;
  301. }
  302. remove {
  303. XplatUI.Idle -= value;
  304. }
  305. }
  306. public static event EventHandler ThreadExit;
  307. public static event ThreadExceptionEventHandler ThreadException;
  308. #endregion // Events
  309. }
  310. }