分享

delphi中玩转keybd

 quasiceo 2015-07-21
分类: Delphi 2012-11-20 09:16 2632人阅读 评论(0) 收藏 举报

模拟键盘平时不是很常用, 但是当调用某些快捷键执行某项功能时, 它真的是那么的方便呀. 你不信? 看看下面的实现, 你就会大呼: 为什么不早点告诉我? 呵呵, 原来没有blog呀, 都靠这些挣分呢.

        //模拟Ctrl+回车(Enter)键,实现在QQ中发送消息
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
        keybd_event(13, MapVirtualKey(13, 0), 0, 0);
        keybd_event(13, MapVirtualKey(13, 0), KEYEVENTF_KEYUP, 0);
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0);

(1) 显示桌面:

很多软件有显示桌面的功能, 并且大家的方法都是遍历窗口, 然后让它们最小化, 其实 win系统给咱们了一个非常方便的WIN键(就是键盘上在CTRL键和ALT键之间的那个带win标志的按键), 利用它, 可以轻松的完成显示桌面的功能.

keybd_event(VK_LWIN, 0, 0 ,0);
keybd_event('M', 0, 0 ,0);
keybd_event('M', 0, KEYEVENTF_KEYUP ,0);
keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP,0);

其他的操作也类似, 比如直接显示开始的运行,就把上面的'M'换成'R'即可。

直接 keybd_event(VK_LWIN, 0, 0 ,0);
keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP,0);

直接显示“开始”对话框了。

2) 实现快速的全选

很多的时候,比如listctrl实现全选,你可以用listctrl循环设置每一项的状态为选中,多罗索的事情呀。用快捷键试一试CTRL+A,其他的快捷键一样的用法,呵呵,你知道怎么办了吧?

keybd_event(VK_CONTROL, (BYTE)0, 0 ,0);
keybd_event('A',(BYTE)0, 0 ,0); //此处可以用 'A', (BYTE)65, 用'a'不起作用.
keybd_event('A', (BYTE)0, KEYEVENTF_KEYUP,0);
keybd_event(VK_CONTROL, (BYTE)0, KEYEVENTF_KEYUP,0);

3) 执行某些特殊的键,比如数字键,大小写,下面是数字键的例子

bool bState=true; //true为按下NumLock,false反之
BYTE keyState[256];

GetKeyboardState((LPBYTE)&keyState);
if( (bState && !(keyState[VK_NUMLOCK] & 1)) ||
(!bState && (keyState[VK_NUMLOCK] & 1)) )
{
// Simulate a key press
keybd_event( VK_NUMLOCK,
0x45,
KEYEVENTF_EXTENDEDKEY | 0,
0 );

// Simulate a key release
keybd_event( VK_NUMLOCK,
0x45,
KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
0);
}

4) 你想CTRL+ALT+DELETE三键一起按下,

keybd_event(VK_CONTROL, 0, 0 ,0);
keybd_event(VK_MENU,0, 0 ,0);
keybd_event(VK_DELETE,0, 0 ,0);

keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP ,0);
keybd_event(VK_MENU,0, KEYEVENTF_KEYUP ,0);
keybd_event(VK_DELETE,0, KEYEVENTF_KEYUP ,0);
呵呵,这样不会成功呀,因为这几个键直接是操作系统来截获执行的,而模拟键盘只能发向应用程序,所以这种方法不行的(想显示锁定对话框,用 LockWorkStation();)

5) Window2000/NT/XP已经不提倡用这个函数了,上面的方法只是为了让大家开阔一下思路,怎么替代呢,呵呵,看下面,所以上面的所有代码都可以用这个来完成

//2000下用这个代替 ,包含 "winable.h"
INPUT input[4];
memset(input, 0, sizeof(input));

input[0].type = input[1].type = input[2].type = input[3].type = INPUT_KEYBOARD;

input[0].ki.wVk = input[3].ki.wVk = VK_LWIN;
input[1].ki.wVk = input[2].ki.wVk = 'R';


//接下来释放它,这一点很重要。
input[2].ki.dwFlags = input[3].ki.dwFlags = KEYEVENTF_KEYUP;
input[0].ki.time = input[1].ki.time = input[2].ki.time = input[3].ki.time = GetTickCount();

SendInput(4, input, sizeof(INPUT));

感觉比那个有点罗索,呵呵。

====================

附WIN键的部分快捷键:

WIN键+D=快速的切到桌面,再次点击返回

WIN键+E=快速打开资源管理器

WIN键+R=“运行”。

WIN键+M=全部视窗最小化。

WIN键+Shift+M=取消全部视窗最小化。

WIN键+F1=Help。

WIN键+F=“寻找”。

WIN键+Ctrl+F=显示“查找电脑”。

WIN键+Tab=切换工作列的程式。

WIN键+Break=显示系统内容。

 

例子控制自动保存WORD,实现定时保存WORD文件,思路:列举窗口,找到WORD窗口,然后模拟键盘操作,进行另存为和保存。

 

新建工程、在属性浏览器分别双击窗体的create、show事件,然后用下列代码覆盖你的unit1:

  1. unit Unit1;  
  2.    
  3. interface  
  4.    
  5. uses  
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  7.   Dialogs, ExtCtrls, StdCtrls, ComCtrls, Spin;  
  8.    
  9. type  
  10.   TForm1 = class(TForm)  
  11.     procedure FormShow(Sender: TObject);  
  12.     procedure FormCreate(Sender: TObject);  
  13.   private  
  14.     { Private declarations }  
  15.     procedure TimerTimer(Sender: TObject);  
  16.     procedure SpinEditChange(Sender: TObject);  
  17.     procedure CheckBoxClick(Sender: TObject);  
  18.   public  
  19.     { Public declarations }  
  20.   end;  
  21.    
  22. var  
  23.   Form1: TForm1;  
  24. //本代码在delphi7 + windows_XP 编译运行通过,如有谬误或更好方法,还请不吝指教。谢谢!  
  25. //中国软件研发联盟QQ群122058606 __广州佬编写  
  26. implementation{$R *.dfm}  
  27.    
  28. const Minute=30;//时间间隔——分钟  
  29.       Interval=100;//用于等待保存对话出现的时间——毫秒(根据机器具体性能而定)  
  30. var x:integer;//用于区分"另存为"的下拉框  
  31.     First:boolean;//是否第一次保存  
  32.     Timer: TTimer;  
  33.     LabeledEdit:TLabeledEdit;  
  34.     SpinEdit:TSpinEdit;  
  35.     CheckBox:TCheckBox;  
  36.     Label1:TLabel;  
  37.    
  38. procedure SimulationKey(key_1:word; alt:word=0; key_2:word=0);//模拟按键  
  39. begin  
  40.   if alt>0 then  
  41.     keybd_event(alt,0,KEYEVENTF_EXTENDEDKEY or 0,0);  
  42.   keybd_event(key_1,0,KEYEVENTF_EXTENDEDKEY or 0,0);  
  43.   keybd_event(key_1,0,KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP,0);  
  44.   if key_2>0 then begin  
  45.     keybd_event(key_2,0,KEYEVENTF_EXTENDEDKEY or 0,0);  
  46.     keybd_event(key_2,0,KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP,0);  
  47.   end;  
  48.   if alt>0 then  
  49.     keybd_event(alt,0,KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP,0);  
  50. end;  
  51.    
  52. function EnumChildWndProc(aHwnd:LongInt;AlParam:lParam):boolean;stdcall;//枚举窗体内组件  
  53. var WndClassName:array[0..254of Char;  
  54.     WndCaption:array[0..254of Char;  
  55. begin  
  56.   GetClassName(aHwnd,wndClassName,254);  
  57.   GetWindowText(aHwnd,WndCaption,254);  
  58.   if string(wndClassName)='RichEdit20W' then begin//控件为下拉框类型  
  59.     inc(x);  
  60.     if x=2 then begin//设置路径和文件名的下拉框  
  61.       sleep(Interval);  
  62.       SendMessage(aHwnd,WM_SETTEXT,0,LongInt(pchar('c:\'+LabeledEdit.Text+'.Doc')));//保存到 C 盘跟  
  63.       sleep(Interval);  
  64.       SimulationKey(83,VK_MENU);//保存  
  65.       result:=false;  
  66.       exit;  
  67.     end;  
  68.   end;  
  69.   result:=true;  
  70. end;  
  71.    
  72. procedure TForm1.TimerTimer(Sender: TObject);  
  73. var hCurrentWindow:HWND;  
  74.     szText:array [0..254of char;  
  75. begin  
  76.   x:=0;  
  77.   hCurrentWindow:=GetWindow(Handle,GW_HWNDFIRST);  
  78.   while hCurrentWindow<>0 do begin//枚举窗体  
  79.     if GetWindowText(hCurrentWindow,@szText,255)>0 then  
  80.     begin  
  81.       if pos('- Microsoft Word',strpas(@szText))>0 then begin//找到 Word 程序窗体  
  82.         SetForegroundWindow(hCurrentWindow);  
  83.         if First then begin //如果是第一次运行  
  84.           SimulationKey(70,VK_MENU,65);//打开另存为对话  
  85.           sleep(Interval);  
  86.           SimulationKey(VK_ESCAPE);//取消保存  
  87.           sleep(Interval);  
  88.           First:=false;  
  89.         end;  
  90.         SimulationKey(70,VK_MENU,65);//打开另存为对话  
  91.         sleep(Interval);  
  92.         hCurrentWindow:=FindWindow(nil,pchar('另存为'));//查找另存为的窗体  
  93.         if hCurrentWindow<>0 then begin//找到  
  94.           EnumChildWindows(hCurrentWindow,@EnumChildWndProc,0);//枚举窗体内的组件  
  95.           exit;  
  96.         end;  
  97.       end;  
  98.     end;  
  99.     hCurrentWindow:=GetWindow(hCurrentWindow,GW_HWNDNEXT);//继续查找下一个  
  100.   end;  
  101. end;  
  102.    
  103. procedure TForm1.FormShow(Sender: TObject);  
  104. var hCurrentWindow:HWND;  
  105.     szText:array [0..254of char;  
  106. begin  
  107.   First:=true;  
  108.   //利用枚举的方法查找 Word 程序的窗体:  
  109.   hCurrentWindow:=GetWindow(Handle,GW_HWNDFIRST);  
  110.   while hCurrentWindow<>0 do begin  
  111.     if GetWindowText(hCurrentWindow,@szText,255)>0 then begin  
  112.       if pos('- Microsoft Word',strpas(@szText))>0 then begin  
  113.         SetForegroundWindow(hCurrentWindow);  
  114.         if First then begin  
  115.           SimulationKey(70,VK_MENU,65);  
  116.           sleep(Interval);  
  117.           SimulationKey(VK_ESCAPE);  
  118.           sleep(Interval);  
  119.           First:=false;  
  120.         end;  
  121.       end;  
  122.     end;  
  123.     hCurrentWindow:=GetWindow(hCurrentWindow,GW_HWNDNEXT);  
  124.   end;  
  125. end;  
  126.    
  127. procedure TForm1.FormCreate(Sender: TObject);  
  128. begin  
  129.   Caption:='自动保存Word文档';  
  130.   Position:=poScreenCenter;  
  131.   Height:=203;  
  132.   Width:=283;  
  133.   LabeledEdit:=TLabeledEdit.Create(self);  
  134.   with LabeledEdit do begin  
  135.     Parent:=Form1;  
  136.     LabeledEdit.Left:=80;  
  137.     LabeledEdit.Top:=24;  
  138.     LabeledEdit.Text:='测试文件';  
  139.     LabeledEdit.EditLabel.Caption:='文件名:';  
  140.   end;  
  141.   SpinEdit:=TSpinEdit.Create(self);  
  142.   with SpinEdit do begin  
  143.     Parent:=Form1;  
  144.     Left:=80;  
  145.     Top:=80;  
  146.     Width:=121;  
  147.     Value:=Minute;  
  148.     OnChange:=SpinEditChange;  
  149.   end;  
  150.   Label1:=TLabel.Create(self);  
  151.   with Label1 do begin  
  152.     AutoSize:=false;  
  153.     Caption:='保存间隔(分钟):';  
  154.     Parent:=Form1;  
  155.     Left:=80;  
  156.     Top:=63;  
  157.     Width:=120;  
  158.   end;  
  159.   CheckBox:=TCheckBox.Create(self);  
  160.   with CheckBox do begin  
  161.     Parent:=Form1;  
  162.     Left:=80;  
  163.     Top:=110;  
  164.     Caption:='自动保存';  
  165.     OnClick:=CheckBoxClick;  
  166.   end;  
  167.   Timer:= TTimer.Create(self);  
  168.   with Timer do begin  
  169.     Enabled:=false;  
  170.     Interval:=Minute*60000;  
  171.     OnTimer:=TimerTimer;  
  172.   end;  
  173. end;  
  174.    
  175. procedure TForm1.SpinEditChange(Sender: TObject);  
  176. begin  
  177.   if SpinEdit.Text='' then exit;  
  178.   Timer.Interval:=SpinEdit.Value * 60000;  
  179. end;  
  180.    
  181. procedure TForm1.CheckBoxClick(Sender: TObject);  
  182. begin  
  183.   Timer.Enabled:=CheckBox.Checked;  
  184.   if First then TimerTimer(nil);  
  185. end;  
  186.    
  187. end

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多