



Autor: Gilberto Rocha da Silva
unit: DTM_ImageCatcher.pas
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | unit DTM_ImageCatcher; interface uses System.Classes,System.SysUtils,Vcl.Controls,Vcl.Graphics, Vcl.Forms,Winapi.Windows,Winapi.D3DX9,Direct3D9,DirectDraw; type TCatchType = (ctWinapi = 0,ctDirectX = 1,ctDDraw); TImageCatcher = class private FBitmap: Vcl.Graphics.TBITMAP; FCatchType: TCatchType; FTargetHandle: HWND; procedure GetTargetRect(out Rect: TRect); procedure GetDDrawData(); procedure GetDirectXData(); procedure GetWinapiData(); procedure GetTargetDimensions(out w, h: integer); procedure GetTargetPosition(out left, top: integer); public constructor Create; procedure Reset; destructor Destroy;override; procedure GetScreenShot(); procedure ActivateTarget; property Bitmap: Vcl.Graphics.TBITMAP read FBitmap write FBitmap; property CatchType: TCatchType read FCatchType write FCatchType; property TargetHandle: HWND read FTargetHandle write FTargetHandle; end; implementation { TImageCather } procedure TImageCatcher.ActivateTarget; begin SetForegroundWindow(TargetHandle); end; constructor TImageCatcher.Create; begin Reset; FBitmap:=Vcl.Graphics.TBitmap.Create; FBitmap.PixelFormat:=pf24bit; end; destructor TImageCatcher.Destroy; begin FreeAndNil(FBitmap); inherited; end; procedure TImageCatcher.GetDDrawData(); var DDSCaps: TDDSCaps; DesktopDC: HDC; DirectDraw: IDirectDraw; Surface: IDirectDrawSurface; SurfaceDesc: TDDSurfaceDesc; x, y, w, h: integer; begin GetTargetDimensions(w, h); GetTargetPosition(x, y); if DirectDrawCreate(nil, DirectDraw, nil) = DD_OK then if DirectDraw.SetCooperativeLevel(GetDesktopWindow, DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN or DDSCL_ALLOWREBOOT) = DD_OK then begin FillChar(SurfaceDesc, SizeOf(SurfaceDesc), 0); SurfaceDesc.dwSize := Sizeof(SurfaceDesc); SurfaceDesc.dwFlags := DDSD_CAPS; SurfaceDesc.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE; SurfaceDesc.dwBackBufferCount := 0; if DirectDraw.CreateSurface(SurfaceDesc, Surface, nil) = DD_OK then begin if Surface.GetDC(DesktopDC) = DD_OK then try Bitmap.Width := Screen.Width; Bitmap.Height := Screen.Height; BitBlt(Bitmap.Canvas.Handle, 0, 0, W, H, DesktopDC, x, y, SRCCOPY); finally Surface.ReleaseDC(DesktopDC); end; end; end; end; procedure TImageCatcher.GetDirectXData(); var BitsPerPixel: Byte; pD3D: IDirect3D9; pSurface: IDirect3DSurface9; g_pD3DDevice: IDirect3DDevice9; D3DPP: TD3DPresentParameters; ARect: TRect; LockedRect: TD3DLockedRect; BMP: VCL.Graphics.TBitmap; i, p: Integer; x, y: integer; w, h: integer; begin GetTargetDimensions(w, h); GetTargetPosition(x, y); BitsPerPixel := 32; FillChar(d3dpp, SizeOf(d3dpp), 0); with D3DPP do begin Windowed := True; Flags := D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; SwapEffect := D3DSWAPEFFECT_DISCARD; BackBufferWidth := Screen.Width; BackBufferHeight := Screen.Height; BackBufferFormat := D3DFMT_X8R8G8B8; end; 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); ARect := Screen.DesktopRect; pSurface.LockRect(LockedRect, @ ARect, D3DLOCK_NO_DIRTY_UPDATE or D3DLOCK_NOSYSLOCK or D3DLOCK_READONLY); BMP := VCL.Graphics.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; Bitmap.SetSize(w, h); BitBlt(Bitmap.Canvas.Handle, 0, 0, w, h, BMP.Canvas.Handle, x, y, SRCCOPY); BMP.Free; pSurface.UnlockRect; end; procedure TImageCatcher.GetScreenShot(); begin case CatchType of ctWinapi : GetWinapiData(); ctDirectX : GetDirectXData(); ctDDraw : GetDDrawData(); end; SetForegroundWindow(Application.Handle); end; procedure TImageCatcher.GetTargetDimensions(out w, h: integer); var Rect: TRect; begin GetTargetRect(rect); w := Rect.Right - Rect.Left; h := Rect.Bottom - Rect.Top; end; procedure TImageCatcher.GetTargetPosition(out left, top: integer); var Rect: TRect; begin GetTargetRect(rect); left := Rect.Left; top := Rect.Top; end; procedure TImageCatcher.GetTargetRect(out Rect: TRect); begin GetWindowRect(TargetHandle, Rect); end; procedure TImageCatcher.Reset; begin CatchType := ctWinapi; TargetHandle := 0; end; procedure TImageCatcher.GetWinapiData(); var hWinDC: THandle; w, h: integer; Begin GetTargetDimensions(w, h); hWinDC := GetWindowDC(TargetHandle); Bitmap.Width := w; Bitmap.Height := h; hWinDC := GetWindowDC(TargetHandle); BitBlt(Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, hWinDC, 0, 0, SRCCOPY); ReleaseDC(TargetHandle, hWinDC); End; end. |
Baixe o exemplo com os fontes:
showdelphi.com.br/download/2027/