【问题标题】:C# global keys and SetForegroundWindowC# 全局键和 SetForegroundWindow
【发布时间】:2011-06-10 20:25:49
【问题描述】:

我正在使用 C# 应用程序来侦听全局键组合 (ctrl+F9),这会将特定窗口置于前面。

这是我用来将窗口置于前面的代码,它仅在由 Button 事件触发时才有效:

    private void button3_Click(object sender, EventArgs e)
    {
        SetForegroundWindow(ptrActiveWindow.ToInt32());
        ShowWindowAsync(ptrActiveWindow, SW_RESTORE);
    }

对于挂钩,我使用了一个取自 http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx 的类,此处完整列出:

http://code.google.com/p/code-commenter/source/browse/trunk/key+preview/globalKeyboardHook.cs?spec=svn3&r=3

每当我在 CTRL KeyDown 之后和 CTRL KeyUp 之前(仍然按下 CTRL)有一个 F9 KeyUp 事件,我都会调用我的方法:

    private void restore(IntPtr hWnd)
    {

      IntPtr ptrCurrentActiveWindow = GetForegroundWindow(); //comment line
      ShowWindowAsync(ptrCurrentActiveWindow, SW_MINIMIZE); //comment line

        ShowWindowAsync(hWnd, SW_RESTORE);
        SetFocus(hWnd);
        SetForegroundWindow(hWnd.ToInt32());

    }

这没有任何作用。我的窗口在后台被激活(我可以看到它在任务栏中闪烁),但没有恢复。

我可以解决这个问题的唯一方法是使用注释代码:最小化当前活动的窗口,然后恢复我想看到的窗口。

感谢所有帮助, 谢谢。

全局热键,工作版本:

    private void Form1_Load(object sender, EventArgs e)
    {
        string atomName = Thread.CurrentThread.ManagedThreadId.ToString("X8") + this.GetType().FullName;
        short HotkeyID = GlobalAddAtom(atomName);
        if (!RegisterHotKey(this.Handle, HotkeyID, (uint)GlobalHotkeys.MOD_CONTROL, (uint)Keys.D5))
            listBox.Items.Add("failed: " + "unable to register hotkey. Error: " + Marshal.GetLastWin32Error().ToString());
        else
            listBox.Items.Add("succeeded adding hotkey id"+(uint)Keys.D5);
    }

    protected override void WndProc(ref Message m)
    {
        const int WM_HOTKEY = 0x0312;

        if (m.Msg == WM_HOTKEY)
        {
            if ((short)m.WParam==HotkeyID)
                listBox.Items.Add("Hotkey."+ (short)m.WParam);
        }
        base.WndProc(ref m);
    }

【问题讨论】:

    标签: c#


    【解决方案1】:

    您的问题是您没有注册全局热键,而是使用了键盘挂钩。键盘挂钩并非设计为用作全局热键。

    请改用RegisterHotKey 函数。
    检查这个例子:http://www.pinvoke.net/default.aspx/user32.registerhotkey

    您的直接问题是应用程序无法随时将自己置于前台。因为这对用户来说很烦人。它只能在特定事件期间这样做。就像应用程序启动或处理真正的全局热键时一样。

    系统限制哪些进程可以设置前台窗口。只有满足以下条件之一,进程才能设置前台窗口:

    • 进程是前台进程。
    • 进程由前台进程启动。
    • 进程收到最后一个输入事件。
    • 没有前台进程。
    • 正在调试前台进程。
    • 前景未锁定(请参阅 LockSetForegroundWindow)。
    • 前台锁定超时已过期(请参阅 SystemParametersInfo 中的 SPI_GETFOREGROUNDLOCKTIMEOUT)。
    • 没有处于活动状态的菜单。

    【讨论】:

    • 包装类有点破旧,但仍然有用。谢谢!
    • hmm 查看已损坏的代码。不要使用 GetHashCode 作为您的唯一 ID。
    【解决方案2】:

    尝试使用另一个 SW_ 常量,例如 SW_SHOW。 SW_RESTORE 仅适用于使用 SW_MINIMIZE 最小化的窗口

    【讨论】:

    • 我已经使用了几乎所有的常量。此外,如果它在从按钮事件调用时工作,它应该在任何地方工作。我的猜测是问题在于热键的使用。
    猜你喜欢
    • 1970-01-01
    • 2012-06-22
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    • 2016-06-04
    • 2015-05-29
    相关资源
    最近更新 更多