键盘钩子 用来截屏

时间:2022-02-08 00:35:04

。点击开始按钮 。a窗体隐藏,b窗体显示 scsysrq截图 。需要在桌面创建bc文件夹。

总的思路就是用钩子获取键盘信息 然后进行截图的线程控制

 

 

 

 

 

 

 

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace ex12
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
       
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(
        IntPtr hWnd, // handle to destination window
        int Msg, // message
        int wParam, // first message parameter
        int lParam // second message parameter
        );
        protected override void DefWndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case HIDDEN_MM:
                    this.Hide();
                    break;
                case SHOW:
                    this.Visible = true;

                    break;
                default:
                    base.DefWndProc(ref m);
                    break;
            }
        }


        public static IntPtr HWND;
        public const int HIDDEN_MM = 0x500;
        public const int SHOW = 0x521;
        private const int WM_KEYDOWN = 0x100;
        private const int WM_KEYUP = 0x101;
        private const int WM_SYSKEYDOWN = 0x104;
        private const int WM_SYSKEYUP = 0x105;
        private const int VK_SNAPSHOT = 0x2C;
        //全局的事件
        static int hKeyboardHook = 0; //键盘钩子句柄
        //鼠标常量
        public const int WH_KEYBOARD_LL = 13; //keyboard hook constant
        HookProc KeyboardHookProcedure; //声明键盘钩子回调事件.
        //声明键盘钩子的封送结构类型
        [StructLayout(LayoutKind.Sequential)]
        public class KeyboardHookStruct
        {
            public int vkCode; //表示一个在 1 到 254 间的虚似键盘码
            public int scanCode; //表示硬件扫描码
            public int fags;
            public int time;
            public int dwExtraInfo;
        }
        //装置钩子的函数
        [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("user32")]
        public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[]
        lpwTransKey, int fuState);
        [DllImport("user32")]
        public static extern int GetKeyboardState(byte[] pbKeyState);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
        [DllImport("kernel32.dll")]
        static extern int GetTickCount();
        public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
        public static ManualResetEvent capture_terminate_e;
        public static ManualResetEvent capture_this_one_e;

        public static ManualResetEvent[] me_cap = new ManualResetEvent[2];
        private void Start_h()
        {
            //安装键盘钩子
            if (hKeyboardHook == 0)
            {
                KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                Process curProcess = Process.GetCurrentProcess();
                ProcessModule curModule = curProcess.MainModule;
                hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0);
                if (hKeyboardHook == 0)
                {
                    Stop_h();
                    throw new Exception("SetWindowsHookEx is failed.");
                }
            }
        }
        private void Stop_h()
        {
            bool retKeyboard = true;
            if (hKeyboardHook != 0)
            {
                retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                hKeyboardHook = 0;
            }
            //如果卸下钩子失败
            if (!(retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");
        }
        //键盘回调函数
        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
            //lParam 参数只是数据的内存地址
            KeyboardHookStruct MyKeyboardHookStruct =
            (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
            Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
            if (wParam == WM_KEYDOWN || wParam == WM_KEYDOWN)
            {
                //PrintScreen 负责执行单次捕捉
                if (keyData == Keys.PrintScreen)
                {
                    capture_this_one_e.Set();
                }
                //End 负责捕捉的任务结束
                if (keyData == Keys.End)
                {
                    capture_terminate_e.Set();
                }
                if (keyData == Keys.A)
                {
                    SendMessage(HWND, HIDDEN_MM, 0, 0);
                }
                if (keyData == Keys.B)
                {
                    SendMessage(HWND, SHOW, 0, 0);
                }
            }
            return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
        }
        static void Capture_screen()
        {
            int s_wid = Screen.PrimaryScreen.Bounds.Width;
            int s_height = Screen.PrimaryScreen.Bounds.Height;
            Bitmap b_1 = new Bitmap(s_wid, s_height);
            Graphics g_ = Graphics.FromImage(b_1);
            //图片路径用户须重新设置,才可正常运行
            String init_dir_fn = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            String dest_fn = null;
            //用事件的方法来抓获图片
            int index = WaitHandle.WaitAny(me_cap, 500);
            while (index != 0)
            {
                if (index == 1)
                {
                    dest_fn = init_dir_fn;
                    dest_fn += "\\bc\\";
                    dest_fn += GetTickCount().ToString();
                    dest_fn += "ab.bmp";
                    g_.CopyFromScreen(0, 0, 0, 0, new Size(s_wid, s_height));
                    b_1.Save(dest_fn, System.Drawing.Imaging.ImageFormat.Bmp);
                    capture_this_one_e.Reset();
                }
                index = WaitHandle.WaitAny(me_cap, 500);
            }
            g_.Dispose();
            b_1.Dispose();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

             HWND = this.Handle;
            //ll = new ManualResetEvent(false);
              

        }
        

        private void button1_Click(object sender, EventArgs e)
        {

            Start_h();
            //初始捕获终止事件为未结束
            capture_terminate_e = new ManualResetEvent(false);
            //初始捕获终止状态为未结束
            capture_this_one_e = new ManualResetEvent(false);
            me_cap[0] = capture_terminate_e;
            me_cap[1] = capture_this_one_e;
            //启动捕捉线程
            ThreadStart workStart = new ThreadStart(Capture_screen);
            Thread workThread = new Thread(workStart);
            workThread.IsBackground = true;
            workThread.Start();
      


        }


    }
}