0

How do you get a screenshot specifically for the screen the application is focused on? If I drag my top most window to screen A, then I want a screenshot of that screen. Same for when I drag the window to screen B. I've tried a lot of the different examples on Stack Overflow to get this behavior to work, but they don't work for any of the screens, only some of them.

The reason is I'm using MadExcept and when a bug is generated I'm trying to get the appropriate screenshot without getting any unnecessary or sensitive info. MadExcept has a flag "ThisappOnly", but even with that I get bitmaps that has nothing in sometimes depending on which screen I'm testing it on.

So I've tried to generate the screenshots myself, also to no avail.

Can someone point me in the right direction please?

Frank Pedro
  • 198
  • 2
  • 10
  • Sounds like a bug you need to take up with the MadExcept author. – Remy Lebeau Feb 23 '22 at 17:16
  • 1
    Are you sure the problem is on which screen your application window is? I'm willing to bet that your screenshot fails to work prperly because you are showing some modal forms which means that screenshot might be taken only after such modal form is closed. You can read more about this in [delphi screen capture in global exception](https://stackoverflow.com/q/10209165/3636228) – SilverWarior Feb 24 '22 at 02:02
  • @RemyLebeau, contacted the author in the meantime too. What bugs me is why am I getting the same results when trying to capture images myself instead of relying on MadExcept? – Frank Pedro Feb 24 '22 at 05:56
  • @SilverWarior, I don't have any modals open no. I just have my main form open. Screenshot works on one of my screens, but not on the other if I follow exact same steps. – Frank Pedro Feb 24 '22 at 05:57
  • 1
    @FrankPedro hard to answer that when we can't see what you have tried – Remy Lebeau Feb 24 '22 at 06:34
  • @RemyLebeau, Yeah I figured as much, I was rushed to just get this out so long. I will revert – Frank Pedro Feb 24 '22 at 13:07
  • Does this answer your question? [Delphi Active Window Screenshot](https://stackoverflow.com/questions/23410377/delphi-active-window-screenshot) – paulsm4 Feb 28 '22 at 06:49

1 Answers1

1

You can use this function to take a screen grab of the desktop area occupied by all of your visible forms:

USES System.Math, WinAPI.DwmApi;

FUNCTION ScreenGrab(IncludeShadow : BOOLEAN = FALSE ; BorderSize : Cardinal = 8 ; BackgroundColor : TColor = clBlack) : TBitMap;
  VAR
    MinX,MinY,MaxX,MaxY,I : INTEGER;
    F                     : TForm;
    DC                    : HDC;
    R                     : TRect;

  FUNCTION GetWindowRect(F : TForm) : TRect;
    BEGIN
      IF IncludeShadow THEN
        Result:=F.BoundsRect
      ELSE
        DwmGetWindowAttribute(F.Handle,DWMWA_EXTENDED_FRAME_BOUNDS,@Result,SizeOf(TRect))
    END;

  BEGIN
    MinX:=MAXINT; MinY:=MinX; MaxX:=-MAXINT; MaxY:=MaxX;
    FOR I:=0 TO PRED(Screen.FormCount) DO BEGIN
      F:=Screen.Forms[I];
      IF F.Visible THEN BEGIN
        R:=GetWindowRect(F);
        MinX:=Min(MinX,R.Left); MinY:=Min(MinY,R.Top);
        MaxX:=Max(MaxX,R.Left+R.Width); MaxY:=Max(MaxY,R.Top+R.Height)
      END
    END;
    DEC(MinX,BorderSize); DEC(MinY,BorderSize);
    INC(MaxX,BorderSize); INC(MaxY,BorderSize);
    Result:=TBitMap.Create(MaxX-MinX,MaxY-MinY);
    TRY
      Result.PixelFormat:=pf24bit;
      Result.Canvas.Brush.Style:=TBrushStyle.bsSolid;
      Result.Canvas.Brush.Color:=BackgroundColor;
      Result.Canvas.FillRect(Rect(0,0,Result.Width,Result.Height));
      DC:=GetDC(0);
      TRY
        FOR I:=0 TO PRED(Screen.FormCount) DO BEGIN
          F:=Screen.Forms[I];
          IF F.Visible THEN BEGIN
            R:=GetWindowRect(F);
            BitBlt(Result.Canvas.Handle,R.Left-MinX,R.Top-MinY,R.Width,R.Height,DC,R.Left,R.Top,SRCCOPY)
          END
        END
      FINALLY
        ReleaseDC(0,DC)
      END
    EXCEPT
      Result.Free;
      RAISE
    END
  END;

Use "IncludeShadow" to include the shadow area around your forms (which may include screen info from the windows behind your forms). You can also specify a "BorderSize" around the grabbed area, and you may specify the background colour (of the area not occupied by your forms) of the returned image.

It also works if your forms are spread across multiple monitors. Please note, however, that if your monitors have different DPI, the composite image is of the raw pixels, so the forms may be of different scale in the final .BMP file, depending on which monitor they are located on.

HeartWare
  • 7,464
  • 2
  • 26
  • 30