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);
        }
Beispiel #4
0
        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();
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #9
0
        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();
            }
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        // 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);
            }
        }
Beispiel #14
0
        // 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);
        }
Beispiel #15
0
        // 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);
        }
Beispiel #16
0
        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);
        }
Beispiel #18
0
        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);
            }
        }