English 中文(简体)
Try to implement global keyboard shortcut in MDI parent/child form and other form by using ProcessCmdKey
原标题:

I override ProcessCmdKey() in my MDI parent form class and have some keyboard shortcut calling method in same class. But I wish to make these hotkeys working in parent/child form and other form. The case now is when focus on the other form(regular form, not MDI), ProcessCmdKey() doesn t capture keyboard anymore. Which class should I put ProcessCmdKey() in and anything to make it work? Thanks!

namespace myNamespace
{
    public class MDIParent : System.Windows.Forms.Form
    {

        public bool NextTab(){...}
        public bool PreviousTab(){...}

        protected override bool ProcessCmdKey(ref Message message, Keys keys)
        {
            switch (keys)
            {
                case Keys.Control | Keys.Tab:
                    NextTab();
                    return true;

                case Keys.Control | Keys.Shift | Keys.Tab:
                    PreviousTab();
                    return true;
            }
            return base.ProcessCmdKey(ref message, keys);
        }
    }

    public class mySecondForm : System.Windows.Forms.Form
    {
        ...
    }
}
最佳回答

You can define a "base" Form with your ProcessCmdKey handler implemented, and then make all your other Forms : the MDI Parent, the Child Windows of the MDI Parent, and any "Independent" Forms you create (i.e., not children of the MDI Form) inherit from the "base Form." Just make sure the IsMdiContainer property is set on the form you wish to be MDI, and the child windows you add to the MDI Form are not TopLevel and have their parent set to the MDI Form.

The question is, then, where do you want to handle the events triggered by the key combinations you ve enabled because ... if you define methods to be triggered by the trapped key combinations in the base Form ... each Form that inherits from the base Form is going to execute them in their own context.

If you want to handle the trapped key-combinations on an application wide basis, then implement a static public class with the key-combination handlers defined as static methods there. Or, since you may want to know from which form the special key-combinations issued just pass a pointer to calling Form to the static handler.

So, your handler for the control + Tab in the ProcessCmdKey override in the base Form might look like this :

    // in ProcessCmdKey override in base Form
    case Keys.Control | Keys.Tab:
        KeyHandler.NextTabHandler(this);
        return true;

Your static class might look something like this :

public static class KeyHandler
{
    public static void NextTabHandler(Form theCallingForm)
    {
        Console.WriteLine("called from : " + theCallingForm.Text + " : ActiveControl : " + theCallingForm.ActiveControl.Name);

        if (theCallingForm is MDIForm)
        {
            // handle Next Tab on MDIForm control
        }
        else if (theCallingForm is childForm)
        {
            // handle Next Tab on ChildForm control
        }
        else
        {
            if(theCallingForm is independentForm)
            {
                // handle Next Tab on "independent Form" control
            }
        }
    }
}

As you can see in the code above, you can use the ActiveControl property of the calling Form to know which control on a given type of Form got the key-combination.

Of course, if you don t want to handle the key-combinations "globally," like this, just insert your ProcessCmdKey over-rides as needed in the other Forms, and don t have them inherit from the base Form.

Handling the key events "application wide" may, or may not be the best strategy for your particular solution, but it is a viable strategy. best,

问题回答

暂无回答




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签