说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

利用Delphi的Tbitmap控件抓取屏幕图象

HTML文档下载 WORD文档下载 PDF文档下载
利用Delphi的Tbitmap控件抓取屏幕图象

相信绝大部分电脑爱好者都使用过不同种类的抓图软件抓取屏幕图形。在本文中,作者要向大家介绍的是利用Delphi的TBitmap控件进行屏幕上任意窗口图形的抓取。同时文章中还有如何利用Delphi的扩展消息处理功能为Delphi的窗口添加热键和在任务栏上添加图标的技巧。

程序的主要思路是:当按下为窗口建立的热键后,首先获得光标所在的窗口的矩形区域,然后建立一个TBitmap对象,将矩形区域复制到TBitmap对象中;最后利用TBitmap的图象保存Method将复制到TBitmap中的位图保存到磁盘中。

程序1是完整的源代码清单:

在运行程序前,首先要执行以下的步骤:

在Form1中加入一个TsavePictureDialog控件,将其Name设置为SavePic。

改变Form1的如下属性:

BorderStyle改变为bsNone;

FormStyle改变为fsStayOnTop;

Visable改变为False。

同时在Project1中的Application.Run语句前加入: Application.ShowMainForm := False;为了直观显示,还可以将Form1的Cursor属性设置为crHandPoint。

unit Unit1;  

interface

uses Windows

Messages

SysUtils

Classes

Graphics

Controls

Forms

Dialogs

StdCtrls

ExtCtrls

Menus

ExtDlgs

ClipBrd

ShellApi;

const

WM_ICONMESSAGE=WM_USER+100;

type

TForm1 = class(TForm)

SavePic: TSavePictureDialog;

procedure FormCreate(Sender: TObject);

procedure FormClose(Sender: TObject; var Action: TCloseAction);

procedure FormMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X

Y: Integer);

Private

//热键消息处理函数

procedure WMHOTKEY(var Message:TMessage);message WM_HOTKEY;

//任务栏消息处理函数

procedure WMBarIcon(var Message:TMessage);message WM_ICONMESSAGE;

public

end;

procedure CaptureControl;

var

Form1: TForm1;

tmpBitmap:TBitmap;

iBitmapValide:Boolean;

implementation

{$R *.DFM}

procedure CaptureControl;

var

iTempWnd

iMeHwnd

iDC:LongWord;

tyRect :TRect;

tpRect : TPoint;

iWidth

iHeight:integer;

begin

//获得光标位置

GetCursorPos(tpRect);

//获得光标所在位置的窗口句柄

iMeHwnd:=WindowFromPoint(tpRect);

//获得窗口的矩形区域

GetWindowRect(iMeHwnd

tyRect);

//获得桌面窗口的句柄

iTempWnd:=GetDesktopWindow;

iDC:=GetDC(iTempWnd);

iWidth:=tyRect.Right-tyRect.Left;

iHeight:=tyRect.Bottom-tyRect.Top;

//建立位图

tmpBitmap:=TBitmap.Create;

iBitmapValide:=True;

tmpBitmap.Width := iWidth;

tmpBitmap.Height := iHeight;

//复制窗口矩形区域到位图中

Bitblt(tmpBitmap.Canvas.Handle

0

0

iWidth

iHeight

iDC

tyRect.Left

tyRect.Top

SRCCOPY);

ReleaseDC(iTempWnd

iDC);

Form1.Visible := True;

//使Form1覆盖光标所在的窗口矩形

Form1.Left := tyRect.Left;

Form1.Top := tyRect.Top;

Form1.Width := iWidth;

Form1.Height := iHeight;

tyRect.Left:=0;

tyRect.Right := iWidth;

tyRect.Top:=0;

tyRect.Bottom:=iHeight;

//将位图绘制到Form1的Canvas中

Form1.Canvas.Draw(0

0

tmpBitmap);

//围绕Form1画出3个相素的红色边框

Frame3D(Form1.Canvas

tyRect

clRed

clRed

3);

end;

//响应热键,进行抓图

procedure TForm1.WMHOTKEY(var Message:TMessage);

begin

if iBitmapValide then

begin

tmpBitmap.FreeImage;

tmpBitmap.Free;

iBitmapValide:=False;

end;

CaptureControl;

end;

procedure TForm1.WMBarIcon (var Message:TMessage);

begin

if ((Message.LParam = WM_RBUTTONDOWN)or (Message.LParam = WM_LBUTTONDOWN)) then

//在任务栏图标上按下鼠标键退出

close;

end;

procedure TForm1.FormCreate(Sender: TObject);

var

lpData:PNotifyIconData;

begin

//注册热键为Ctrl+Shift+A

RegisterHotKey(Form1.handle

0

MOD_SHIFT OR MOD_CONTROL

65);

//在任务栏上建立图标

lpData := new(PNotifyIconDataA);

lpData.cbSize := 88;

lpData.Wnd := Form1.Handle;

lpData.hIcon := Form1.Icon.Handle;

lpData.uCallbackMessage := WM_ICONMESSAGE;

lpData.uID :=0;

lpData.szTip := '屏幕捕捉';

lpData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;

Shell_NotifyIcon(NIM_ADD

lpData);

dispose(lpData);

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

var

lpData:PNotifyIconData;

begin

//退出时删除任务栏图标

lpData := new(PNotifyIconDataA);

lpData.cbSize := 88;

lpData.Wnd := Form1.Handle;

lpData.hIcon := Form1.Icon.Handle;

lpData.uCallbackMessage := WM_ICONMESSAGE;

lpData.uID :=0;

lpData.szTip := '屏幕捕捉';

lpData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;

Shell_NotifyIcon(NIM_DELETE

lpData);

dispose(lpData);

//退出时注销窗口热键

UnRegisterHotKey(Form1.Handle

0);

if iBitmapValide then

begin

tmpBitmap.FreeImage;

tmpBitmap.Free;

iBitmapValide:=False;

end;

end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X

Y: Integer);

begin

//按下鼠标左键保存窗口图象

if (Button=mbLeft)then

with SavePic do

begin

DefaultExt := 'Bmp';

Execute;

if FileName<>'' then

tmpBitmap.SaveToFile(FileName);

end;

//保存完图象后删除位图

tmpBitmap.FreeImage;

tmpBitmap.Free;

iBitmapValide:=False;

Form1.Visible := False;

end;

end.

按F9键运行程序,将光标移动到任意窗口上按下热键Ctrl+Shift+A,则光标所在窗口被捕捉下来(同时被捕捉区域被红色边框框住作为标识)。在框内按下鼠标左键就可以保存位图图像。这个程序也可以用来捕捉菜单。

同时程序也可以将图象发送到剪贴板中,只要将上面程序中Form1的OnMouseUp事件置换为下面的程序段就可以了(程序2):

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X

Y: Integer);

var

MyFormat : Word;

AData : THandle;

APalette : HPALETTE;

begin

if (Button=mbLeft)then

//按下鼠标左键将tmpBitmap中的内容发送的剪贴板

begin

tmpBitmap.SaveToClipBoardFormat(MyFormat

AData

APalette);

ClipBoard.SetAsHandle(MyFormat

AData);

end;

tmpBitmap.FreeImage;

tmpBitmap.Free;

iBitmapValide:=False;

Form1.Visible := False;

end;

以上的程序在Windows95,Delphi4.0下运行通过。

更加开放?Path向13家应用开发商开放API 重金力邀开发者 联想智能桌面应用开发大赛开幕 SDCC 2013大会讲师名单议题出炉 8月20日五折票价最后一天 程序员困境:底层编码能力正逐步丧失 寓教于乐 给代码审查者的几点建议 裁员4千、总裁员人数超过7.5万,难掩思科锋芒 物联网离普罗大众还有多远? 悼念斯诺登使用的加密电邮服务——Lavabit架构解析 运营商上阵OTT “一笑泯恩仇”后路在何方 [企业开源系列]后起之秀Facebook凭什么挑战互联网霸主Google? 谷歌推出免费标签管理应用Tag Manager McAfee CTO Phyllis Schneck被任命为NPPD副部长 Bootstrap 3.0发布 更好地支持移动端和响应式开发 国内创业公司QingCloud的魄力:做一个世界级的IaaS服务 从毫秒到微妙,纯硬的闪存阵列IBM Flash System来了! 中科创达邹鹏程:黑客精神逐渐被人遗忘 有点让人感伤 通过讲故事的方式来设计优秀网站 “肮脏的”IT工作排行榜 Clank:带有SCSS的高效率移动应用原型框架 欧朋 CTO 罗志宇:谈Sphinx游戏引擎的前世今生 John Carmack大神亲手操刀,Oculus Rift SDK即将发布 从南极之争谈软件架构十个技巧,及成功团队具备的气质 Imation重拳出击,推出新型混合存储平台 张建华:FusionSphere不是简单的OpenStack发行版 Chrome 29来了:地址栏变得更“兼容” Android版增WebRTC 工程师谈在Facebook工作最糟糕的事情 用Scala重构19楼——SDCC 2013讲师王治专访 10款最新且超实用的开发框架 创业公司为什么应该写博客? 向iOS SDK看齐:Facebook Android SDK迎来重大更新 闯向海外:对话AppFlood产品总监陈霄 新手请教问题 我的安装老是不能成功,那一位大虾能告诉我,谢了 各位大虾,谁能给我提供,匿名发送邮件的程序代码啊。。。。 那位打下知道有什么针对BMP图像的压缩算法? 怎样使WAV播放的幅度表达出来?象WINDOWs的录音机显示一致? 窗口的问题(稍后加分,100分) 大家是如何解决数据库平台无关性的问题的? 呦,阿紫,你真的改名啦,红袖添香夜读书的小乖乖,太长了,你还当斑竹吗? vb开发进程?Hook技术? 所谓的基础的是什么 识别上网状态问题,请教各位大虾。 再问:请问可以在applet中使用MenuBar吗?(昨天的已经给分了) 统计一下win2000下可以玩的游戏 *.chm文件能作在线帮助吗?在窗体的helpfile、和helpcontext如何设置??? 如何根据列名用object来取出字段,急!!!! 关于箭头在数据窗口移动的问题? 再问个菜鸟问题,showmodaldialog的title怎样控制 javascript中如何取整? ALT和MFC的区别是什么?? 试用DELPHI6,BUG太多了! 我是新手,请问在delphi5中如何建库(orcle和sybase)? 问一个比较弱智的问题 js文件里如何使用另一个js文件里的函数30? 哪位大虾知道可以在哪里下载mpeg-1的codec,谁先告诉有效地址谁先得分!(不给分是小狗!) 可能很菜的问题,送分的问题!! 一个关于CDaoTableDefInfo的问题 ado的问题??求救!!!高分!!! 有关代码重用的问题,对Form的继承。 一个关于CString.Format的问题 学习编程时学图算法怎么学好? 一个很简单的CREATE TABLE语句为什么出错呢?向大家请教! jbuilder5运行需要最低配置 ,傻傻的问 Delphi6的盗版已经到了@_@ 喂,为什么我提问只能给最多37分,原先可比这要多的多 一个关于派生类的问题 关于页面关闭的问题 用new JTalbe(10, 20)创建了一个table,如何设置该table列(column)的宽度 请教一个关于用VC6开发outlook\exchange的问题。急!急! 时间服务器 请问一下,用DBM,如果用户注册的数量多了以后,程序的速度很一般的文本速度比较哪个快 纯数学问题:如何求模逆元? VB中实现进程间通信的方法?VB中的CallWindowProc的用法?VB中如何发送自定义的消息? 请问哪里能免费下载BCB5?下载多长时间没有关系,只要能够正确使用就可以了。 怎样得知CListCtrl中当前选项? 我想从WINME中自带的一个驱动程序提取出来在WIN97中安装,请问应如何做? 菜问题(2) 请教:为何数据库数据无法在网页上显示? CEditView 一定要override onChange function(ON_CONTROL_REFLECT(EN_CHANGE, OnChange))????;否则input 时不我待会错??? 请教:不通过页面,用VB如何得知来访者的IP? 如何将vcd转化为real的格式???????????急!!!!!!!!!!!!!! 对DMO播放内存MPEG2数据没有头绪,谁能给点提示? 成功中学七年级(1)、(2)、(3)班向希望小学共捐书385本,2班捐书的本书是1班的0.75倍,一班与3班的捐书成功中学7年级1、2、3班向希望小学那个捐书385本,2班捐书的本书是1班的0.75倍,一班与3 父亲的年龄是聪聪的9倍,母亲的年龄是聪聪的7.5倍,父亲弊母亲的6岁.聪聪今年几 某中学为帮助贫困山区的失学儿童重返课堂,要在全校开展一次献爱心捐款、捐物、捐书活动.请你为这次活动要求.运用对联,有文采并体现人文关怀,每条不少于十字 成功中学7年级1、2、3班向希望小学那个捐书385本,2班捐书的本书是1班的0.75倍,一班与3班的捐书之比为6:7数学老师正在黑板上抄上述题目,还没抄完,校长便叫他去接个电话,现在请你替老师把未 下面图(1)是某市实验小学四五六年级在希望工程自愿捐款活动中学生捐款情况统计图,图(2)是该小学四五六年级分布图,已知三个年级共有学生950人,图(1):人均捐款数每元:四年级5元; 派立方木门发起的爱心捐书活动要捐多少本书啊?已经报名参加了书香暖童心活动了,想问下这个活动捐书有没有最低限制啊? 聪聪明明从家相对出发,聪聪的速度15分之1千米分,明明速度是12分之1千米分,15分钟后他们两家相距多少 . 四年级同学为"希望工程"捐款,1班,2班,3班平均每班捐25元,2班,3班,4班平均每班捐28元,已知一班捐款26元,求4班捐款多少元 在为西部的捐书活动中,六年级五个班共捐书630本,其中一班捐书140本,二班比一班少捐10本,三班捐的本数是全年级的百分之20,四班于五班捐的本数比是6:7,四班捐了多少本? 聪聪行走的路程比明明多三分之二,明明用的时间比聪聪多五分之二.求聪聪与明明的速度比. 小学二年级四个班的同学为希望工程捐款,一班,二班,三班平均每班捐款24元,二班,三班,四班,平均每班捐款26元,已知一班捐款22元,那么四班捐款多少元?用多元次方程解~ 班上要进行一次捐书活动,请在班上做一次捐书倡议的发言 实验小学六年级的女生占全年级的5分之2,男生人数比女生人数多12人,那么实验小学六年级人数共有多少人? 从学校走到少年宫,聪聪用了10分钟,明明用了8分钟,聪聪和明明的速度比是多少完整一点,急 为了过一个有意义的“六、一”儿童借,实验小学发起了向某希望小学捐赠图书的活动.在活动中,五年级一班捐赠图书100册,五年级二班捐赠图书180册,二班的人数是一班人数的1.2倍,二班平均没 实验小学六年级共有学生180人,其中,女生人数是男生的十一分之九.六年级男生和女生各有多少人? 从学校走到少年宫聪聪用了10分钟明明用了18分钟聪聪和明明的速度比是多少?打错了!明明用了8分钟 实验小学向“希望小学”捐赠一批图书,其中文艺书占40%,连环画占1/4,余下的 840册是科普读物.实验小学共捐图书多少册? 实验小学六年级有学生180人,其中女生是男生的9/11,.六年级男生和女生各有多少人?我看别人的时180/(1+9/11)=99人,为什么用1+9/11? 从学校走到少年宫.聪聪用了10分钟.明明用了8分钟.聪聪和明明的速度比是多少? 新化小学为希望小学捐款,六年级捐2448元,比五年级多20%, 光明小学一年级有学生380人,男生人数的1/5比女生人数的1/6多10人.一年级男女生各多少人? 星期天小红去图书馆借书,原来打算每分钟走50米,但为了提早到10分钟她把速度加快到了每分钟70米,问小红家离图书馆有多远?(要要文字解释 学校组织为希望工程捐款活动,五,六年级捐款数的比是3:5.已知六年级比五年级多捐了400元,两个年级各捐少元? 光明小学男女人数的比是4:5,女生比男生多()%,已知全校学生人数是90人,男生有()人. 图书馆距聪聪家1950米.一天,聪聪从家里出发,步行去图书馆,开始的步行速度为60米|分,走了十五分钟后,步行速度改为|分.聪聪还要都久才能到达?请例方程. 五年级共有72名学生向希望工程捐款零花钱,捐的总数刚好是72的倍数,而记账时有两个数字不清楚:( )52.7( )元 某小学有学生975人,全校男生人数是六年级学生人数的4倍少23人,全校女生人数是六年级学生人数的3倍多11人,问全校有男、女生各多少人?不能用方程. 聪聪骑自行车从家去相距5千米的图书馆借书,从给的统计图中可以看出他去时用的时间是返回所用时间的()%去时骑车的平均速度与返回时骑车的平均速度的最见证书比是(),比值是多少? 某校六年级同学为地震灾区共捐款4000元,占全校捐款总数的七分之四,五年级捐款数占全校的25%,五年级同学共计捐款多少元? 光明小学六年级学生占全校的六分之一,六年级男女比是6:5,男生比女生多23人全校有多少人 聪聪家和明明家合用一个水龙头,聪聪家有4口人,明明家有5口人,上月两家共用10.8吨.按每吨水2.35元计算,两家各应分摊多少元水费? 五、六年级同学共为希望小学捐款4500元, 4、六年级一班有男生23人,女生22人,全班学生占六年级学生总数的5/31. 聪聪家 650米 少年宫 820 明明家 聪聪家和明明家距离多少米? 五、六年级同学共为希望小学捐款4500元,五、六年级同学各捐款多少元 某校五年级共有学生152人,选出男生的1/11和5名女生参加数学竞赛,剩下的男女人数正好相等.这个学校五年级男、女各有多少人?列方程解 明明家离书店有800米,聪聪家离书店比明明家近1/8,求明明家与聪聪家的距离.(通过不同的位置.方向思考) 某校七年级四个班为希望工程捐款7 1班是四个班捐款的总和的六分之一.72班是四个班综合的三分之一.7 3 班是四个班总和的四分之一.7 4 班捐了169元.设四个班总和为x元,方程怎么列? 设计一条捐款捐物捐书的宣传语 聪聪家 书店相距800米,明明家比聪聪家离书店近8分之1,聪聪家和明明两家距离是多少米? 某校七年级(2) 班40 名同学为“希望工程”捐款,共捐款400 元,捐款情况如下表:表格中捐款10元和15 元的人数被墨水污染了.问:捐10元和15元的人数各是多少?{最好是一元一次方程或算术法}( 六年级共捐书540本六年级1班比六年级2班2倍少60本六年级1班和六年级2班各多少本 红红家和聪聪家分别在学校的南\北两个方向上放学后他们同时走出校门各自回家,红红每分钟走80米,聪聪与红红速度比是5:4,10分钟后两个人同时到家.红红家和聪聪家相距多少米? 新城小学六年级同学向希望小学捐款4200元,五年级捐款的4\5和六年级同学捐款的4\7相等, 甲同学捐书的数量是已同学的5/21,丙同学捐书的数量是甲同学的4/5,三名同学捐书总数是310本已同学捐书?求已同学捐多少本?最好有算式! 打同一份稿件,聪聪要用九分之四小时,明明要用35分钟,丽丽要用十五分之七,他们三个人中,谁的打字速度快.(写出算式) 星光小学六年级同学向希望工程捐款,五年级(1)班45人,一共捐款450.7元,五年级(2)班50元,平均每人捐款8.65元,两个班平均每人捐款多少元? 某小学有1000名学生,为了支援南方灾区,纷纷捐书,有一半男生每人捐9本,另一半男生每人捐5本书;一半女生每人捐了8本书,另一半女生每人捐了6本书.全校捐了多少本书? 父亲的年龄是聪聪年龄的9倍,母亲的年龄是聪聪年龄的7.5倍,父亲比母亲大6岁.聪聪今年几岁呢?(列方程解答) 六年级捐款860元,比五年级多捐110元,五年级相当全校捐款的67分之15,全校捐款多少元? 正义路小学共有1000名学生,为支援“希望工程”.同学们纷纷捐书,有一半男生每人捐了9本书,另一半男生每人捐了5本书;一半女生每人捐了8本书,另一半女生每人捐了6本书.全校学生共捐了多 父亲的年龄是聪聪年龄的9倍,母亲的年龄是聪聪年龄的7.5倍,父亲比母亲大6岁.聪聪今年几岁? 六年级师生向汶川地震区小朋友捐书170本五年级捐书的本数是六年级的17分之15.算式答 育才小学六年级为希望工程捐书,男生捐的本书是女生的5分之3,六年级一共捐了640本.男生和女生各捐了多少本 爸爸的年龄是聪聪的3倍,爸爸比聪聪大26岁,爸爸今年几岁?聪聪几岁?急 胜利小学学生开展支援灾区捐书活动,六年级捐书90本,占全校捐书总数的4分之1,全校捐书多少本? 某校六年级三个班为希望工程捐书,一班捐了六年级捐书总数的4/11,二班捐了90册,三班捐的书是一、二班捐书的和的一半,六年级三个班共捐了多少册? 妈妈的年龄是聪聪的5倍.爸爸的年龄比妈妈大三岁.是聪聪的5.5倍、聪聪几岁? 某班开展贫困山区学校捐书活动,捐的书比平均每人捐3本多21本,比平均每人捐4本少27本,有多少名学生算式
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn