ag游戏庄闲|官方网站
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
?用户名
?密??码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: sy1368364703
今日帖子: 12
在线用户: 20
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil ?
作者:
男 tx001 (tx) ▲△△△△ -
注册会员
2019/8/22 10:12:27
标题:
美化调用的dll中ShowMessage弹出的消息窗体 浏览:457
加入我的收藏
楼主: 调用第三方delphi写的dll,dll中的消息是用ShowMessage弹出的,和程序的风格不匹配,想美化ShowMessage弹出窗体,或者能获取到ShowMessage的消息也行
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2019/8/22 10:29:15
1楼: 抓消息可以反编译找找字符串,或者hook掉showmessage函数。
再或者用findwindow等函数查找对话框窗口句柄,再用setwindowlongptr替换窗口函数,然后你就可以为所欲为了。
----------------------------------------------
--
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲▲ -
普通会员
2019/8/22 11:17:27
2楼: ShowMessage?和?MessageBox?是两个概念。
ShowMessage?是?DELPHI?FORM?做的。
改起来很难。
达成条件
1?你?IDE?必须和?DLL?的编译环境一样,控件一样。控件版本或源码一样。
2?你的美化代码,必须获取到?这个?Message?Form?对象。
然后?你才能修改。
不过?VCL?是有?皮肤接口的。
很多?VCL?皮肤控件,都是?利用?皮肤接口美化控件的。
最简单的是?VCLSKIN?最复杂的是?AlphaControls
----------------------------------------------
(C)(P)Flying?Wang
作者:
男 tx001 (tx) ▲△△△△ -
注册会员
2019/8/22 13:56:37
3楼: @bahamut8348?能详细说一下如何抓消息吗?想法是用findwindow函数找到ShowMessage弹出的窗口句柄,将他关闭,再根据消息弹自己的窗口
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2019/8/22 16:10:14
4楼: 看看findwindow的参数。然后自己用spy照一下你要折腾的窗口就行。
----------------------------------------------
--
作者:
男 tx001 (tx) ▲△△△△ -
注册会员
2019/8/22 17:49:49
5楼: 用findwindow能取到窗体句柄,但用WM_GETTEXT只能取到标题,取不到内容
----------------------------------------------
-
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2019/8/23 9:23:33
6楼: ShowMessage/MessageDlg在不同Windows/Delphi环境中可能会采用不同的方法,有用TMessageForm实现的,也有调用Windows?API创建的,此时窗口类名为#32770,并且新的windows会采用DirectUIHWND来画窗口,此时用FindWindow是找不到显示Message的组件的,必须用OleAcc单元中的接口函数来访问。
不知道楼主想怎样美化,如果只是取Message内容,倒是有办法,可以用我写的一些方法:
uses
??...,?Forms,?Dialogs,?OleAcc,?...;

function?MyGetClassName(Handle:?THandle):?string;
var
??buf:?array[0..255]?of?Char;
begin
??if?GetClassName(Handle,?buf,?SizeOf(buf))?>?0?then?begin
????Result?:=?buf;
??end?else?begin
????Result?:=?'';
??end;
end;

function?MyGetWindowText(hWnd:?THandle):?string;
var
??len:?Integer;
begin
??Result?:=?'';
??len?:=?SendMessage(hWnd,?WM_GETTEXTLENGTH,?0,?0);
??if?len?>?0?then?begin
????SetLength(Result,?len?+1);
????len?:=?SendMessage(hWnd,?WM_GETTEXT,?len?+1,?Integer(PChar(Result)));
????if?len?>?0?then?begin
??????SetLength(Result,?len);
????end?else?begin
??????Result?:=?'';
????end;
??end;
end;

function?FindFormByClass(const?AClassName:?string):?TForm;
var
??i:?Integer;
begin
??Result?:=?nil;
??for?i?:=?0?to?Application.ComponentCount?-1?do?begin
????if?Application.Components[i].ClassNameIs(AClassName)?then?begin
??????Result?:=?TForm(Application.Components[i]);
??????Exit;
????end;
??end;
end;

function?GetRoleTextW(dwRole:?DWORD;?lpszRole:?PWideChar;
??cchRoleMax:?UINT):?UINT;?stdcall;?external?'OLEACC.DLL';

function?MyGetRoleText(Acc:?IAccessible;?varChild:?OleVariant):?string;
var
??varRole?:?OleVariant;
??Len:?Integer;
begin
??Result?:=?'';
??if?Acc.get_accRole(varChild,?varRole)?=?S_OK?then?begin
????if?TVariantArg(varRole).vt?=?VT_I4?then?begin
??????Len?:=?GetRoleTextW(TVariantArg(varRole).lVal,?nil,?0);
??????SetLength(Result,?Len);
??????GetRoleTextW(TVariantArg(varRole).lVal,?PWideChar(Result),?Len?+?1);
????end;
??end;
end;

function?GetDialogMsgText(Handle:?THandle):?string;
var
??clsName:?string;
??frmMsg:?TForm;
??lblMsg:?TLabel;
??h:?THandle;
??i:?Integer;
??childCount:?Integer;
??acc:?????IAccessible;
??oChild:??IDispatch;
??s:?WideString;
begin
??Result?:=?'';
??if?Handle?=?0?then?Exit;

??clsName?:=?MyGetClassName(Handle);
??if?SameText('TMessageForm',?clsName)?then?begin
????frmMsg?:=?FindFormByClass('TMessageForm');
????if?Assigned(frmMsg)?then?begin
??????lblMsg?:=?frmMsg.FindComponent('Message')?as?TLabel;
??????if?Assigned(lblMsg)?then?begin
????????Result?:=?lblMsg.Caption;
??????end;
????end;
??end?else?if?SameText('#32770',?clsName)?then?begin
????h?:=?FindWindowEx(Handle,?0,?'DirectUIHWND',?nil);
????if?h?<>?0?then?begin
??????///?DirectUI
??????if?AccessibleObjectFromWindow(h,?OBJID_CLIENT,?IID_IAccessible,?acc)?=?S_OK?then?begin
????????if?S_OK?=?acc.Get_accChildCount(childCount)?then?begin
??????????for?i?:=?1?to?childCount?do?begin
??????????if?(S_OK?=?acc.Get_accChild(i,?oChild))?and
??????????SameText('text',?MyGetRoleText(oChild?as?IAccessible,?0))?then?begin
??????????s?:=?'';
??????????if?(S_OK?=?IAccessible(oChild).Get_accName(0,?s))?and?(s?<>?'')?then?begin
??????????Result?:=?s;
??????????Break;
??????????end;
??????????end;
??????????end;
????????end;
??????end;
????end?else?begin
??????///?Tradiontal?dialog
??????h?:=?0;
??????repeat
????????h?:=?FindWindowEx(Handle,?h,?'Static',?nil);
????????if?h?<>?0?then?begin
??????????Result?:=?MyGetWindowText(h);
????????end;
??????until?(h?=?0)?or?(Result?<>?'');
????end;
??end;
end;
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河)?博客挂了……
作者:
男 earthsbest (全能中间件) ▲▲△△△ -
注册会员
2019/8/23 12:08:54
7楼: D10.3调用D7的DLL,vclstyle除了标题栏,其他有效。
此帖子包含附件:
PNG 图像
大小:70.1K
----------------------------------------------
Delphi4Linux交流群:734515869?http://www.cnblogs.com/rtcmw
作者:
男 earthsbest (全能中间件) ▲▲△△△ -
注册会员
2019/8/23 13:44:33
8楼: 如果DLL也是D10,showmessage?正常了。
此帖子包含附件:
PNG 图像
大小:17.2K
----------------------------------------------
Delphi4Linux交流群:734515869?http://www.cnblogs.com/rtcmw
作者:
男 tx001 (tx) ▲△△△△ -
注册会员
2019/8/23 14:13:17
9楼: @iamdream谢谢帮助,但按照你提供的方法,只能获取程序自己弹出的ShowMessage的内容,无法获取其他dll中ShowMessage的内容,其他的dll是delphi6的,我自己的程序也是用delphi6的
@earthsbest谢谢帮助,最初想法是把ShowMessage弹出窗体标题加上公司名,增加背景图片,程序中没有使用皮肤,都是用图片美化的
----------------------------------------------
-
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2019/8/23 15:36:59
10楼: Delphi6应该用的是TMessageForm实现的,我的代码没试过DLL,的确是只能在程序内部使用。如果你只改标题,那应该可以用WM_GETTEXT/WM_SETTEXT消息来实现,往DLL中窗体里加图片没弄过,不知道能不能实现,毕竟TMessageForm传统上是用一个Label来显示消息文字的。
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河)?博客挂了……
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲▲ -
普通会员
2019/8/23 15:42:50
11楼: FindFormByClass
写的明明白白,只是本?exe?的?Application。
DLL?的没被列入。
----------------------------------------------
(C)(P)Flying?Wang
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2019/8/23 19:12:06
12楼: 我的意思是说替换窗口函数,并不是用getwindowtext。
无论什么方式,只要是windows平台上的ui,总是有一个消息循环的。
直接处理这个消息循环就可以拦截原有窗口的所有处理过程。
----------------------------------------------
--
作者:
男 tx001 (tx) ▲△△△△ -
注册会员
2019/8/24 10:58:03
13楼: 谢谢各位帮助,用了非常麻烦的方式实现了,
在调用dll中的函数时,启动hooh?api检测DrawText,如果获取到内容,用FindWindow找弹窗,找到弹窗后发送SendMessage将弹窗关闭,再调用程序中通用的弹窗,将内容显示
bahamut8348说的方法不会用,用setwindowlongptr替换哪个函数?我试了替换消息函数,想抓取WM_PAINT消息中的内容,再调用程序中已有的弹窗显示内容,但窗体已经显示了才能用FindWindow找到句柄,不再触发WM_PAINT消息,没有抓到消息
SetWindowLong(WH,?GWL_WNDPROC,?LongInt(MakeObjectInstance(GridProc)));
procedure?TForm1.GridProc(var?Meg:?Tmessage);
begin
??if?Meg.Msg?=?WM_PAINT?then
??begin
????Memo1.Lines.Add('没有抓到消息');
??end;
end;
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2019/8/25 12:33:06
14楼: ..

过程拦截了,它自己不触发,你不会强制刷新么??按此在新窗口浏览图片
----------------------------------------------
--
作者:
男 stacker (OOP才是王道) ★☆☆☆☆ -
普通会员
2019/8/26 9:14:03
15楼: 如果你是用AlphaControl的元件的话,记得他有个单元叫sDialogs,然后所有sShowMessage,sMessageDlg...都经过加工了,应该就是如楼主的意思。
----------------------------------------------
-
作者:
男 tx001 (tx) ▲△△△△ -
注册会员
2019/8/26 13:36:42
16楼: bahamut8348谢谢,没有想到,在调用RedrawWindow()就可以抓到了
----------------------------------------------
-
信息
登陆以后才能回复
Copyright ? 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行27.34375毫秒 RSS