怎么发送消息给计算器? ( 积分: 100 )

  • 主题发起人 主题发起人 bbscom
  • 开始时间 开始时间
B

bbscom

Unregistered / Unconfirmed
GUEST, unregistred user!
下面的代码是发送消息给计算器显示8,也就是相当于按8键。
PostMessage(Wnd,WM_KEYDOWN,Ord('8'),0);

请问怎么发消息给计算器上“CE”“C”“MC”等按钮呢?
 
这和盗qq密码等都差不多,先找句柄,再发消息;
具体的句柄信息你可以用vc6的工具spy++(个人感觉比delphi自带的winsight32好);
计算器上“CE”“C”“MC”等按钮其classname都是‘button’,windowname都是相应的
显示值,即:‘CE’,‘C’,‘MC’;
写了个小例子,我试过了,ok
procedure TForm1.Button1Click(Sender: TObject);
var
aHandle,childHandle: THandle;
begin
aHandle:= FindWindow('SciCalc','计算器');
if aHandle<> 0 then
begin
childHandle:= FindWindowEx(aHandle,0,'button','8'); //模拟按钮8
if childHandle<>0 then
begin
SendMessage(childHandle,WM_LBUTTONDOWN,0,0);
SendMessage(childHandle,WM_LBUTTONUP,0,0);
end;

childHandle:= FindWindowEx(aHandle,0,'button','CE'); //模拟按钮CE
if childHandle<>0 then
begin
SendMessage(childHandle,WM_LBUTTONDOWN,0,0);
SendMessage(childHandle,WM_LBUTTONUP,0,0);
end;
end;
end;
 
PostMessage(Wnd, WM_COMMAND, $51, 0);//C
PostMessage(Wnd, WM_COMMAND, $52, 0);//CE
PostMessage(Wnd, WM_COMMAND, $71, 0);//MC

每个按钮都有个COMMANDID,用SPY++截取WM_COMMAND消息可以知道每个按钮的COMMANDID
计算器上有两个"C"按钮,它们的COMMANDID不同的

1楼发送WM_LBUTTONDOWN+WM_LBUTTONUP不如直接发送BM_CLICK消息
 
对对,我就是一时想不起来是哪个消息了,呵呵,就是 BM_CLICK
(两个效果都是一样的)
 
那年黄梅花开,你好!
我怎么执行没有任何反应呀?
procedure TForm1.Button3Click(Sender: TObject);
begin
aHandle:= FindWindow('SciCalc','计算器');
if aHandle<> 0 then // 没有执行
begin
childHandle:= FindWindowEx(aHandle,0,'button','8'); //模拟按钮8
if childHandle<>0 then
begin
SendMessage(childHandle,WM_LBUTTONDOWN,0,0);
SendMessage(childHandle,WM_LBUTTONUP,0,0);
end;
end else // 没有执行
ShowMessage(IntToStr(aHandle));
end;
 
哇赛,不是吧,这你自己都不明白;
没有反应,说明计算器没有运行啊,
你可以在form的oncreate事件中先启动计算器啊
WinExec('calc.exe',SW_SHOW);
 
那年黄梅花开,你好!
请你修改全单元里的代码!!!
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
aHandle,childHandle: THandle;

implementation

{$R *.dfm}
{=================================================================
功 能: 调用Windows计算器
=================================================================}
procedure WindowsCalc;
var
lRet: integer;
begin
aHandle := FindWindow('SciCalc', '计算器');
if aHandle > 0 then
begin
SetWindowPos(aHandle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW
or SWP_NOSIZE or SWP_NOMOVE);
ShowWindow(aHandle, SW_RESTORE);
end else begin
lRet := WinExec('calc.exe', SW_SHOWNORMAL);
if lRet < 31 then
showmessage('执行Windows计算器出错。');
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
WindowsCalc;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
aHandle:= FindWindow('SciCalc','计算器');
if aHandle<> 0 then
begin
childHandle:= FindWindowEx(aHandle,0,'button','8'); //模拟按钮8
if childHandle<>0 then
begin
SendMessage(childHandle,WM_LBUTTONDOWN,0,0);
SendMessage(childHandle,WM_LBUTTONUP,0,0);
end;
end else
ShowMessage(IntToStr(aHandle));
end;

end.
 
模拟按钮8可以啊,真的可以,我什么都没改你的,可以啊
 
可是要我的电脑里不行呀,没有任何反应。
我点击BUTTON好像没有执行procedure TForm1.Button1Click(Sender: TObject);一样。
我是在简体WIN2K+D7呀。
 
有意思了,想研究研究。
我的是winxp + d7;
winexec计算器能启动吗?
你的form.create事件中就写这一句WinExec('calc.exe', SW_SHOWNORMAL),
其他的次要代码暂时不写;
你再跟踪一下,特别是Button1Click中的if 判断位置的handle值;
 
在Win2K + D7
procedure TForm1.Button1Click(Sender: TObject);
begin
aHandle:= FindWindow('SciCalc','计算器');
if aHandle<> 0 then
begin
childHandle:= FindWindowEx(aHandle,0,'button','8'); //模拟按钮8
if childHandle<>0 then
begin
SendMessage(childHandle,WM_LBUTTONDOWN,0,0);
SendMessage(childHandle,WM_LBUTTONUP,0,0);
end else
ShowMessage(IntToStr(childHandle)); // 会执行这一句,也就是childHandle等于0
end;
end;
 
那你用spy++看看win2k下的计算器的类名和窗体名,我估计可能不是'SciCalc'和'计算器'
 
或者你用下面的试试
//aHandle:= FindWindow('SciCalc','计算器');
aHandle:= FindWindow(nil,'计算器');

aHandle:= FindWindowEx(0,0,'SciCalc','计算器');

aHandle:= FindWindowEx(0,0,nil,'计算器');
 
那年黄梅花开, 你好!
aHandle:= FindWindow(nil,'计算器');

aHandle:= FindWindowEx(0,0,'SciCalc','计算器');
aHandle已经等于0了。
请你再找一找!!!
 
那我不知道了,惭愧啊。。。。
 
WinSight32、spy++工具发到我的邮箱里吧。
Delphi2005@163.com
 
楼主的代码在winxp下运行是正常的,但在win2k下确实没有出现预期的结果,那个8没有出来。我用spy++查过了,在win2k下类名和窗口名是一样的,估计模拟按键的语句有问题,最有可能的是消息可能不一样。
 
这个问题好解决。

procedure TForm1.Button1Click(Sender: TObject);
var
hwin:THandle;
begin
hwin:= FindWindow('SciCalc','计算器');
if hwin<> 0 then
begin
SendMessage(hwin,WM_COMMAND,MAKEWPARAM(125,BN_CLICKED),0); // 1
Sleep(500);
SendMessage(hwin,WM_COMMAND,MAKEWPARAM(126,BN_CLICKED),0); // 2
Sleep(500);
SendMessage(hwin,WM_COMMAND,MAKEWPARAM(127,BN_CLICKED),0); // 3
Sleep(500);
SendMessage(hwin,WM_COMMAND,MAKEWPARAM(92,BN_CLICKED),0); // +
Sleep(500);
SendMessage(hwin,WM_COMMAND,MAKEWPARAM(125,BN_CLICKED),0); // 1
Sleep(500);
SendMessage(hwin,WM_COMMAND,MAKEWPARAM(126,BN_CLICKED),0); // 2
Sleep(500);
SendMessage(hwin,WM_COMMAND,MAKEWPARAM(127,BN_CLICKED),0); // 3
Sleep(500);
SendMessage(hwin,WM_COMMAND,MAKEWPARAM(112,BN_CLICKED),0); // =
end;
end;

模拟按下123+123=这几个键,其它按键的编码自己用spy抓一下。方法是:抓消息,然后按下计算器的按键,看消息队列里面WM_COMMAND为BN_CLICKED的ID是多少。例如:除号是90,乘号是91,加号是92,减号是93 。。。
 
问最后一个类似的问题:
怎么一次性向另一程序里的EDIT控件发送:ABC
 
要看你能否得到这个Edit控件的句柄了,得到的话,那就好好办了。可以发送KEYDOWN信息,也可以发送虚拟键,模拟按下键盘(这招对一些特殊程序有用,例如操控skype发送信息)。如果你想一次性发送“ABC”,用粘贴字符串的方法也行。
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部