繁体   English   中英

C# 全局热键在首先最小化到托盘时不起作用,但在显示并再次最小化后它起作用

[英]C# Global hotkeys won't work in first minimize to tray but after showing and minimize again it works

对不起,如果我像傻瓜一样错过了什么,但我必须发送这个项目,我有一个问题

我已经在创建的句柄上注册了全局热键(编辑!!)

    protected override void OnHandleCreated(EventArgs e) 
    {
    base.OnHandleCreated(e);
        RegisterHotKey(this.Handle, 1, 0x0000,0x70);
        RegisterHotKey(this.Handle, 2, 0x0000,0x71);
        RegisterHotKey(this.Handle, 3, 0x0000,0x72);
        RegisterHotKey(this.Handle, 4, 0x0000,0x73);
        RegisterHotKey(this.Handle, 5, 0x0000,0x74);
        RegisterHotKey(this.Handle, 6, 0x0000,0x75);
        RegisterHotKey(this.Handle, 7, 0x0000,0x76);
        RegisterHotKey(this.Handle, 8, 0x0000,0x77);
        RegisterHotKey(this.Handle, 9, 0x0000,0x78);
        RegisterHotKey(this.Handle, 10, 0x0000,0x79);
        RegisterHotKey(this.Handle, 11, 0x0000,0x7A);
        RegisterHotKey(this.Handle, 12, 0x0000,0x7B);
        RegisterHotKey(this.Handle, 13, 0x0002,0x45);
    }

我的 button1 确实隐藏了表单并使托盘图标可见

    void Button1Click(object sender, EventArgs e)
    {
        trayicon.Visible=true;

        ShowInTaskbar=false;
        this.Hide();




        trayicon.ShowBalloonTip(2000,"Corrector is now minimized","Right click at check symbol to Exit or show and change hotkey",ToolTipIcon.Info);
    }

我也有双击托盘图标后显示表单的功能

    private void trayicon_DoubleClick(object Sender, EventArgs e) 
    {
        this.Show();
        Visible=true;
        ShowInTaskbar=true;
    }

现在问题来了,我设置全局热键13退出程序。

1.我打开程序,按Ctrl+E(热键)>>>它确实退出了程序

2.我打开程序按按钮1然后Ctrl+E>>>它不退出程序

3.我打开程序,按下按钮1并双击图标,表格显示然后Ctrl+E>>>>它确实退出了程序

4.我打开程序,按下按钮1并双击图标,表格显示然后再次按下按钮1表格消失然后Ctrl + E>>>它确实退出了程序。

这就是为什么我很困惑,2 和 4 应该有相同的结果,但是在 4 上它确实有效,而在 2 上它不起作用

有人请帮助我

谢谢

编辑:!!

我的 Wndproc

     protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x0312)
        {
            int id = m.WParam.ToInt32();
            if(id==14)
            {
                Application.Exit();
            }
            if(id==13)
            {
                Application.Exit();
            }
            if(check2==0)
            {
                this.TopMost=true;
                MessageBox.Show("กรุณาเลือกปุ่มที่จะใช้เเก้ก่อน,Select hotkey first","ข้อผิดพลาด",MessageBoxButtons.OK,MessageBoxIcon.Error);
                this.TopMost=false;
            }

            if(id==check2)
            {
            translate();//You can replace this statement with your desired response to the Hotkey.
            }

        }
        base.WndProc(ref m);
    }

很确定您的问题与ShowInTaskbar属性的不断切换有关。 据我所知,这样做会破坏并重新创建您的窗口,这意味着您注册热键的句柄现在指向错误的内容。

就您现在的代码而言,只有在首次创建表单时才会分配热键,因为调用Hide()不会处理窗口(记录, Visible调用是多余的;Show()/Hide() 是相当于将Visible切换为真/假)。

据我所知,有两种方法可以解决这个问题。 ShowInTaskbar属性上切换后分配热键,或者覆盖表单的OnHandleCreated方法并在那里进行分配。

我不知道为什么你的第 3 步和第 4 步按照他们的方式工作; 我认为他们都不应该退出该程序。 这是否可靠地发生? 也许更聪明的人可以冒险猜测它为什么起作用。 手柄是否有可能被回收?

我进一步调查了这个问题(遇到了同样的问题),发现在您将应用程序发送到托盘后窗口句柄立即被销毁,然后当我被发送到托盘时立即重新创建窗口句柄:

  1. OnHandleDestroyed(EventArgs e)调用
  2. 之后调用OnHandleCreated(EventArgs e)

只需在 OnHandleCreated 回调中重新注册您的热键,然后每当您将应用程序发送到托盘时,您的热键就会起作用。

PS:当您最小化到任务栏时,您的热键将始终有效。

问候

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM