Parsing UnregisterHotkey from usercontrol to parent form

家住魔仙堡 提交于 2021-02-17 06:33:31

问题


So I'm attempting to get the userinputs when someone presses hotkeys, also outside the form (in this case SHIFT+A). Now since I wanted to add tabs to my forms application I decided to go with usercontrols, now the problem is, that I am unable to access the formclosing event (from form1) on the usercontrol, meaning I would have to somehow parse whatever I wanted to execute in the formclosing event.

Usercontrol (named home)

public partial class Home : UserControl
    { 
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        enum KeyModifier
        {
            None = 0,
            Alt = 1,
            Control = 2,
            Shift = 4,
            WinKey = 8
        }

        public Home()
        {
            InitializeComponent();

            int id = 0;     // The id of the hotkey. 
            RegisterHotKey(this.Handle, id, (int)KeyModifier.Shift, Keys.A.GetHashCode());       //Register Shift + A as global hotkey. 
        }

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);

            if (m.Msg == 0x0312)
            {
                /* Note that the three lines below are not needed if you only want to register one hotkey.
                 * The below lines are useful in case you want to register multiple keys, which you can use a switch with the id as argument, or if you want to know which key/modifier was pressed for some particular reason. */

                Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);                  // The key of the hotkey that was pressed.
                KeyModifier modifier = (KeyModifier)((int)m.LParam & 0xFFFF);       // The modifier of the hotkey that was pressed.
                int id = m.WParam.ToInt32();                                        // The id of the hotkey that was pressed.


                MessageBox.Show("Hotkey has been pressed!");
                // do something
            }
        }
    }

Now I wish to parse the unregisterHotKey method to clear all hotkeys after the program has been closed (this way you will be unable to press SHIFT-A when the app is closed)

UnregisterHotKey(this.Handle, 0);

Now my question is: How come you parse the above from the usercontrol to the formclosing event on my main form, so that all keys will be succesfully cleared if that makes sense...


回答1:


I found a solution (that works partially).

I simply added a public void that would unregister the keys and called that from the mainform inside the formclosing event

In the IDE, it sometimes wont work. But when building the solution it seems to be working flawlessly




回答2:


This is how I suggest to handle it:

since you're already overriding WndProc to handle WM_HOTKEY, also handle WM_DESTROY. This message is sent when the UserControl Windows is about to be destroyed because its Parent Form is being closed.
You can call UnregisterHotKey() when your UserControl receives this message.

The UserControls doesn't need to know anything about its ParentForm container: the HotKey is registered when the UserControl is created and unregistered when it's detroyed.

It's better than handling Dispose(), since a UserControl may not be actually disposed of until the application closes, unless the Parent Form explicitly calls Dispose().

I've made a couple of modifications to the original code, since it was missing a few pieces.

public partial class Home : UserControl
{ 
    [DllImport("user32.dll")]
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifier fsModifiers, int vk);

    [DllImport("user32.dll")]
    private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

    private const int WM_DESTROY = 0x0002;
    private const int WM_HOTKEY = 0x0312;
    private const int baseHotKeyID = 0x100;

    enum KeyModifier : int
    {
        None = 0,
        Alt = 1,
        Control = 2,
        Shift = 4,
        WinKey = 8,
        NoRepeat = 0x4000
    }

    public Home() => InitializeComponent();

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        if (!RegisterHotKey(this.Handle, baseHotKeyID, KeyModifier.Shift | KeyModifier.NoRepeat, (int)Keys.F11)) {
            MessageBox.Show("RegisterHotKey Failed");
        }
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        switch (m.Msg) {

            case WM_DESTROY:
                UnregisterHotKey(this.Handle, baseHotKeyID);
                m.Result = IntPtr.Zero;
                break;

            case WM_HOTKEY:
                int hotKeyID = m.WParam.ToInt32();
                var keyPressed = (Keys)(m.LParam.ToInt32() >> 16);
                var modifier = (KeyModifier)(m.LParam.ToInt32() & 0xFF);
                switch (hotKeyID) {
                    case baseHotKeyID:  // Identifier of the SHIFT+F11 HotKey just registered
                        // Handle single HotKey
                        if (modifier == KeyModifier.Shift) {
                            MessageBox.Show("Hotkey SHIFT+F11 has been pressed!");
                        }
                        break;
                    //case baseHotKeyID + 1:
                    // Handle another HotKey
                    //    break;

                }
                m.Result = IntPtr.Zero;
                break;
        }
    }
}


来源:https://stackoverflow.com/questions/61144651/parsing-unregisterhotkey-from-usercontrol-to-parent-form

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!