博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Delphi版 关于QQ输入控件无法Spy到句柄的实现方案可行性研究
阅读量:7105 次
发布时间:2019-06-28

本文共 4641 字,大约阅读时间需要 15 分钟。

    QQ2009版本的界面,和以前的版本有个显著的不同,就是无法通过Spy++抓到界面上某些元素的句柄了,对于这个技术的实现方案,相信好多人都有一些揣度,实现方法怎样,有人说是应用的DirectUI技术,也有人说是用反Hook,等等一些列的说道!在这,我也说说我的一点看法!我说的一种方法不属于以上的任何一种方法。至于如何,且听我慢慢道来!此思路,来源于一个偶然,在聊天窗口失去焦点与获得焦点时的一个偶然。

  聊天的时候,我们要输入信息,首先要让窗口获得焦点!然后输入框也要获得焦点,才能输入。那么我们可以想象一下,在Delphi中什么情况下的控件时没有句柄的,用Delphi的同僚都知道,TGraphicControl继承下来的控件都没有焦点,既然如此,那么咱们就可以有一个混淆视听的方式,写的控件都从TGraphicControl继承来写,那么肯定就没句柄的,这个Button,ScrollBar等不必体现输入的,我相信没有争议,那么我实现一个编辑框Edit,也从TGraphicControl继承来写!这样,别人不就无法找到这个编辑框的句柄了么?嘿嘿,此时一定会有很多人大惑不解,那么输入呢,从TGraphicControl继承的Edit,如何实现输入?难道全部自己模拟消息来实现输入?当然不是,如果这样,那将让工作量增大N倍而不尽然能成功!重点就在这里,这是,我们可以在内部放一个TEdit,本Edit是活动的,在鼠标点下,或者模拟获得焦点的时候,我们将内置的Edit的Parent设置成我们从TGraphicControl继承的Edit的Parent,也就是Edt.parent := self.parent;并且设置内置Edit的区域,然后在内置Edit.setFocus,这样就能够输入了,然后当这个内置Edit失去焦点的时候,我们将内置Edit的显示文字抓成图片,之后,将内置edit的parent设置为nil,然后在在这个GrphicControl的Edit的对应区域绘制上我们抓取出来的那个真实Edit的图片,这样,内置的Edit已经不再本界面上了,从而当外部Spy++在Spy的时候,就无法找到那个Edit进而进行信息的获取等操作了!这便是我的实现思路。那么就可以想象,QQ聊天窗口在我们要输入信息的时候,获得焦点了,RichEdit的parent为QQ聊天窗口,然后我们输入信息,当信息输入完成,我们离开了之后,将内部的RichEdit的parent设置为nil,然后再将RichEdit的画面获得到绘制到原来的位置上去。这样 ,我们就无法Spy到RichEdit的句柄了。

下面给出俺的模拟代码:

这个代码中的DxEdit就是了,大家可用Spy查一下,肯定是查不到句柄的说!呵呵!

不过这个只是实现了一个简单的模拟而已,如果要完全达到QQ的那个效果,还有许多其他工作要做,这里仅提供一个实现的思路参考

 

{不得闲2010-2-25}
unit
 Unit4;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TDxEdit 
=
 
class
(TGraphicControl)
private
edt: TEdit;
edtbndrect: TRect;
bmp: TBitmap;
OldEdtwndproc: TWndMethod;
protected
procedure
 Paint;
override
;
procedure
 HookedtWndProc(
var
 msg: TMessage);
procedure
 MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); 
override
;
procedure
 SetParent(AParent: TWinControl);
override
;
public
constructor
 Create(AOwner: TComponent);
procedure
 BeforeDestruction;
override
;
destructor
 Destroy;
override
;
end
;
TForm4 
=
 
class
(TForm)
procedure
 FormCreate(Sender: TObject);
private
{
 Private declarations 
}
public
{
 Public declarations 
}
medt,edt2: TDxEdit;
end
;
var
Form4: TForm4;
implementation
var
edt: TEdit;
type
TWControl 
=
 
class
(TWinControl) 
end
;
procedure
 GetControlBitmap(Control: TWinControl;bmp: TBitmap);
var
ControlWidth,ControlHeight: integer;
ControlDc,hCaptureDC: HDC;
begin
ControlWidth :
=
 Control.ClientWidth;
ControlHeight :
=
 Control.ClientHeight;
ControlDc :
=
 GetDC(Control.Handle);
hCaptureDC :
=
 CreateCompatibleDC(ControlDc);
bmp.Handle :
=
CreateCompatibleBitmap(ControlDc,ControlWidth,ControlHeight);
SelectObject(hCaptureDC,bmp.Handle);
BitBlt(hCaptureDC,
0
,
0
,ControlWidth,ControlHeight,ControlDc,
0
,
0
,SRCCOPY);
ReleaseDC(GetDesktopWindow,ControlDc);
DeleteDC(hCaptureDC);
end
;
{
$R *.dfm
}
procedure
 TForm4.FormCreate(Sender: TObject);
begin
medt :
=
 TDxEdit.Create(self);
medt.Parent :
=
 self;
edt2 :
=
 TDxEdit.Create(self);
edt2.Parent :
=
 self;
edt2.Left :
=
 
150
;
edt2.Top :
=
 
10
;
end
;
{
 TDxEdit 
}
procedure
 TDxEdit.BeforeDestruction;
begin
inherited
;
end
;
constructor
 TDxEdit.Create(AOwner: TComponent);
begin
inherited
;
edtbndrect :
=
 Rect(
0
,
0
,
0
,
0
);
bmp :
=
 TBitmap.Create;
Cursor :
=
 crIBeam;
Height :
=
 
21
;
Width :
=
 
121
;
end
;
destructor
 TDxEdit.Destroy;
begin
inherited
;
bmp.Free;
end
;
procedure
 TDxEdit.HookedtWndProc(
var
 msg: TMessage);
begin
OldEdtwndproc(msg);
case
 msg.Msg 
of
WM_KILLFOCUS:
begin
GetControlBitmap(edt,bmp);
//
bmp.SaveToFile(
'
C:\1.bmp
'
);
edtbndrect.Left :
=
 
2
;
edtbndrect.Top :
=
 (Height 
-
 edt.Height) 
div
 
2
;
edtbndrect.Right :
=
 edtbndrect.Left 
+
 edt.Width;
edtbndrect.Bottom :
=
 edtbndrect.Top 
+
 edt.Height;
edt.Parent :
=
 
nil
;
end
;
end
;
end
;
procedure
 TDxEdit.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
inherited
;
if
 Button 
=
 mbLeft 
then
begin
if
 edt 
=
 
nil
 
then
begin
edt :
=
 TEdit.Create(
nil
);
OldEdtwndproc :
=
 edt.WindowProc;
edt.WindowProc :
=
 HookedtWndProc;
edt.BorderStyle :
=
 bsNone;
edt.Height :
=
 
14
;
end
;
edt.Left :
=
 Left 
+
 
2
;
edt.Top :
=
 top 
+
 (Height 
-
 edt.Height) 
div
 
2
;
edt.Width :
=
 Width 
-
 
4
;
edt.Parent :
=
 self.Parent;
edt.SetFocus;
//
edt.SelLength :
=
 
0
;
end
;
end
;
procedure
 TDxEdit.Paint;
begin
Canvas.Brush.Color :
=
 clWhite;
Canvas.FillRect(ClientRect);
Canvas.Brush.Color :
=
 clBlue;
Canvas.FrameRect(ClientRect);
//
然后开始绘制文字
if
 (edt 
<>
 
nil
and
 (edt.Parent 
=
 
nil
then
begin
//
bmp :
=
 TBitmap.Create;
//
GetControlBitmap(edt);
if
 edtbndrect.Left 
<>
 edtbndrect.Right 
then
Canvas.CopyRect(edtbndrect,bmp.Canvas,bmp.Canvas.ClipRect);
end
;
end
;
procedure
 TDxEdit.SetParent(AParent: TWinControl);
begin
inherited
;
end
;
initialization
finalization
end
.

  不得闲作于2010-2-25

本文转自 不得闲 博客园博客,原文链接:http://www.cnblogs.com/DxSoft/archive/2010/02/25/1673601.html   ,如需转载请自行联系原作者

你可能感兴趣的文章
bootstrap 代码
查看>>
jsp自定义标签
查看>>
我的技术博客-公告板!
查看>>
Websense:Android的安全性令人担忧
查看>>
Office 365 系列之四:添加自定义域
查看>>
Android应用程序启动过程——Launcher源码分析
查看>>
(实战)从关联表中取得JSON数据
查看>>
maven添加repository仓库
查看>>
vSAN 6.0设计与规模设定——vSAN设计概览
查看>>
zabbix邮件报警之完整总结
查看>>
我的友情链接
查看>>
Windows 10:现代化世界中安全与身份的守卫者
查看>>
查找相关数据结构和算法
查看>>
Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析(下)
查看>>
我的友情链接
查看>>
将命名规范的一些列文件合并成一个完整的文件
查看>>
数据恢复过程之:服务器raid5两块硬盘离线数据恢复
查看>>
戴尔Dell Latitude E6410/E6510官方拆机图解维修手册
查看>>
SAS硬盘与SATA硬盘的区别
查看>>
html语义化
查看>>