抓屏技巧二三例_Delphi 編程

這裏有一些抓屏的技巧彙總,是本人平時編程積累下來的。在這裏寫出來,但願對你們有用。其實其技巧也不難,只要知道幾個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,這時候抓到的就是這個控件了。是否是頗有意思呢。
其實,有了句柄,真的是好辦,能夠作好多的事情。
相關文章
相關標籤/搜索