从用户控件解析UnregisterHotkey到父窗体 [英] Parsing UnregisterHotkey from usercontrol to parent form

查看:53
本文介绍了从用户控件解析UnregisterHotkey到父窗体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我试图在有人按下热键时也从表单(在本例中为SHIFT + A)之外获取用户输入.现在,由于我想将标签添加到表单应用程序中,所以我决定使用usercontrols,现在的问题是,我无法访问usercontrol上的formcloses事件(来自form1),这意味着我必须以某种方式解析我想要的任何内容在封闭事件中执行.

用户控件(命名为首页)

 公共局部类Home:UserControl{[System.Runtime.InteropServices.DllImport("user32.dll")]私有静态外部布尔RegisterHotKey(IntPtr hWnd,int id,int fsModifiers,int vk);[System.Runtime.InteropServices.DllImport("user32.dll")]私有静态外部布尔UnregisterHotKey(IntPtr hWnd,int id);枚举KeyModifier{无= 0,Alt = 1控制= 2Shift = 4WinKey = 8}公共房屋{InitializeComponent();int id = 0;//热键的ID.RegisterHotKey(this.Handle,id,(int)KeyModifier.Shift,Keys.A.GetHashCode());//将Shift + A注册为全局热键.}受保护的覆盖无效WndProc(参考消息m){base.WndProc(ref m);如果(m.Msg == 0x0312){/*请注意,如果您只想注册一个热键,则不需要以下三行.*如果要注册多个键,可以使用下面的几行,您可以使用带有id作为参数的开关,或者想知道由于某些特定原因按下了哪个键/修饰符.*/键key =(Keys)((((int)m.LParam>> 16)& 0xFFFF);//所按下的热键的键.KeyModifier修饰符=(KeyModifier)((int)m.LParam& 0xFFFF);//所按下的热键的修改键.int id = m.WParam.ToInt32();//所按下的热键的ID.MessageBox.Show(热键已被按下!");//做一点事}}} 

现在,我希望解析unregisterHotKey方法,以在程序关闭后清除所有热键(这样,当应用程序关闭时,您将无法按SHIFT-A键)

  UnregisterHotKey(this.Handle,0); 

现在我的问题是:您怎么将用户控件中的内容解析为我的主窗体上的formclosing事件,以便在有意义的情况下成功清除所有键...

解决方案

这是我建议的处理方式:

因为您已经覆盖了 WndProc 以处理 WM_HOTKEY ,所以还可以处理

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...

解决方案

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
{ 
    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;
        }
    }

    [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
    }
}

这篇关于从用户控件解析UnregisterHotkey到父窗体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆