- 首先,你必须得到正确的窗口。正如 sharptooth 已经指出的那样,你应该使用
GetForegroundWindow
而不是 GetDesktopWindow
。在你的改进版中已经正确实现了这一点。
- 然后,你需要将位图调整为 DC/窗口的实际大小。你还没有做到这一点。
- 最后,请确保不要截取全屏窗口!
当我执行你的代码时,我的 Delphi IDE 被截取了,因为它默认是全屏的,造成了全屏截图的错觉。(尽管你的代码大部分是正确的)
考虑到以上步骤,我成功地使用你的代码创建了单个窗口的截图。
小提示:如果你只对客户端区域感兴趣(无窗口边框),可以使用 GetDC
而不是 GetWindowDC
。
编辑:这是我用你的代码做的:
你不应该使用这段代码!请查看下面的改进版本。
procedure TForm1.Button1Click(Sender: TObject);
const
FullWindow = True;
var
hWin: HWND;
dc: HDC;
bmp: TBitmap;
FileName: string;
r: TRect;
w: Integer;
h: Integer;
begin
form1.Hide;
sleep(500);
hWin := GetForegroundWindow;
if FullWindow then
begin
GetWindowRect(hWin,r);
dc := GetWindowDC(hWin) ;
end else
begin
Windows.GetClientRect(hWin, r);
dc := GetDC(hWin) ;
end;
w := r.Right - r.Left;
h := r.Bottom - r.Top;
bmp := TBitmap.Create;
bmp.Height := h;
bmp.Width := w;
BitBlt(bmp.Canvas.Handle, 0, 0, w, h, DC, 0, 0, SRCCOPY);
form1.Show ;
FileName := 'Screenshot_'+FormatDateTime('mm-dd-yyyy-hhnnss',now());
bmp.SaveToFile(Format('C:\Screenshots\%s.bmp', [FileName]));
ReleaseDC(hwin, DC);
bmp.Free;
end;
编辑2: 如所要求,我将添加一个更好的代码版本,但我会保留旧版本作为参考。您应认真考虑使用此代码而不是原始代码。在出现错误时它会表现得更好。(资源被清理,你的表格将再次可见,...)
procedure TForm1.Button1Click(Sender: TObject);
const
FullWindow = True;
var
Win: HWND;
DC: HDC;
Bmp: TBitmap;
FileName: string;
WinRect: TRect;
Width: Integer;
Height: Integer;
begin
Form1.Hide;
try
Application.ProcessMessages;
Win := GetForegroundWindow;
if FullWindow then
begin
GetWindowRect(Win, WinRect);
DC := GetWindowDC(Win);
end else
begin
Windows.GetClientRect(Win, WinRect);
DC := GetDC(Win);
end;
try
Width := WinRect.Right - WinRect.Left;
Height := WinRect.Bottom - WinRect.Top;
Bmp := TBitmap.Create;
try
Bmp.Height := Height;
Bmp.Width := Width;
BitBlt(Bmp.Canvas.Handle, 0, 0, Width, Height, DC, 0, 0, SRCCOPY);
FileName := 'Screenshot_' +
FormatDateTime('mm-dd-yyyy-hhnnss', Now());
Bmp.SaveToFile(Format('C:\Screenshots\%s.bmp', [FileName]));
finally
Bmp.Free;
end;
finally
ReleaseDC(Win, DC);
end;
finally
Form1.Show;
end;
end;