首页  编辑  

实用的Delphi屏幕拷贝程序

Tags: /超级猛料/Picture.图形图像编程/抓图/   Date Created:

Borland公司(现改名为INPRISE公司)的DELPHI是当前最为方便的Windows程序设计工具之一。许多人以为DELPHI是作为数据库开发工具出现的,其实用DELPHI可以以极快的速度开发出高效的Windows程序。现在我们就用DELPHI来编写一个实用的屏幕拷贝程序。瞧瞧,下面的画面就是所编程序运行后进行区域屏幕拷贝的例子,还不错吧!Borland公司的天才设计师们用画布(Tcanvas)对象封装了Windows的大部分图形输出功能,这使得我们可以通过他以更直观的方式和Windows的屏幕打交道,而不必关心令人头疼的WindowsAPI函数。下面的一小段程序就可以实现整个屏幕的图象拷贝了。

 var     //变量声明

 Fullscreen:Tbitmap;  

 FullscreenCanvas:TCanvas;

 dc:HDC;

 //------------------------------------------------------------

 DC := GetDC (0);      //取得屏幕的 DC,参数0指的是屏幕

 FullscreenCanvas := TCanvas.Create;    //创建一个CANVAS对象

 FullscreenCanvas.Handle := DC;        //将屏幕的DC赋给HANDLE

 Fullscreen.Canvas.CopyRect

 (Rect (0, 0, screen.Width,screen.Height),

 fullscreenCanvas,

 Rect (0, 0, Screen.Width, Screen.Height));

                           //把整个屏幕复制到BITMAP中

 FullscreenCanvas.Free;          //释放CANVAS对象

 ReleaseDC (0, DC);              //释放DC

 //SCREEN对象是DELPHI预先定义的屏幕对象,直接使用就行了。

看了以上代码,你就会发现用DELPHI写屏幕拷贝程序的确很简单。当然要写一个实用的屏幕拷贝程序,光靠上述代码是不够的,下面讲一下主要的编程思路:

1.全屏幕拷贝的实现首先隐藏拷屏程序,延长一定时间后,利用上述的程序即可实现屏幕的拷贝。

2.区域拷贝的实现要实现区域拷贝要用个小技巧,首先调用全屏幕拷贝程序把整个屏幕拷贝下来,然后把拷贝下来的图象显示在屏幕上,之后就可以让用户在上面选择需要的区域,最后才将用户选定的区域复制下来。编 程 实 现:

1. 首 先 用DELPHI3 开 一 个 工 程。

2.在FORM上放置一个TPANEL元件,设置ALIGN=ALTOP,再选部件条ADDITIONAL上的TSCROLLBOX,放到FORM上,设置ALIGN=ALCLIENT,然后在SCROLLBOX上放置一个TIMAGE对象。

3.在PANEL上放置4个按钮,分别为FULLSCREEN,REGIN,SAVE,EXIT。

4.容易干的先干,在EXIT按钮的CLICK事件里写下代码

procedure TForm1.ExitClick(Sender: TObject);

begin

   close;

end;

5.接着是实现全屏幕拷贝了,在FROM上放置一个记时器TTIMER,ENABLED设为FALSE,INTERVAL设为500,也就是半秒钟激活一次。双击TIMER部件,写上如下的代码。

procedure TForm1.Timer1Timer(Sender: TObject);

var

Fullscreen:Tbitmap;

FullscreenCanvas:TCanvas;

dc:HDC;

begin

   timer1.Enabled:=false;   //取消时钟

   Fullscreen := TBitmap.Create;      //创建一个BITMAP来存放图象

   Fullscreen.Width := screen.width;

   Fullscreen.Height := screen.Height;

   DC := GetDC (0);   //取得屏幕的 DC,参数0指的是屏幕

   FullscreenCanvas := TCanvas.Create; //创建一个CANVAS对象

   FullscreenCanvas.Handle := DC;

Fullscreen.Canvas.CopyRect

(Rect (0, 0, screen.Width, screen.Height), fullscreenCanvas,

Rect (0, 0, Screen.Width, Screen.Height));

           //把整个屏幕复制到BITMAP中

   FullscreenCanvas.Free;          //释放CANVAS对象

   ReleaseDC (0, DC);              //释放DC

   //*******************************

   image1.picture.Bitmap:=fullscreen;//拷贝下的图象赋给IMAGE对象

   image1.Width:=fullscreen.Width;

   image1.Height:=fullscreen.Height;

   fullscreen.free;                //释放bitmap

   form1.WindowState:=wsNormal;    //复原窗口状态

   form1.show;                     //显示窗口

   messagebeep(1);  //BEEP叫一声,报告图象已经截取好了。

end;

6. 接 下 去FULLSCREEN 按 钮 上 的 代 码 就 很 简 单 了。

procedure TForm1.FullscreenClick(Sender: TObject);

begin

   form1.WindowState:=wsMinimized; //最小化程序窗口

   form1.hide;                     //把程序藏起来

   timer1.enabled:=true;           //打开记时器

end;

7.拷贝到了图象当然要存起来了,SAVE按钮就有了用武之地,我们写下如下代码。

procedure TForm1.Save1Click(Sender: TObject);

begin

 if savedialog1.Execute then

   begin

    form1.Image1.Picture.SaveToFile(savedialog1.filename)

   end;

end;

8.下面是区域拷贝的实现。再New一个FORM,BorderStype设为bsNone,这样能够显示为全屏幕,上面放置一个TIMAGE部件,ALIGN设为ALCLIENT,另外放置一个TTIMER部件,TIMER部件的程序跟上面的很象,因为它首先要实现的是全屏幕的拷贝。

procedure TForm2.Timer1Timer(Sender: TObject);

var

Fullscreen:Tbitmap;

FullscreenCanvas:TCanvas;

dc:HDC;

begin

   timer1.Enabled:=false;

   Fullscreen := TBitmap.Create;    

   Fullscreen.Width := screen.width;

   Fullscreen.Height := screen.Height;

   DC := GetDC (0);  

   FullscreenCanvas := TCanvas.Create;

   FullscreenCanvas.Handle := DC;

Fullscreen.Canvas.CopyRect (Rect

(0, 0, screen.Width, screen.Height), fullscreenCanvas,

    Rect (0, 0, Screen.Width, Screen.Height));

   FullscreenCanvas.Free;        

   ReleaseDC (0, DC);

   image1.picture.Bitmap:=fullscreen;

   image1.Width:=fullscreen.Width;

   image1.Height:=fullscreen.Height;

   fullscreen.free;                

   form2.WindowState:=wsMaximized;

   form2.show;

   messagebeep(1);

   foldx:=-1;

   foldy:=-1;

   image1.Canvas.Pen.mode:=pmnot; //笔的模式为取反

   image1.canvas.pen.color:=clblack; //笔为黑色

   image1.canvas.brush.Style:=bsclear; //空白刷子

   flag:=true;

end;

9.TIMAGE 部 件 上 有 两 个 事 件 的 程 序 需 要 编 写, 一 个 是ONMOUSEDOWN, 另 一 个

是ONMOUSEMOVE。

10.可以回头看看区域拷贝的思路,此时需要作区域拷贝的屏幕我们已经得到,也显示在屏幕上了,按下鼠标左键是区域的原点,此后移动鼠标,将有一个矩形在原点和鼠标之间,它会随着鼠标的移动而变化,再次按下鼠标的左键,此时矩形所包含的区域就是我们要得到的图象了。

11. 所 以MOUSEDOWN 有 两 次 响 应 的 处 理, 见 以 下 程 序。

procedure TForm2.Image1MouseDown

(Sender: TObject; Button: TMouseButton;

 Shift: TShiftState; X, Y: Integer);

var

width,height:integer;

newbitmap:Tbitmap;

begin

 if (trace=false) then  // TRACE表示是否在追踪鼠标

  begin      //首次点击鼠标左键,开始追踪鼠标。

     flag:=false;

  with image1.canvas do

     begin              

       moveTo(foldx,0);

       LineTo(foldx,screen.height);

       moveto(0,foldy);

       lineto(screen.width,foldy);

     end;

  x1:=x;            

  y1:=y;

  oldx:=x;

  oldy:=y;

  trace:=true;

  image1.Canvas.Pen.mode:=pmnot;     //笔的模式为取反

       //这样再在原处画一遍矩形,相当于擦除矩形。

  image1.canvas.pen.color:=clblack;  //笔为黑色

  image1.canvas.brush.Style:=bsclear;//空白刷子

  end

 else            

  begin       //第二次点击,表示已经得到矩形了,

              //把它拷贝到FORM1中的IMAGE部件上。

   x2:=x;

   y2:=y;

   trace:=false;

   image1.canvas.rectangle(x1,y1,oldx,oldy);

   width:=abs(x2-x1);

   height:=abs(y2-y1);

   form1.image1.Width:=Width;

   form1.image1.Height:=Height;

   newbitmap:=Tbitmap.create;  

   newbitmap.width:=width;

   newbitmap.height:=height;

newbitmap.Canvas.CopyRect

(Rect (0, 0, width, Height),form2.image1.canvas,

    Rect (x1, y1,x2,y2)); //拷贝

   form1.image1.picture.bitmap:=newbitmap; //放到FORM的IMAGE上

   newbitmap.free;    

   form2.hide;

   form1.show;

 end;

end;

12.MOUSEMOVE的处理就是在原点和鼠标当前位置之间不断地画矩形和擦

除矩形。

procedure TForm2.Image1MouseMove

(Sender: TObject; Shift: TShiftState; X,

 Y: Integer);

begin

if trace=true then   //是否在追踪鼠标?

   begin             //是,擦除旧的矩形并画上新的矩形

    with image1.canvas do

     begin

      rectangle(x1,y1,oldx,oldy);

      Rectangle(x1,y1,x,y);

      oldx:=x;

      oldy:=y;

     end;

   end

 else if flag=true then  //在鼠标所在的位置上画十字

     begin

      with image1.canvas do

       begin

       moveTo(foldx,0);          //擦除旧的十字

       LineTo(foldx,screen.height);

       moveto(0,foldy);

       lineto(screen.width,foldy);

       moveTo(x,0);              //画上新的十字

       LineTo(x,screen.height);

       moveto(0,y);

       lineto(screen.width,y);

       foldx:=x;

       foldy:=y;

       end;

     end;

end;

13.好了,让我们回过头来编写REGION按钮的代码。

procedure TForm1.RegionClick(Sender: TObject);

begin

form1.Hide;

form2.hide;

form2.Timer1.Enabled:=true;

end;

好了,我们终于胜利完工了,赶快运行一遍,把漂亮的屏幕拷下来!瞧DELPHI不仅是一个优秀的数据库开发工具,而且是一个优秀的编写WINDOWS程序的好帮手。让我们不禁赞叹:伟大的DELPHI!

宁波市游河巷贾学杰