vc+如何实现模拟键盘输入,自动输入文字(创世纪篇)

键盘对于每个操作电脑的人员来说是最熟悉不过的了。键盘上的按键可分为两类: 按下后会在电脑的输入窗口上出现对应字符的按键,如字母键和数字键等,我们称之为字符键;按下后虽然看不到字符但会产生控制作用的按键,如回车键、光标键等,我们称之为控制键。

  对于vc+程序员来说,键盘上的每个按键都一样,无非是不同按键产生的键盘扫描码不同。在不同的操作系统下,键盘扫描码常常被转换为不同的编码以方便应用程序调用,比如在Windows系统下的ASCII码,在Windows系统下的虚拟键盘码等等。

  有时我们希望能以程序的方式模拟键盘按键,以达到自动输入文字或者控制操作的目的。在DOS系统下通常使用中断调用,产生键盘的扫描码的方法来实现。在Windows 系统下,由于Windows本身的一些限制和特点,一般不直接使用中断调用。

  了解一点Windows编程的朋友应该知道, Windows系统是通过消息的传递(或称事件的发生)来控制各个应用程序的执行和数据通信的。例如:应用程序打开和关闭会产生相应的窗口消息,鼠标的移动、点击动作会产生相应的鼠标消息,同样键盘的按下、弹起也会产生相应的键盘消息。那么如果用程序产生键盘消息,也就达到了模拟键盘按键的目的。

  有了这样的思路,我们现在就来实验一下。

  首先要知道在Windows系统中与键盘按键相关的消息有:WM_KEYDOWN、WM_KEYUP、 WM_SYSKEYDOWN、WM_SYSKEYUP、WM_CHAR等。其中,WM_KEYDOWN为键按下,WM_KEYUP为键弹起,WM_SYSKEYDOWN为系统键按下,WM_SYSKEYUP为系统键弹起,WM_CHAR为按键对应的字符。

  要模拟键盘产生键盘消息,我们就发送一条键盘消息给指定窗口。比如要模拟一个字母键“A”,可以这样:PostMessage(hWnd, WM_CHAR, ‘A‘, 0); 模拟按一个回车:PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0)。这里的关键问题是要确定窗口句柄(hWnd),使用GetFocus()函数可以得到键盘光标所在窗口句柄,但该函数只能得到当前进程内的窗口句柄。

  如果要得到其他应用程序的键盘光标所在窗口句柄,需要调用 AttachThreadInput()函数。该函数的作用就是将其他窗口线程的输入附加到本窗口线程的输入操作中,这样就可以调用GetFocus()函数得到其他窗口的句柄了。

  

AttachThreadInput()函数的原形如下:

BOOL AttachThreadInput(

DWORD idAttach, // 需要附加的线程ID

DWORD idAttachTo, // 附加到的线程ID

BOOL fAttach // true 附加 false 取消

);

函数使用的过程大致如下:

HWND hWnd;

hWnd = GetForegroundWindow(); // 得到当前窗口

if (hWnd == Form1->Handle) return; // 排除程序本身的窗口

DWORD FormThreadID = GetCurrentThreadId(); // 本程序的线程ID

// 当前窗口的线程ID

DWORD CWndThreadID = GetWindowThreadProcessId(hWnd, NULL);

// 附加输入线程

AttachThreadInput(CWndThreadID, FormThreadID, true);

// 得到当前键盘光标所在的窗口

hWnd = GetFocus();

// 取消附加的输入线程

AttachThreadInput(CWndThreadID, FormThreadID, false);

  hWnd就是当前键盘光标所在的窗口句柄。另外,经过测试发现,在Windows2000系统下发送字符消息(WM_CHAR)时,如果字符是一个汉字,则该字符对应的虚拟键盘码高位不为0,这样得到的字符就不正确。解决办法是做一个“与”运算: ch & 0xFF就可以了。

下面又到了给出例程的时间了。例程“刷刷刷”能够在键盘光标所在的文本输入框中自动输入文字(中文、英文、数字),程序使用C++ Builder 5开发。首先运行C++ Builder并新建工程。接着,将窗体Form1的边框样式(BorderStyle)改为对话框(bsDialog),并放置相应控件如图所示,其中SS_Text是一个用于输入文本的TComboBox控件,当然,你可以在设计阶段预先向控件中输入一些常用文本,以便程序运行后可以直接选用; txtTimes和txtDelay为TEdit控件,分别用于控制发送文本的次数和间隔时间;chkAutoWrap和chkAutoNumber为TCheckBox控件,决定是否在每一行发送文本后面自动回车或自动加记数编号; 以上控件包含在Panel1(TPanel控件)中; Timer1用于控制循环发送和时间间隔。

下面是程序清单:

  1. //--------------------------------------------
  2. #include
  3. #pragma hdrstop
  4. #include "Unit1.h"
  5. //--------------------------------------------
  6. #pragma package(smart_init)
  7. #pragma resource "*.dfm"
  8. int nTotalTimes, // 发送本文的总次数
  9. nTimes; // 已经发送的次数
  10. TForm1 *Form1;
  11. //--------------------------------------------
  12. __fastcall TForm1::TForm1(TComponent* Owner)
  13. : TForm(Owner)
  14. {
  15. }
  16. //--------------------------------------------
  17. void __fastcall TForm1::btnStartClick(TObject *Sender) // 开始刷屏
  18. { if (SS_Text->Text.IsEmpty())
  19. {
  20. // 文本不能为空
  21. ShowMessage("请输入刷刷文本!");
  22. SS_Text->SetFocus();
  23. return;
  24. }
  25. __try
  26. {
  27. // Timer1->Interval取值为n秒(最小为50毫秒)
  28. int Interval = StrToInt(txtDelay->Text);
  29. Timer1->Interval = (Interval > 0) ? Interval * 1000 : 50;
  30. // nTotalTimes取值为n次(最小为0次)
  31. nTotalTimes = StrToInt(txtTimes->Text);
  32. if (nTotalTimes < 0)
  33. nTotalTimes = 0;
  34. nTimes = 0;
  35. Timer1->Enabled = true;
  36. }
  37. __except(EXCEPTION_EXECUTE_HANDLER)
  38. {
  39. ShowMessage("请输入数值类型数据!");
  40. return;
  41. }
  42. btnStart->Enabled = false;
  43. btnStop->Enabled = true;
  44. Panel1->Enabled = false;
  45. Application->Minimize(); // 最小化刷刷窗口
  46. }
  47. //--------------------------------------------
  48. void __fastcall TForm1::btnStopClick(TObject *Sender)// 停止刷屏
  49. {
  50. Timer1->Enabled = false;
  51. btnStart->Enabled = true;
  52. btnStop->Enabled = false;
  53. Panel1->Enabled = true;
  54. }
  55. //--------------------------------------------
  56. void __fastcall TForm1::Timer1Timer(TObject *Sender)
  57. {
  58. // 现刷屏nTimes次,到nTotalTimes次后完成。
  59. if (nTimes == nTotalTimes)
  60. {
  61. btnStopClick(Sender);
  62. return;
  63. }
  64. HWND hWnd;
  65. hWnd = GetForegroundWindow(); // 得到当前窗口
  66. if (hWnd == Form1->Handle) return; // 不需要程序本身的窗口
  67. DWORD FormThreadID = GetCurrentThreadId();
  68. DWORD CWndThreadID = GetWindowThreadProcessId(hWnd, NULL);
  69. // 附加输入线程
  70. AttachThreadInput(CWndThreadID, FormThreadID, true);
  71. hWnd = GetFocus(); // 得到当前键盘光标所在的窗口
  72. AttachThreadInput(CWndThreadID, FormThreadID, false); // 取消
  73. if (hWnd == NULL) return;
  74. nTimes++;
  75. for (int i = 1; i <= SS_Text->Text.Length(); i++)
  76. { // 模拟键盘按键输入文本
  77. PostMessage(hWnd, WM_CHAR, (WPARAM)(SS_Text->Text[i] & 0xFF), 0);
  78. }
  79. if (chkAutoNumber->Checked)
  80. { // 自动编号
  81. AnsiString Lines = IntToStr(nTimes);
  82. for (int j = 1; j <= Lines.Length(); j++)
  83. PostMessage(hWnd, WM_CHAR, (WPARAM)(Lines[j]), 0);
  84. }
  85. if (chkAutoWrap->Checked) // 自动回车
  86. PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0);
  87. }
  88. //-----------
  89. end
时间: 2024-10-19 09:34:43

vc+如何实现模拟键盘输入,自动输入文字(创世纪篇)的相关文章

模拟键盘输入

微软有个软键盘,可以通过命令行输入osk调出来. 有时候我们想自己模拟几个键盘按键,怎么办?其实Win32 API中有一个keybd_event可以模拟键盘按键的输入.以C#语言为例. 首先引用namesapce,并导入API. using System.Runtime.InteropServices; [DllImport("user32.dll")]private static extern void keybd_event(byte bVk, byte bScan, int dw

【java+selenium3】模拟键盘操作 (十二)

一.键盘操作 用代码来模拟键盘的Enter或一系列的组合键,前面使用sendkeys()方法模拟键盘的输入,除此之外还可以模拟键盘组合键输入如下: 整理一些比较常用的键盘操作如下: sendKeys(Keys.BACK_SPACE);  //删除键--BackspacesendKeys(Keys.SPACE);   //空格键 SpacesendKeys(Keys.TAB);   //制表键 TabsendKeys(Keys.ESCAPE);   //回退键 ESCsendKeys(Keys.E

【转】C# winform 加载网页 模拟键盘输入自动接入访问网络

[转]C# winform 加载网页 模拟键盘输入自动接入访问网络 声明: 本文原创,首发于博客园 http://www.cnblogs.com/EasyInvoice/p/6070563.html 转载请注明出处. 背景: 由于所在办公室网络限制,笔者每天都使用网络都要先连接无线网.如下图,输入授权用户信息登录后才能使用WIFI. 丧心病狂的是该网页Cookie 过期时间为24小时,所以每天重复以下动作:打开浏览器 -> 手动输入 工号密码.密码 -> 点击"登录"按钮.

C# winform 模拟键盘输入自动接入访问网络

声明: 本文原创,首发于博客园 http://www.cnblogs.com/EasyInvoice/p/6070563.html 转载请注明出处. 背景: 由于所在办公室网络限制,笔者每天都使用网络都要先连接无线网.如下图,输入授权用户信息登录后才能使用WIFI. 丧心病狂的是该网页Cookie 过期时间为24小时,所以每天重复以下动作:打开浏览器 -> 手动输入 工号密码.密码 -> 点击"登录"按钮. 作为一个懒出天际的程序员,逃避这种重复劳动是必须滴~~ 解决方案:

VB模拟键盘输入的N种方法

VB模拟键盘输入的N种方法http://bbs.csdn.net/topics/90509805hd378发表于: 2006-12-24 14:35:39用VB模拟键盘事件的N种方法 键盘是我们使用计算机的一个很重要的输入设备了,即使在鼠标大行其道的今天,很多程序依然离不开键盘来操作.但是有时候,一些重复性的,很繁琐的键盘操作总会让人疲惫,于是就有了用程序来代替人们按键的方法,这样可以把很多重复性的键盘操作交给程序来模拟,省了很多精力,按键精灵就是这样的一个软件.那么我们怎样才能用VB来写一个程

SendInput模拟键盘输入的问题

SendInput模拟键盘输入的问题 http://www.cnblogs.com/yedaoq/archive/2010/12/30/1922305.html 最近接触到这个函数,因此了解了一下,总结一下列在这. 我了解它的出发点是如何通过它向活动窗口输入字符,这是很多程序都有的功能(我猜Visual Assist X就用了这个功能). 根据MSDN,此函数模拟按键操作,将一些消息插入键盘或鼠标的输入流中,Windows对它进行处理,生成相应的WM_KEYDOWN或WM_KEYUP事件,这些事

输入法切换小程序(js模拟键盘按键输入成功版)

花了半天时间写了个小程序,基本满足最初需求(但目前只支持IE浏览器). 需求: 在输入汉字的时候没有切换出中文输入法而导致输入了拼音,我们要做的是:将输入的拼音删除并且切换出中文输入法,重新自动在输入法中打出相应的字母. 我的电脑上默认只有两个输入法,中文输入法和美式键盘,所以模拟出”ctrl+空格键“即可在两个输入法之间进行切换. 做的过程和想法: 最初想的是使用网页配合js来做,毕竟界面好做一些.首先想到的就是用js来模拟键盘的输入,想法很好,但是却很难,主要是因为浏览器为了考虑安全性,所以

用Delphi模拟键盘输入

在Windows大行其道的今天,windows界面程序受到广大用户的欢迎.对这些程序的操作不外乎两种,键盘输入控制和鼠标输入控制.有时,对于繁杂的,或重复性的操作,我们能否通过编制程序来代替手工输入,而用程序来模拟键盘及鼠标的输入呢?答案是肯定的.这主要是通过两个API函数来实现的. 下面以Delphi为例来介绍一下如何实现这两个功能.模拟键盘我们用Keybd_event这个api函数,模拟鼠标按键用mouse_event函数.大家不用担心,在delphi里调用api函数是很方便的事. 先介绍一

Android模拟键盘输入功能的实现

在做关于输入框的操作指引时,用动态的输入效果比用静态的图片指示效果会好很多,本文结合最近需要实现的一个搜索输入操作指引的功能介绍一下android平台模拟键盘输入的实现. 在android上不知道怎么录制gif的动态图,直接截图看一下效果吧,具体看demo就行啦. 实现起来很简单,开一个线程,通过sleep控制输入字符的间隔时间,封装一个模拟键盘输入的方法,最终代码是这样子的: public class TypeInActivity extends BaseActivity { @Overrid