看到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,并响应 按钮,
大家帮个忙。

解决方案 »

  1.   

    外部程序不是我写的。
    我现在是要我自己的程序  通过虚拟的Desktop 调用一个ABCD.EXE文件,这个ABCD.exe,组件有listbox,和2个按钮,(一个是《添加》,一个是《运行》),添加按钮是向listbox里插入项目,插入项目后,,相应运行按钮 ,
      

  2.   

    ABCD.EXE 添加按钮事件的值从哪里来,有Edit之类的编辑框吗?有的话模拟按键吧
      

  3.   

    我现在是  按照http://blog.csdn.net/tonylk/archive/2005/04/21/357701.aspx
    这样,,后台完美调用外部程序,,,我自己写的程序 在当前窗口运行,,然后创建一个虚拟的Desktop ,在虚拟的Desktop,运行外部程序,例如QQ的聊天窗口,我的程序向QQ聊天窗口 插入一条信息,然后按下发送按钮。后台完美调用外部程序,就是不让人看到 ,我在调用其他软件。
      

  4.   

    我现在想 通过http://blog.csdn.net/tonylk/archive/2005/04/21/357701.aspx这篇文章说的那样,后台完美调用外部程序
    调用下面这个程序,
    这个软件 我共享了
    http://u.115.com/file/t741585673#
      

  5.   

    我运行没有什么问题呀const
      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;
      

  6.   

    创建虚拟桌面估计没啥问题,关键是怎么向QuickPar传值 文件名 大小 路径,如果还要更改其他选项,估计更难,比较好的办法  找找有没有控制台下的QuickPar程序。
      

  7.   

    把我自己程序的。listbox item  传给 虚拟的Desktop里运行的QuickPar 的listbox,然后按下<创建>按钮。
    这里好像说明了下
    http://blog.csdn.net/tonylk/archive/2005/07/01/409614.aspx
    keeley20
    能帮我写个例子嘛
      

  8.   

    FDesktop:=CreateDesktop(DesktopName,nil,nil,0,GENERIC_ALL,nil);
    这句好像没执行呢
      

  9.   

    FDesktop:=CreateDesktop(DesktopName,nil,nil,0,GENERIC_ALL,nil);
    这句好像怎么没执行呢
      

  10.   

    你看一下,这是两个按钮,你先点Button2 ,在点 Button1 ,
      

  11.   

    zhaodog
     能帮忙写个不,
    好依样画葫芦。
      

  12.   

    zhaodog
    这个调试是成功的,
    在当前住窗口是看不到那个QuickPar的界面的,在进程中能看到QuickPar已经在打开了,
    但是
    zhaodog
     能帮忙写一下,怎么样向虚拟的Desktop里运行的QuickPar,传递那个按钮呢,
    或者怎么样能把 我程序的listbox的item,传递给 QuickPar的listbox,在按下那个创建按钮呢。
      

  13.   

    zhaodoghttp://blog.csdn.net/tonylk/archive/2005/04/21/357701.aspx
    原文中
    {但是,程序运行后,该函数却返回了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 }这个你编译的过吗
      

  14.   

    新建线程
    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
    后台完美调用外部程序