请问如何控制一个外部程序(调用我已经掌握了,就是不知如何控制它)而且让我调用的这个程序隐藏。(100分)

  • 主题发起人 主题发起人 yzy25
  • 开始时间 开始时间
Y

yzy25

Unregistered / Unconfirmed
GUEST, unregistred user!
请问如何控制一个外部程序(调用我已经掌握了,就是不知如何控制它)而且让我调用的这个程序隐藏。
例如:
我用ShellExecute或WinExe调用了C:/Windows/Dialer.exe(电话拨号程序)
用户可以通过我的程序界面输入电话号码,通过我的程序拨号,通过我的程序来告诉用户战线,接通等。
但是我不希望Dialer这个程序出现在屏幕上
 
procedure TForm1.Button5Click(Sender: TObject);
begin
ShellExecute(handle,'open',pchar('C:/Windows/Dialer.exe'),0,0,sw_hide);
end;
 
简单的处理方法,当创建这个窗口的同时,获取其句柄,向它发送消息,
立即隐藏该窗口,要控制该窗口的使用,可以在调试时打开SPY++(VC提供的)
工具,看其控件的ID,并进行相应的操作,具体的你可以用GOOGLE搜
或者在DFW离线包中搜索,肯定有实际的代码和例子
 
可是怎么样才可以让用户可以通过我的程序界面输入电话号码,通过我的程序拨号,
通过我的程序来告诉用户战线,接通等。
并且我不希望Dialer这个程序出现在屏幕上。
 

哈哈. 我能明白你的意思: 你想将Dialer所有的功能都实现一遍(至少在界面上), 然后你调用
Dialer来做具体的事, 你自己的程序来接受输入和显示信息.

要想隐藏Dialer, 然后接受输入并传给Dialer都并不难, 前面的都说得很正确. 你直接取得句
柄, 然后向输入框里传值和填消息就可以了. 具体的, 你应该能在网上查到例子.

但是要将Dialer的显示信息截取并在你的程序中显示, 就不是一件容易的事了. 你可能得做Hook
程序. 或者利用句柄, 定时地扫描指定的panel/label上的显示变化. 这些操作比较难, 我不
是太建议你做...----有点得不偿失.

这个例子程序能给你足够多的帮助:
http://www.torry.net/vcl/vcltools/macros/mumacro.zip
 

可是我用WinSight获得了窗体的句柄,但是我不知道如何控制外部程序的按钮,比如
用户按了我的‘拨号’按钮就相当于按了dialer 中的‘拨号’按钮。
另外我不知道如何获得一个"按钮"的句柄。
也不知道发送什么消息才能灵活控制外部应用程序。


我让我的程序模拟按下按键来控制
procedure TForm1.Button1Click(Sender: TObject);
var
h:hwnd;
begin
h:=winprocs.FindWindow(nil,'电话拨号程序');
if h=0 then
begin
winexec(pchar('dialer.exe'),SW_SHOWNORMAL); 显然这种方法不能让dialer隐藏。
SendKeys('10060');
keybd_event(VK_RETURN,0,0,0);
end
else
begin
SendKeys('10060');
SimulateKeystroke(VK_RETURN, 0);
end;
end;

SendKeys实现如下:
procedure SendKeys(s : string);
var
i : integer;
flag : bool;
w : word;
begin
{Get the state of the caps lock key}
flag := not GetKeyState(VK_CAPITAL) and 1 = 0;
{If the caps lock key is on then turn it off}

if flag then
SimulateKeystroke(VK_CAPITAL, 0);
for i := 1 to Length(s) do begin
w := VkKeyScan(s);
{If there is not an error in the key translation}
if ((HiByte(w) <> $FF) and
(LoByte(w) <> $FF)) then begin
{If the key requires the shift key down - hold it down}
if HiByte(w) and 1 = 1 then
SimulateKeyDown(VK_SHIFT);
{Send the VK_KEY}
SimulateKeystroke(LoByte(w), 0);
{If the key required the shift key down - release it}
if HiByte(w) and 1 = 1 then
SimulateKeyUp(VK_SHIFT);
end;
end;
{if the caps lock key was on at start, turn it back on}
if flag then
SimulateKeystroke(VK_CAPITAL, 0);
end;


SimulateKeystroke实现如下:

procedure SimulateKeystroke(Key : byte;
extra : DWORD);
begin
keybd_event(Key,
extra,
0,
0);
keybd_event(Key,
extra,
KEYEVENTF_KEYUP,
0);
end;


有没有其他更好更灵活的方法啊!
 
to aimingo:
可是隐藏Dialer, 然后接受输入并传给Dialer也不容易实现啊,隐藏了dialer以后我就没
办法用上面的方法来实现接受键盘输入并传给Dialer了。
 
这个功能有个性
我再加100分
谁解决了,我开贴加分
 
hParent:=FindWindow(nil,'窗口名称');
hEdit:=ChildWindowFromPointEx(hParent, Point(50, 100){坐标},CWP_ALL);
hbutton:=FindWindowEx(hparent,0,nil,'确定(&amp;O){要带上快捷键}');

sendmessage(hButton,BM_CLICK,0,0); //按下此按钮
有很多消息 参看Messages单元 350行左右

如果是自己写的程序就多写些消息函数吧,向WinAmp的所有功能全都可以通过消息响应
 
直接调用TAPI控制MODEN来拨号不就行了

控制别人的程序并不是那么容易的
 
就象aimingoo说的,隐藏程序,输入数据并执行指定命令都不是问题,关键是错误处理就
比较麻烦了,除非你预先知道它在什么情况下会弹出什么样的错误,然后用线程检测错误
窗口,并取得错误信息,这样搞还是非常麻烦的,对中英文系统还要分别处理
我同意LiChaoHui的说法,还不如直接调用相应的API自己实现一个
实现拔号上网的代码应该有不少现成的,搜索一下吧。
 
请使用拨号的 API 写。省时省力省心,更重要的是在 DFW 或其他网上资料库中有 n 多
的源代码可以一抄了事。
 
谢谢大家,通过我的程序界面输入电话号码,通过我的程序拨号等问题已经圆满解决。
可是如何通过我的程序来告诉用户占线,接通等信息啊。
(好急啊,在线等待。)
 
呵呵,拦截消息
占线、接通等的时候Windows应该都会受到相应的消息(猜测,但是应该是这样的)
找点资料看看

不过我还是认为自己用API拨号比较简单
 
to yayx:
我用Delphi的WinSight试过了,没有关于这些的消息啊!
 
我曾经用语音卡写过这样的程序,我的解决方法是检测线路信号音,可以检测到的信号
音主要有以下几种:
1 拨号音
2 忙音1/2
3 回铃音
4 振铃音
5 其它
 
对上面的补充:
如果检测线路占线,提机拨号后检测信号音状态就可以了。
占线:线路忙音
接通:线路静音或未知信号音
 
呵呵
我确实也没找到
所以我还是推荐用API自己拨号
我写过一个打IP电话的程序,就是自己拨号的,没什么问题
 
to yayx:
用用API自己拨号也得告诉用户占线,接通等信息啊,这些你是怎么实现的。
谢谢!
 
呵呵,你干脆自己写个拨号的程序算了,免得截获消息,你可以查查csdn上的文章看看,
昨天我一看过你的贴子了。感觉没什么好办法。帮你提前!
 
后退
顶部