看到老是有人问DirectDraw抓屏幕的问题,也没人来解答,是不是很多大虾不愿意把方法
告诉新手啊?下面贴上程序,用的是标准的DirectX7.0的接口,不用DelphiX,那个用起来
太麻烦,效率也低。不过注意了,采用DirectDraw来Capture Screen可不会象你们想的那么
快速,实际上和GDI差不多,因为GDI的Bitblt和DirectDraw在最后实现上都是相同的。
注意需要 uses DirectDraw;这个单元可以在 Jedi-GraphX 找到。
delphi6 的第2张盘上也有。
全局变量:
Var
Draw7:IDirectDraw7;
PriSurface7,
BakSurface7:IDirectDrawSurface7;
OnFormCreate 时初始化
Var Rs:HResult;
Desc:TDDSURFACEDESC2 ;
PF:TDDpixelFormat;
Begin
Rs:=DirectDrawCreateEx(nil,Draw7,IID_IDirectDraw7,nil);
IF Rs<>DD_OK Then Exit; //DirectDraw7初始化失败
Rs:=Draw7.SetCooperativeLevel(Handle,DDSCL_NORMAL );
IF Rs<>DD_OK Then Exit; //DirectDraw7设置协作级别失败
// 下面建立主表面
FillChar(Desc,sizeof(desc),0);
Desc.dwSize := Sizeof(desc);
Desc.dwFlags := DDSD_CAPS;
Desc.ddsCaps.dwCaps:=DDSCAPS_PRIMARYSURFACE;
Rs:=Draw7.CreateSurface(Desc,PriSurface7, nil);
IF Rs<>DD_OK then Exit; // 建立主表面失败
// 下面建立内存缓冲表面
Desc.dwFlags := DDSD_CAPS OR DDSD_HEIGHT OR DDSD_WIDTH OR DDSD_PIXELFORMAT ;
Desc.dwWidth := Screen.Width;
Desc.dwHeight:= Screen.Height;
Desc.ddsCaps.dwCaps:=DDSCAPS_OFFSCREENPLAIN OR DDSCAPS_SYSTEMMEMORY ;
//定义像素格式为32bit,你也可以自己定义,参看msdn 相关内容
FillChar(PF,Sizeof(PF),0);
PF.dwSize:=Sizeof(PF);
PF.dwFlags:=DDPF_RGB;
PF.dwRGBBitCount:=32;
PF.dwRBitMask:=$FF;
PF.dwGBitMask:=$FF00;
PF.dwBBitMask:=$FF0000;
PF.dwRGBAlphaBitMask:=$FF000000;
Desc.ddpfPixelFormat:=PF;
Rs:=Draw7.CreateSurface(desc,BakSurface7, nil);
IF Rs<>DD_OK then Exit; //建立缓冲表面失败
BakSurface7.PageLock(0); //启动DMA能力(如果可能的话)
//至此初始化完成
End;
抓屏幕过程
假设输入指针 myPtr 是你自己处理的位图指针 ,注意你的指针必须已申请内存,且大小
能够容纳你开始设置的满屏图象。
Var DSD:TDDSURFACEDESC2;
PS,PD
DWord;
Y:Integer;
Begin
BakSurface7.Blt(nil,PriSurface7,nil,0,nil) ; //拷贝屏幕到后台缓冲
Fillchar(DSD,Sizeof(DSD),0);
DSD.dwSize:=Sizeof(DSD);
IF BakSurface7.Lock(nil,DSD,DDLOCK_SURFACEMEMORYPTR,0)=DD_OK then
For Y:=0 to DSD.dwHeight-1 DO
Begin
PD:=Pointer(DWORD(DSD.lpSurface)+Y*DWord(DSD.lPitch));
PS:=Pointer(DWORD(myPtr)+(DSD.dwHeight-1-Y)*Dword(DSD.dwWidth)*4);
Move(PS^,PD^,DSD.dwWidth*4);
End;
BakSurface7.unLock(nil);
//到这里已获得屏幕
End;
OnFormClose 释放对象 注意不要写在 OnFormDestroy
Begin
BakSurface7.PageUnLock(0);
BakSurface7:=Nil;
PriSurface7:=Nil;
Draw7:=Nil;
End;