C# 如何通过全局钩子(HOOK)控制其它程序输入控件的输入内容

gjchen2010 2015-09-28 02:48:26
想做一个控制指定输入框输入内容的全局钩子程序,根据个人的知识和能力主要从以下几个方面着手:
1.做一个全局钩子监控窗体消息事件,当窗体获得焦点的时候判断当前窗体是否符合要求,符合要求即为指定输入框,通过该句柄即可控制。全局钩子监听(SetWindowsHookEx函数的WH_TCB消息),本程序监听没有问题,但是不能监听其它程序。
2.做一个全局钩子键盘监控,通过GetFocus获取当前输入窗口的控件,然后监听输入OnKeyDown事件,再去获取输入,但是此方法获得的输入焦点经常不准。
对于以上二种方案试过多种方式,查找了很多资料仍然没有得到很好的解决,希望集思广议听听大家的意见,如果方便的话是否可以提供相关的源码,谢谢大家!
...全文
1453 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
风吹腚腚凉 2015-09-28
  • 打赏
  • 举报
回复
好吧, 这样吧我仔细看了一下 第一部根据某种方式定位到指定控件的句柄, 例如选择一个目标进程,然后获取到进程,然后遍历控件里所有的子控件的句柄,也有这么个API名字忘记了。 自行百度。 第二部获取焦点的时候获取子控件的句柄,有这么一个api具体忘记了,获取到句柄以后对比两个句柄。 一致的话, 进行逻辑操作。 完美解决。 而不是通过按键的方式。
gjchen2010 2015-09-28
  • 打赏
  • 举报
回复
键盘钩子函数 SetWindowsHookEx( WH_KEYBOARD_LL, kbHook, GetModuleHandle( Process.GetCurrentProcess().MainModule.ModuleName ), 0 )
风吹腚腚凉 2015-09-28
  • 打赏
  • 举报
回复
百度[color=#FFFFFF][/color]
风吹腚腚凉 2015-09-28
  • 打赏
  • 举报
回复
C# 魔兽争霸改建外挂。
gjchen2010 2015-09-28
  • 打赏
  • 举报
回复
引用 8 楼 gjchen2010 的回复:
private void OnKeyDown(object sender, KeyEventArgs e) { int x = Cursor.Position.X; int y = Cursor.Position.Y; Point p = new Point(x, y); IntPtr hWnd = WindowFromPoint(p); StringBuilder buffer =new StringBuilder(2000); int l= SendMessage(hWnd, WM_GETTEXTLENGTH, 2000, buffer); GetWindowText(hWnd, buffer, 2000); listBox1.Items.Add(e.KeyCode.ToString() + " (Up KeyPress)" + "-" + hWnd.ToString() + "-" + l.ToString() + "-" + buffer.ToString()); GetCursorPos(out p); hWnd = WindowFromPoint(p); buffer =new StringBuilder(2000); l= SendMessage(hWnd, WM_GETTEXTLENGTH, 2000, buffer); GetWindowText(hWnd, buffer, 2000); listBox1.Items.Add(e.KeyCode.ToString() + " (Up KeyPress)" + "-" + hWnd.ToString() + "-" + l.ToString() + "-" + buffer.ToString()); hWnd =GetFocus(); buffer = new StringBuilder(2000); l = SendMessage(hWnd, WM_GETTEXTLENGTH, 2000, buffer); GetWindowText(hWnd, buffer, 2000); listBox1.Items.Add(e.KeyCode.ToString() + " (Up KeyPress)" + "-" + hWnd.ToString() + "-" + l.ToString() + "-" + buffer.ToString()); } 这个是键盘事件的代码, 图片是运行的结果
下面是程序自身输入框的结果 Time:2015/8/27 17:24:21,Msg:D (WindowFromPoint Up KeyPress)-1050028-5-Form1 Time:2015/8/27 17:24:21,Msg:D (GetCursorPos Up KeyPress)-1050028-5-Form1 Time:2015/8/27 17:24:21,Msg:D (GetFocus Up KeyPress)-984548-4-fgdf 下面是其它程序输入框的结果 Time:2015/8/27 17:25:38,Msg:F (WindowFromPoint Up KeyPress)-5375054-13- Time:2015/8/27 17:25:38,Msg:F (GetCursorPos Up KeyPress)-5375054-13- Time:2015/8/27 17:25:38,Msg:F (GetFocus Up KeyPress)-0-0-
gjchen2010 2015-09-28
  • 打赏
  • 举报
回复
private void OnKeyDown(object sender, KeyEventArgs e)
{
int x = Cursor.Position.X;
int y = Cursor.Position.Y;
Point p = new Point(x, y);
IntPtr hWnd = WindowFromPoint(p);
StringBuilder buffer =new StringBuilder(2000);
int l= SendMessage(hWnd, WM_GETTEXTLENGTH, 2000, buffer);
GetWindowText(hWnd, buffer, 2000);
listBox1.Items.Add(e.KeyCode.ToString() + " (Up KeyPress)" + "-" + hWnd.ToString() + "-" + l.ToString() + "-" + buffer.ToString());
GetCursorPos(out p);
hWnd = WindowFromPoint(p);
buffer =new StringBuilder(2000);
l= SendMessage(hWnd, WM_GETTEXTLENGTH, 2000, buffer);
GetWindowText(hWnd, buffer, 2000);
listBox1.Items.Add(e.KeyCode.ToString() + " (Up KeyPress)" + "-" + hWnd.ToString() + "-" + l.ToString() + "-" + buffer.ToString());
hWnd =GetFocus();
buffer = new StringBuilder(2000);
l = SendMessage(hWnd, WM_GETTEXTLENGTH, 2000, buffer);
GetWindowText(hWnd, buffer, 2000);
listBox1.Items.Add(e.KeyCode.ToString() + " (Up KeyPress)" + "-" + hWnd.ToString() + "-" + l.ToString() + "-" + buffer.ToString());

}
这个是键盘事件的代码,
图片是运行的结果
gjchen2010 2015-09-28
  • 打赏
  • 举报
回复
引用 6 楼 crystal_lz 的回复:
[quote=引用 5 楼 gjchen2010 的回复:] [quote=引用 3 楼 crystal_lz 的回复:] 但是此方法获得的输入焦点经常不准。 什么意思。。
就是说明明是某个输入窗口获得焦点,但是用GetFocus函数有时候获得的这个窗口的句柄,有时候有是0,有时候又会是该窗口的父窗口的句柄[/quote] The return value is the handle to the window with the keyboard focus. If the calling thread's message queue does not have an associated window with the keyboard focus, the return value is NULL. 这位是 函数的返回说明 至于你说的 有时候回事 父窗口的句柄 有些比如QQ的输入框 他压根就不存在句柄 都是绘制上去的一个文本框 所以 你只能得到一个父窗口的句柄 如果说 是标准的windows的文本控件 那我也不知道了 得试了才清楚[/quote] 谢谢你的意见!
crystal_lz 2015-09-28
  • 打赏
  • 举报
回复
引用 5 楼 gjchen2010 的回复:
[quote=引用 3 楼 crystal_lz 的回复:] 但是此方法获得的输入焦点经常不准。 什么意思。。
就是说明明是某个输入窗口获得焦点,但是用GetFocus函数有时候获得的这个窗口的句柄,有时候有是0,有时候又会是该窗口的父窗口的句柄[/quote] The return value is the handle to the window with the keyboard focus. If the calling thread's message queue does not have an associated window with the keyboard focus, the return value is NULL. 这位是 函数的返回说明 至于你说的 有时候回事 父窗口的句柄 有些比如QQ的输入框 他压根就不存在句柄 都是绘制上去的一个文本框 所以 你只能得到一个父窗口的句柄 如果说 是标准的windows的文本控件 那我也不知道了 得试了才清楚
gjchen2010 2015-09-28
  • 打赏
  • 举报
回复
引用 3 楼 crystal_lz 的回复:
但是此方法获得的输入焦点经常不准。 什么意思。。
就是说明明是某个输入窗口获得焦点,但是用GetFocus函数有时候获得的这个窗口的句柄,有时候有是0,有时候又会是该窗口的父窗口的句柄
qbilbo 2015-09-28
  • 打赏
  • 举报
回复
这样行否?Hook WH_KEYBOARD_LL,然后用:GetForegroundWindow判断当前Window是否满足要求。这样全部用c#就能搞定,也不用到处注入,被杀毒软件当病毒。当然,别人粘贴你管不了,但你原来的方法也管不了。 至于输入焦点不准,同问:什么意思.....,如果是想获取输入的完整内容,可以考虑SendMessage WM_GETTEXT。
crystal_lz 2015-09-28
  • 打赏
  • 举报
回复
但是此方法获得的输入焦点经常不准。 什么意思。。
gjchen2010 2015-09-28
  • 打赏
  • 举报
回复
谢谢你的关注和回复!因为.NET是委托方式,所以窗口句柄是不固定的,用SPY++获取后关闭窗口又变了。因此需要反复的取,这样无法锁定窗口,容易变换
本拉灯 2015-09-28
  • 打赏
  • 举报
回复
取他的语句柄不就可以了么, 你找找Spy++ .net的就可以呀。

110,555

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧