模拟按键的问题,代码简单,原理不明,UP有分.
有朋友让做一个自动在记事本后面加文本内容的一个小程序,我用DELPHI实现代码如下:
shellexecute(handle,'open', PChar('c:\winnt\system32\notepad.exe'), nil, nil,SW_SHOWNORMAL);
for i:=0 to Length(SendEdt.Text)-1 do begin
keybd_event(Ord(SendEdt.Text[i]),MapVirtualKey(Ord(SendEdt.Text[i]),0),0,0);
keybd_event(Ord(SendEdt.Text[i]),MapVirtualKey(Ord(SendEdt.Text[i]),0),KEYEVENTF_KEYUP,0);
end;
经过测试发现,可以打开记事本,但是却往里面加不了内容,想想,估计是没有获得焦点吧,便改成这样:
var aHWND:THandle;
i:Integer;
s:Char;
begin
shellexecute(handle,'open', PChar('c:\winnt\system32\notepad.exe'), nil, nil,SW_SHOWNORMAL);
aHWND:= FindWindow('Notepad',nil);
if aHWND<>0 then begin
SetForegroundWindow(aHWND);
for i:=0 to Length(SendEdt.Text)-1 do begin
PostMessage(aHWND, WM_KEYDOWN, Ord(SendEdt.Text[i]), 0);
end;
end;
发现还是不行,郁闷至极,太打击人了,这点事也搞不定...没得办法后,改用VB来写...代码如下:
Private Sub Command1_Click()
Dim i As Integer
Shell "c:\winnt\system32\notepad.exe", vbNormalFocus
DoEvents
SendKeys SendEdt.Text
DoEvents
SendKeys "{enter}" '发送回车
End Sub
轻松搞定.
至此有一些不明白,是不是我DELPHI代码有写错致使目标窗体收不到消息呢?还是我理解上有问题?其实从想法上VB和DELPHI的代码基本上实现相同功能,为什么一个可以一个却不可以呢?怎么样DELPHI才可以呢?能不能详细解释一下?
嘿嘿,问了这么多,请各位多多解答,谢谢!
问题点数:100、回复次数:16Top
1 楼bee2518(迷茫ing)回复于 2004-12-01 14:20:10 得分 15
整个想法都错了
应该是获得文件后在文件尾加入文件
如:
procedure TForm1.btnAppendClick(Sender: TObject);
var
MyTextFile: TextFile;
s: string;
i: integer;
begin
//关联文件
AssignFile(MyTextFile, 'C:\MyTextFile.txt');//你的文件路径和文件名
//判断文件是否存在
if FileExists('MyTextFile.txt') then
//以添加的方式打开文本
Append(MyTextFile)
else
raise Exception.Create('MyTextFile.txt不存在');
//向文本添加字符串
try
for i := 6 to 10 do
begin
s := 'This is line #';
Writeln(MyTextFile, s, i);
end;
finally
CloseFile(MyTextFile);
end;
end;Top
2 楼xjb2001(便衣超人)回复于 2004-12-01 14:28:26 得分 20
想被添加的文本并一定在我们知道的路径啊
你的方法可以实现添加文本,但是不能解决楼主的想法;Top
3 楼PrettyMurphy(土豆)回复于 2004-12-01 14:52:02 得分 0
对阿,我的想法是向其它过程传递按键消息.
开文本窗口加内容只是一个例子而已.
var TmpStr:TStringList;
begin
TmpStr:=TStringList.Create;
if FileExists('C:\MyTextFile.txt') then begin
TmpStr.LoadFromFile('C:\MyTextFile.txt');
TmpStr.Add('这是添加的内容');
TmpStr.SaveToFile('C:\MyTextFile.txt');
end;
TmpStr.Free;
end;
我这样做也可以...嘿嘿.Top
4 楼bee2518(迷茫ing)回复于 2004-12-01 15:17:35 得分 0
你这家伙,简直就是误导我
现在有事,有空再研究了Top
5 楼PrettyMurphy(土豆)回复于 2004-12-01 15:29:23 得分 0
呵呵,多谢楼上的支持,谢谢!
我刚看了一下,好象这并不是一个个案,有大量的贴子有相类似的问题呢.....Top
6 楼qingfengsishi(不懂程序)回复于 2004-12-01 15:50:38 得分 5
模拟键盘……以前用它写过挂机的小工具!Top
7 楼nyf1220(我是党员----不过听说最近风声紧,打算换名字)回复于 2004-12-01 16:10:14 得分 5
VOID keybd_event(
BYTE bVk, // virtual-key code
BYTE bScan, // hardware scan code
DWORD dwFlags, // flags specifying various function options
DWORD dwExtraInfo // additional data associated with keystroke
);
直接使用KEYBOARD时间试下Top
8 楼xufenglong(天天向上)回复于 2004-12-01 16:38:02 得分 5
up有分Top
9 楼XuDunYu(西门吹雪)回复于 2004-12-01 16:45:50 得分 20
procedure TForm1.Button1Click(Sender: TObject);
Var
hw:thandle;
he:thandle;
begin
hw := FindWindow('notepad','1.txt - 记事本');
if hw = 0 then
begin
showmessage('记事本没有打开!');
Exit;
end;
he := GetTopWindow(hw);
SendMessage(he, WM_CHAR, ord('C'), 0);
end;Top
10 楼PrettyMurphy(土豆)回复于 2004-12-01 18:22:50 得分 0
搞定....
西门的这句:SendMessage(he, WM_CHAR, ord('C'), 0);
呵呵...
Top
11 楼whitetiger8(键盘未敲坏,基本功未练成)回复于 2004-12-01 20:55:30 得分 5
好像来晚了啊。吹吹解决了Top
12 楼extcsdn(Studing VB now)回复于 2004-12-01 21:54:04 得分 5
晚了我也顶!!Top
13 楼nyf1220(我是党员----不过听说最近风声紧,打算换名字)回复于 2004-12-02 09:56:33 得分 5
WM_CHAR 啊,哈哈,学习了Top
14 楼dreamonce(小虫)回复于 2004-12-02 10:06:34 得分 5
就是啊,keybd_event怎么可能向别的程序模拟击键呢Top
15 楼FlyBird2004(Phoenix)回复于 2004-12-02 10:33:58 得分 10
procedure TMainForm.Button2Click(Sender: TObject);
var
H : HWND;
PI : TProcessInformation;
SI : TStartupInfo;
begin
FillChar(SI, SIZEOF(SI), 0);
SI.cb := SizeOf(SI);
if CreateProcess(Nil, 'NotePad', Nil, Nil, False, 0, Nil, Nil, SI, PI) then
begin
WaitForInputIdle(PI.hProcess, INFINITE);
H := FindWindow('NotePad', '未定标题 - 记事本');
if SetForegroundWindow(H) then
SendKeys('Hello From The Delphi Developer''s Guide SendKeys '+ 'example!{ENTER}');
end
else
MessageDlg(Format('Failed to invoke Notepad. Error code &d', [GetLastError]), mtError, [mbOK], 0);
end;
注:sendkeys函数为发送模拟按键函数。主要代码在《Dephi5开发人员指南》405也可见Top
16 楼PrettyMurphy(土豆)回复于 2004-12-02 17:03:48 得分 0
哇靠,楼上太猛了吧?简单的事搞得这么复杂?
呵呵.....
结贴了,就不浪费CSDN的资源了...Top




