WPF는 키보드 갈고리를 이용해 키보드를 포획하고 알려지지 않은 일을 하는데...전체 인스턴스
이 말을 보고 사실 키보드 갈고리는 많은 일을 할 수 있다고 생각했지.
장면
당신의 프로그램이 전체적인 단축키를 필요로 할 때 키보드 갈고리를 사용할 수 있습니다. 예를 들어 사람들이 qq의 캡처 단축키를 자주 사용한다면 WPF에서 어떻게 실현합니까?
물론 윈도 창에 Key Down, Key Up을 직접 등록하는 것은 아니다. 이렇게 하면 프로그램이 초점인 상황에서만 터치할 수 있다.
우리가 여기서 해야 할 일은 더욱 강력하다. 즉, 비초점에서 키보드를 얻은 사건이다.
이루어지다
일단 저희가 이렇게 WinAPI가 많이 필요해요.
//
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
//
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
//
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
대략적인 논리는 다음과 같다.
키보드 갈고리를 설치한 후 의뢰를 통해 얻은 키보드 메시지를 처리합니다
두 가지 클래스로 정리(winapi[Win32Api.cs] 클래스와 키보드 갈고리[KeyboardHook.cs] 클래스)는 다음과 같다.
public class Win32Api
{
public const int WM_KEYDOWN = 0x100;
public const int WM_KEYUP = 0x101;
public const int WM_SYSKEYDOWN = 0x104;
public const int WM_SYSKEYUP = 0x105;
public const int WH_KEYBOARD_LL = 13;
[StructLayout(LayoutKind.Sequential)] //
public class KeyboardHookStruct
{
public int vkCode; // 1 254
public int scanCode; //
public int flags;
public int time;
public int dwExtraInfo;
}
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
//
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
//
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
//
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
}
public class KeyboardHook
{
int hHook;
Win32Api.HookProc KeyboardHookDelegate;
/// <summary>
///
/// </summary>
public void SetHook()
{
KeyboardHookDelegate = new Win32Api.HookProc(KeyboardHookProc);
ProcessModule cModule = Process.GetCurrentProcess().MainModule;
var mh = Win32Api.GetModuleHandle(cModule.ModuleName);
hHook = Win32Api.SetWindowsHookEx(Win32Api.WH_KEYBOARD_LL, KeyboardHookDelegate, mh, 0);
}
/// <summary>
///
/// </summary>
public void UnHook()
{
Win32Api.UnhookWindowsHookEx(hHook);
}
/// <summary>
///
/// </summary>
/// <param name="nCode"></param>
/// <param name="wParam"></param>
/// <param name="lParam"></param>
/// <returns></returns>
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
// (nCode<0
if (nCode >= 0)
{
Win32Api.KeyboardHookStruct KeyDataFromHook = (Win32Api.KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(Win32Api.KeyboardHookStruct));
int keyData = KeyDataFromHook.vkCode;
//WM_KEYDOWN WM_SYSKEYDOWN , OnKeyDownEvent
if (OnKeyDownEvent != null && (wParam == Win32Api.WM_KEYDOWN || wParam == Win32Api.WM_SYSKEYDOWN))
{
//
// keyData ,
}
//WM_KEYUP WM_SYSKEYUP , OnKeyUpEvent
if (OnKeyUpEvent != null && (wParam == Win32Api.WM_KEYUP || wParam == Win32Api.WM_SYSKEYUP))
{
//
}
}
return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam);
}
}
당시에 가상 코드를 가져왔을 때 사실 나는 거절했다. 왜냐하면 다음에 나는 이 가상 코드에 대해 어떤 처리를 해야 할지 몰랐기 때문이다. 설마 하나하나 전환해야만 WPF에서 누르는 키가 무엇인지 진일보 판단할 수 있겠는가?
마지막으로 블로그
namespace System.Windows.Input
{
// :
// Win32 WPFSystem.Windows.Input.Key 。
public static class KeyInterop
{
// :
// Win32 WPFSystem.Windows.Input.Key。
//
// :
// virtualKey:
// 。
//
// :
// WPF 。
public static Key KeyFromVirtualKey(int virtualKey);
//
// :
// WPFSystem.Windows.Input.Key Win32 。
//
// :
// key:
// WPF。
//
// :
// Win32 。
public static int VirtualKeyFromKey(Key key);
}
}
결실
그래서 저희가 기우의 키보드 조작 기록을 즐겁게 받았어요.
KeyInterop.KeyFromVirtualKey(KeyData)
노노야, 난 그냥 피아노 건반을 만들었어.
코드가 이미 붙었으니, 기우에게 별도로 데모를 제공하지 않는 것을 용서하십시오
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.