将 UnregisterHotkey 从用户控件解析到父窗体

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

问题描述

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

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.

用户控件(命名为 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
            }
        }
    }

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

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);

现在我的问题是:您如何将上述内容从用户控件解析到我的主窗体上的 formclosure 事件,以便在有意义的情况下成功清除所有键...

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

推荐答案

我建议这样处理:

由于您已经覆盖 WndProc 来处理 WM_HOTKEY,因此还要处理 WM_DESTROY.当 UserControl Windows 即将被销毁时发送此消息,因为它的父窗体正在关闭.
当您的 UserControl 收到此消息时,您可以调用 UnregisterHotKey().

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.

UserControls 不需要知道关于它的 ParentForm 容器的任何信息:HotKey 在创建 UserControl 时注册,而在销毁时取消注册.

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.

这比处理 Dispose() 要好,因为除非父窗体显式调用 Dispose(),否则在应用程序关闭之前可能不会真正释放 UserControl.

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 从用户控件解析到父窗体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)