做出来了,是不是真有500分给哦:)var h,k: HWND; vClassName,vText:array [0..1024] of char; begin h := FindWindow(nil, '记事本'); k:=GetWindow(h,GW_CHILD) ; //子控件- 最後一个产生的控件 while k<>0 do begin getClassName(k,vclassname,1024); if SameText(vclassname,'Static') then begin Getwindowtext(k, vText,1024); if vText <> '' then ShowMessage(vText); end; k:=GetWindow(k,GW_HWNDNEXT) ; //上一个产生的子控件 end; end;
to merkey2002(小样的) 当然,但是要符合我的要求
其实我要做的就是用hook来捕捉应用程序运行时产生的错误对话框中的错误提示信息!
赶紧试试哦, h := FindWindow(nil, '记事本');把这里的'记事本'换成你知道的title
Getwindowtext 得到是窗口的标题 不是窗口中的提示信息
呵呵,merkey2002(小样的)的程序是可以的不知道楼主的测试环境是怎样的。
测试例子: project1: ================================ procedure TForm1.Button1Click(Sender: TObject); begin MessageBox(handle,'错误异常','错误',MB_ICONERROR or MB_OK); end; ================================ project2: ================================ procedure TForm1.Button1Click(Sender: TObject); var hTitle: HWND; hTitle1: HWND; hTitle2: HWND; pText: array[0..254] of Char; begin hTitle := FindWindow(nil, '错误'); if hTitle <> 0 then begin hTitle1:= findwindowex(hTitle,0,'Static',nil); SendMessage(hTitle1, WM_GETTEXT, 256, LPARAM(@pText)); while pText = '' do begin hTitle2:= GetNextWindow(hTitle1,GW_HWNDNEXT); SendMessage(hTitle2, WM_GETTEXT, 256, LPARAM(@pText)); end; edit1.Text:= pText; end; end; ============================== 代码离完善还差的很远,只是写出简单的思路。 1、先通过title找到消息框的handle,FindWindow。 2、通过FindWindowEx找类名为Static的句柄,然后发消息获得text。
var h,k: HWND; vClassName,vText:array [0..1024] of char; begin h := FindWindow(nil, 'Microsoft Word'); if h = 0 then ShowMessage('A'); k:=GetWindow(h,GW_CHILD) ; //子控件- 最後一个产生的控件 while k<>0 do begin getClassName(k,vclassname,1024); if SameText(vclassname,'Static') or SameText(vclassname,'MSOUNISTAT') then begin Getwindowtext(k, vText,1024); if vText <> '' then ShowMessage(vText); end; k:=GetWindow(k,GW_HWNDNEXT) ; //上一个产生的子控件 end;//word里弹出的提示框要找类名是'MSOUNISTAT',要是其它的提示框还是找不到,就把 if SameText(vclassname,'Static') or SameText(vclassname,'MSOUNISTAT') then 这句话注释掉, showmessage(vclassname)出来,看看它到底是哪个类
比较麻烦,
h,k: HWND;
vClassName,vText:array [0..1024] of char;
begin
h := FindWindow(nil, '记事本');
k:=GetWindow(h,GW_CHILD) ; //子控件- 最後一个产生的控件
while k<>0 do
begin
getClassName(k,vclassname,1024);
if SameText(vclassname,'Static') then
begin
Getwindowtext(k, vText,1024);
if vText <> '' then
ShowMessage(vText);
end;
k:=GetWindow(k,GW_HWNDNEXT) ; //上一个产生的子控件
end;
end;
当然,但是要符合我的要求
h := FindWindow(nil, '记事本');把这里的'记事本'换成你知道的title
project1:
================================
procedure TForm1.Button1Click(Sender: TObject);
begin
MessageBox(handle,'错误异常','错误',MB_ICONERROR or MB_OK);
end;
================================
project2:
================================
procedure TForm1.Button1Click(Sender: TObject);
var
hTitle: HWND;
hTitle1: HWND;
hTitle2: HWND;
pText: array[0..254] of Char;
begin
hTitle := FindWindow(nil, '错误');
if hTitle <> 0 then
begin
hTitle1:= findwindowex(hTitle,0,'Static',nil);
SendMessage(hTitle1, WM_GETTEXT, 256, LPARAM(@pText));
while pText = '' do
begin
hTitle2:= GetNextWindow(hTitle1,GW_HWNDNEXT);
SendMessage(hTitle2, WM_GETTEXT, 256, LPARAM(@pText));
end;
edit1.Text:= pText;
end;
end;
==============================
代码离完善还差的很远,只是写出简单的思路。
1、先通过title找到消息框的handle,FindWindow。
2、通过FindWindowEx找类名为Static的句柄,然后发消息获得text。
-----------
倒
Getwindowtext(k, vText,1024);这里的句柄k并不是窗口的,而是窗口子控件的
你要先看看系统消息框的类结构是什么啊?然后再用HOOK来做要容易些。或者你告诉我怎么能搞出一个系统的错误对话框,我试着再写一个,哈哈哈。
”或者你告诉我怎么能搞出一个系统的错误对话框,我试着再写一个“这个很容易啊,比如说:你试图删除一个已经打开的word文档!
就会弹出一个对话框“无法删除temp.doc ... ”
我试过了,不行,根本就得不到对话框中的文本信息
h,k: HWND;
vClassName,vText:array [0..1024] of char;
begin
h := FindWindow(nil, 'Microsoft Word');
if h = 0 then
ShowMessage('A');
k:=GetWindow(h,GW_CHILD) ; //子控件- 最後一个产生的控件
while k<>0 do
begin
getClassName(k,vclassname,1024);
if SameText(vclassname,'Static') or SameText(vclassname,'MSOUNISTAT') then
begin
Getwindowtext(k, vText,1024);
if vText <> '' then
ShowMessage(vText);
end;
k:=GetWindow(k,GW_HWNDNEXT) ; //上一个产生的子控件
end;//word里弹出的提示框要找类名是'MSOUNISTAT',要是其它的提示框还是找不到,就把
if SameText(vclassname,'Static') or SameText(vclassname,'MSOUNISTAT') then
这句话注释掉, showmessage(vclassname)出来,看看它到底是哪个类
是无法通过简单的
SendMessage(.. WM_GETTEXT, ...);
Getwindowtext
来取得的,楼上这么多人说可以,倒把我搞糊涂了我知道的做法,是 Hook 系统的 drawtext, drawtextEx 之类的函数,
然后发个repaint的消息给那个窗口,这样来取得,
实际写代码,还是有点小麻烦,需要调试
但是屏幕取词需要移动鼠标,将鼠标停在取词的文本上!!!
我需要程序自动的获取对话框中的文本,怎么实现呢?
是无法通过简单的
SendMessage(.. WM_GETTEXT, ...);
Getwindowtext
来取得的,楼上这么多人说可以,倒把我搞糊涂了
=========================
可是我试了几个系统的提示消息框、错误信息框,用Spy查看到都是Static类的,都是可以通过WM_GETTEXT获得的,而且测试成功了。
不知系统的消息框是否还有其它类结构的。
就会弹出一个对话框“无法删除temp.doc ... ”
============================
这个我也测试过了,没问题,可以获得信息啊。晕
procedure TForm1.Button1Click(Sender: TObject);
var
hTitle: HWND;
hTitle1: HWND;
pText: array[0..254] of Char;
begin
hTitle := FindWindow(nil, '删除文件或文件夹时出错');
//这里的title只是测试你说的这种错误情况,实际需要HOOK来获得。
if hTitle <> 0 then
begin
hTitle1:= findwindowex(hTitle,0,'Static',nil);
SendMessage(hTitle1, WM_GETTEXT, 256, LPARAM(@pText));
while pText = '' do
begin
hTitle1:= GetNextWindow(hTitle1,GW_HWNDNEXT);
SendMessage(hTitle1, WM_GETTEXT, 256, LPARAM(@pText));
end;
edit1.Text:= pText;
end;
end;
但是屏幕取词需要移动鼠标,将鼠标停在取词的文本上!!!
我需要程序自动的获取对话框中的文本,怎么实现呢------------------------------------------------------
当错误提示框弹出来的时候,在如果在错误提示框弹上按CTRL+C,就可以把内容复制进剪贴板。
楼主可以试下按照这个思路来获取,先让错误提示框获得焦点,再模拟键盘的CTRL+C,然后就可以从剪贴板中获取错误提示内容
我说的删除word文档出错,只是一个例子而已,实际的应用程序(第三方程序)在运行时,可能出现各种各样的错误对话框,我的目的是要获取这些错误对话框中的内容!!!
如果是用 hook api 的方法,可以用遍历上面的控件,然后过滤,
给关键的那个 发送个 repaint 的消息让他重新刷新但很奇怪,xixuemao 和 csnight 的说法,似乎已经可以解决大部分的情况了
===================================
和系统相关的我想这个办法应该都可以解决。
但如果是三方程序自己做的消息框,比如上面的文本是个TPanel或TLabel类的话,好像就不行了@_@