DwmRegisterThumbnail to TBitmap

933 Views Asked by At

I have found a demo application that is able to get a screenshot of a minimized/hidden window using DwmRegisterThumbnail. It works perfect but the result image is draw in the form itself instead of a TBitmap.

This is the code:

procedure TfrmMain.PreviewWindow(const ASource, ADest: HWND; const ARect: TRect);
var
  LResult: HRESULT;
  LThumpProp: DWM_THUMBNAIL_PROPERTIES;
begin
  if NOT DwmCompositionEnabled then begin
    MessageDlg('DWM composition is NOT enabled.', mtWarning, [mbOK], 0);
    Exit;
  end;

  PreviewDisable;
  FPreviewEnabled := Succeeded(DwmRegisterThumbnail(ADest, ASource, @FTumbnail));
  if FPreviewEnabled then begin

    LThumpProp.dwFlags := DWM_TNP_SOURCECLIENTAREAONLY or DWM_TNP_VISIBLE or
      DWM_TNP_OPACITY or DWM_TNP_RECTDESTINATION;
    LThumpProp.fSourceClientAreaOnly := False;
    LThumpProp.fVisible := True;
    LThumpProp.opacity := 200;
    LThumpProp.rcDestination := ARect;
    LResult := DwmUpdateThumbnailProperties(FTumbnail, LThumpProp);
    FPreviewEnabled := (LResult = S_OK);
  end else
    MessageDlg('Cannot link to window  ' + IntToStr(ASource), mtError, [mbOK], 0);
end;

And the function is called in the following way:

PreviewWindow( TargetWindow.Handle,  Self.Handle,  LRect);

The second parameter is the handle of the form itself. So far I tried to use GetFormImage but it does not capture the area where the captured window was drew. I have tried to get the image into a TBitmap in the following way but I have 2 problems: 1. Get the correct size, 2. Succeeded returns false when a handle of the TBitmap is used as the parameter.

procedure TfrmMain.PreviewWindow(const ASource, ADest: HWND; const ARect: TRect);
var
  LResult: HRESULT;
  LThumpProp: DWM_THUMBNAIL_PROPERTIES;
  Bitmap: TBitmap;
  Width, Height: integer;
begin
  if NOT DwmCompositionEnabled then begin
    MessageDlg('DWM composition is NOT enabled.', mtWarning, [mbOK], 0);
    Exit;
  end; // if NOT DwmCompositionEnabled then begin
  Bitmap := TBitmap.Create;

  try
  Width:=500; //default size....
  Height:=500;
    Bitmap.SetSize(Width, Height);

  PreviewDisable;
  //THE FOLLOWING LINE RETURN FALSE WHEN BITMAP.HANDLE IS USED INSTEAD OF ADest
  FPreviewEnabled := Succeeded(DwmRegisterThumbnail(Bitmap.Handle, ASource, @FTumbnail));
  if FPreviewEnabled then begin

    LThumpProp.dwFlags := DWM_TNP_SOURCECLIENTAREAONLY or DWM_TNP_VISIBLE or
      DWM_TNP_OPACITY or DWM_TNP_RECTDESTINATION;
    LThumpProp.fSourceClientAreaOnly := False;
    LThumpProp.fVisible := True;
    LThumpProp.opacity := 200;
    LThumpProp.rcDestination := ARect;
    LResult := DwmUpdateThumbnailProperties(FTumbnail, LThumpProp);
    FPreviewEnabled := (LResult = S_OK);
    BitBlt(Bitmap.Canvas.Handle, 0, 0, Width, Height, ADest, 0, 0, SRCCOPY);
    Bitmap.SaveToFile('d:\test.bmp'); //Test if the image is correct
  end else
    MessageDlg('Cannot link to window  ' + IntToStr(ASource), mtError, [mbOK], 0);
  finally
    Bitmap.Free;
  end;
end;

It is possible to get the image into a TBitmap? Thanks in advance.

0

There are 0 best solutions below