请教:有一个应用程序,窗口上有8个文本框,以前是手工录入数据的。
现要求写一个工具,自动往其中5个文本框中写入数据。目前已经可以获得那个应用程序的句柄,现不知如何得到那个窗口上的文本框的名称。

解决方案 »

  1.   

    1.i:=FindWindow
    2.SendMessage(i,WM_SETTEXT,256,Integer(字符串变量))
      

  2.   


    var
      i,j:Thandle; //句柄变量
      MyText : String; //发送的字符串
    begin
      i:=FindWindow(nil,'窗口名称);     
      j:=FindWindowEx(i,0,'Edit',nil);  //用Spy++ Lite查看类
      MyTest:='XXX';
      SendMessage(j, WM_SETTEXT, 256,integer(MyText)); 
    end;
      

  3.   

    我用delphi建了一个接收程序,再用delphi建一个发送程序,可以实现功能(因为指定了文本框名称)。但我目前无法知道第三方的程序是什么语言开发的。
      

  4.   

    hwindows:=FindWindow(nil,'窗口名称);  通过EnumChildWindows(hwindows,@EnumChildProc,0)枚举出所有父窗口下的子句柄
    然后再通过GetClassName来取得所有父窗口下的子句柄的类名,通过这些类句来判断那些是文本框,然后就开始向文本框发送消息
      

  5.   

    记得给分呀,现在可以向Edit写入信息,测试已经通过,记得给分呀unit Unit6;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm6 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Label1: TLabel;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form6: TForm6;
      hPar:thandle;
      hcl,hc12:array[1..100] of thandle;
       i:cardinal;
    implementationfunction EnumChildProc( handle:thandle; lParam:integer):boolean;stdcall;
     begin
        if handle<>0 then
        begin
          hcl[i]:=handle;
          i:=i+1;
          Result:=true;    end
        else
         Result:=false;
        
     end;{$R *.dfm}procedure TForm6.Button1Click(Sender: TObject);
    var
    n:cardinal;
    text:string;
    buf:array[0..99] of char;
    begin
    fillchar(buf,100,0);
    text:='嘿嘿这是一个测试程序';
    i:=1;
    if   Edit1.Text='' then
    begin
      showmessage('应用程序标题没填');
      exit;
    end;
    hpar:=Findwindow(nil,pchar(Edit1.Text));
    if hpar=0 then
    begin
      showmessage('标题不正确或者该程序不存在');
      exit;
    end;
    EnumChildWindows(hpar,@EnumChildProc,0);
    for n:= 1 to 100 do
      begin    if hcl[n]<>0 then
      begin
        getclassname(hcl[n],buf,100);
        if buf='TEdit' then
        hc12[n]:=hcl[n]
        else
        Button1.Caption:=buf;
      end;  end;
    for n := 1 to 100 do
    begin
      if hc12[n]<>0 then
      begin
        sendmessage(hc12[n],wm_settext,0,integer(text));
      end;
    end;
      i:=1;
    end;end.
      

  6.   

     if buf='TEdit' then  忘了说明不同的程序编辑框的类名会不同,所以如果不是delphi的应用程序的话,请自己查那个编辑框是什么类名的,delphi的是TEdit,这程序可以向其它的delphi应用程序的文本框写数据
      

  7.   


    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Label1: TLabel;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
       hPar:thandle;
      hcl,hc12:array[1..100] of thandle;
       i:cardinal;implementation
     function EnumChildProc( handle:thandle; lParam:integer):boolean;stdcall;
     begin
        if handle<>0 then
        begin
          hcl[i]:=handle;
          i:=i+1;
          Result:=true;    end
        else
         Result:=false;
        
     end;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
     var
    n:cardinal;
    text:string;
    buf:array[0..99] of char;
    begin
    fillchar(buf,100,0);
    text:='嘿嘿这是一个测试程序';
    i:=1;
    if   Edit1.Text='' then
    begin
      showmessage('应用程序标题没填');
      exit;
    end;
    hpar:=Findwindow(nil,'无标题 - 记事本');
    if hpar=0 then
    begin
      showmessage('标题不正确或者该程序不存在');
      exit;
    end;
    EnumChildWindows(hpar,@EnumChildProc,0);
    for n:= 1 to 100 do
      begin    if hcl[n]<>0 then
      begin
        getclassname(hcl[n],buf,100);
        if buf='TEdit' then
        hc12[n]:=hcl[n]
        else
        Button1.Caption:=buf;
      end;  end;
    for n := 1 to 100 do
    begin
      if hc12[n]<>0 then
      begin
        sendmessage(hc12[n],wm_settext,0,integer(text));
      end;
    end;
      i:=1;
    end;end.
    测试结果,并未放记事本的edit中写入东西?不知错在哪里?
      

  8.   

    真不好意思,忘记了xp的记事本不是d写的
    类名没有t
    这是我测试的代码,贴出来,给楼主当例子看看.
    我测试的是13楼的代码,用记事本测试,通过
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Label1: TLabel;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
       hPar:thandle;
      hcl,hc12:array[1..100] of thandle;
       i:cardinal;implementation
     function EnumChildProc( handle:thandle; lParam:integer):boolean;stdcall;
     begin
        if handle<>0 then
        begin
          hcl[i]:=handle;
          i:=i+1;
          Result:=true;    end
        else
         Result:=false;
        
     end;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
     var
    n:cardinal;
    text:string;
    buf:array[0..99] of char;
    begin
    fillchar(buf,100,0);
    text:='嘿嘿这是一个测试程序';
    i:=1;
    if   Edit1.Text='' then
    begin
      showmessage('应用程序标题没填');
      exit;
    end;
    hpar:=Findwindow(nil,'无标题 - 记事本');
    if hpar=0 then
    begin
      showmessage('标题不正确或者该程序不存在');
      exit;
    end;
    EnumChildWindows(hpar,@EnumChildProc,0);
    for n:= 1 to 100 do
      begin    if hcl[n]<>0 then
      begin
        getclassname(hcl[n],buf,100);
        if buf='Edit' then
        hc12[n]:=hcl[n]
        else
        Button1.Caption:=buf;
      end;  end;
    for n := 1 to 100 do
    begin
      if hc12[n]<>0 then
      begin
        sendmessage(hc12[n],wm_settext,0,integer(text));
      end;
    end;
      i:=1;
    end;end.
      

  9.   

    谢谢13,15楼的兄弟,发送测试是成功了,但还有一点不明白:
    sendmessage过去的内容的顺序是颠倒的,
    即用for n:=1 to 100 第一个sendmessage的信息被传给最后一个文本框,
                第二个sendmessage的信息被传给倒数第二个文本框,依次
    也就是说文本框的顺序,刚好与 for n to 结构中的顺序相反。不明白什么原因,请再帮解释一下。
      

  10.   

    这个要确定文本框的顺序,只能通过一个一个找啦,找过后就知道他的顺序了,这样以后再用就可以不用找了(除非你知道他的文本框名),查找句柄的时候好像跟Tab的顺序有关,那你倒过来发送就可以了
      

  11.   

    sendmessage(hc12[n],wm_settext,0,integer(text)+inttostr(n)); 
    我这样测出来的
      

  12.   

    有其他朋友指点说:通过窗体句柄与控件句柄的一个偏移量就可以定位某一个文本框了,我通过spy++是可以得到窗体的句柄,也可以得到文本框控件的句柄,朋友说控件句柄与窗体句柄的偏移量是固定的,所以,只要得到窗体的句柄,然后与偏移量一计算,即可以得到文本框的句柄,然后对这个句柄sendmessage.朋友是搞C++的,不清楚这个在delphi如何实现。
      

  13.   


    这个可以指定的,要自己加.他可能自己加上去了吧,关键是找到文本框的顺序(我只想到一个一个找,sendmessage(hc12[n],wm_settext,0,integer(text)); 在这里加个sleep(3000);),这样就可以有定时间看到顺序了,这样就很容易搞定了
      

  14.   

    sendmessage(hc12[n],wm_settext,0,integer(text+inttostr(n))
      

  15.   

    我用delphi做了一个接收的窗体,窗体中只有三个文本框,但是发送程序传过来的数据是从第三个文本框开始倒序接收数据的。
    即 for n:=1 to 100 do 
          sendmessage(hc12[n],wm_settext,0,integer(text+inttostr(n))接收窗口不是从第一个文本框开始,而是从第三个,然后第二个,再第一个,以这种方式接收
      

  16.   

    应该跟EnumChildWindows的查找方式有关,
    比如HWND FindWindowEx(
      HWND hwndParent,      // handle to parent window
      HWND hwndChildAfter,  // handle to child window
      LPCTSTR lpszClass,    // class name
      LPCTSTR lpszWindow    // window name
    );
    hwndChildAfter 
    [in] Handle to a child window. The search begins with the next child window in the Z order. The child window must be a direct child window of hwndParent, not just a descendant window. 
      

  17.   

    看来还只有用for n:=1 to 100这种方式去查出我要写数据的文本框在这个for 结构中的顺序了,再往里面sendmessage了。
    不知还有没有通过窗口句柄与控件句柄的偏移里的方式来定位的办法了,请高手帮兄弟一把啊。谢谢啦!
      

  18.   

    个人觉得窗口句柄与控件句柄的偏移里的方式来定位的办法了这个更麻烦,你又怎么知道那个定位的是第一个,那个是第二个呀,还不是一样要自己来判断,太麻烦了,你可能知道第一个控件句柄放在那里,但你那里知道第二个会在那里呀,因他们中间可能有其它控件,而且这加载关系跟他定义的关系有关,所以还是用findwindows简单
      

  19.   

    请qxf32和zhangxiaommmm再去http://topic.csdn.net/u/20081222/11/30dd388f-21a1-4181-b3b9-7ee5f5f8ca83.html 领分
    http://topic.csdn.net/u/20081222/11/4f61ba29-e2bd-48ed-b3e2-941541e92512.html领分