procedure CaptureScreen(Const FileName: string); var BitsPerPixel: Byte; pD3D: IDirect3D9; pSurface: IDirect3DSurface9; g_pD3DDevice: IDirect3DDevice9; D3DPP: TD3DPresentParameters; ARect: TRect; LockedRect: TD3DLockedRect; BMP: TBitmap; i, p: Integer; begin BitsPerPixel := GetDeviceCaps(Canvas.Handle, BITSPIXEL); FillChar(d3dpp, SizeOf(d3dpp), 0); D3DPP.Windowed := True; D3DPP.Flags := D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; D3DPP.SwapEffect := D3DSWAPEFFECT_DISCARD; D3DPP.BackBufferWidth := Screen.Width; D3DPP.BackBufferHeight := Screen.Height; D3DPP.BackBufferFormat := D3DFMT_X8R8G8B8; pD3D := Direct3DCreate9(D3D_SDK_VERSION); pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetDesktopWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, @D3DPP, g_pD3DDevice); g_pD3DDevice.CreateOffscreenPlainSurface(Screen.Width, Screen.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, pSurface, nil); g_pD3DDevice.GetFrontBufferData(0, pSurface); // use D3D to save surface. Notes: D3DX%ab.dll is required! // D3DXSaveSurfaceToFile('Desktop.bmp', D3DXIFF_BMP, pSurface, nil, nil); // use Bitmap to save surface ARect := Screen.DesktopRect; pSurface.LockRect(LockedRect, @ARect, D3DLOCK_NO_DIRTY_UPDATE or D3DLOCK_NOSYSLOCK or D3DLOCK_READONLY); BMP := TBitmap.Create; BMP.Width := Screen.Width; BMP.Height := Screen.Height; case BitsPerPixel of 8: BMP.PixelFormat := pf8bit; 16: BMP.PixelFormat := pf16bit; 24: BMP.PixelFormat := pf24bit; 32: BMP.PixelFormat := pf32bit; end; p := Cardinal(LockedRect.pBits); for i := 0 to Screen.Height - 1 do begin CopyMemory(BMP.ScanLine[i], Ptr(p), Screen.Width * BitsPerPixel div 8); p := p + LockedRect.Pitch; end; BMP.SaveToFile(FileName); BMP.Free; pSurface.UnlockRect; end; procedure CaptureScreen(const FileName: string;Const FileType: TD3DXImageFileFormat); var pD3D: IDirect3D9; pSurface: IDirect3DSurface9; g_pD3DDevice: IDirect3DDevice9; D3DPP: TD3DPresentParameters; begin FillChar(d3dpp, SizeOf(d3dpp), 0); D3DPP.Windowed := True; D3DPP.Flags := D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; D3DPP.SwapEffect := D3DSWAPEFFECT_DISCARD; D3DPP.BackBufferWidth := Screen.Width; D3DPP.BackBufferHeight := Screen.Height; D3DPP.BackBufferFormat := D3DFMT_X8R8G8B8; pD3D := Direct3DCreate9(D3D_SDK_VERSION); pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetDesktopWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, @D3DPP, g_pD3DDevice); g_pD3DDevice.CreateOffscreenPlainSurface(Screen.Width, Screen.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, pSurface, nil); g_pD3DDevice.GetFrontBufferData(0, pSurface); D3DX9.D3DXSaveSurfaceToFile(PChar(FileName),FileType,pSurface,nil,nil); pSurface := nil; g_pD3DDevice := nil; pD3D := nil; end; 传递两个参数,第一个参数指定为文件名,第二个参数指定为文件类型 支持7种类型 _D3DXIMAGE_FILEFORMAT = ( D3DXIFF_BMP {= 0}, D3DXIFF_JPG {= 1}, D3DXIFF_TGA {= 2}, D3DXIFF_PNG {= 3}, D3DXIFF_DDS {= 4}, D3DXIFF_PPM {= 5}, D3DXIFF_DIB {= 6} ); 再给一个使用dX8实现的,上面给的是用Dx9实现的函数 procedure CaptureScreen(const FileName: string;Const FileType: TD3DXImageFileFormat); var pD3D: IDirect3D8; pSurface: IDirect3DSurface8; g_pD3DDevice: IDirect3DDevice8; D3DPP: TD3DPresentParameters; begin FillChar(d3dpp, SizeOf(d3dpp), 0); D3DPP.Windowed := True; D3DPP.Flags := D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; D3DPP.SwapEffect := D3DSWAPEFFECT_DISCARD; D3DPP.BackBufferWidth := Screen.Width; D3DPP.BackBufferHeight := Screen.Height; D3DPP.BackBufferFormat := D3DFMT_X8R8G8B8; pD3D := Direct3DCreate8(D3D_SDK_VERSION); pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetDesktopWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, D3DPP, g_pD3DDevice); g_pD3DDevice.CreateImageSurface(Screen.Width, Screen.Height, D3DFMT_A8R8G8B8, pSurface); g_pD3DDevice.GetFrontBuffer(pSurface); D3DX8.D3DXSaveSurfaceToFile(PChar(FileName),FileType,pSurface,nil,nil); pSurface := nil; g_pD3DDevice := nil; pD3D := nil; end; 再给一个直接使用系统GDI实现的抓屏 procedure CaptureScreen(const FileName: string);overload; var nScreenWidth,nScreenHeight: integer; ScreenDc,hCaptureDC: HDC; bmp: TBitmap; begin nScreenWidth := GetSystemMetrics(SM_CXSCREEN); nScreenHeight := GetSystemMetrics(SM_CYSCREEN); ScreenDc := GetDC(GetDesktopWindow); hCaptureDC := CreateCompatibleDC(ScreenDc); bmp := TBitmap.Create; bmp.Handle :=CreateCompatibleBitmap(ScreenDc,nScreenWidth, nScreenHeight); SelectObject(hCaptureDC,bmp.Handle); BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,ScreenDc,0,0,SRCCOPY); bmp.SaveToFile(fileName); ReleaseDC(GetDesktopWindow,ScreenDc); DeleteDC(hCaptureDC); bmp.Free; end; 通过上面这一步,我们可以很容易联想到用来抓取任何一个控件的表面图象,函数如下: procedure CaptureControl(Control: TWinControl;const FileName: string);overload; var ControlWidth,ControlHeight: integer; ControlDc,hCaptureDC: HDC; bmp: TBitmap; begin ControlWidth := Control.ClientWidth; ControlHeight := Control.ClientHeight; ControlDc := GetDC(Control.Handle); hCaptureDC := CreateCompatibleDC(ControlDc); bmp := TBitmap.Create; bmp.Handle :=CreateCompatibleBitmap(ControlDc,ControlWidth,ControlHeight); SelectObject(hCaptureDC,bmp.Handle); BitBlt(hCaptureDC,0,0,ControlWidth,ControlHeight,ControlDc,0,0,SRCCOPY); bmp.SaveToFile(fileName); ReleaseDC(GetDesktopWindow,ControlDc); DeleteDC(hCaptureDC); bmp.Free; end;