如何遍历其他程序窗口,并得到窗口文本?
ERP系统状态栏有显示:操作员:xxx
现在需遍历ERP主界面,而后取出操作员怎么办.深夜加班,请各位在线大佬救急(如哈欠,大风,故国,月亮....)
暂时上不了QQ

解决方案 »

  1.   

    遍历窗口的方法已经知道(由于以前ERP的做法是在主界面caption上会显示易飞ERP系统 用户名,所以很方便的取得了登陆用户,可用友的登陆用户放在了窗口的子控件状态栏中,就不知道怎么搞了)
      

  2.   

      EnumChildWindows(Handle,   @EnumChildProc,   Integer(Memo1))
    试试吧……在下菜鸟一个,高手莫拍砖头
      

  3.   

    FindWindow找到主窗体的句柄,EnumChildWindows枚举子窗口(所有Windows控件都是窗口,所以状态栏也算是子窗口)。比较窗口类名,比如你用的VCL的TStatusBar类名就是"TStatusBar",然后用Windows消息取得状态栏对应格的文本。消息ID我忘记了,你可以参阅msdn,也可以参考VCL里的实现。
      

  4.   

    可惜这个程序是VB.NET写的,DELPHI取不到
      

  5.   

    感觉应该调用windows的api来实现。
      

  6.   

    FindWindow来找窗体
    FindWindowEx来找控件,
    找到控件再用什么WM_GETTEXT来取信息
      

  7.   

    可以用Spy++看一看你那个关心的那个界面控件
      

  8.   

    不管你用什么写,控件(窗体)总有一个类名的,用SPY++就可以看到
      

  9.   

    那个状态栏的不一定搞得定,目标程序是什么写的知道不?
    怎么说呢,譬如我来写这个状态栏组件的话,我都不一定从TWinControl继承,因为一般来说状态栏根本不需要焦点什么的,直接从TGraphicControl继承,这样一来,状态栏变成了一个纯GDI绘图的假窗体,没有窗体的Handle,所以用API根本找不到。即使状态栏是从TWinControl继承(TStatusBar是从TWinControl继承的),有Handle,但也一般不会将子区域(TStatusPanel)从TWinControl继承,因此,每个Panel上面的文字并不是WindowText,而是用GDI将文字绘制上去的,因此别想用GetWindowText、WM_GETTEXT来获得文本。
    如果知道目标程序是Delphi写的,并且能够查出状态栏组件,可以尝试自己装上该组件,然后用dll注入目标进程的方式来获取文本,不知道有没有牛人知道更好更方便的方式
      

  10.   

    下面的代码可以解决你的问题:
    窗体:
    object Form1: TForm1
      Left = 192
      Top = 114
      Width = 555
      Height = 158
      Caption = '获取其它程序的状态栏信息'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      FormStyle = fsStayOnTop
      OldCreateOrder = False
      Position = poScreenCenter
      PixelsPerInch = 96
      TextHeight = 13
      object Edit1: TEdit
        Left = 24
        Top = 56
        Width = 497
        Height = 21
        TabOrder = 0
        Text = 'Edit1'
      end
      object Timer1: TTimer
        OnTimer = Timer1Timer
        Left = 192
        Top = 16
      end
    endPas文件:unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls;type
      TForm1 = class(TForm)
        Edit1: TEdit;
        Timer1: TTimer;
        procedure Timer1Timer(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }  end;var
      Form1: TForm1;implementation{$R *.dfm}uses CommCtrl;
    function GetStatusBarText(mHandle: THandle): string;
    var
      vBuffer: array[0..$1000] of Char;
      vSize: Integer;
      I: Integer;
      vCount: Integer;
      vProcessId: DWORD;
      vProcess: THandle;
      vPointer: Pointer;
      vNumberOfBytesRead: Cardinal;
    begin
      Result := '';
      vCount := SendMessage(mHandle, SB_GETPARTS, 0, 0);
      if vCount <= 0 then Exit;
      GetWindowThreadProcessId(mHandle, @vProcessId);
      vProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
        PROCESS_VM_WRITE, False, vProcessId);
      vPointer := VirtualAllocEx(vProcess, nil, $1000, MEM_RESERVE or MEM_COMMIT,
        PAGE_READWRITE);
      try
        for I := 0 to vCount - 1 do
        begin
          vSize := SendMessage(mHandle, SB_GETTEXT, I, 0) + 1;
          SendMessage(mHandle, SB_GETTEXT, I, Integer(vPointer));
          ReadProcessMemory(vProcess, vPointer, @vBuffer[0],
            vSize, vNumberOfBytesRead);
          Result := Result + #9 + vBuffer;
        end;
        Delete(Result, 1, 1);
      finally
        VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
        CloseHandle(vProcess);
      end;
    end; { GetStatusBarText } procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    Edit1.Text := GetStatusBarText(      WindowFromPoint(Mouse.CursorPos));
    end;end.备注:    在窗体上放一个Edit和Timer,写入上面的代码。打开你要的程序(例如任务管理器),然后鼠标移到它的状态栏下就可以发现你的程序Edit中已经取得到任务管理器的状态栏信息。当然,这是根据取鼠标位置取句柄的方法,你可以自己写遍历窗体得到状态栏的句柄。其实,你的提问方式不好,问题应该改为《如何获取其它程序的状态栏信息》。希望我的回答对你有所帮助。
      

  11.   

    楼上的,你的代码针对“msctls_statusbar32”我想是管用的,今天又学习了
    不知道第三方控件是不是也是基于“msctls_statusbar32”的哦
      

  12.   

    无条件为你,你的代码应该不能解决问题
    我刚说了,其他程序是.net写的,并且可能是自定义控件,所以取不到.
      

  13.   

    浮云MM说,用Managed Spy可以取到文字浮云(7146269) 09:23:20
    Managed Spy我记得创建了一个跨进程的对象代理,在Managed Spy里面可以直接用属性编辑器来编辑其他进程控件的属性,就和本地一样
      

  14.   

    c#的label好像是用drawtext"画"上去的,所以不是窗口也没有句柄据说,just据说,这样的情况只能通过你重写个同名dll截获drawtext函数来实现.
      

  15.   

    据549说,Microsoft© Active Accessibility 可能可以做到.
      

  16.   

    包括Spy++也没办法把状态栏分开来取
    是否可以考虑根据状态栏相对坐标,屏幕取词?不过这样需要考虑一下屏幕分辨率的问题。
    屏幕取词的例子网上有很多。