前面我们讲述了一个按键精灵的实现,现在的问题如何监视HP 既血的变化,来控制 补血.
先看下面几个API函数:
第一个函数BitBlt 就是用来截屏的.前面我们定义了timer2,下在我们来看看他是用来做什么的:
private
void
timer2_Tick(
object
sender, System.EventArgs e)
{
// 创建显示器的DC
IntPtr hdlDisplay = CreateDC("DISPLAY", null, null, IntPtr.Zero);
// 从指定设备的句柄创建新的 Graphics 对象
Graphics gfxDisplay = Graphics.FromHdc(hdlDisplay);
// 创建只有一个象素大小的 Bitmap 对象
Bitmap bmp1 = new Bitmap(1, 1, gfxDisplay);
Bitmap bmp2 = new Bitmap(1, 1, gfxDisplay);
// 从指定 Image 对象创建新的 Graphics 对象
Graphics gfxBmp1 = Graphics.FromImage(bmp1);
Graphics gfxBmp2 = Graphics.FromImage(bmp2);
// 获得屏幕的句柄
IntPtr hdlScreen = gfxDisplay.GetHdc();
// 获得位图的句柄
IntPtr hdlBmp1 = gfxBmp1.GetHdc();
IntPtr hdlBmp2 = gfxBmp2.GetHdc();
// 把当前屏幕中鼠标指针所在位置的一个象素拷贝到位图中
//97, 25,和97, 20,是游戏屏幕上HP值显示的坐标位置,
BitBlt(hdlBmp1, 0, 0, 1, 1, hdlScreen, 97, 25, 13369376);
BitBlt(hdlBmp2, 0, 0, 1, 1, hdlScreen, 97, 20, 13369376);
// 释放屏幕句柄
gfxDisplay.ReleaseHdc(hdlScreen);
// 释放位图句柄
gfxBmp1.ReleaseHdc(hdlBmp1);
gfxBmp2.ReleaseHdc(hdlBmp2);
Color temp1 = bmp1.GetPixel(0, 0); // 获取像素的颜色
Color temp2 = bmp2.GetPixel(0, 0);
int beforeCount = this.count;
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
if((temp1.ToArgb().ToString("x").ToUpper() == "FFFFFFFF") && (temp2.ToArgb().ToString("x").ToUpper() == "FFFFFFFF"))
this.count ++;
if(beforeCount == this.count)
this.count = 0;
![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
if((temp1.ToArgb().ToString("x").ToUpper() == "FFFFFFFF") &&(count == 2) &&(beforeCount != this.count))
{
this.count = 0;
System.Windows.Forms.SendKeys.Send(strHP); //按下补血键,就是喝药瓶的那个快界键
}
gfxDisplay.Dispose();
gfxBmp1.Dispose();
gfxBmp2.Dispose();
bmp1.Dispose(); // 释放 bmp 所使用的资源
bmp2.Dispose();
}
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
我们用temp1 和temp2分别捕获了屏幕上2点的颜色,然后看他们的RGB值,如果他们同时为0xFFFFFF那么就意味这2点都变成了白色,说明,HP直低于200了,这时就需要补血了,于是执行System.Windows.Forms.SendKeys.Send,其中的count和beforeCount 用来缓冲,时间是this.timer2.Interval * 3 .
这样,一个外挂就实现了!
[ DllImport (
"
gdi32.dll
"
) ]
private
static
extern
bool
BitBlt (
IntPtr hdcDest,
//
目标设备的句柄
int
nXDest,
//
目标对象的左上角的X坐标
int
nYDest,
//
目标对象的左上角的X坐标
int
nWidth,
//
目标对象的矩形的宽度
int
nHeight,
//
目标对象的矩形的长度
IntPtr hdcSrc,
//
源设备的句柄
int
nXSrc,
//
源对象的左上角的X坐标
int
nYSrc,
//
源对象的左上角的X坐标
int
dwRop
//
光栅的操作值
);
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
[ DllImport (
"
gdi32.dll
"
) ]
private
static
extern
IntPtr CreateDC (
string
lpszDriver,
//
驱动名称
string
lpszDevice,
//
设备名称
string
lpszOutput,
//
无用,可以设定位"NULL"
IntPtr lpInitData
//
任意的打印机数据
);
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
我们从游戏屏幕上 捕获 左上角用来显示血多少的数值颜色 的变化来实现监视.