将UnregisterHotkey从用户控件解析为父表单

问题描述 投票:0回答:2

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

用户控件(命名为首页)

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键]

UnregisterHotKey(this.Handle, 0);

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

c# winforms parsing user-controls windows-forms-designer
2个回答
0
投票

我找到了一个解决方案(部分起作用)。

我只是添加了一个将取消注册密钥并从formclosing事件内部的主表单中调用密钥的公共void

在IDE中,有时无法正常工作。但是,在构建解决方案时,它似乎可以正常工作


0
投票

这是我建议的处理方式:

因为您已经覆盖了WndProc以处理WM_HOTKEY,所以也要处理WM_DESTROY。当UserControl Windows由于其父窗体已关闭而将被销毁时,将发送此消息。当您的UserControl收到此消息时,您可以调用UnregisterHotKey()

UserControls不需要了解有关其ParentForm容器的任何信息:热键在创建UserControl时注册,而在销毁UserControl时取消注册。

比处理Dispose()更好,因为除非应用程序关闭,除非父窗体明确调用Dispose(),否则可能不会真正处理UserControl。

我已经对原始代码进行了一些修改,因为它缺少了几段。

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:
                        // Handle single HotKey
                        if (modifier == KeyModifier.Shift) {
                            MessageBox.Show("Hotkey has been pressed!");
                        }
                        break;
                }
                m.Result = IntPtr.Zero;
                break;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.