困惑:如何调用另一个程序,并控制它

困惑:如何调用另一个程序,并控制它 Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiAPI/html/delphi_20061113000418245.html
我现在想调用B(也是delphi)程序,我用的是  
  procedure   TForm1.Button1Click(Sender:   TObject);  
  begin  
      ShellExecute(0,'open',projectB.exe'),nil,nil,SW_ShowNormal);  
  end;  
  启动后出现B程序的登陆界面,界面上有登陆框  
     
  问题是:如何向里面传进用户名和密码  
  并能实现自动点击登陆按钮的操作?

有好多方法实现。我给你一个我的实例(看门狗WatchDog)  
  var  
      Dir:   string;  
  begin  
      ...  
      Dir   :=   ExtractFileDir(Application.ExeName);  
      Winexec(Pchar(Dir+'\SMSEVALUATE.EXE   00001   11111),1);  
      //SMSEVALUATE.EXE是我的程序名称与WatchDog在同一目录下  
        用户代码:00001   用户密码:11111(你不一定这样设置,只要区分有没有参数就可以了)  
      ...  
   
   
  在SMSEVALUATE的Project中这样写:  
   
      Application.Initialize;  
      Application.Title   :=   '我的系统;  
      with     TFormLogin.Create(Application)   do  
      begin  
          if   ParamCount   =   0   then   //重要点,  
                                                          //如果没有参数就正常显示登陆窗口,  
                                                          //如果有参数就不显示,  
                                                          //在FormLogin中要加入带参数运行时的处理代码  
              ShowModal;  
          if   ModalResult   =   1   then  
          ...

楼主碰到的情况可能是B程序用不了参数的吧,要给他的文本框里发信息

//  
  楼主碰到的情况可能是B程序用不了参数的吧,要给他的文本框里发信息  
  //  
  任何程序都可以带参数运行,就看你程序内部如何处理参数啦。所以不用给他的文本框里发信息  
   
  //  
  给他的文本框里发信息  
  //  
  太僵硬的思路啦  
 

呵呵,谢谢两位:)  
  补充一下:B程序里的代码改动不了  
  只能往B的文本框里传信息  
   
  这种情况怎么处理?  
 

先启动B这个进程,然后用FindWindow/FindWindowEx/GetWindow等API查找目标程序主窗口上的文本框和按钮(这个过程可能要试好几次才能准确找到),成功得到文本框句柄后,用SetWindowText或WM_SETTEXT给文本框赋值,再向按钮发送BM_CLICK消息,例如:  
  SendMessage(hButton,   BM_CLICK,   0,   0);

对对,这种实现方法很适合我的情况  
  就是能不能给点   代码demo之类的,如上面的sanmaotuo(老冯)兄弟那样  
  感激ing...

那都是些API应用,还需要详细代码?  
   
  这样吧,你去www.ccrun.com/spy4win下载spy4win,可以自动产生一些简单的查找窗口的代码)for   C++,Delphi,VB),看看你就明白了。

经指点后,我写了以下一段代码  
  但是还有一个问题:如下,  
   
  procedure   TForm1.Button3Click(Sender:   TObject);  
  var  
      FHwnd   :   THandle;  
      t1Hwnd:THandle;  
      t2Hwnd:   THandle;  
      BHwnd:   THandle;  
   
  begin  
      WinExec(PChar('project1.exe'),SW_HIDE)   ;  
      FHwnd:=FindWindow(nil,'form1');  
      if   fHwnd>0   then  
      begin  
          t1Hwnd:=FindWindowEx(fHwnd,0,nil,'edit1');  
          t2Hwnd:=FindWindowEx(fHwnd,0,nil,'edit2');  
  //这样成功取到edit1句柄的前提是edit1的text必须有值  
      但是当edit1的text属性为空的时候就取不到句柄,这可咋整??  
   
          BHwnd:=FindWindowEx(fHwnd,0,nil,'button1');  
   
          if   t1Hwnd>0   then   PostMessage(t1Hwnd,WM_IME_CHAR,ord('a'),0)   ;  
          if   t2Hwnd>0   then   PostMessage(t2Hwnd,WM_IME_CHAR,ord('b'),0)   ;  
          if   BHwnd>0   then   PostMessage(BHwnd,WM_KEYDOWN,VK_RETURN   ,0)   ;  
      end;  
      //PostMessage(FHwnd,WM_KEYDOWN,VK_RETURN   ,0)  
      //SendMessage(FHwnd,   BM_CLICK,   0,   0);  
  end;  
      还望指点!

查找Edit时,先用FindWindowEx找到第一个文本框,第四个参数可为空,直接查找类名就可以。成功后用GetWnidow再查找下一个兄弟窗口。  
  可以参考一下这个:  
   
  自动填写序列号演示  
  AutoFillSnDemo,安装Office2003时自动填写序列号工具源码,ccrun(老妖)编写。读者可自己扩展一下,成为一个通用的序列号填写工具。  
  http://www.ccrun.com/view.asp?id=349

在主模块调用子模块时(主模块与子模块是独立的程序),用DLL或DDE即可!  
 

ccrun(老妖)已经说得很清楚了,   我来把老妖的精神Coding一下。很认真做的哦,不是说笑哈。  
  type  
      TSAppForm   =   class(TForm)  
          Button:   TButton;  
          procedure   ButtonClick(Sender:   TObject);  
      private  
          function   FindControlByNumber(hApp:   HWND;   ControlClassName:   string;   ControlNumber:   Integer):   HWND;  
          procedure   SetEditText(hApp:   HWND;   EditClassName,   AText:   string;   EditNumber:   Integer);  
          procedure   SetButtonActive(hApp:   HWND;   ButtonClassName:   string;   ButtonNumber:   Integer);  
      public  
          {   Public   declarations   }  
      end;  
   
  var  
      SAppForm:   TSAppForm;  
   
  implementation  
   
  {$R   *.dfm}  
   
  {   TSAppForm   }  
   
  function   TSAppForm.FindControlByNumber(hApp:   HWND;  
      ControlClassName:   string;   ControlNumber:   Integer):   HWND;  
  var  
      i:   Word;  
      hControl:   HWND;  
  begin  
      Result   :=   0;  
      hControl   :=   0;  
      if   IsWindow(hApp)   then  
      begin  
          hControl   :=   0;  
          for   i   :=   0   to   Pred(ControlNumber)   do  
          begin  
              hControl   :=   FindWindowEx(hApp,   hControl,   PChar(ControlClassName),   nil);  
              if   hControl   =   0   then  
                  Exit;  
          end;  
      end;  
      Result   :=   hControl;  
  end;  
   
  procedure   TSAppForm.SetEditText(hApp:   HWND;   EditClassName,   AText:   string;  
      EditNumber:   Integer);  
  var  
      hEdit:   HWND;  
  begin  
      hEdit   :=   FindControlByNumber(hApp,   EditClassName,   EditNumber);  
      if   hEdit   <>   0   then  
          SendMessage(hEdit,   WM_SETTEXT,   0,   Integer(PChar(AText)));  
  end;  
   
  procedure   TSAppForm.ButtonClick(Sender:   TObject);  
  var  
      hApp:   HWND;  
  begin  
      hApp   :=   FindWindow(nil,   'RAppForm');  
      if   hApp   >   0   then  
      begin  
          SetEditText(hApp,   'TEdit',   'Cock',   1);  
          SetEditText(hApp,   'TEdit',   'Pussy',   2);  
          SetButtonActive(hApp,   'TButton',   1);  
      end;  
  end;  
   
  procedure   TSAppForm.SetButtonActive(hApp:   HWND;   ButtonClassName:   string;  
      ButtonNumber:   Integer);  
  var  
      hButton:   HWND;  
  begin  
      hButton   :=   FindControlByNumber(hApp,   ButtonClassName,   ButtonNumber);  
      if   hButton   >   0   then  
          SendMessage(hButton,   WM_KEYDOWN,   VK_RETURN,   0);  
  end;  
   
  end.  
   
   
  -------------------------------  
   
   
  type  
      TRAppForm   =   class(TForm)  
          Button:   TButton;  
          Edit1:   TEdit;  
          Edit2:   TEdit;  
          procedure   ButtonKeyDown(Sender:   TObject;   var   Key:   Word;  
              Shift:   TShiftState);  
      private  
          {   Private   declarations   }  
      public  
          {   Public   declarations   }  
      end;  
   
  var  
      RAppForm:   TRAppForm;  
   
  implementation  
   
  {$R   *.dfm}  
   
  procedure   TRAppForm.ButtonKeyDown(Sender:   TObject;   var   Key:   Word;  
      Shift:   TShiftState);  
  begin  
      if   Key   =   VK_Return   then  
          ShowMessage(Edit1.Text+'\'+Edit2.Text);  
  end;

经过你两多次指点,问题解决  
  非常感谢,好人啊!  
 

献上我的拙码给其他需要的人:  
  (B程序上为   两个edit和一个button)  
  procedure   TForm1.Button1Click(Sender:   TObject);  
  var  
      FHwnd   :   THandle;  
      t1Hwnd:THandle;  
      t2Hwnd:   THandle;  
      BHwnd:   THandle;  
   
  begin  
      WinExec(PChar('projectB.exe'),SW_HIDE)   ;  
      FHwnd:=FindWindow(nil,'form1');  
      if   fHwnd>0   then  
      begin  
          t1Hwnd:=FindWindowEx(FHwnd,0,'TEdit',nil);  
          if   t1Hwnd<>0   then  
              t2Hwnd:=GetWindow(t1Hwnd,   GW_HWNDNEXT);  
          BHwnd:=FindWindowEx(FHwnd,0,'TButton',nil);  
   
          if   t1Hwnd>0   then    
                SendMessage(t1Hwnd,   WM_SETTEXT,   0,   Integer(PChar('user')));  
          if   t2Hwnd>0   then    
                SendMessage(t2Hwnd,   WM_SETTEXT,   0,   Integer(PChar('pwd')));  
          if   BHwnd>0   then  
              PostMessage(BHwnd,WM_KEYDOWN,VK_RETURN   ,0)   ;  
      end;  
  end;  
 

posted on 2009-02-03 09:47  delphi2007  阅读(377)  评论(0编辑  收藏  举报