看到CSDN一位兄弟的博文
http://blog.csdn.net/tonylk/archive/2005/04/21/357701.aspx
再谈
http://blog.csdn.net/tonylk/archive/2005/07/01/409614.aspx我现在也需要控制一个外部程序,想让我的外部程序在虚拟的Desktop上运行,然后在这外部程序的listbox里插入项目,在运行。
我用了他博文的代码,但是编译不过,
那位兄弟用过次类,帮忙写个例子,在虚拟Desktop运行外部程序,并在这个外部程序的listbox插入 我自己程序的listbox的一个item,并响应 按钮,
大家帮个忙。
http://blog.csdn.net/tonylk/archive/2005/04/21/357701.aspx
再谈
http://blog.csdn.net/tonylk/archive/2005/07/01/409614.aspx我现在也需要控制一个外部程序,想让我的外部程序在虚拟的Desktop上运行,然后在这外部程序的listbox里插入项目,在运行。
我用了他博文的代码,但是编译不过,
那位兄弟用过次类,帮忙写个例子,在虚拟Desktop运行外部程序,并在这个外部程序的listbox插入 我自己程序的listbox的一个item,并响应 按钮,
大家帮个忙。
解决方案 »
- 实现Delphi访问网页,并且返回网页的错误代码
- 日期类型如何转换成long型
- ■■■如何解决用TIcon.saveToFile保存的图标仅有16色的问题?■■■
- Delphi里edit1如何读取一个excel里某表格的内容??
- ShortCutToKey的问题
- 请为我这个初学者提供好的DELPHI的网站,多谢!
- Delphi高手请进 解决问题 送高分 再送分
- 求高手赐教:关于dbgrid交叉表保存数据问题
- 请教各位大虾,我想编一个物业管理软件,该怎么做系统分析???
- 200分!!如何使有背景图的TreeView文字背景透明?
- delphi中显示图片的控件哪个比较好用
- 使用自己编写的运行期bpl,必须选中“Build with runtime packages”检查框吗?
我现在是要我自己的程序 通过虚拟的Desktop 调用一个ABCD.EXE文件,这个ABCD.exe,组件有listbox,和2个按钮,(一个是《添加》,一个是《运行》),添加按钮是向listbox里插入项目,插入项目后,,相应运行按钮 ,
这样,,后台完美调用外部程序,,,我自己写的程序 在当前窗口运行,,然后创建一个虚拟的Desktop ,在虚拟的Desktop,运行外部程序,例如QQ的聊天窗口,我的程序向QQ聊天窗口 插入一条信息,然后按下发送按钮。后台完美调用外部程序,就是不让人看到 ,我在调用其他软件。
调用下面这个程序,
这个软件 我共享了
http://u.115.com/file/t741585673#
DesktopName = 'MYDESK';
procedure TForm1.Button1Click(Sender: TObject);
var
StartInfo:TStartupInfo;
FProceInfo :TProcessInformation;
begin FillChar(StartInfo, sizeof(StartInfo), 0);
StartInfo.cb:=sizeof(StartInfo);
StartInfo.lpDesktop:=PChar(DesktopName); //指定Desktop的名称即可
StartInfo.wShowWindow:=SW_SHOW;
StartInfo.dwFlags:=STARTF_USESHOWWINDOW;
StartInfo.hStdError:=0;
StartInfo.hStdInput:=0;
StartInfo.hStdOutput:=0;
if not CreateProcess('D:\Downloads\quickpar\QuickPar\QuickPar.exe', nil,nil,nil,true,0,nil,'D:\Downloads\quickpar\QuickPar',StartInfo,FProceInfo) then begin
MessageBox(Application.Handle,PChar(inttostr(GetLastError)),PChar(Application.Title),MB_ICONWARNING);
exit;
end;
end;procedure TForm1.Button2Click(Sender: TObject);
var FDesktop:HDESK;begin
FDesktop:=CreateDesktop(DesktopName,nil,nil,0,GENERIC_ALL,nil);
if FDesktop=0 then
ShowMessage( IntToStr(GetLastError));
end;
这里好像说明了下
http://blog.csdn.net/tonylk/archive/2005/07/01/409614.aspx
keeley20
能帮我写个例子嘛
这句好像没执行呢
这句好像怎么没执行呢
能帮忙写个不,
好依样画葫芦。
这个调试是成功的,
在当前住窗口是看不到那个QuickPar的界面的,在进程中能看到QuickPar已经在打开了,
但是
zhaodog
能帮忙写一下,怎么样向虚拟的Desktop里运行的QuickPar,传递那个按钮呢,
或者怎么样能把 我程序的listbox的item,传递给 QuickPar的listbox,在按下那个创建按钮呢。
原文中
{但是,程序运行后,该函数却返回了false,说明方法调用失败了,再仔细看MSDN,发现有这么一句话:The SetThreadDesktop function will fail if the calling thread has any windows or hooks on its current desktop (unless the hDesktop parameter is a handle to the current desktop).
哦,原来需要切换Desktop的线程中不能有任何UI方面的东西,而我是在程序的主线程中调用该方法的,当然会失败拉,知道了这点就好办了,我只需要用一个“干净”的线程,让它绑定到新的Desktop上,再让它用FindWindow()方法找到我要找的WindowHandle,不就可以了吗,于是,这一步就需要借助一个线程了,线程的代码如下: TFindWindowThread = class(TThread)
private
FDesktop:THandle;
FWindowHandle:THandle;
protected
procedure Execute();override;
public
constructor Create(ACreateSuspended:Boolean;const ADesktop:THandle);reintroduce;
property WindowHandle:THandle read FWindowHandle;
end;
{ TFindWindowThread }这个你编译的过吗
unit Unit3;interfaceuses
Classes {$IFDEF MSWINDOWS} , Windows {$ENDIF};type TFindWindowThread = class(TThread)
private
FDesktop:THandle;
FWindowHandle:THandle;
protected
procedure Execute; override;
public
constructor Create(ACreateSuspended:Boolean;const ADesktop:THandle);reintroduce;
property WindowHandle:THandle read FWindowHandle;
end;implementationuses Unit2;procedure TFindWindowThread.Execute;
var
I:Integer;
begin
NameThreadForDebugging('TThread');
//make the current thread find window on the new desktop!
if not SetThreadDesktop(FDesktop) then begin
exit;
end;
for I:=0 to 60 do begin //wait 30 seconds for open the main window
FWindowHandle:=FindWindow(nil,PChar('WindowCaption'));
if FWindowHandle<>0 then begin
break;
end;
Sleep(500);
end;
end;constructor TFindWindowThread.Create(ACreateSuspended:Boolean;const ADesktop:THandle);
begin
inherited Create(ACreateSuspended);
FDesktop:=ADesktop;
end;end.
主代码
unit Unit2;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm2 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
FDesktop:HDESK; { Private declarations }
public
{ Public declarations }
end;var
Form2: TForm2;
const
DesktopName = 'MYDESK';implementationuses Unit3;{$R *.dfm}procedure TForm2.Button1Click(Sender: TObject);
var
StartInfo:TStartupInfo;
FProceInfo :TProcessInformation;
begin
FillChar(StartInfo, sizeof(StartInfo), 0);
StartInfo.cb:=sizeof(StartInfo);
StartInfo.lpDesktop:=PChar(DesktopName); //指定Desktop的名称即可
StartInfo.wShowWindow:=SW_SHOW;
StartInfo.dwFlags:=STARTF_USESHOWWINDOW;
StartInfo.hStdError:=0;
StartInfo.hStdInput:=0;
StartInfo.hStdOutput:=0;
if not CreateProcess('D:\Downloads\quickpar\QuickPar\QuickPar.exe', nil,nil,nil,true,0,nil,'D:\Downloads\quickpar\QuickPar',StartInfo,FProceInfo) then begin
MessageBox(Application.Handle,PChar(inttostr(GetLastError)),PChar(Application.Title),MB_ICONWARNING);
exit;
end;
end;procedure TForm2.Button2Click(Sender: TObject);
begin
FDesktop:=CreateDesktop(DesktopName,nil,nil,0,GENERIC_ALL,nil);
if FDesktop=0 then
ShowMessage( IntToStr(GetLastError));end;procedure TForm2.Button3Click(Sender: TObject);
begin
FindWindowThread:=TFindWindowThread.Create(false,FDesktop); //这里一直编译不过
try
FindWindowThread.WaitFor;
FMainWindowHandle:=FindWindowThread.WindowHandle;
finally
FindWindowThread.Free;
end;
if FMainWindowHandle=0 then begin
MessageBox(Application.Handle,'Error when init voice (6).',PChar(Application.Title),MB_ICONWARNING);
exit;
end;
end;
原文地址http://blog.csdn.net/tonylk/archive/2005/04/21/357701.aspx
后台完美调用外部程序