123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- 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;
- }
- }
- }
|