原创:如何截取被看不见的视窗内容?
作者: 陆岛工作室
为一方便使用,我把它整理成了一个常用的函数:
这是老问题,一直没有得到解决, 昨天做了一个Pahi 游戏的外挂,又想到了这个问题。于是上网找找。找到了以下的一个页面,里面有比较详细的解释。
http://www.delphipages.com/threads/thread.cfm?ID=131830&G=131747
原来,在 Window2K下实现这个功能还真不容易。在XP下有一个新的API函数,PrintWindow,网上有一段代码。整理如下,测试后发现OK。
PrintWindow 的声明如下:
function PrintWindow(SourceWindow: hwnd; Destination: hdc; nFlags: cardinal): bool; stdcall; external 'user32.dll' name 'PrintWindow';
我们用一小段代码测试一下:
procedure TForm1.FormCreate(Sender: TObject);
var
bmp : TBitmap;
wnd : cardinal;
rec : TRect;
begin
wnd := FindWindow('windowtitle', nil); // get the handle
// of your window
GetWindowRect(wnd, rec);
bmp := TBitmap.Create;
try
bmp.Width := rec.Right - rec.Left;
bmp.Height := rec.Bottom - rec.Top;
bmp.PixelFormat := pf24bit;
PrintWindow(wnd, bmp.Canvas.Handle, 0);
bmp.SaveToFile('d:\window.bmp');
finally
bmp.Free;
end;
end;
var
bmp : TBitmap;
wnd : cardinal;
rec : TRect;
begin
wnd := FindWindow('windowtitle', nil); // get the handle
// of your window
GetWindowRect(wnd, rec);
bmp := TBitmap.Create;
try
bmp.Width := rec.Right - rec.Left;
bmp.Height := rec.Bottom - rec.Top;
bmp.PixelFormat := pf24bit;
PrintWindow(wnd, bmp.Canvas.Handle, 0);
bmp.SaveToFile('d:\window.bmp');
finally
bmp.Free;
end;
end;
为一方便使用,我把它整理成了一个常用的函数:
procedure CaptureWindowToBitmap(WndHandle: HWND; Bitmap: TBitmap);
procedure DoCaptureWindow;
var
ImageDC: HDC;
R: TRect;
begin
SetForegroundWindow(WndHandle);
Sleep(200);
ImageDC := GetWindowDC(WndHandle);
try
GetWindowRect(WndHandle, R);
if GetWindowLong(WndHandle, GWL_STYLE) and WS_MAXIMIZE <> 0 then
SetRect(R, Abs(R.Left), Abs(R.Top), Abs(R.Right), Abs(R.Bottom)) else
OffsetRect(R, -R.Left, -R.Top);
with Bitmap do
begin
FillRect(Canvas.Handle, Rect(0, 0, Width, Height), GetStockObject(BLACK_BRUSH));
StretchBlt(Canvas.Handle, 0, 0, Width, Height, ImageDC, R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top, cmSrcCopy);
end;
finally
ReleaseDC(WndHandle, ImageDC);
end;
end;
var
R: TRect;
begin
if not Assigned(Bitmap) then Exit;
Bitmap.Width :=0;
Bitmap.Height := 0;
GetWindowRect(WndHandle, R);
try
Bitmap.Width := (R.Right - R.Left);
Bitmap.Height := (R.Bottom - R.Top);
Bitmap.PixelFormat := pf24bit;
if @PrintWindow<>nil then
PrintWindow(WndHandle, Bitmap.Canvas.Handle, 0)
else
DoCaptureWindow;
finally
{}
end;
end;
procedure DoCaptureWindow;
var
ImageDC: HDC;
R: TRect;
begin
SetForegroundWindow(WndHandle);
Sleep(200);
ImageDC := GetWindowDC(WndHandle);
try
GetWindowRect(WndHandle, R);
if GetWindowLong(WndHandle, GWL_STYLE) and WS_MAXIMIZE <> 0 then
SetRect(R, Abs(R.Left), Abs(R.Top), Abs(R.Right), Abs(R.Bottom)) else
OffsetRect(R, -R.Left, -R.Top);
with Bitmap do
begin
FillRect(Canvas.Handle, Rect(0, 0, Width, Height), GetStockObject(BLACK_BRUSH));
StretchBlt(Canvas.Handle, 0, 0, Width, Height, ImageDC, R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top, cmSrcCopy);
end;
finally
ReleaseDC(WndHandle, ImageDC);
end;
end;
var
R: TRect;
begin
if not Assigned(Bitmap) then Exit;
Bitmap.Width :=0;
Bitmap.Height := 0;
GetWindowRect(WndHandle, R);
try
Bitmap.Width := (R.Right - R.Left);
Bitmap.Height := (R.Bottom - R.Top);
Bitmap.PixelFormat := pf24bit;
if @PrintWindow<>nil then
PrintWindow(WndHandle, Bitmap.Canvas.Handle, 0)
else
DoCaptureWindow;
finally
{}
end;
end;
作者: 陆岛工作室