如何在Delphi中拍摄活动窗口的屏幕截图? [英] How to take a screenshot of the Active Window in Delphi?

查看:95
本文介绍了如何在Delphi中拍摄活动窗口的屏幕截图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

完整的屏幕截图,我使用以下代码:

For full screenshots, I use this code:

form1.Hide;
sleep(500);
bmp := TBitmap.Create;
bmp.Height := Screen.Height;
bmp.Width := Screen.Width;
DCDesk := GetWindowDC(GetDesktopWindow);
BitBlt(bmp.Canvas.Handle, 0, 0, Screen.Width, Screen.Height, DCDesk, 0, 0, SRCCOPY);
form1.Show ;
FileName := 'Screenshot_'+FormatDateTime('mm-dd-yyyy-hhnnss',now());
bmp.SaveToFile(Format('C:\Screenshots\%s.bmp', [FileName]));
ReleaseDC(GetDesktopWindow, DCDesk);
bmp.Free;

如何将其转换为仅包含活动窗口的屏幕截图。

How can I convert that to take a screenshot of only the active window.

推荐答案


  1. 首先,您必须获得正确的窗口。正如Sharptooth已经指出的那样,您应该使用 GetForegroundWindow 而不是 GetDesktopWindow 。您已经在改进的版本中完成了操作

  2. 但是您有将位图调整为DC / Window的实际大小。

  3. 然后确保您没有捕获一些全屏窗口!

  1. First of all you have to get the right window. As sharptooth already noted you should use GetForegroundWindow instead of GetDesktopWindow. You have done it right in your improved version.
  2. But then you have to resize your bitmap to the actual size of the DC/Window. You haven't done this yet.
  3. And then make sure you don't capture some fullscreen window!

当我执行您的代码时,我的Delphi IDE被捕获,并且默认情况下它处于全屏状态,因此产生了全屏截图的错觉。 (即使您的代码大部分是正确的)

When I executed your code, my Delphi IDE was captured and as it is on fullscreen by default, it created the illusion of a fullscreen screenshot. (Even though your code is mostly correct)

考虑到上述步骤,我成功地使用您的代码创建了一个单窗口的屏幕截图。

Considering the above steps, I was successfully able to create a single-window screenshot with your code.

只是一个提示:如果您只感兴趣,可以使用 GetDC 代替 GetWindowDC 在客户区。 (无窗口边框)

Just a hint: You can GetDC instead of GetWindowDC if you are only interested in the client area. (No window borders)

编辑:这是我用您的代码制作的内容:

Here's what I made with your code:

您不应使用此代码!看看下面的改进版本。

procedure TForm1.Button1Click(Sender: TObject);
const
  FullWindow = True; // Set to false if you only want the client area.
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:根据要求,我添加了一个更好的版本代码,但我保留旧的代码作为参考。您应该认真考虑使用它而不是原始代码。如果出现错误,它将表现得更好。 (清理资源,您的表单将再次可见,...)

EDIT 2: As requested I'm adding a better version of the code, but I'm keeping the old one as a reference. You should seriously consider using this instead of your original code. It'll behave much nicer in case of errors. (Resources are cleaned up, your form will be visible again, ...)

procedure TForm1.Button1Click(Sender: TObject);
const
  FullWindow = True; // Set to false if you only want the client area.
var
  Win: HWND;
  DC: HDC;
  Bmp: TBitmap;
  FileName: string;
  WinRect: TRect;
  Width: Integer;
  Height: Integer;
begin
  Form1.Hide;
  try
    Application.ProcessMessages; // Was Sleep(500);
    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;

这篇关于如何在Delphi中拍摄活动窗口的屏幕截图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆