internal override void Dismiss(ToolStripDropDownCloseReason reason) { this.Close(reason); base.Dismiss(reason); // ContextMenuStrip won't have a parent if (this.OwnerItem == null) { ToolStripManager.ToolStripDropDownDismissed(this, reason); return; } // Ensure Submenu loes keyboard capture when closing. ToolStripManager.SetActiveToolStrip(null, false); }
private void MoveOutsideContainer(ToolStrip toolStripToDrag, Point screenLocation) { ToolStripPanel controlToLayout = ToolStripManager.ToolStripPanelFromPoint(toolStripToDrag, screenLocation); if (controlToLayout != null) { using (new LayoutTransaction(controlToLayout, controlToLayout, null)) { controlToLayout.MoveControl(toolStripToDrag, screenLocation); } toolStripToDrag.PerformLayout(); } else { this.GiveToolStripPanelFeedback(toolStripToDrag, screenLocation); } }
internal override bool ProcessArrowKey(Keys keyData) { switch (keyData) { case Keys.Down: case Keys.Tab: this.SelectNextToolStripItem(this.GetCurrentlySelectedItem(), true); return(true); case Keys.Up: case Keys.Shift | Keys.Tab: this.SelectNextToolStripItem(this.GetCurrentlySelectedItem(), false); return(true); case Keys.Right: this.GetTopLevelToolStrip().SelectNextToolStripItem(this.TopLevelOwnerItem, true); return(true); case Keys.Left: case Keys.Escape: this.Dismiss(ToolStripDropDownCloseReason.Keyboard); // ContextMenuStrip won't have a parent if (this.OwnerItem == null) { return(true); } ToolStrip parent_strip = this.OwnerItem.Parent; ToolStripManager.SetActiveToolStrip(parent_strip, true); if (parent_strip is MenuStrip && keyData == Keys.Left) { parent_strip.SelectNextToolStripItem(this.TopLevelOwnerItem, false); this.TopLevelOwnerItem.Invalidate(); } else if (parent_strip is MenuStrip && keyData == Keys.Escape) { (parent_strip as MenuStrip).MenuDroppedDown = false; this.TopLevelOwnerItem.Select(); } return(true); } return(false); }
internal override bool OnMenuKey() { // Set ourselves active and select our first item ToolStripManager.SetActiveToolStrip(this, true); ToolStripItem tsi = this.SelectNextToolStripItem(null, true); if (tsi == null) { return(false); } if (tsi is MdiControlStrip.SystemMenuItem) { this.SelectNextToolStripItem(tsi, true); } return(true); }
internal void ChildFormClosed(Form form) { FormWindowState closed_form_windowstate = form.WindowState; form.Visible = false; Controls.Remove(form); if (Controls.Count == 0) { ((MdiWindowManager)form.window_manager).RaiseDeactivate(); } else if (closed_form_windowstate == FormWindowState.Maximized) { Form current = (Form)Controls [0]; current.WindowState = FormWindowState.Maximized; ActivateChild(current); } if (Controls.Count == 0) { XplatUI.RequestNCRecalc(Parent.Handle); ParentForm.PerformLayout(); #if NET_2_0 // If we closed the last child, unmerge the menus. // If it's not the last child, the menu will be unmerged // when another child takes focus. MenuStrip parent_menu = form.MdiParent.MainMenuStrip; if (parent_menu != null) { if (parent_menu.IsCurrentlyMerged) { ToolStripManager.RevertMerge(parent_menu); } } #endif } SizeScrollBars(); SetParentText(false); form.Dispose(); }
protected internal override bool ProcessMnemonic(char charCode) { if (!this.Selected) { this.Parent.ChangeSelection(this); } if (this.HasDropDownItems) { ToolStripManager.SetActiveToolStrip(this.Parent, true); this.ShowDropDown(); this.DropDown.SelectNextToolStripItem(null, true); } else { this.PerformClick(); } return(true); }
protected override void Dispose(bool disposing) { if (!IsDisposed) { if (this.HasDropDownItems) { foreach (ToolStripItem tsi in this.DropDownItems) { if (tsi is ToolStripMenuItem) { ToolStripManager.RemoveToolStripMenuItem((ToolStripMenuItem)tsi); } } } if (drop_down != null) { ToolStripManager.RemoveToolStrip(drop_down); } base.Dispose(disposing); } }
public int Add(ToolStripItem value) { if (value == null) { throw new ArgumentNullException("value"); } value.InternalOwner = owner; if (value is ToolStripMenuItem && (value as ToolStripMenuItem).ShortcutKeys != Keys.None) { ToolStripManager.AddToolStripMenuItem((ToolStripMenuItem)value); } int index = base.Add(value); if (this.internal_created) { owner.OnItemAdded(new ToolStripItemEventArgs(value)); } return(index); }
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(); } }
private void ApplySettings(ArrayList toolStripSettingsToApply) { if (toolStripSettingsToApply.Count == 0) { return; } SuspendAllLayout(form); // iterate through all the toolstrips and build up a hash of where the items // are right now. Dictionary <string, ToolStrip> itemLocationHash = BuildItemOriginationHash(); // build up a hash of where we want the ToolStrips to go Dictionary <object, List <SettingsStub> > toolStripPanelDestinationHash = new Dictionary <object, List <SettingsStub> >(); foreach (SettingsStub toolStripSettings in toolStripSettingsToApply) { object destinationPanel = !string.IsNullOrEmpty(toolStripSettings.ToolStripPanelName) ? toolStripSettings.ToolStripPanelName : null; if (destinationPanel == null) { // Not in a panel. if (!string.IsNullOrEmpty(toolStripSettings.Name)) { // apply the toolstrip settings. ToolStrip toolStrip = ToolStripManager.FindToolStrip(form, toolStripSettings.Name); ApplyToolStripSettings(toolStrip, toolStripSettings, itemLocationHash); } } else { // This toolStrip is in a ToolStripPanel. We will process it below. if (!toolStripPanelDestinationHash.ContainsKey(destinationPanel)) { toolStripPanelDestinationHash[destinationPanel] = new List <SettingsStub>(); } toolStripPanelDestinationHash[destinationPanel].Add(toolStripSettings); } } // build up a list of the toolstrippanels to party on ArrayList toolStripPanels = FindToolStripPanels(true, form.Controls); foreach (ToolStripPanel toolStripPanel in toolStripPanels) { // set all the controls to visible false/ foreach (Control c in toolStripPanel.Controls) { c.Visible = false; } string toolStripPanelName = toolStripPanel.Name; // Handle the ToolStripPanels inside a ToolStripContainer if (string.IsNullOrEmpty(toolStripPanelName) && toolStripPanel.Parent is ToolStripContainer && !string.IsNullOrEmpty(toolStripPanel.Parent.Name)) { toolStripPanelName = toolStripPanel.Parent.Name + "." + toolStripPanel.Dock.ToString(); } toolStripPanel.BeginInit(); // get the associated toolstrips for this panel if (toolStripPanelDestinationHash.ContainsKey(toolStripPanelName)) { List <SettingsStub> stubSettings = toolStripPanelDestinationHash[toolStripPanelName]; if (stubSettings != null) { foreach (SettingsStub settings in stubSettings) { if (!string.IsNullOrEmpty(settings.Name)) { // apply the toolstrip settings. ToolStrip toolStrip = ToolStripManager.FindToolStrip(form, settings.Name); ApplyToolStripSettings(toolStrip, settings, itemLocationHash); toolStripPanel.Join(toolStrip, settings.Location); } } } } toolStripPanel.EndInit(); } ResumeAllLayout(form, true); }
internal bool SetWindowStates(MdiWindowManager wm) { /* * MDI WindowState behaviour: * - If the active window is maximized, all other maximized windows are normalized. * - If a normal window gets focus and the original active window was maximized, * the normal window gets maximized and the original window gets normalized. * - If a minimized window gets focus and the original window was maximized, * the minimzed window gets maximized and the original window gets normalized. * If the ex-minimized window gets deactivated, it will be normalized. */ Form form = wm.form; if (setting_windowstates) { return(false); } if (!form.Visible) { return(false); } bool is_active = wm.IsActive; bool maximize_this = false; if (!is_active) { return(false); } ArrayList minimize_these = new ArrayList(); ArrayList normalize_these = new ArrayList(); setting_windowstates = true; foreach (Form frm in mdi_child_list) { if (frm == form) { continue; } else if (!frm.Visible) { continue; } if (frm.WindowState == FormWindowState.Maximized && is_active) { maximize_this = true; if (((MdiWindowManager)frm.window_manager).was_minimized) { minimize_these.Add(frm); } else { normalize_these.Add(frm); } } } if (maximize_this && form.WindowState != FormWindowState.Maximized) { wm.was_minimized = form.window_state == FormWindowState.Minimized; form.WindowState = FormWindowState.Maximized; } foreach (Form frm in minimize_these) { frm.WindowState = FormWindowState.Minimized; } foreach (Form frm in normalize_these) { frm.WindowState = FormWindowState.Normal; } SetParentText(false); XplatUI.RequestNCRecalc(ParentForm.Handle); XplatUI.RequestNCRecalc(Handle); SizeScrollBars(); setting_windowstates = false; if (form.MdiParent.MainMenuStrip != null) { form.MdiParent.MainMenuStrip.RefreshMdiItems(); } // Implicit menu strip merging // - When child is activated // - Parent form must have a MainMenuStrip // - Find the first menustrip on the child // - Merge MenuStrip parent_menu = form.MdiParent.MainMenuStrip; if (parent_menu != null) { if (parent_menu.IsCurrentlyMerged) { ToolStripManager.RevertMerge(parent_menu); } MenuStrip child_menu = LookForChildMenu(form); if (form.WindowState != FormWindowState.Maximized) { RemoveControlMenuItems(wm); } if (form.WindowState == FormWindowState.Maximized) { bool found = false; foreach (ToolStripItem tsi in parent_menu.Items) { if (tsi is MdiControlStrip.SystemMenuItem) { (tsi as MdiControlStrip.SystemMenuItem).MdiForm = form; found = true; } else if (tsi is MdiControlStrip.ControlBoxMenuItem) { (tsi as MdiControlStrip.ControlBoxMenuItem).MdiForm = form; found = true; } } if (!found) { parent_menu.SuspendLayout(); parent_menu.Items.Insert(0, new MdiControlStrip.SystemMenuItem(form)); parent_menu.Items.Add(new MdiControlStrip.ControlBoxMenuItem(form, MdiControlStrip.ControlBoxType.Close)); parent_menu.Items.Add(new MdiControlStrip.ControlBoxMenuItem(form, MdiControlStrip.ControlBoxType.Max)); parent_menu.Items.Add(new MdiControlStrip.ControlBoxMenuItem(form, MdiControlStrip.ControlBoxType.Min)); parent_menu.ResumeLayout(); } } if (child_menu != null) { ToolStripManager.Merge(child_menu, parent_menu); } } return(maximize_this); }
// Returns true if the message should be dropped. internal static IntPtr SendMessage(ref MSG msg, out bool drop, out bool quit) { drop = false; quit = false; Message m = Message.Create(msg.hwnd, (int)msg.message, msg.wParam, msg.lParam); if (Application.FilterMessage(ref m)) { drop = true; return(IntPtr.Zero); } 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.message == Msg.WM_SYSKEYDOWN) { if (m.WParam.ToInt32() == (int)Keys.Menu) { keyboard_capture.GetTopLevelToolStrip().Dismiss(ToolStripDropDownCloseReason.Keyboard); drop = true; return(IntPtr.Zero); } } m.HWnd = keyboard_capture.Handle; switch (keyboard_capture.PreProcessControlMessageInternal(ref m)) { case PreProcessControlState.MessageProcessed: drop = true; return(IntPtr.Zero); case PreProcessControlState.MessageNeeded: case PreProcessControlState.MessageNotNeeded: if (((msg.message == Msg.WM_KEYDOWN || msg.message == Msg.WM_CHAR) && keyboard_capture != null && !keyboard_capture.ProcessControlMnemonic((char)m.WParam))) { if (c == null || !ControlOnToolStrip(c)) { drop = true; return(IntPtr.Zero); } m.HWnd = msg.hwnd; } else { drop = true; return(IntPtr.Zero); } break; } } if (((c != null) && c.PreProcessControlMessageInternal(ref m) != PreProcessControlState.MessageProcessed) || (c == null)) { goto default; } return(new IntPtr(1)); // Drop 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; } // 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(); } } goto default; case Msg.WM_QUIT: quit = true; // make sure we exit break; default: XplatUI.TranslateMessage(ref msg); return(XplatUI.DispatchMessage(ref msg)); } return(IntPtr.Zero); }
private void ShowInternal(Control control, Point screenPosition, ToolStripDropDownDirection direction) { this.PerformLayout(); Point show_point = CalculateShowPoint(screenPosition, direction, Size); if (this.Location != show_point) { this.Location = show_point; } // Prevents recursion if (Visible) { return; } SetSourceControl(control); CancelEventArgs e = new CancelEventArgs(); this.OnOpening(e); if (e.Cancel) { return; } // The tracker lets us know when the form is clicked or loses focus ToolStripManager.AppClicked += new EventHandler(ToolStripMenuTracker_AppClicked); ToolStripManager.AppFocusChange += new EventHandler(ToolStripMenuTracker_AppFocusChange); bool useNativeMenu = true; foreach (var item in this.Items) { useNativeMenu &= item is ToolStripMenuItem || item is ToolStripSeparator; } // Prevent closing native menus by the Application object - it would be too early, in MouseDown. // Native menus will close automatically, *after MouseUp*. This way, we can handle both // ways of selecting the item: mouse_down-move-mouse_up and click-move-click. ToolStripManager.DismissingHandledNatively = useNativeMenu; #if XAMARINMAC if (useNativeMenu) { currentMenu = ToNSMenu(); ((MonoMenuDelegate)currentMenu.Delegate).BeforePopup(); show_point = CalculateShowPoint(screenPosition, direction, new Size((int)currentMenu.Size.Width, (int)currentMenu.Size.Height)); PostMouseUp(control, show_point); NSApplication.SharedApplication.BeginInvokeOnMainThread(delegate { if (control != null) { var winPosition = control.PointToClient(show_point); currentMenu.PopUpMenu(null, new CGPoint(winPosition.X, winPosition.Y), control.Handle.ToNSView()); } else { Size displaySize; XplatUI.GetDisplaySize(out displaySize); currentMenu.PopUpMenu(null, new CGPoint(show_point.X, displaySize.Height - show_point.Y), null); } }); } #endif base.Show(); ToolStripManager.SetActiveToolStrip(this, ToolStripManager.ActivatedByKeyboard); // Called from NSMenuDelegate for native menus if (!useNativeMenu) { this.OnOpened(EventArgs.Empty); } }
// Returns true if the message should be dropped. internal static IntPtr SendMessage(ref MSG msg, out bool drop, out bool quit) { drop = false; quit = false; Message m = Message.Create(msg.hwnd, (int)msg.message, msg.wParam, msg.lParam); if (Application.FilterMessage(ref m)) { drop = true; return(IntPtr.Zero); } switch (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 && !c.Enabled) { break; } // If we have a control with keyboard capture (usually a *Strip) // give it the message, and then drop the message if (keyboard_capture != null && c != keyboard_capture && !Control.IsChild(keyboard_capture.Handle, c?.Handle ?? IntPtr.Zero)) { // WM_SYSKEYUP does not make it into ProcessCmdKey, so do it here if (msg.message == Msg.WM_SYSKEYDOWN) { if (m.WParam.ToInt32() == (int)Keys.Menu) { keyboard_capture.GetTopLevelToolStrip().Dismiss(ToolStripDropDownCloseReason.Keyboard); drop = true; return(IntPtr.Zero); } } m.HWnd = keyboard_capture.Handle; } goto default; case Msg.WM_LBUTTONDOWN: case Msg.WM_MBUTTONDOWN: case Msg.WM_RBUTTONDOWN: case Msg.WM_XBUTTONDOWN: Control c2 = Control.FromHandle(msg.hwnd); if (keyboard_capture != null) { // 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; } // Native menus have their own closing mechanism. if (ToolStripManager.DismissingHandledNatively) { 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((short)(m.LParam.ToInt32() & 0xffff), (short)(m.LParam.ToInt32() >> 16))); while (keyboard_capture != null && !keyboard_capture.ClientRectangle.Contains(keyboard_capture.PointToClient(c2_point))) { keyboard_capture.Dismiss(); } } if (c2 != null && !c2.Enabled) { break; } goto default; case Msg.WM_LBUTTONDBLCLK: case Msg.WM_MBUTTONDBLCLK: case Msg.WM_RBUTTONDBLCLK: case Msg.WM_XBUTTONDBLCLK: Control dbl = Control.FromHandle(msg.hwnd); if (dbl != null && !dbl.Enabled) { break; } goto default; case Msg.WM_LBUTTONUP: case Msg.WM_RBUTTONUP: case Msg.WM_MBUTTONUP: case Msg.WM_XBUTTONUP: Control up = Control.FromHandle(msg.hwnd); if (up != null && !up.Enabled) { break; } goto default; case Msg.WM_QUIT: quit = true; // make sure we exit break; default: if (PreTranslateMessage(ref msg)) { return((IntPtr)1); } XplatUI.TranslateMessage(ref msg); return(XplatUI.DispatchMessage(ref msg)); } return(IntPtr.Zero); }
// Returns true if the message should be dropped. internal static IntPtr SendMessage(ref MSG msg, out bool drop, out bool quit) { drop = false; quit = false; Message m = Message.Create(msg.hwnd, (int)msg.message, msg.wParam, msg.lParam); if (Application.FilterMessage(ref m)) { drop = true; return(IntPtr.Zero); } 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.message == Msg.WM_SYSKEYDOWN) { if (m.WParam.ToInt32() == (int)Keys.Menu) { keyboard_capture.GetTopLevelToolStrip().Dismiss(ToolStripDropDownCloseReason.Keyboard); drop = true; return(IntPtr.Zero); } } m.HWnd = keyboard_capture.Handle; switch (keyboard_capture.PreProcessControlMessageInternal(ref m)) { case PreProcessControlState.MessageProcessed: drop = true; return(IntPtr.Zero); case PreProcessControlState.MessageNeeded: case PreProcessControlState.MessageNotNeeded: if (((msg.message == Msg.WM_KEYDOWN || msg.message == Msg.WM_CHAR) && !keyboard_capture.ProcessControlMnemonic((char)m.WParam))) { if (c == null || !ControlOnToolStrip(c)) { drop = true; return(IntPtr.Zero); } m.HWnd = msg.hwnd; } else { drop = true; return(IntPtr.Zero); } 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); // 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 { Control dropDownParent = c2.Parent; while (dropDownParent != null) { if (dropDownParent is ToolStripDropDown) { if ((dropDownParent as ToolStripDropDown).GetTopLevelToolStrip() == keyboard_capture.GetTopLevelToolStrip()) { goto default; } break; } dropDownParent = dropDownParent.Parent; } if (!Control.IsChild(keyboard_capture.Handle, c2.Handle)) { ToolStripManager.FireAppClickedInternal(); goto default; } if (c2.TopLevelControl == null) { goto default; } ToolStripManager.FireAppClicked(); } } goto default; case Msg.WM_QUIT: quit = true; // make sure we exit break; default: XplatUI.TranslateMessage(ref msg); return(XplatUI.DispatchMessage(ref msg)); } return(IntPtr.Zero); }
public static bool Merge(ToolStrip sourceToolStrip, ToolStrip targetToolStrip) { // Check for exceptions if (sourceToolStrip == null) { throw new ArgumentNullException("sourceToolStrip"); } if (targetToolStrip == null) { throw new ArgumentNullException("targetName"); } if (targetToolStrip == sourceToolStrip) { throw new ArgumentException("Source and target ToolStrip must be different."); } // If the toolstrips don't allow merging, don't merge them if (!sourceToolStrip.AllowMerge || !targetToolStrip.AllowMerge) { return(false); } // We currently can't support merging multiple times if (sourceToolStrip.IsCurrentlyMerged || targetToolStrip.IsCurrentlyMerged) { return(false); } // What I wouldn't give to be able to modify a collection // while enumerating through it... List <ToolStripItem> items_to_move = new List <ToolStripItem> (); // Create a list of every ToolStripItem we plan on moving foreach (ToolStripItem tsi in sourceToolStrip.Items) { switch (tsi.MergeAction) { case MergeAction.Append: default: items_to_move.Add(tsi); break; case MergeAction.Insert: if (tsi.MergeIndex >= 0) { items_to_move.Add(tsi); } break; case MergeAction.Replace: case MergeAction.Remove: case MergeAction.MatchOnly: foreach (ToolStripItem target_tsi in targetToolStrip.Items) { if (tsi.Text == target_tsi.Text) { items_to_move.Add(tsi); break; } } break; } } // If there was nothing valid to merge, return false if (items_to_move.Count == 0) { return(false); } // Set some state so we can unmerge later sourceToolStrip.BeginMerge(); targetToolStrip.BeginMerge(); sourceToolStrip.SuspendLayout(); targetToolStrip.SuspendLayout(); while (items_to_move.Count > 0) { ToolStripItem tsi = items_to_move[0]; items_to_move.Remove(tsi); switch (tsi.MergeAction) { case MergeAction.Append: default: // Just changing the parent will append it to the target // and remove it from the source ToolStrip.SetItemParent(tsi, targetToolStrip); break; case MergeAction.Insert: // Do the same work as Append, except Insert it into the // location specified by the MergeIndex RemoveItemFromParentToolStrip(tsi); if (tsi.MergeIndex == -1) { continue; } else if (tsi.MergeIndex >= CountRealToolStripItems(targetToolStrip)) { targetToolStrip.Items.AddNoOwnerOrLayout(tsi); } else { targetToolStrip.Items.InsertNoOwnerOrLayout(AdjustItemMergeIndex(targetToolStrip, tsi), tsi); } tsi.Parent = targetToolStrip; break; case MergeAction.Replace: // Find a target ToolStripItem with the same Text, remove it // and replace it with the source one foreach (ToolStripItem target_tsi in targetToolStrip.Items) { if (tsi.Text == target_tsi.Text) { RemoveItemFromParentToolStrip(tsi); // Insert where the old one is, then remove the old one targetToolStrip.Items.InsertNoOwnerOrLayout(targetToolStrip.Items.IndexOf(target_tsi), tsi); targetToolStrip.Items.RemoveNoOwnerOrLayout(target_tsi); // Store the replaced one so we can get it back in unmerge targetToolStrip.HiddenMergedItems.Add(target_tsi); break; } } break; case MergeAction.Remove: // Find a target ToolStripItem with the same Text, and remove // it from the target, nothing else foreach (ToolStripItem target_tsi in targetToolStrip.Items) { if (tsi.Text == target_tsi.Text) { targetToolStrip.Items.RemoveNoOwnerOrLayout(target_tsi); // Store the removed one so we can get it back in unmerge targetToolStrip.HiddenMergedItems.Add(target_tsi); break; } } break; case MergeAction.MatchOnly: // Ugh, find the target ToolStripItem with the same Text, and take // all the subitems from the source one, and append it to the target one foreach (ToolStripItem target_tsi in targetToolStrip.Items) { if (tsi.Text == target_tsi.Text) { if (target_tsi is ToolStripMenuItem && tsi is ToolStripMenuItem) { ToolStripMenuItem source = (ToolStripMenuItem)tsi; ToolStripMenuItem target = (ToolStripMenuItem)target_tsi; ToolStripManager.Merge(source.DropDown, target.DropDown); } break; } } break; } } sourceToolStrip.ResumeLayout(); targetToolStrip.ResumeLayout(); // Store who we merged with, so we can unmerge when only given the target toolstrip sourceToolStrip.CurrentlyMergedWith = targetToolStrip; targetToolStrip.CurrentlyMergedWith = sourceToolStrip; return(true); }
public void Show(Point position, ToolStripDropDownDirection direction) { this.PerformLayout(); Point show_point = position; Point max_screen = new Point(SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height); if (this is ContextMenuStrip) { // If we are going to go offscreen, adjust our direction so we don't... // X direction switch (direction) { case ToolStripDropDownDirection.AboveLeft: if (show_point.X - this.Width < 0) { direction = ToolStripDropDownDirection.AboveRight; } break; case ToolStripDropDownDirection.BelowLeft: if (show_point.X - this.Width < 0) { direction = ToolStripDropDownDirection.BelowRight; } break; case ToolStripDropDownDirection.Left: if (show_point.X - this.Width < 0) { direction = ToolStripDropDownDirection.Right; } break; case ToolStripDropDownDirection.AboveRight: if (show_point.X + this.Width > max_screen.X) { direction = ToolStripDropDownDirection.AboveLeft; } break; case ToolStripDropDownDirection.BelowRight: case ToolStripDropDownDirection.Default: if (show_point.X + this.Width > max_screen.X) { direction = ToolStripDropDownDirection.BelowLeft; } break; case ToolStripDropDownDirection.Right: if (show_point.X + this.Width > max_screen.X) { direction = ToolStripDropDownDirection.Left; } break; } // Y direction switch (direction) { case ToolStripDropDownDirection.AboveLeft: if (show_point.Y - this.Height < 0) { direction = ToolStripDropDownDirection.BelowLeft; } break; case ToolStripDropDownDirection.AboveRight: if (show_point.Y - this.Height < 0) { direction = ToolStripDropDownDirection.BelowRight; } break; case ToolStripDropDownDirection.BelowLeft: if (show_point.Y + this.Height > max_screen.Y && show_point.Y - this.Height > 0) { direction = ToolStripDropDownDirection.AboveLeft; } break; case ToolStripDropDownDirection.BelowRight: case ToolStripDropDownDirection.Default: if (show_point.Y + this.Height > max_screen.Y && show_point.Y - this.Height > 0) { direction = ToolStripDropDownDirection.AboveRight; } break; case ToolStripDropDownDirection.Left: if (show_point.Y + this.Height > max_screen.Y && show_point.Y - this.Height > 0) { direction = ToolStripDropDownDirection.AboveLeft; } break; case ToolStripDropDownDirection.Right: if (show_point.Y + this.Height > max_screen.Y && show_point.Y - this.Height > 0) { direction = ToolStripDropDownDirection.AboveRight; } break; } } switch (direction) { case ToolStripDropDownDirection.AboveLeft: show_point.Y -= this.Height; show_point.X -= this.Width; break; case ToolStripDropDownDirection.AboveRight: show_point.Y -= this.Height; break; case ToolStripDropDownDirection.BelowLeft: show_point.X -= this.Width; break; case ToolStripDropDownDirection.Left: show_point.X -= this.Width; break; case ToolStripDropDownDirection.Right: break; } // Fix offscreen horizontal positions if ((show_point.X + this.Width) > max_screen.X) { show_point.X = max_screen.X - this.Width; } if (show_point.X < 0) { show_point.X = 0; } // Fix offscreen vertical positions if ((show_point.Y + this.Height) > max_screen.Y) { show_point.Y = max_screen.Y - this.Height; } if (show_point.Y < 0) { show_point.Y = 0; } if (this.Location != show_point) { this.Location = show_point; } CancelEventArgs e = new CancelEventArgs(); this.OnOpening(e); if (e.Cancel) { return; } // The tracker lets us know when the form is clicked or loses focus ToolStripManager.AppClicked += new EventHandler(ToolStripMenuTracker_AppClicked); ToolStripManager.AppFocusChange += new EventHandler(ToolStripMenuTracker_AppFocusChange); base.Show(); ToolStripManager.SetActiveToolStrip(this, ToolStripManager.ActivatedByKeyboard); this.OnOpened(EventArgs.Empty); }
private void ShowInternal(Control control, Point screenPosition, ToolStripDropDownDirection direction) { this.PerformLayout(); Point show_point = CalculateShowPoint(screenPosition, direction, Size); if (this.Location != show_point) { this.Location = show_point; } // Prevents recursion if (Visible) { return; } CancelEventArgs e = new CancelEventArgs(); this.OnOpening(e); if (e.Cancel) { return; } // The tracker lets us know when the form is clicked or loses focus ToolStripManager.AppClicked += new EventHandler(ToolStripMenuTracker_AppClicked); ToolStripManager.AppFocusChange += new EventHandler(ToolStripMenuTracker_AppFocusChange); bool useNativeMenu = true; foreach (var item in this.Items) { useNativeMenu &= item is ToolStripMenuItem || item is ToolStripSeparator; } if (useNativeMenu) { currentMenu = ToNSMenu(); ((MonoMenuDelegate)currentMenu.Delegate).BeforePopup(); show_point = CalculateShowPoint(screenPosition, direction, new Size((int)currentMenu.Size.Width, (int)currentMenu.Size.Height)); PostMouseUp(control, show_point); NSApplication.SharedApplication.BeginInvokeOnMainThread(delegate { if (control != null) { var winPosition = control.PointToClient(show_point); currentMenu.PopUpMenu(null, new CGPoint(winPosition.X, winPosition.Y), control.Handle.ToNSView()); } else { Size displaySize; XplatUI.GetDisplaySize(out displaySize); currentMenu.PopUpMenu(null, new CGPoint(show_point.X, displaySize.Height - show_point.Y), null); } }); } base.Show(); ToolStripManager.SetActiveToolStrip(this, ToolStripManager.ActivatedByKeyboard); // Called from NSMenuDelegate for native menus if (!useNativeMenu) { this.OnOpened(EventArgs.Empty); } }