How create a screenshot of a particular area?

2019-03-27 16:17发布

问题:

I have code that receives a specific area already defined before on server side and creates a hole on Form in client side. Instead of this, i want to get a screen capture of this same area but without appears my Form in final result, like a normal desktop capture, but in this case will be only captured, this small area.

So, how i can adapt this my code below for this?

procedure TForm1.CS1Read(Sender: TObject; Socket: TCustomWinSocket);
var
  X1, X2, Y1, Y2: Integer;
  List: TStrings;
  FormRegion, HoleRegion: HRGN;
  StrCommand: String;
begin
  StrCommand := Socket.ReceiveText;

  if Pos('§', StrCommand) > 0 then
  begin
    List := TStringList.Create;
    try
      FormRegion := CreateRectRgn(0, 0, Form12.Width, Form12.Height);
      ExtractStrings(['§'], [], PChar(StrCommand), List);

      X1 := StrToIntDef(List[0], 0) - Form12.Left - 2;
      Y1 := StrToIntDef(List[1], 0) - Form12.Top - 2;
      X2 := StrToIntDef(List[2], 0) - Form12.Left - 2;
      Y2 := StrToIntDef(List[3], 0) - Form12.Top - 2;

      HoleRegion := CreateRectRgn(X1, Y1, X2, Y2);
      CombineRgn(FormRegion, FormRegion, HoleRegion, RGN_DIFF);
      SetWindowRgn(Form12.Handle, FormRegion, True);
    finally
      List.Free;
    end;
  end;
end;

回答1:

I don't have all of your extraneous information, but I can show you how to capture the contents of a region into a bitmap. You'll need to adjust the coordinates appropriately to suit your needs, of course. You may want to see GetRgnBox to see how to get the total region's bounding rectangle after you've combined them. My example doesn't do so, because I have a single region.

The example requires two TButtons and a TImage on a form. I've sized the form and located the three components in code, so that it's not necessary to include a DFM. You will need to drop the components on a form and connect the event handlers, however. :-)

Clicking Button1 will create a rectangular region on the form, fill it with a grid type pattern of red lines and a bit of text, just to define where the region is located. Clicking the second button will draw a copy of that region's content on a bitmap and assign that bitmap to the image control.

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    // Region coords
    R: TRect;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// Create the region (hole)
procedure TForm1.Button1Click(Sender: TObject);
var
  Region: HRGN;
begin
  Canvas.TextOut(R.Left + 60, R.Top + 60, 'Test text');
  Canvas.Brush.Style := bsCross;
  Canvas.Brush.Color := clRed;
  Region := CreateRectRgn(R.Left, R.Top, R.Right, R.Bottom);
  { 
    Note: Normally you'd want to check the result of the above API call
    and only proceed if it's not NULL (0). You'd also want to use a
    try..finally to make sure that the region was deleted properly.
    Omitted here because 
      a) This code was tested to work properly, and
      b) It's a demo app for doing something with the region and
         nothing else. If the call to create the region fails, the
         app is useless, and you'll close it anyway, which means
         the region will be automatically destroyed.
  }
  FillRgn(Canvas.Handle, Region, Canvas.Brush.Handle);
  DeleteObject(Region);
  Button2.Enabled := True;
end;

// Capture the region (hole) and display in the TImage.
procedure TForm1.Button2Click(Sender: TObject);
var
  Bmp: TBitmap;
begin
  Bmp := TBitmap.Create;
  try
    Bmp.SetSize(R.Right - R.Left, r.Bottom - R.Top);
    Bmp.Canvas.CopyRect(Rect(0, 0, Bmp.Width, Bmp.Height), Canvas, R);
    Image1.Picture.Assign(Bmp);
  finally
    Bmp.Free;
  end;
end;

// Set up the coordinates for the region (hole) in the form
procedure TForm1.FormCreate(Sender: TObject);
begin
  R := Rect(10, 40, 175, 175);
  // Size the image we'll use later to fit the rectangle. We set
  // the position below.
  Image1.Width := R.Right - R.Left;
  Image1.Height := R.Bottom - R.Top;

  Self.Height := 375;
  Self.Width := 350;
  Button1.Left := 238;
  Button1.Top := 16;
  Button2.Left := 238;
  Button2.Top := 48;
  Image1.Left := 160;
  Image1.Top := 190;
  // Disable the second button until the first has been clicked
  Button2.Enabled := False;
end;

end.