Хук клавиатуры - C#
Формулировка задачи:
вот хороший клавиатурный хук, который я использую для отлова клавиши PrtSc(код ниже).
При нажатии данной клавиши, как вы, наверное, догадались, я делаю скриншот экрана и далее обрабатываю его.
Только вот одно "но":
Все работает на отлично, но в некоторых играх(например dota 2) каким-то волшебным образом получается скриншот рабочего стола. Может быть данная тема уже обсуждалась, но помогите незнайке)
И еще одна менее значимая проблемка, которую я уже затрагивал на этом форме, но вразумительного ответа не последовало:
моя прога свернута в трее и я вместо клавиши PrtSc могу назначить другу в настройках. Но как сделать, чтобы нажатие клавиши передавалось только в мою программу, но не передавалось системе. Т.е. если я назначаю клавишу, а потом нажимаю на нее, то моя прога срабатывает на отлично, только вот эта клавиша срабатывает и в системе.
от NickoTin:
Этот↑
вопрос продолжайте в старой теме.using System; using System.ComponentModel; using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows.Forms; namespace Hooks { public static class KBDHook { #region Declarations public delegate void HookKeyPress ( LLKHEventArgs e ); public static event HookKeyPress KeyUp; public static event HookKeyPress KeyDown; [StructLayout(LayoutKind.Sequential)] struct KBDLLHOOKSTRUCT { public uint vkCode; public uint scanCode; public KBDLLHOOKSTRUCTFlags flags; public uint time; public IntPtr dwExtraInfo; } [Flags] enum KBDLLHOOKSTRUCTFlags : int { LLKHF_EXTENDED = 0x01, LLKHF_INJECTED = 0x10, LLKHF_ALTDOWN = 0x20, LLKHF_UP = 0x80, } static IntPtr hHook = IntPtr.Zero; static IntPtr hModule = IntPtr.Zero; static bool hookInstall = false; static bool localHook = true; static API.HookProc hookDel; #endregion /// <summary> /// Hook install method. /// </summary> public static void InstallHook() { if (IsHookInstalled) return; hModule = Marshal.GetHINSTANCE(AppDomain.CurrentDomain.GetAssemblies()[0].GetModules()[0]); hookDel = new API.HookProc(HookProcFunction); if (localHook) hHook = API.SetWindowsHookEx(API.HookType.WH_KEYBOARD, hookDel, IntPtr.Zero, AppDomain.GetCurrentThreadId()); else hHook = API.SetWindowsHookEx(API.HookType.WH_KEYBOARD_LL, hookDel, hModule, 0); if (hHook != IntPtr.Zero) hookInstall = true; else throw new Win32Exception("Can't install low level keyboard hook!"); } /// <summary> /// If hook installed return true, either false. /// </summary> public static bool IsHookInstalled { get { return hookInstall && hHook != IntPtr.Zero; } } /// <summary> /// Module handle in which hook was installed. /// </summary> public static IntPtr ModuleHandle { get { return hModule; } } /// <summary> /// If true local hook will installed, either global. /// </summary> public static bool LocalHook { get { return localHook; } set { if (value != localHook) { if (IsHookInstalled) throw new Win32Exception("Can't change type of hook than it install!"); localHook = value; } } } /// <summary> /// Uninstall hook method. /// </summary> public static void UnInstallHook() { if (IsHookInstalled) { if (!API.UnhookWindowsHookEx(hHook)) throw new Win32Exception("Can't uninstall low level keyboard hook!"); hHook = IntPtr.Zero; hModule = IntPtr.Zero; hookInstall = false; } } /// <summary> /// Hook process messages. /// </summary> /// <param name="nCode"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns></returns> static IntPtr HookProcFunction ( int nCode, IntPtr wParam, [In] IntPtr lParam ) { if (nCode == 0) { LLKHEventArgs args = null; if (localHook) { bool pressed = false; if (lParam.ToInt32() >> 31 == 0) pressed = true; Keys keys = (Keys)wParam.ToInt32(); args = new LLKHEventArgs(keys, pressed, 0U, 0U); if (pressed) { if (KeyUp != null) KeyUp(args); } else { if (KeyDown != null) KeyDown(args); } } else { KBDLLHOOKSTRUCT kbd = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT)); bool pressed = false; if (wParam.ToInt32() == 0x100 || wParam.ToInt32() == 0x104) pressed = true; Keys keys = (Keys)kbd.vkCode; args = new LLKHEventArgs(keys, pressed, kbd.time, kbd.scanCode); if (pressed) { if (KeyUp != null) KeyUp(args); } else { if (KeyDown != null) KeyDown(args); } } if (args != null && args.Hooked) return (IntPtr)1; } return API.CallNextHookEx(hHook, nCode, wParam, lParam); } } public class LLKHEventArgs { Keys keys; bool pressed; uint time; uint scCode; public LLKHEventArgs(Keys keys, bool pressed, uint time, uint scanCode) { this.keys = keys; this.pressed = pressed; this.time = time; this.scCode = scanCode; } /// <summary> /// Key. /// </summary> public Keys Keys { get { return keys; } } /// <summary> /// Is key pressed or no. /// </summary> public bool IsPressed { get { return pressed; } } /// <summary> /// The time stamp for this message, equivalent to what GetMessageTime would return for this message. /// </summary> public uint Time { get { return time; } } /// <summary> /// A hardware scan code for the key. /// </summary> public uint ScanCode { get { return scCode; } } /// <summary> /// Is user hook key. /// </summary> public bool Hooked { get; set; } } static class API { public delegate IntPtr HookProc(int nCode, IntPtr wParam, [In] IntPtr lParam); [DllImport("user32.dll")] public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, [In] IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr SetWindowsHookEx(HookType hookType, HookProc lpfn, IntPtr hMod, int dwThreadId); [DllImport("user32.dll", SetLastError = true)] public static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr GetModuleHandle(string lpModuleName); public enum HookType : int { WH_JOURNALRECORD = 0, WH_JOURNALPLAYBACK = 1, WH_KEYBOARD = 2, WH_GETMESSAGE = 3, WH_CALLWNDPROC = 4, WH_CBT = 5, WH_SYSMSGFILTER = 6, WH_MOUSE = 7, WH_HARDWARE = 8, WH_DEBUG = 9, WH_SHELL = 10, WH_FOREGROUNDIDLE = 11, WH_CALLWNDPROCRET = 12, WH_KEYBOARD_LL = 13, WH_MOUSE_LL = 14 } } }
Решение задачи: «Хук клавиатуры»
textual
Листинг программы
[DllImport("gdi32.dll")] static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, CopyPixelOperation rop); [DllImport("user32.dll")] static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc); [DllImport("gdi32.dll")] static extern IntPtr DeleteDC(IntPtr hDc); [DllImport("gdi32.dll")] static extern IntPtr DeleteObject(IntPtr hDc); [DllImport("gdi32.dll")] static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); [DllImport("gdi32.dll")] static extern IntPtr CreateCompatibleDC(IntPtr hdc); [DllImport("gdi32.dll")] static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp); [DllImport("user32.dll")] public static extern IntPtr GetDesktopWindow(); [DllImport("user32.dll")] public static extern IntPtr GetWindowDC(IntPtr ptr); private Bitmap GetScreen() { var sz = Screen.PrimaryScreen.Bounds.Size; var hDesk = GetDesktopWindow(); var hSrce = GetWindowDC(hDesk); var hDest = CreateCompatibleDC(hSrce); var hBmp = CreateCompatibleBitmap(hSrce, sz.Width, sz.Height); var hOldBmp = SelectObject(hDest, hBmp); BitBlt(hDest, 0, 0, sz.Width, sz.Height, hSrce, 0, 0, rop: CopyPixelOperation.CaptureBlt | CopyPixelOperation.SourceCopy); var bmp = Image.FromHbitmap(hBmp); SelectObject(hDest, hOldBmp); DeleteObject(hBmp); DeleteDC(hDest); ReleaseDC(hDesk, hSrce); return bmp; }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д