⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit_screenspy.pas

📁 dos example for create a profesional templeta
💻 PAS
字号:
{*******************************************}
{          图片分块快速比较单元             }
{          作者:hf                          }
{          Blog:http://hfnet.n3t.nu/        }
{          MSN:hf-net@hotmail.com           }
{*******************************************}

unit Unit_ScreenSpy;

interface

uses
  Windows,Graphics,Classes,SysUtils,ShellAPI  ;

const
  BMPBlockSize = 128;  //BMP块大小(宽和高都为BMPBlockSize)


type
  PDifBlock = ^TDifBlock ;
  TDifBlock = record     //不同块
    x,y:Integer;
    changed:boolean; //是否变化
  end;

//  TScreenChangeEvent = procedure(var Width,Height:Integer ) of object;

  TScreenSpy = class
  private
    FPixelFormat : TPixelFormat ;
    TMPStream : TMemoryStream ;    
    TmpBmp : TBitmap;
    BlockCount,LineBlockCount,LineCount:Integer;        //
    BlockList : array of PDifBlock;
//    FOnScreenChange : TScreenChangeEvent;
    FirstL:Integer;
    function GetPixelFormat:Byte;
    procedure SetixelFormat(PixelFormat : Byte );
    procedure MakeIndex4;
    procedure MakeIndex8;
    procedure MakeIndex16;
    procedure MakeIndex32;
    function IsScreenChange:Boolean ;
    procedure IniBlockList;
  protected
    ScreenBMP,LineBMP:TBitmap;
    ScreenDC: HDC;
    procedure MakeIndex;        //生成索引
    function GetFirstLine:Integer;
  public
    ScreenWidth,ScreenHeight:Integer ;
    procedure GetFirstBMP(FirstBmp : TStream );   //取第一幅屏幕图片并存入流中
    procedure GetNextBMP(NextBmp : TStream );     //取下一幅屏幕图片并存入流中
    constructor Create; reintroduce;
    destructor Destroy; override;
    property PixelFormat : Byte read GetPixelFormat write SetixelFormat default 8;
//    property OnScreenSizeChange : TScreenChangeEvent  read FOnScreenChange write FOnScreenChange;
  end;

implementation



constructor TScreenSpy.Create;
begin
  TMPStream :=TMemoryStream.Create;
  ScreenBMP:= TBitmap.Create;
  LineBMP:= TBitmap.Create;
  FPixelFormat := pf8bit ;                //默认
  FirstL := 0;
  ScreenWidth := GetSystemMetrics(SM_CXSCREEN);   //显示器水平分辨率
  ScreenHeight := GetSystemMetrics(SM_CYSCREEN);  //显示器垂直分辨率
  ScreenBMP.PixelFormat := FPixelFormat;
  ScreenBMP.Width := ScreenWidth;
  ScreenBMP.Height := ScreenHeight;
  LineBMP.PixelFormat := FPixelFormat;
  LineBMP.Width := ScreenWidth;
  LineBMP.Height := 1;
  TmpBmp := TBitmap.Create;
  TmpBmp.PixelFormat := FPixelFormat;
  TmpBmp.Width := BMPBlockSize;
  TmpBmp.Height := BMPBlockSize;
  IniBlockList;               //初始化列表
  inherited Create;
end;

destructor TScreenSpy.Destroy;
var
  i:Integer;
begin
  TMPStream.Free;
  TmpBmp.Destroy;
  ScreenBMP.Destroy;
  LineBMP.Destroy;
  for I := Low(BlockList) to High(BlockList) do                  //释放
    begin
      freeMem(BlockList[i]);
    end;
  inherited destroy;
end;

procedure TScreenSpy.IniBlockList;
var
  x,y,i:Integer;
begin
  if (ScreenWidth mod BMPBlockSize <> 0) then
    LineBlockCount := ScreenWidth div BMPBlockSize +1
  else
    LineBlockCount := ScreenWidth div BMPBlockSize;
  if ScreenHeight mod BMPBlockSize <> 0 then
    LineCount := ScreenHeight Div BMPBlockSize +1
  else
    LineCount := ScreenHeight Div BMPBlockSize;
  BlockCount := LineBlockCount * LineCount;
  SetLength(BlockList,BlockCount);
  y := 0;
  i :=0;
  while y < LineCount do
  begin
    x := 0;
    while x < LineBlockCount  do
    begin
      GetMem(BlockList[i],SizeOf(TDifBlock));
      BlockList[i]^.X := x*BMPBlockSize;
      BlockList[i]^.Y := y*BMPBlockSize;
      BlockList[i]^.changed := false;
      Inc(i);
      Inc(x);
    end;
    Inc(y);
  end;
end;  

function TScreenSpy.GetPixelFormat:Byte;
begin
  case FPixelFormat of
    pf4bit: Result := 4;
    pf8bit: Result := 8;
    pf24bit: Result := 24;
  end;
end;


procedure TScreenSpy.SetixelFormat(PixelFormat : Byte );
begin
  case PixelFormat of
    4:FPixelFormat := pf4bit;
    8:FPixelFormat := pf8bit;
    16:FPixelFormat := pf16bit;
    24:FPixelFormat := pf24bit;
  end;
  if TmpBmp.PixelFormat <> FPixelFormat  then
    TmpBmp.PixelFormat := FPixelFormat;

end;



function TScreenSpy.GetFirstLine:Integer;
var
  i:Integer;
begin
  Inc(FirstL );
  if FirstL = 20 then FirstL := 0;
  Result := FirstL;
end;

procedure TScreenSpy.MakeIndex4;
var
  c1,c2:PDWORD;
  x,y,yi,i,j:Integer;
begin
  y := FirstL;
  while y < ScreenBMP.height do
  begin
    BitBlt(LineBMP.Canvas.Handle,0,0,ScreenWidth,1,ScreenDC,0,y,SRCCOPY);
    c1 := LineBMP.ScanLine[0];
    c2 := ScreenBMP.ScanLine[y];
    x := 0;
    yi := (y div BMPBlockSize) * LineBlockCount;
    while x < ScreenBMP.Width  do
    begin
      j:=0;
      i :=yi + x div BMPBlockSize;
      while j < BMPBlockSize do
      begin
        if c1^ <> c2^ then
            BlockList[i]^.changed := true;
        Inc(c1,1);
        Inc(c2,1);
        inc(j,8);
      end;
      Inc(x,BMPBlockSize);
    end;
    Inc(y,20);   //隔行扫描
  end;
  FirstL := GetFirstLine();
end;

procedure TScreenSpy.MakeIndex8;
var
  c1,c2:PDWORD;
  x,y,yi,i,j:Integer;
begin
  y := FirstL;
  while y < ScreenBMP.height do
  begin
    BitBlt(LineBMP.Canvas.Handle,0,0,ScreenWidth,1,ScreenDC,0,y,SRCCOPY);
    c1 := LineBMP.ScanLine[0];
    c2 := ScreenBMP.ScanLine[y];
    x := 0;
    yi := (y div BMPBlockSize) * LineBlockCount;
    while x < ScreenBMP.Width  do
    begin
      j:=0;
      i :=yi + x div BMPBlockSize;
      while j < BMPBlockSize do
      begin
        if c1^ <> c2^ then      //8位色一次比较的是4个象素
            BlockList[i]^.changed := true;
        Inc(c1,1);
        Inc(c2,1);
        inc(j,4);
      end;
      Inc(x,BMPBlockSize);
    end;
    Inc(y,20);   //隔行扫描
  end;
  FirstL := GetFirstLine();
end;

procedure TScreenSpy.MakeIndex16;
var
  c1,c2:PDWORD;
  x,y,yi,i,j:Integer;
begin
  y := FirstL;
  while y < ScreenBMP.height do
  begin
    BitBlt(LineBMP.Canvas.Handle,0,0,ScreenWidth,1,ScreenDC,0,y,SRCCOPY);
    c1 := LineBMP.ScanLine[0];
    c2 := ScreenBMP.ScanLine[y];
    x := 0;
    yi := (y div BMPBlockSize) * LineBlockCount;
    while x < ScreenBMP.Width  do
    begin
      j:=0;
      i :=yi + x div BMPBlockSize;
      while j < BMPBlockSize do
      begin
        if c1^ <> c2^ then
            BlockList[i]^.changed := true;
        Inc(c1,1);
        Inc(c2,1);
        inc(j,2);
      end;
      Inc(x,BMPBlockSize);
    end;
    Inc(y,20);   //隔行扫描
  end;
  FirstL := GetFirstLine();
end;

procedure TScreenSpy.MakeIndex32;
var
  c1,c2:PDWORD;
  x,y,yi,i,j:Integer;
begin
  y := FirstL;
  while y < ScreenBMP.height do
  begin
    BitBlt(LineBMP.Canvas.Handle,0,0,ScreenWidth,1,ScreenDC,0,y,SRCCOPY);
    c1 := LineBMP.ScanLine[0];
    c2 := ScreenBMP.ScanLine[y];
    x := 0;
    yi := (y div BMPBlockSize) * LineBlockCount;
    i :=yi + x div BMPBlockSize;
    while x < ScreenBMP.Width  do
    begin
      j:=0;
      while j < BMPBlockSize do
      begin
        if c1^ <> c2^ then
            BlockList[i]^.changed := true;
        Inc(c1,1);
        Inc(c2,1);
        inc(j,1);
      end;
      Inc(x,BMPBlockSize);
      Inc(i); 
    end;
    Inc(y,20);   //隔行扫描
  end;
  FirstL := GetFirstLine();
end;



procedure TScreenSpy.MakeIndex;
begin
case FPixelFormat of
  pf4bit: MakeIndex4;
  pf8bit: MakeIndex8;
  pf16bit : MakeIndex16;
  pf32bit: MakeIndex32;
end;
end;

function TScreenSpy.IsScreenChange:Boolean;
begin

end;

procedure TScreenSpy.GetFirstBMP(FirstBmp : TStream );       //取第一幅屏幕图片并存入流中
var
  P:TPoint;
  c:Char;
begin
  FirstBmp.Size := 0;
  c:='F';
  FirstBmp.Write(c,1);
//  GetCursorPos(p);
//  FirstBmp.Write(p,SizeOf(TPoint));
  p.X := ScreenWidth ;
  p.Y := ScreenHeight;
  FirstBmp.Write(p,SizeOf(TPoint));
  ScreenDC:=GetDC(0);
  BitBlt(ScreenBMP.Canvas.Handle ,0,0,ScreenWidth,ScreenHeight,ScreenDC,0,0,SRCCOPY);
  ReleaseDC(0,ScreenDC);
//  TmpBmp.Width :=ScreenWidth;
//  ScreenHeight;
  ScreenBMP.SaveToStream(FirstBmp );
end;

procedure TScreenSpy.GetNextBMP(NextBmp : TStream );        //取下一幅屏幕图片并存入流中
var
  i:Integer;
  Ssize:Integer;
  R1,R2:TRect;
  c:Char;
  p:TPoint;
begin
  NextBmp.Size := 0;
  R2.Left := 0;
  R2.Top := 0;
  R2.Bottom := BMPBlockSize;
  c:='N';
  NextBmp.Write(c,1);
  ScreenDC:=GetDC(0);
  MakeIndex;
//  GetCursorPos(p);
//  NextBmp.Write(p,SizeOf(TPoint));
  I := Low(BlockList);
  while I <= High(BlockList) do
  begin
    if BlockList[i]^.changed then
      begin
        R1.Left := BlockList[i]^.x; R1.Top := BlockList[i]^.y;
        R1.Right := R1.Left + BMPBlockSize ; R1.Bottom := R1.Top + BMPBlockSize;
        BlockList[i]^.changed := False;
        R2.Right := R1.Right - R1.Left ;
        TmpBmp.Width := R2.Right;
        BitBlt(ScreenBMP.Canvas.Handle,R1.Left,R1.Top,R1.Right ,R1.Bottom,
              ScreenDC,R1.Left ,R1.Top ,SRCCOPY );
        BitBlt(TmpBmp.Canvas.Handle,0,0,R2.Right ,R2.Bottom,
              ScreenBMP.Canvas.Handle,R1.Left ,R1.Top ,SRCCOPY );
        TMPStream.Clear;
        TmpBmp.SaveToStream(TMPStream);
        NextBmp.WriteBuffer(R1.TopLeft,SizeOf(TPoint));   //图象坐标
        Ssize := TMPStream.Size;
        NextBmp.WriteBuffer(Ssize,SizeOf(Integer));
        NextBmp.CopyFrom(TMPStream,0);
      end
    else
      inc(i);
  end;
  ReleaseDC(0,ScreenDC);

end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -