using PTMedicalInsurance.Variables; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace PTMedicalInsurance.Common { class HookApi { delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); // 导入用户32位API函数 [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); // 导入用户32位API函数 [DllImport("user32.dll", SetLastError = true)] static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern int GetWindowTextLength(IntPtr hWnd); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); public HookProc _hookProc; public IntPtr _hHook; public ManualResetEvent _windowCreatedEvent = new ManualResetEvent(false); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName); [DllImport("kernel32.dll", SetLastError = true)] private static extern uint GetLastError(); public HookApi() { Global.writeLog("创建HookAPI"); _hookProc = new HookProc(HookCallback); IntPtr hInstance = GetModuleHandle(null); Global.writeLog($"hInstance:{hInstance}"); _hHook = SetWindowsHookEx(WH_CBT, _hookProc, hInstance, 0); // 设置全局钩子 if (_hHook == IntPtr.Zero) { uint lastError = GetLastError(); Global.writeLog($"Failed to set hook. Error code: {lastError}"); return; } // 启动消息循环 Application.Run(new Form()); // 使用一个空的Form来启动消息循环 } const uint WM_KEYDOWN = 0x100; const uint WM_KEYUP = 0x101; const int VK_CONTROL = 0x11; // Ctrl键 const int VK_A = 0x41; // A键 const int VK_R = 0x52; const int VK_P = 0x50; const int VK_S = 0x53; const int VK_F = 0x46; const int VK_C = 0x43; const int WH_CBT = 5; const int HCBT_CREATEWND = 3; const uint WM_CLOSE = 0x0010; public int HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { Global.writeLog($"创建HookCallback:{nCode}" ); if (nCode < 0) { return CallNextHookEx(_hHook, nCode, wParam, lParam); } if (nCode == HCBT_CREATEWND) { IntPtr hWnd = wParam; if (IsTargetWindow(hWnd)) { Global.writeLog("检测到身份识别窗口且成功获取句柄"); // 窗口创建成功,执行操作 OperateYHControl((int)hWnd, "身份识别"); // 设置事件,通知主线程窗口已创建 _windowCreatedEvent.Set(); // 可以选择关闭窗口 SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); // 移除钩子 UnhookWindowsHookEx(_hHook); } } return CallNextHookEx(_hHook, nCode, wParam, lParam); } private bool IsTargetWindow(IntPtr hWnd) { // 根据窗口标题判断是否为目标窗口 const string targetWindowTitle = "身份识别"; StringBuilder sb = new StringBuilder(256); GetWindowText(hWnd, sb, sb.Capacity); return sb.ToString() == targetWindowTitle; } public void OperateYHControl(int key,string title) { //// 获取窗口句柄 //IntPtr hWnd = FindWindow(null, title); // 替换为实际的窗口标题 // 枚举所有顶级窗口 IntPtr hWnd = FindWindowByPartialTitle(title); // 替换为实际的部分窗口标题 if (hWnd != IntPtr.Zero) { Global.writeLog("找到了窗口,句柄: " + hWnd.ToString()); // 发送单快捷键 SendShortcutKey(hWnd, key); } else { Global.writeLog("未找到窗口" + title); } } private void SendShortcutKey(IntPtr hWnd, int key) { // 按下A键 PostMessage(hWnd, WM_KEYDOWN, (IntPtr)key, IntPtr.Zero); // 释放A键 PostMessage(hWnd, WM_KEYUP, (IntPtr)key, IntPtr.Zero); } private void SendShortcutKey(IntPtr hWnd, int controlKey, int key) { // 按下Ctrl键 PostMessage(hWnd, WM_KEYDOWN, (IntPtr)controlKey, IntPtr.Zero); // 按下A键 PostMessage(hWnd, WM_KEYDOWN, (IntPtr)key, IntPtr.Zero); // 释放A键 PostMessage(hWnd, WM_KEYUP, (IntPtr)key, IntPtr.Zero); // 释放Ctrl键 PostMessage(hWnd, WM_KEYUP, (IntPtr)controlKey, IntPtr.Zero); } private IntPtr FindWindowByPartialTitle(string partialTitle) { IntPtr hWnd = IntPtr.Zero; EnumWindows((hWndIter, lParam) => { if (IsWindowVisible(hWndIter)) { int length = GetWindowTextLength(hWndIter); StringBuilder sb = new StringBuilder(length + 1); GetWindowText(hWndIter, sb, sb.Capacity); string windowText = sb.ToString(); if (windowText.Contains(partialTitle)) { hWnd = hWndIter; return false; // 停止枚举 } } return true; // 继续枚举 }, IntPtr.Zero); return hWnd; } } }