如何遍历其他程序窗口,并得到窗口文本?
ERP系统状态栏有显示:操作员:xxx
现在需遍历ERP主界面,而后取出操作员怎么办.深夜加班,请各位在线大佬救急(如哈欠,大风,故国,月亮....)
暂时上不了QQ
ERP系统状态栏有显示:操作员:xxx
现在需遍历ERP主界面,而后取出操作员怎么办.深夜加班,请各位在线大佬救急(如哈欠,大风,故国,月亮....)
暂时上不了QQ
解决方案 »
- 上次做了个2D象棋,这次要做3D的,求教大家。
- 求DELPHI通过GDI+实现"通过位图创建多边形区域"(300分)
- 请教各位高手,在程序中如何实现以下功能,给定一个字符串,程序会调用以该字符串为函数名称的函数?
- 怎么样让tabsheet1充满整个pagecontrl??
- 如何使程序运行后,任务栏上不显示
- 请问一个过程中使用ADOQUERY的问题??
- 求救!Delphi中TCheckListBox达到ReadOnly的效果怎么做?
- 寻求简单的答案
- Delphi里有没有类似于c里面的memcpy一样的函数?
- delphi 如何在 已有的 ini 文件后,继续写入内容(不删除原来的内容)
- 我用的delphi2007没有sqlmonitor
- 主从表中的下拉框选择列表问题
试试吧……在下菜鸟一个,高手莫拍砖头
FindWindowEx来找控件,
找到控件再用什么WM_GETTEXT来取信息
怎么说呢,譬如我来写这个状态栏组件的话,我都不一定从TWinControl继承,因为一般来说状态栏根本不需要焦点什么的,直接从TGraphicControl继承,这样一来,状态栏变成了一个纯GDI绘图的假窗体,没有窗体的Handle,所以用API根本找不到。即使状态栏是从TWinControl继承(TStatusBar是从TWinControl继承的),有Handle,但也一般不会将子区域(TStatusPanel)从TWinControl继承,因此,每个Panel上面的文字并不是WindowText,而是用GDI将文字绘制上去的,因此别想用GetWindowText、WM_GETTEXT来获得文本。
如果知道目标程序是Delphi写的,并且能够查出状态栏组件,可以尝试自己装上该组件,然后用dll注入目标进程的方式来获取文本,不知道有没有牛人知道更好更方便的方式
窗体:
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中已经取得到任务管理器的状态栏信息。当然,这是根据取鼠标位置取句柄的方法,你可以自己写遍历窗体得到状态栏的句柄。其实,你的提问方式不好,问题应该改为《如何获取其它程序的状态栏信息》。希望我的回答对你有所帮助。
不知道第三方控件是不是也是基于“msctls_statusbar32”的哦
我刚说了,其他程序是.net写的,并且可能是自定义控件,所以取不到.
Managed Spy我记得创建了一个跨进程的对象代理,在Managed Spy里面可以直接用属性编辑器来编辑其他进程控件的属性,就和本地一样
是否可以考虑根据状态栏相对坐标,屏幕取词?不过这样需要考虑一下屏幕分辨率的问题。
屏幕取词的例子网上有很多。