这里有一些抓屏的技巧汇总,是本人平时编程积累下来的。在这里写出来,但愿对你们有用。其实其技巧也不难,只要知道几个API函数,再加一些设备描述表的操做,你几乎能够作出很是好的抓屏软件。废话少说,如今开始介绍吧:
一,抓取全屏:
这个几乎能够说是抓屏中最简单的一个了,相信不少人都会,但为了讲述完整,这里也列举出来。思想很简单,取得屏幕的设备描述表,赋值给一个Canvas的句柄,这时该Canvas就至关于有了屏幕的画布了。再将这个画布复制给一个位图对象便可,代码以下:
procedure GetDesktopBim(FScreen:TBitmap);
var
FCanvas:TCanvas;
dc:HDC;
begin
FCanvas:=TCanvas.Create();
try
Fscreen.Width := screen.width;
Fscreen.Height := screen.Height;
//取得屏幕设备描述表,0指屏幕
dc:=GetDC(0);
//将屏幕设备描述表赋给画布的句柄,此时画布就表明整个屏幕了
FCanvas.Handle:=dc;
//把整个屏幕复制到BITMAP中,以后就能够将画布对象和设备描述表释放,
Fscreen.Canvas.CopyRect(Rect (0, 0, screen.Width, screen.Height),
fCanvas,
Rect (0, 0, Screen.Width, Screen.Height));
finally
FCanvas.Free;
ReleaseDC (0, dc);
end;
end;
二,局部抓屏:
有时候并不须要抓取整个屏幕,只须要其中一部分,那么应该怎么作到呢。仔细看看那些抓屏软件,当抓取局部屏幕时,你看你的屏幕所有静止了,连QQ好友来信息,头像也不动了应该想到了吧,其实它是先将整个屏幕抓下来,放在真正的屏幕上面,让你在这个抓下来的屏幕上面操做。
通常来讲,抓局部的屏幕有几种类型,这里只说明三种:
第一种是矩形,这个固然是最简单的啦,因一整个静止的位图都摆在你的面前了,你只处理鼠标的点下,移动,弹起消息,整个过程就像咱们作一个小画图程序画一个矩形同样。最后将这个区域的位图拷贝到你抓屏窗口就好了。代码有些凌乱,这里就不列出来了。应该也不是很难吧。
第二种状况是画椭圆,在屏幕画布画出一个椭圆,而后将这个椭圆拷贝到抓屏窗口上。但问题是如何拷贝椭圆形的图呢。其实这里它拷贝的仍是一个矩形,但拷到抓屏窗口上时,做了一些改变如下是关键代码,是我之前做的程序中的一些代码,这里很差做出通常性的代码,因此只好将之前的代码拉下来,应该能够看得懂的:
{这是实现位图蒙板的代码,先在抓屏窗体中画布全画为白,白色为0,而用屏幕位图窗体画的椭圆形为大小,给抓屏窗体的画布画一个黑色的椭圆,黑色为1。以后调用API函数BitBlt将屏幕位图窗体中选取的椭圆外框(矩形)所有复制给抓屏窗体,但其复制模式为SRCPAINT,即椭圆外框的位图与抓屏窗体画布进行and运算,结果椭圆外框的位图只有在抓屏窗体中黑色区域即椭圆部分的图像获得显示,而其余部分都被与掉了,因此看到的就只有椭圆部分位图,而其他的以白色代替了。这就是椭圆抓屏的实现技术}
Form1.ScrImage.Canvas.Pen.Color:=clWhite;
Form1.ScrImage.Canvas.Brush.Style:=bsSolid;
Form1.ScrImage.Canvas.Brush.Color:=clWhite;
Form1.ScrImage.Canvas.Rectangle(0,0,width,Height);
Form1.ScrImage.Canvas.Pen.Color:=clBlack;
Form1.ScrImage.Canvas.Brush.Color:=clBlack;
Form1.ScrImage.Canvas.Ellipse(0,0,width,Height);
p_w_picpath1.Canvas.Ellipse(orgPoint.X,orgPoint.Y,X,Y);
BitBlt (Form1.ScrImage.Canvas.Handle, 0, 0,width ,Height,
Image1.Canvas.Handle, orgPoint.X, orgPoint.Y, SRCPAINT);
第三种是任意形状的抓屏,其实所谓的任意形状并不是真的是任意的。它是一个多边形,只不过它的边不少因此你看起来,就像是任意的同样。当你的鼠标在屏幕位图窗体上画线时,边些线的点就组成了一个多边形,而后要计算出这个多边形的外框,即与这个多边形相切的矩形。接着再用上面讲到的技术就能够实现一个任意形状的抓屏了。有了上面椭圆的讲解,我想,任意形的大概也能本身作出来了吧。实际上是因为代码有些乱,很差放上来。
等一下我会作一个代码简单,但却颇有意思的抓屏例子。请接着往下看吧。
三。当前工做窗口的抓屏:
当你想抓取当前正激活的窗口,你会怎么作呢,你能够按Ctrl+PrintScreenSysRp.便可以抓下这个口了。但咱们要用程序来实现,怎么作呢,其实很是简单,就是得到这个活动窗口的句柄,再根据这个句柄到该窗口的设备描述表,这样就能够画出这个窗口了。那么要得到当前工做的窗口是要用到什么函数呢,主要是用到这样一个API:GetForegroundWindow(),它返回当前正在工做的窗口的句柄。好了,如今给出代码吧:
procedure TForm1.GetActiveWndImg(b:TBitmap);
var C:TCanvas; H:HDC; R:TRect; hand:THandle;
begin
C:=TCanvas.Create;
Hand:= GetForegroundWindow();
if hand=0 then exit;
H:=GetWindowDC(Hand);//取得这个窗口的句柄
try
GetWindowRect(hand,R);//取得这个窗口的大小,将其赋给位图对象
B.Width:=R.Right-R.Left;
B.Height:=R.Bottom-R.Top;
C.Handle:=H;
B.Canvas.CopyRect(Rect(0,0,B.Width,B.Height),C
,Rect(0,0,B.Width,B.Height));
finally
C.Free;
ReleaseDC(Hand, H);
end;
end;
上面已经讲解了抓屏的几种方式,只是一个引玉的做用,虽然没有详细的代码,我想思路应该是有了吧,再加上一本帮助你应该能够作出很不错的抓屏软件。
----------------------------------------------------
做为最后,我想出一个更有意思的抓屏方式,就是当你的鼠标指针指向屏幕的某一个地方,再按设定好的热键。就能够抓到鼠标指向的窗口(这个窗口也包括控件如按钮等)。这真的是不错,现实也并非很难。主要有两个问题,这里一一做答吧,找到相应的API就好了:
一,热键问题,用到的API是RegisterHotKey和UnRegisterHotKey。这里不打算详细解说,能够本身看API帮助,当热键被按下时,会触发WM_HOTKEY消息,咱们就在这个消息处理函数中抓鼠标位置的窗口位图。
二。光标位置的窗口,先用GetCurSorPos取得光标的位置,再用WindowFromPoint取得该位置的窗口句柄。
有了句柄,真是什么都好办呀。如下是程序代码:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls;
type
TForm1 = class(TForm)
ScrollBox1: TScrollBox;
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
hotkey:Integer;
procedure HotKeyDown(var Msg: Tmessage); message WM_HOTKEY;
procedure GetActiveWndImg;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.GetActiveWndImg;
var C:TCanvas; b:TBitmap; H:HDC; R:TRect; hand:THandle;
p:TPoint;
begin
B:=TBitmap.Create;
C:=TCanvas.Create;
GetCurSorPos(P);
Hand:= WindowFromPoint(P);
if hand=0 then exit;
H:=GetWindowDC(Hand);
try
GetWindowRect(hand,R);
B.Width:=R.Right-R.Left;
B.Height:=R.Bottom-R.Top;
C.Handle:=H;
B.Canvas.CopyRect(Rect(0,0,B.Width,B.Height),C
,Rect(0,0,B.Width,B.Height));
Image1.Picture.Bitmap.Assign(B);
finally
C.Free;
B.Free;
ReleaseDC(Hand, H);
end;
end;
procedure TForm1.HotKeyDown(var Msg: Tmessage);
begin
if (Msg.LParamHi = VK_SPACE)and (Msg.LParamLo=MOD_CONTROL) then
GetActiveWndImg;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
hotkey:=0;
if not RegisterHotKey(Handle,hotkey,MOD_CONTROL ,VK_Space) then
showmessage('can not register the hotkey');
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
UnRegisterHotKey(handle, HotKey);
end;
end.
上面没有什么解释,真是抱歉,但若是看了上面的文字,我想也不难看得懂吧。把你的光标放在任何一个窗口上,按Ctrl+Space,看是否是把这个窗口抓下来了呢若是你将光标指在一个窗口内部的控件上,再按Ctrl+Space,这时候抓到的就是这个控件了。是否是颇有意思呢。
其实,有了句柄,真的是好办,能够作好多的事情。