Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi MagSetWindowFilterList function not remove specified window of screenshot (https://www.delphipraxis.net/195027-magsetwindowfilterlist-function-not-remove-specified-window-screenshot.html)

flashcoder 27. Jan 2018 03:13

Delphi-Version: 10 Seattle

MagSetWindowFilterList function not remove specified window of screenshot
 
Liste der Anhänge anzeigen (Anzahl: 1)
I had build part of this code below based in this C++ example (source file attached) where the goal is make a screenshot without the main form appear on capture.

Then i have two troubles with this following code:

1 - MagSetWindowFilterList function not remove main form (Form1).

2 - How recovery the content of "MagnifierWindow" to a image format?

My actual code is this:

Magnification.pas
Delphi-Quellcode:
unit Magnification;

{$ALIGN ON}
{$MINENUMSIZE 4}

interface

uses
  Windows;

const
  // Magnifier Class Name
  WC_MAGNIFIERA: AnsiString = 'Magnifier';
  WC_MAGNIFIERW: WideString = 'Magnifier';
  WC_MAGNIFIER = 'Magnifier';

  // Magnifier Window Styles
  MS_SHOWMAGNIFIEDCURSOR = $0001;
  MS_CLIPAROUNDCURSOR = $0002;
  MS_INVERTCOLORS = $0004;

  // Filter Modes
  MW_FILTERMODE_EXCLUDE = 0;
  MW_FILTERMODE_INCLUDE = 1;

type
  tagMAGTRANSFORM = record
    v: array[1..3, 1..3] of Single;
  end;
  MAGTRANSFORM = tagMAGTRANSFORM;
  TMagTransform = tagMAGTRANSFORM;
  PMagTransform = ^TMagTransform;

  tagMAGIMAGEHEADER = record
    width: UINT;
    height: UINT;
    format: TGUID;
    stride: UINT;
    offset: UINT;
    cbSize: UINT;
  end;
  MAGIMAGEHEADER = tagMAGIMAGEHEADER;
  TMagImageHeader = tagMAGIMAGEHEADER;
  PMagImageHeader = ^TMagImageHeader;

  tagMAGCOLOREFFECT = record
    transform: array[1..5, 1..5] of Single;
  end;
  MAGCOLOREFFECT = tagMAGCOLOREFFECT;
  TMagColorEffect = tagMAGCOLOREFFECT;
  PMagColorEffect = ^TMagColorEffect;

  TMagImageScalingCallback = function (hwnd: HWND; srcdata: Pointer;
    srcheader: MAGIMAGEHEADER; destdata: Pointer; destheader: MAGIMAGEHEADER;
    unclipped: TRect; clipped: TRect; dirty: HRGN): BOOL; stdcall;

  THWNDArray = array[0..0] of HWND;
  PHWNDArray = ^THWNDArray;

  // Public Functions
  function MagInitialize(): BOOL; stdcall;
  function MagUninitialize(): BOOL; stdcall;

  function MagSetWindowSource(hwnd: HWND; rect: TRect): BOOL; stdcall;
  function MagGetWindowSource(hwnd: HWND; var Rect: TRect): BOOL; stdcall;
  function MagSetWindowTransform(hwnd: HWND; var Transform: TMagTransform): BOOL; stdcall;
  function MagGetWindowTransform(hwnd: HWND; var Transform: TMagTransform): BOOL; stdcall;
  function MagSetWindowFilterList(hwnd: HWND; dwFilterMode: DWORD;
    count: Integer; pHWND: PHWNDArray): BOOL; stdcall;
  function MagGetWindowFilterList(hwnd: HWND; var dwFilterMode: DWORD;
    count: Integer; pHWND: PHWNDArray): Integer; stdcall;
  function MagSetImageScalingCallback(hwnd: HWND;
    MagImageScalingCallback: TMagImageScalingCallback): BOOL; stdcall;
//  MagImageScalingCallback WINAPI MagGetImageScalingCallback(HWND hwnd );
  function MagSetColorEffect(hwnd: HWND; var Effect: TMagColorEffect): BOOL; stdcall;
  function MagGetColorEffect(hwnd: HWND; var Effect: TMagColorEffect): BOOL; stdcall;

implementation

const
  MagnificationDll = 'Magnification.dll';

  function MagInitialize; external MagnificationDll name 'MagInitialize';
  function MagUninitialize; external MagnificationDll name 'MagUninitialize';
  function MagSetWindowSource; external MagnificationDll name 'MagSetWindowSource';
  function MagGetWindowSource; external MagnificationDll name 'MagGetWindowSource';
  function MagSetWindowTransform; external MagnificationDll name 'MagSetWindowTransform';
  function MagGetWindowTransform; external MagnificationDll name 'MagGetWindowTransform';
  function MagSetWindowFilterList; external MagnificationDll name 'MagSetWindowFilterList';
  function MagGetWindowFilterList; external MagnificationDll name 'MagGetWindowFilterList';
  function MagSetImageScalingCallback; external MagnificationDll name 'MagSetImageScalingCallback';
  function MagSetColorEffect; external MagnificationDll name 'MagSetColorEffect';
  function MagGetColorEffect; external MagnificationDll name 'MagGetColorEffect';

end.
Main
Delphi-Quellcode:
var
  Form1: TForm1;

implementation

uses
  Unit3, Magnification;

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
var
  desktop, hwndMag: HWND;
  desktoprect, sourceRect: TRect;
  filterList: PHWNDArray;
  m_ScreenX, m_ScreenY, m_ScreenT, m_ScreenL: Integer;
begin

  desktop := GetDesktopWindow;
  GetWindowRect(desktop, desktoprect);

  m_ScreenT := desktoprect.Top;
  m_ScreenL := desktoprect.Left;
  m_ScreenX := desktoprect.right;
  m_ScreenY := desktoprect.bottom;

  Form3 := TForm3.Create(Form3);

  SetWindowPos(Form3.Handle, 0, 0, 0, desktoprect.right, desktoprect.bottom, SWP_SHOWWINDOW);

  SetWindowLong(Form3.Handle, GWL_EXSTYLE, GetWindowLong(Form3.Handle,
    GWL_EXSTYLE) or WS_EX_LAYERED);
  SetLayeredWindowAttributes(Form3.Handle, 0, 255, LWA_ALPHA);

  if (not MagInitialize) then
  begin
    Application.MessageBox('Init magnification failed', 'Error',
      mb_Ok + mb_IconError);
    Exit;
  end;

  hwndMag := CreateWindow(WC_MAGNIFIER, 'MagnifierWindow',
    WS_CHILD {or MS_SHOWMAGNIFIEDCURSOR} or WS_VISIBLE, 0, 0, m_ScreenX,
    m_ScreenY, Form3.Handle, 0, hInstance, nil);

  if (hwndMag = 0) then
  begin
    Application.MessageBox('MagnifierWindow creation failed', 'Error',
      mb_Ok + mb_IconError);
    Exit;
  end;

  try
    filterList[0] := Handle;
  except
  end;

  if (not MagSetWindowFilterList(hwndMag, MW_FILTERMODE_EXCLUDE, 1, filterList))
  then
  begin
    Application.MessageBox('Cannot exclude main window', 'Error',
      mb_Ok + mb_IconError);
    Exit;
  end;

  sourceRect.Top := m_ScreenT;
  sourceRect.Left := m_ScreenL;
  sourceRect.right := m_ScreenX;
  sourceRect.bottom := m_ScreenY;

  if (not MagSetWindowSource(hwndMag, sourceRect)) then
  begin
    Application.MessageBox('Cannot set source to MagnifierWindow', 'Error',
      mb_Ok + mb_IconError);
    Exit;
  end;

  { if (not MagUninitialize) then
    begin
    Application.MessageBox('Finalize magnification failed', 'Error',
    mb_Ok + mb_IconError);
    Exit;
    end; }
end;

Fukiszo 27. Jan 2018 11:57

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
Delphi-Quellcode:
{ Here's how you can save the screen content into a bitmapfile.
  If you don't want to include the active (Delphi-)Application
  just put easily a 'Application.Minimize;' at the beginning
  of the procedure }

uses
  Windows, Graphics, Forms;

procedure TForm1.Button1Click(Sender: TObject);
var
  DC: HDC;
  Canvas: TCanvas;
  MyBitmap: TBitmap;
begin
  Canvas := TCanvas.Create;
  MyBitmap := TBitmap.Create;
  DC := GetDC(0);

  try
    Canvas.Handle := DC;
    with Screen do
    begin
      { detect the actual height and with of the screen }
      MyBitmap.Width := Width;
      MyBitmap.Height := Height;

      { copy the screen content to the bitmap }
      MyBitmap.Canvas.CopyRect(Rect(0, 0, Width, Height), Canvas,
                               Rect(0, 0, Width, Height));
      { stream the bitmap to disk }
      MyBitmap.SaveToFile('c:\windows\desktop\screen.bmp');
    end;

  finally
    { free memory }
    ReleaseDC(0, DC);
    MyBitmap.Free;
    Canvas.Free
  end;
end;

flashcoder 27. Jan 2018 13:26

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
Zitat:

Zitat von Fukiszo (Beitrag 1392225)
Delphi-Quellcode:
{ Here's how you can save the screen content into a bitmapfile.
  If you don't want to include the active (Delphi-)Application
  just put easily a 'Application.Minimize;' at the beginning
  of the procedure }

uses
  Windows, Graphics, Forms;

procedure TForm1.Button1Click(Sender: TObject);
var
  DC: HDC;
  Canvas: TCanvas;
  MyBitmap: TBitmap;
begin
  Canvas := TCanvas.Create;
  MyBitmap := TBitmap.Create;
  DC := GetDC(0);

  try
    Canvas.Handle := DC;
    with Screen do
    begin
      { detect the actual height and with of the screen }
      MyBitmap.Width := Width;
      MyBitmap.Height := Height;

      { copy the screen content to the bitmap }
      MyBitmap.Canvas.CopyRect(Rect(0, 0, Width, Height), Canvas,
                               Rect(0, 0, Width, Height));
      { stream the bitmap to disk }
      MyBitmap.SaveToFile('c:\windows\desktop\screen.bmp');
    end;

  finally
    { free memory }
    ReleaseDC(0, DC);
    MyBitmap.Free;
    Canvas.Free
  end;
end;

The main Form not must be minimized in my situation.
I really need of help to fix code that was posted on question.

Fukiszo 27. Jan 2018 13:48

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
use this command wherever you need
this will hide a window by its handle
Code:
 ShowWindow(EnterHandle, SW_HIDE); // Enter Handle of Window wich needs to become invisible

or

 ShowWindow(FindWindow(EnterClassName,nil), SW_HIDE); // EnterClassName can be something like TForm1 etc, adjust to your

or

 ShowWindow(FindWindow(nil,'Enter Forms Caption'), SW_HIDE); // self explaining

replace SW_HIDE with SW_SHOW to bring it back
use this code careful, it can be used to also tweak control (in and outside of your program)

Zacherl 27. Jan 2018 14:28

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
Hiding / minimizing a window to exclude it from a screenshot is an invasive operation and I as an user would not like it (even if it's only for a split second).

Zitat:

Zitat von flashcoder (Beitrag 1392206)
1 - MagSetWindowFilterList function not remove main form (Form1).

You should not declare your
Delphi-Quellcode:
filterList
as
Delphi-Quellcode:
PHWNDArray
. Just use a normal
Delphi-Quellcode:
THWNDArray
as variable declaration and pass it like this:
Delphi-Quellcode:
MagSetWindowFilterList(hwndMag, MW_FILTERMODE_EXCLUDE, 1, @filterList[0])
. You could even use plain
Delphi-Quellcode:
HWND
as type for
Delphi-Quellcode:
filterList
(in case there's always only one handle in your "list").

Zitat:

Zitat von flashcoder (Beitrag 1392206)
2 - How recovery the content of "MagnifierWindow" to a image format?

I never used the magnification API, but the linked article shows a way by using the so called
Delphi-Quellcode:
MagImageScalingCallback
.

flashcoder 27. Jan 2018 19:43

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
@Zacherl,

thank you very much, your suggestion about MagSetWindowFilterList worked fine.
I will try translate the part of save content of hwndmag to a image format.

I tried the suggestion of @Fukiszo but not worked see:

Delphi-Quellcode:
Canvas := TCanvas.Create;
  MyBitmap := TBitmap.Create;
  DC := GetWindowDC(hwndMag);

  GetWindowRect(hwndMag, r);

  try
    Canvas.Handle := DC;

      MyBitmap.Width := r.Width;
      MyBitmap.Height := r.Height;

      MyBitmap.Canvas.CopyRect(Rect(0, 0, MyBitmap.Width, MyBitmap.Height), Canvas,
                               Rect(0, 0, r.Width, r.Height));

      MyBitmap.SaveToFile('c:\screen.bmp');

  finally
    ReleaseDC(0, DC);
    MyBitmap.Free;
    Canvas.Free
  end;
But if someone know a way in Delphi and that works, i will accept.

Fukiszo 27. Jan 2018 20:48

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
Zitat:

Zitat von flashcoder (Beitrag 1392258)
Delphi-Quellcode:
 MyBitmap.Canvas.CopyRect(Rect(0, 0, MyBitmap.Width, MyBitmap.Height), Canvas,
                               Rect(0, 0, r.Width, r.Height));

Delphi-Quellcode:
my example was made for a full screen, not part of screen
use it like this:
 MyBitmap.Canvas.CopyRect(Rect(X.Start, Y.Start, X.End, Y.End), Canvas,
                          Rect(X.Start, Y.Start, X.End, Y.End));

X and Y are Screen Offsets, not your Application Window Offsets
eg, Position [0,0] = topleft screen corner and not your application windows coordinate!
but better wait, others may give much better methods than my rude ones.

flashcoder 27. Jan 2018 21:52

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
@Fukiszo,

i tried your two suggestions and none works, but this can be the reason:

Zitat:

Saving the data

Normally, we could save the content of a window into a file, or copy its content into memory by using the BitBlt function. The main problem while saving the captured data by the magnification library is that we cannot access the bitmap of the host window or the magnification window with the BitBlt function as usual. So we use a work around by using the MagSetImageScalingCallback() function, which is described as below.
This alert can be found on C++ example linked on question.
So, i think that with BMP.Canvas.CopyRect() also not is different.

Fukiszo 27. Jan 2018 22:04

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
sorry i dont know MagXXXXX.pas units neither their .dll,
i gave general examples,
if MAGxxx uses overlay to display something, my method fail. that i think your warning is telling.
I'm sorry!

Zitat:

Zitat von flashcoder (Beitrag 1392268)
...using the MagSetImageScalingCallback() function, which is described as below...

can you show that?

flashcoder 27. Jan 2018 22:14

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
Zitat:

Zitat von flashcoder (Beitrag 1392268)
...using the MagSetImageScalingCallback() function, which is described as below...

Zitat:

Zitat von Fukiszo (Beitrag 1392270)
can you show that?

@Fukiszo, i still will try translate this part :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:18 Uhr.
Seite 1 von 4  1 23     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz