3

アプリケーションが常にデスクトップ レベルで表示されるようにしようとしています。これは、アプリが LWin+D や RWin+D などのキー シーケンスを無視する必要があることを意味します。私はそれをこのように動作させようとしました:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (prefixSeen)
    {
        if (keyData == Keys.D)
        {
            MessageBox.Show("Got it!");
        }
        prefixSeen = false;
        return true;
    }
    if (keyData == Keys.LWin)
    {
        prefixSeen = true;
        return true;
    }
    return base.ProcessCmdKey(ref msg, keyData);
}

ただし、D ボタンなしで、RWin/LWin ボタンのみをキャッチします。

また、独自のメッセージ フィルタを作成しようとしましたが、うまくいきませんでした。これらすべてのメッセージと Bitwise:

    public class KeystrokMessageFilter : System.Windows.Forms.IMessageFilter
    {
        public KeystrokMessageFilter() { }

        public bool PreFilterMessage(ref Message m)
        {
            if ((m.Msg == 256 /*0x0100*/))
            {
                switch (((int)m.WParam) | ((int)Control.ModifierKeys))
                {
                    case (int)(Keys.Control | Keys.Alt | Keys.K):
                        MessageBox.Show("You pressed ctrl + alt + k");
                        break;
                    case (int)(Keys.Control | Keys.C): MessageBox.Show("ctrl+c");
                        break;
                    case (int)(Keys.Control | Keys.V): MessageBox.Show("ctrl+v");
                        break;
                    case (int)Keys.Up: MessageBox.Show("You pressed up");
                        break;
                }
            }
            return false;
        }
}

Application.AddMessageFilter(keyStrokeMessageFilter);

では、アプリケーションで R/LWin+D をキャッチ/無視するにはどうすればよいでしょうか?

4

3 に答える 3

2

このコードは、低レベルのキーボード フックを登録Dし、Windows キーが押されている間、キーの押下をリッスンします。これが検出された場合、フックは単にキー押下を無視します。それ以外の場合は、キープレスを転送します。

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace KbHook
{
    public static class Program
    {
        const int HC_ACTION = 0;
        const int WH_KEYBOARD_LL = 13;
        const int WM_KEYDOWN = 0x0100;
        static IntPtr HookHandle = IntPtr.Zero;
        static Form1 Form1;

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr SetWindowsHookEx(int idHook, KbHook lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr GetModuleHandle(string lpModuleName);

        [STAThread]
        static void Main()
        {
            try
            {
                using (var proc = Process.GetCurrentProcess())
                    using (var curModule = proc.MainModule)
                    {
                        var moduleHandle = GetModuleHandle(curModule.ModuleName);
                        HookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, IgnoreWin_D, moduleHandle, 0);
                    }

                Form1 = new Form1();
                Application.Run(Form1);
            }
            finally
            {
                UnhookWindowsHookEx(HookHandle);
            }
        }

        [DllImport("user32.dll")]
        static extern short GetAsyncKeyState(Keys vKey);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        static IntPtr IgnoreWin_D(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode == HC_ACTION
                && IsWin_D(wParam, lParam))
                return (IntPtr) 1; //just ignore the key press

            return CallNextHookEx(HookHandle, nCode, wParam, lParam);
        }

        static bool IsWin_D(IntPtr wParam, IntPtr lParam)
        {
            if ((int) wParam != WM_KEYDOWN)
                return false;

            var keyInfo = (KbHookParam) Marshal.PtrToStructure(lParam, typeof (KbHookParam));
            if (keyInfo.VkCode != (int) Keys.D) return false;
            return GetAsyncKeyState(Keys.LWin) < 0
                   || GetAsyncKeyState(Keys.RWin) < 0;
        }

        delegate IntPtr KbHook(int nCode, IntPtr wParam, [In] IntPtr lParam);

        [StructLayout(LayoutKind.Sequential)]
        struct KbHookParam
        {
            public readonly int VkCode;
            public readonly int ScanCode;
            public readonly int Flags;
            public readonly int Time;
            public readonly IntPtr Extra;
        }
    }
}

LowLevelKeyboardHook を使用して Win + Tab をフックする方法も参照してください。

于 2015-08-03T13:40:14.277 に答える