11

完全なスクリーンショットについては、次のコードを使用します。

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;

それを変換して、アクティブなウィンドウのみのスクリーンショットを撮るにはどうすればよいですか。

4

8 に答える 8

19
  1. まず、適切なウィンドウを取得する必要があります。Sharptooth が既に述べたようGetForegroundWindowに、 の代わりに使用する必要がありGetDesktopWindowます。改善されたバージョンでそれを正しく行いました。
  2. ただし、ビットマップのサイズを DC/ウィンドウの実際のサイズに変更する必要があります。あなたはまだこれを行っていません。
  3. そして、フルスクリーン ウィンドウをキャプチャしないように注意してください。

あなたのコードを実行すると、私の Delphi IDE がキャプチャされ、デフォルトでフルスクリーンになっているため、フルスクリーンのスクリーンショットのように見えました。(あなたのコードはほとんど正しいですが)

上記の手順を考慮すると、コードを使用して単一ウィンドウのスクリーンショットを作成することができました.

ヒント:クライアント領域のみに関心がある場合は、GetDC代わりに使用できます。GetWindowDC(ウィンドウ枠なし)

編集:これが私があなたのコードで作ったものです:

このコードは使用しないでください。以下の改良版を見てください。

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:要求に応じて、より良いバージョンのコードを追加していますが、古いバージョンを参照として保持しています。元のコードの代わりにこれを使用することを真剣に検討する必要があります。エラーが発生した場合は、はるかに適切に動作します。(リソースがクリーンアップされ、フォームが再び表示されます...)

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;
于 2009-03-19T07:27:22.073 に答える
17

あなたのコードはもっと簡単になるかもしれません。保存するフォームが決まったら、私が使用するコードを試してください。

procedure SaveFormBitmapToBMPFile( AForm : TCustomForm; AFileName : string = '' );
// Copies this form's bitmap to the specified file
var
  Bitmap: TBitMap;
begin
  Bitmap := AForm.GetFormImage;
  try
    Bitmap.SaveToFile( AFileName );
  finally
    Bitmap.Free;
  end;
end;
于 2009-03-19T08:41:08.370 に答える
6

JCLが再び助けに来ます..

    hwnd := GetForegroundWindow;
    Windows.GetClientRect(hwnd, r);
    JclGraphics.ScreenShot(theBitmap, 0, 0, r.Right - r.Left, r.Bottom - r.Top, hwnd);

    // use theBitmap...
于 2009-03-19T20:30:03.523 に答える
0

GetDesktopWindow() の代わりに GetForegroundWindow() を使用します。

GetForegroundWindow() が返すハンドルを保存し、保存された値を ReleaseDC() に渡す必要があります。呼び出し間でアクティブなウィンドウが変更された場合に、GetWindowDC() と ReleaseDC() が同じウィンドウに対して正確に呼び出されるようにするためです。

于 2009-03-19T06:51:19.630 に答える
-3

Brian Frost コードの最短バージョン:

Screen.ActiveForm.GetFormImage.SaveToFile(Screen.ActiveForm.Caption+'.bmp');

コードの 1 行のみ (MDI アプリケーションのアクティブ ウィンドウのスクリーンショット)。

于 2012-06-03T15:39:09.757 に答える