作者: 陸島工作室
這是老問題,一直沒有得到解決, 昨天做了一個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;
為一方便使用,我把它整理成了一個常用的函數:
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;