Delphi-PRAXiS
Seite 2 von 4     12 34      

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)

Fukiszo 27. Jan 2018 22:18

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
if it is allowed, upload the 80kb source, i dont have access on your link to look at.
edit: forget it, i just scrolled down and what i read is pretty simple,
when you translated the callback part you automatic have imported BMP format from where you can create hundrets of copies.

Code:
LONG lineSize = bmif.biWidth * bmif.biBitCount / 8;
BYTE* pLineData = new BYTE[lineSize];
BYTE* pStart;
BYTE* pEnd;
LONG lineStart = 0;
LONG lineEnd = bmif.biHeight - 1;
while (lineStart < lineEnd)
{
   // Get the address of the swap line
   pStart = pData + (lineStart * lineSize);
   pEnd = pData + (lineEnd * lineSize);
   // Swap the top with the bottom
   memcpy(pLineData, pStart, lineSize);
   memcpy(pStart, pEnd, lineSize);
   memcpy(pEnd, pLineData, lineSize);
   // Adjust the line index
   lineStart++;
   lineEnd--;

delete pLineData;
at that point the image is ready

flashcoder 27. Jan 2018 22:29

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

Zitat von Fukiszo (Beitrag 1392274)
if it is allowed, upload the 80kb source, i dont have access on your link to look at.
edit: forget it, i just scrolled down and what i read is pretty simple,
when you translated the callback part you automatic have imported BMP format from where you can create hundrets of copies.

Code:
LONG lineSize = bmif.biWidth * bmif.biBitCount / 8;
BYTE* pLineData = new BYTE[lineSize];
BYTE* pStart;
BYTE* pEnd;
LONG lineStart = 0;
LONG lineEnd = bmif.biHeight - 1;
while (lineStart < lineEnd)
{
   // Get the address of the swap line
   pStart = pData + (lineStart * lineSize);
   pEnd = pData + (lineEnd * lineSize);
   // Swap the top with the bottom
   memcpy(pLineData, pStart, lineSize);
   memcpy(pStart, pEnd, lineSize);
   memcpy(pEnd, pLineData, lineSize);
   // Adjust the line index
   lineStart++;
   lineEnd--;

delete pLineData;
at that point the image is ready

I attached the source file of C++ example on question :-D
Look to the MagCaptureDlg.cpp file

flashcoder 28. Jan 2018 01:30

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
Here is my complete code updated, i tried translate callback function (was a combine of these 2 links: LNK1 and LNK2), seems right but not is executing when MagSetImageScalingCallback api is called.


Delphi-Quellcode:
var
  Form1: TForm1;

implementation

uses
  Unit3, Magnification;

{$R *.dfm}

function ImageScaling(hwnd: hwnd; srcdata: Pointer; srcheader: MAGIMAGEHEADER;
  destdata: Pointer; destheader: MAGIMAGEHEADER; unclipped: TRect;
  clipped: TRect; dirty: HRGN): Boolean;
var
  lpbmih: TBitmapInfoHeader;
  lpbmi: TBitmapInfo;
  aBitmap: HBITMAP;
  aDC: HDC;
  bmp: TBitmap;
begin
  Fillchar(lpbmih, SizeOf(lpbmih), 0);
  lpbmih.biSize := SizeOf(lpbmih);
  lpbmih.biWidth := srcheader.width;
  lpbmih.biHeight := srcheader.height;
  lpbmih.biPlanes := 1;
  lpbmih.biBitCount := Floor(lpbmih.biSizeImage / lpbmih.biHeight /
    lpbmih.biWidth * 8);
  lpbmih.biCompression := BI_RGB;

  Fillchar(lpbmi, SizeOf(lpbmi), 0);
  lpbmi.bmiHeader.biSize := SizeOf(lpbmi.bmiHeader);
  lpbmi.bmiHeader.biWidth := srcheader.width;
  lpbmi.bmiHeader.biHeight := srcheader.height;
  lpbmi.bmiHeader.biPlanes := 1;
  lpbmi.bmiHeader.biBitCount :=
    Floor(lpbmi.bmiHeader.biSizeImage / lpbmi.bmiHeader.biHeight /
    lpbmi.bmiHeader.biWidth * 8);
  lpbmi.bmiHeader.biCompression := BI_RGB;

  aDC := GetWindowDC(hwnd);
  bmp := TBitmap.Create;
  aBitmap := 0;
  try
    aBitmap := CreateDIBitmap(aDC, lpbmih, 0, nil, lpbmi, DIB_RGB_COLORS);
    bmp.handle := aBitmap;
  finally
    DeleteObject(aBitmap);
    DeleteDC(aDC);
    bmp.Free;
  end;
  Result := True;
end;

procedure MagScreenShot;
var
  desktop, hwndMag: hwnd;
  desktoprect, sourceRect: TRect;
  filterList: THWNDArray;
  m_ScreenX, m_ScreenY, m_ScreenT, m_ScreenL: Integer;
begin

  if not Form3.Showing then
    Form3.Show;

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

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

  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, Form1.handle, 0, hInstance, nil);

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

  if (not MagSetImageScalingCallback(hwndMag, TMagImageScalingCallback(@ImageScaling))) then
  begin
    Application.MessageBox('Cannot set callback', 'Error',
      mb_Ok + mb_IconError);
    Exit;
  end;

  try
    filterList[0] := Form3.handle;
  except
  end;

  if (not MagSetWindowFilterList(hwndMag, MW_FILTERMODE_EXCLUDE, 1,
    @filterList[0])) 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;

procedure TForm1.tmr1Timer(Sender: TObject);
begin
  MagScreenShot;
end;
Timer is be to 10000ms

Zacherl 28. Jan 2018 12:29

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
The calling convention of the callback should be
Delphi-Quellcode:
stdcall
. But besides that MSDN says:
Zitat:

Note The MagSetImageScalingCallback function is deprecated in Windows 7 and later, and should not be used in new applications. There is no alternate functionality.
and
Zitat:

This function works only when Desktop Window Manager (DWM) is off.

I guess the "magnifier window" uses a DirectX surface to display the desktop screenshot. It might be possible to obtain its handle (e.g. by hooking the corresponding DirectX interface(s), if there is no other way to do it).

flashcoder 28. Jan 2018 13:40

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

Zitat von Zacherl
This function works only when Desktop Window Manager (DWM) is off.

@Zacherl,

The C++ example works fine with DWM enable :).
And i followed your suggestion below, thank you:

Zitat:

Zitat von Zacherl
The calling convention of the callback should be
Delphi-Quellcode:
stdcall

Delphi-Quellcode:

TMagImageScalingCallback = function (hwnd: HWND; srcdata: Pointer;
    srcheader: MAGIMAGEHEADER; destdata: Pointer; destheader: MAGIMAGEHEADER;
    unclipped: TRect; clipped: TRect; dirty: HRGN): BOOL; stdcall; // definition found in Magnification.pas posted on question

function ImageScaling(hwnd: hwnd; srcdata: Pointer; srcheader: MAGIMAGEHEADER;
  destdata: Pointer; destheader: MAGIMAGEHEADER; unclipped: TRect;
  clipped: TRect; dirty: HRGN): BOOL; stdcall;
var
  lpbmih: TBitmapInfoHeader;
  lpbmi: TBitmapInfo;
  aBitmap: HBITMAP;
  aDC: HDC;
  bmp: TBitmap;
begin
  Fillchar(lpbmih, SizeOf(lpbmih), 0);
  lpbmih.biSize := SizeOf(lpbmih);
  lpbmih.biWidth := srcheader.width;
  lpbmih.biHeight := srcheader.height;

//...
end;

//...

// calling in MagSetImageScalingCallback api

if (not MagSetImageScalingCallback(hwndMag, TMagImageScalingCallback(@ImageScaling))) then
So, like already said, when i put breakpoint inside my ImageScaling function, debug not go to function, then i noted that this callback function not is executed.

Here is how be is C++ code:
Code:

typedef BOOL (CALLBACK* MagImageScalingCallback)(HWND hwnd, void * srcdata, MAGIMAGEHEADER srcheader, void * destdata, MAGIMAGEHEADER destheader, RECT unclipped, RECT clipped, HRGN dirty );

//...

BOOL MagImageScaling(HWND hwnd, void *srcdata, MAGIMAGEHEADER srcheader,
                void *destdata, MAGIMAGEHEADER destheader,
                RECT unclipped, RECT clipped, HRGN dirty)
{
   // Setup the bitmap info header
      bmif.biSize = sizeof(BITMAPINFOHEADER);
      bmif.biHeight = srcheader.height;
      bmif.biWidth = srcheader.width;

//...
}

if (!MagSetImageScalingCallback(hwndMag, (MagImageScalingCallback)MagImageScaling))

Zacherl 28. Jan 2018 16:29

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
Thats strange :? If
Delphi-Quellcode:
MagSetImageScalingCallback
returns
Delphi-Quellcode:
true
, the callback should at least get invoked. I'm trying out the C++ example now. Could you upload your complete Delphi project files as well?

Edit:
C++ example does not work for me (Windows 10 64-bit Build 1709).
Delphi-Quellcode:
MagSetWindowSource
raises an access violation in `Magnification.dll`. It does not crash, if I remove the call to
Delphi-Quellcode:
MagSetImageScalingCallback
, tho. I guess MSDN is correct about the deprecation :wink: Never mind, the callback is getting invoked, but something inside the callback crashes the example for some reason.

Edit2:
Wow, the author of the C++ example forgot about the
Delphi-Quellcode:
stdcall
as well :wall: :-D It seems to work now.

flashcoder 28. Jan 2018 16:55

AW: MagSetWindowFilterList function not remove specified window of screenshot
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Zacherl
Could you upload your complete Delphi project files as well?

My Delphi project is attach below.

EWeiss 28. Jan 2018 19:42

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

Zitat von flashcoder (Beitrag 1392312)
Zitat:

Zitat von Zacherl
Could you upload your complete Delphi project files as well?

My Delphi project is attach below.

Here is your fix..
but which works only in the IDE.
Changed with D2010

for the future your should initialize a new Form if is NIL. ;)
callback works..

greets

flashcoder 28. Jan 2018 20:10

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

Zitat von EWeiss
Here is your fix..
but which works only in the IDE.
Changed with D2010

Sorry, but this is the same project and with the same trouble, callback not is executed.
The diference here was only that you created the Form3 in runtime.

EWeiss 28. Jan 2018 20:36

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

Zitat von flashcoder (Beitrag 1392317)
Zitat:

Zitat von EWeiss
Here is your fix..
but which works only in the IDE.
Changed with D2010

Sorry, but this is the same project and with the same trouble, callback not is executed.
The diference here was only that you created the Form3 in runtime.

execute always by me..
Win7 64 Bit as you can see on my Screenshot!
MagScreenShot is no longer Global is a part of Form1 now.

and i get the Shot from any Window where the mouse hover.
Delphi-Quellcode:
  GetCursorPos(Point);
  desktop := WindowFromPoint(Point);
  Caption := IntToStr(desktop);
as say works always by me.
I'm out ;)

shot removed..

greets


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:10 Uhr.
Seite 2 von 4     12 34      

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