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 Exit() { #if NET_2_0 Exit(new CancelEventArgs()); #else XplatUI.PostQuitMessage(0); CloseForms(null); #endif }
protected virtual void ExitThreadCore() { if (Application.MWFThread.Current.Context == this) { XplatUI.PostQuitMessage(0); } if (!thread_exit_raised && ThreadExit != null) { thread_exit_raised = true; ThreadExit(this, EventArgs.Empty); } }
internal static void RunLoop(bool Modal, ApplicationContext context) { Queue toplevels; MSG msg; Object queue_id; MWFThread thread; ApplicationContext previous_thread_context; thread = MWFThread.Current; /* * There is a NotWorking test for this, but since we are using this method both for Form.ShowDialog as for ApplicationContexts we'll * fail on nested ShowDialogs, so disable the check for the moment. */ //if (thread.MessageLoop) { // throw new InvalidOperationException ("Starting a second message loop on a single thread is not a valid operation. Use Form.ShowDialog instead."); //} msg = new MSG(); if (context == null) { context = new ApplicationContext(); } previous_thread_context = thread.Context; thread.Context = context; if (context.MainForm != null) { context.MainForm.is_modal = Modal; context.MainForm.context = context; context.MainForm.closing = false; context.MainForm.Visible = true; // Cannot use Show() or scaling gets confused by menus // XXX the above line can be used to close the form. another problem with our handling of Show/Activate. if (context.MainForm != null) { context.MainForm.Activate(); } } #if DebugRunLoop Console.WriteLine("Entering RunLoop(Modal={0}, Form={1})", Modal, context.MainForm != null ? context.MainForm.ToString() : "NULL"); #endif if (Modal) { toplevels = new Queue(); DisableFormsForModalLoop(toplevels, context); // FIXME - need activate? /* make sure the MainForm is enabled */ if (context.MainForm != null) { XplatUI.EnableWindow(context.MainForm.Handle, true); XplatUI.SetModal(context.MainForm.Handle, true); } } else { toplevels = null; } queue_id = XplatUI.StartLoop(Thread.CurrentThread); thread.MessageLoop = true; bool quit = false; while (!quit && XplatUI.GetMessage(queue_id, ref msg, IntPtr.Zero, 0, 0)) { 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_CHAR: case Msg.WM_SYSCHAR: case Msg.WM_KEYUP: case Msg.WM_SYSKEYUP: Control c = Control.FromHandle(msg.hwnd); // 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_SYSKEYDOWN) { if (m.WParam.ToInt32() == (int)Keys.Menu) { keyboard_capture.GetTopLevelToolStrip().Dismiss(ToolStripDropDownCloseReason.Keyboard); continue; } } m.HWnd = keyboard_capture.Handle; switch (keyboard_capture.PreProcessControlMessageInternal(ref m)) { case PreProcessControlState.MessageProcessed: 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; } } if (((c != null) && c.PreProcessControlMessageInternal(ref m) != PreProcessControlState.MessageProcessed) || (c == null)) { goto default; } break; case Msg.WM_LBUTTONDOWN: case Msg.WM_MBUTTONDOWN: case Msg.WM_RBUTTONDOWN: if (keyboard_capture != null) { Control c2 = Control.FromHandle(msg.hwnd); var contextMenuStrip = keyboard_capture.GetTopLevelToolStrip() as ContextMenuStrip; // The target is not a winforms control (an embedded control, perhaps), so // release everything if (c2 == null) { ToolStripManager.FireAppClicked(); goto default; } // Skip clicks on owner windows, eg. expanded ComboBox if (Control.IsChild(keyboard_capture.Handle, msg.hwnd)) { goto default; } // Close any active toolstrips drop-downs if we click outside of them, // but also don't close them all if we click outside of the top-most // one, but into its owner. Point c2_point = c2.PointToScreen(new Point( (int)(short)(m.LParam.ToInt32() & 0xffff), (int)(short)(m.LParam.ToInt32() >> 16))); while (keyboard_capture != null && !keyboard_capture.ClientRectangle.Contains(keyboard_capture.PointToClient(c2_point))) { keyboard_capture.Dismiss(); } var iter_OwnerItem = (c2 as ToolStripDropDown)?.OwnerItem; while (iter_OwnerItem != null && iter_OwnerItem.Owner != contextMenuStrip) { iter_OwnerItem = iter_OwnerItem.OwnerItem; } var contextMenuStripIsOwnerOf_c2 = (iter_OwnerItem != null); if (c2 != contextMenuStrip && !contextMenuStripIsOwnerOf_c2) { contextMenuStrip.Dismiss(); } } goto default; case Msg.WM_QUIT: quit = true; // make sure we exit break; default: XplatUI.TranslateMessage(ref msg); XplatUI.DispatchMessage(ref msg); break; } // 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); } else { break; } } } #if DebugRunLoop Console.WriteLine(" RunLoop loop left"); #endif thread.MessageLoop = false; XplatUI.EndLoop(Thread.CurrentThread); if (Modal) { Form old = context.MainForm; context.MainForm = null; EnableFormsForModalLoop(toplevels, context); if (old != null && old.IsHandleCreated) { XplatUI.SetModal(old.Handle, false); } #if DebugRunLoop Console.WriteLine(" Done with the SetModal"); #endif 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"); #endif if (context.MainForm != null) { context.MainForm.context = null; context.MainForm = null; } thread.Context = previous_thread_context; if (!Modal) { thread.Exit(); } }
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); }
internal static void RunLoop(bool Modal, ApplicationContext context) { MWFThread thread = MWFThread.Current; // There is a NotWorking test for this, but since we are using this method both for Form.ShowDialog as for ApplicationContexts we'll // fail on nested ShowDialogs, so disable the check for the moment. //if (thread.MessageLoop) { // throw new InvalidOperationException ("Starting a second message loop on a single thread is not a valid operation. Use Form.ShowDialog instead."); //} if (context == null) { context = new ApplicationContext(); } ApplicationContext previous_thread_context = thread.Context; thread.Context = context; if (context.MainForm != null) { context.MainForm.is_modal = Modal; context.MainForm.context = context; context.MainForm.closing = false; context.MainForm.Visible = true; // Cannot use Show() or scaling gets confused by menus // XXX the above line can be used to close the form. another problem with our handling of Show/Activate. if (context.MainForm != null) { context.MainForm.Activate(); } } #if DebugRunLoop Console.WriteLine("Entering RunLoop(Modal={0}, Form={1})", Modal, context.MainForm != null ? context.MainForm.ToString() : "NULL"); #endif Queue toplevels = new Queue(); if (Modal) { DisableFormsForModalLoop(toplevels, context); // FIXME - need activate? // make sure the MainForm is enabled if (context.MainForm != null) { XplatUI.EnableWindow(context.MainForm.Handle, true); XplatUI.SetModal(context.MainForm.Handle, true); } } Object queue_id = XplatUI.StartLoop(Thread.CurrentThread); var prevMessageLoop = thread.MessageLoop; thread.MessageLoop = true; bool quit = false, drop = false; MSG msg = new MSG(); while (!quit) { using (var cleanup = XplatUI.StartCycle(queue_id)) { if ((quit = !XplatUI.GetMessage(queue_id, ref msg, IntPtr.Zero, 0, 0))) { continue; } if (msg.message != Msg.WM_NULL) { Application.SendMessage(ref msg, out drop, out quit); } if (drop) { continue; } var mainForm = context.MainForm; if (mainForm == null) { continue; } // If our Form doesn't have a handle anymore, it means it was destroyed and we need to *wait* for WM_QUIT. if (!mainForm.IsHandleCreated) { continue; } // Handle exit, Form might have received WM_CLOSE and set 'closing' in response. if (mainForm.closing || (Modal && !mainForm.Visible)) { if (!Modal) { XplatUI.PostQuitMessage(0); } else { break; } } } } #if DebugRunLoop Console.WriteLine(" RunLoop loop left"); #endif thread.MessageLoop = prevMessageLoop; XplatUI.EndLoop(Thread.CurrentThread); if (Modal) { Form old = context.MainForm; context.MainForm = null; EnableFormsForModalLoop(toplevels, context); if (old != null && old.IsHandleCreated) { XplatUI.SetModal(old.Handle, false); } #if DebugRunLoop Console.WriteLine(" Done with the SetModal"); #endif 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"); #endif if (context.MainForm != null) { context.MainForm.context = null; context.MainForm = null; } thread.Context = previous_thread_context; if (!Modal) { thread.Exit(); } }
static public bool TrackPopupMenu(Menu menu, Point_ pnt) { if (menu.MenuItems.Count <= 0) // No submenus to track { return(true); } MenuTracker tracker = menu.tracker; tracker.active = true; tracker.popup_active = true; // Set GrabControl Control src_ctrl = (tracker.TopMenu as ContextMenu).SourceControl; tracker.GrabControl = src_ctrl.FindForm(); if (tracker.GrabControl == null) { tracker.GrabControl = src_ctrl.FindRootParent(); } tracker.GrabControl.ActiveTracker = tracker; menu.Wnd = new PopUpWindow(tracker.GrabControl, menu); menu.Wnd.Location = menu.Wnd.PointToClient(pnt); ((PopUpWindow)menu.Wnd).ShowWindow(); bool no_quit = true; Object queue_id = XplatUI.StartLoop(Thread.CurrentThread); while ((menu.Wnd != null) && menu.Wnd.Visible && no_quit) { MSG msg = new MSG(); no_quit = XplatUI.GetMessage(queue_id, ref msg, IntPtr.Zero, 0, 0); switch ((Msg)msg.message) { case Msg.WM_KEYDOWN: case Msg.WM_SYSKEYDOWN: case Msg.WM_CHAR: case Msg.WM_SYSCHAR: case Msg.WM_KEYUP: case Msg.WM_SYSKEYUP: Control c = Control.FromHandle(msg.hwnd); if (c != null) { Message m = Message.Create(msg.hwnd, (int)msg.message, msg.wParam, msg.lParam); c.PreProcessControlMessageInternal(ref m); } break; default: XplatUI.TranslateMessage(ref msg); XplatUI.DispatchMessage(ref msg); break; } } if (tracker.GrabControl.IsDisposed) { return(true); } if (!no_quit) { XplatUI.PostQuitMessage(0); } if (menu.Wnd != null) { menu.Wnd.Dispose(); menu.Wnd = null; } return(true); }