Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Screenshot von dem Clienten eines fremden Fensters machen (https://www.delphipraxis.net/146926-screenshot-von-dem-clienten-eines-fremden-fensters-machen.html)

KahPee 29. Jan 2010 14:06


Screenshot von dem Clienten eines fremden Fensters machen
 
Hallo,

ich möchte einen Screenshot von dem Clienten eines fremden Fensters machen, welches ich mit einem Handle anspreche. (also einen Screen ohne titlebar und borders). Dazu habe ich mir das hier zusammen-geschrieben/kopiert:

Delphi-Quellcode:
function TForm1.FormularSaveScreenShot(FileName: String; h : hWnd): Boolean;
var
  Rec: TRect;
  iWidth, iHeight,left,top: Integer;
  window: TWindowInfo;

begin
  GetWindowInfo(h,window);


  with TBitmap.Create do try
    GetWindowRect(h, Rec);

    iWidth := window.rcclient.right-window.rcClient.left;
    iHeight := window.rcclient.bottom-window.rcClient.top;
    left:=window.rcWindow.Left-window.rcclient.Left;
    top:=window.rcwindow.Top-window.rcClient.top;
    Width := iWidth;
    Height := iHeight;

    BitBlt(Canvas.Handle, left, top, iWidth, iHeight, GetWindowDC(h), 0, 0, SRCCOPY);

    Result := True;

    try SaveToFile(Filename) except Result := False end;
  finally
    ReleaseDC(h, GetWindowDC(h));
    Free;
  end;
end;
Das ausgebene Bitmap hat jetzt allerdings rechts einen weißen Rand (recht schmal, ungefähr die Borderdicke [evtl. nen bisschen mehr]) und außerdem habe ich den Eindruck, dass er eine ein oder zwei pixelbreite spalte des clienten rechts nicht abbildet. Wisst ihr wo der Fehler liegt?

mfg Kahpee

himitsu 29. Jan 2010 14:14

Re: Screenshot von dem Clienten eines fremden Fensters mache
 
Delphi-Quellcode:
iWidth := window.rcclient.right - window.rcClient.left + 1;
iHeight := window.rcclient.bottom - window.rcClient.top + 1;

KahPee 29. Jan 2010 14:18

Re: Screenshot von dem Clienten eines fremden Fensters mache
 
Das löst das Problen nicht. Weiterhin weiße Ränder. Außerdem geht es um mehr als einen Pixel
Ich habe grad gesehen, dass unten auch ein ordentliches Stück fehlt. Dort ist ebenfalls ein weißer Rand (ca. Höhe der Titelbar). Und auch dort fehlt ein stück des Clienten

himitsu 29. Jan 2010 14:33

Re: Screenshot von dem Clienten eines fremden Fensters mache
 
Zumindestens sind diese beiden Variablen nun richtig berechnet. :stupid:

Delphi-Quellcode:
window.cbSize := SizeOf(window);
if not GetWindowInfo(h, window) then
  ShowMessage(SysErrorMessage(getLastError));
siehe MSDN-Library durchsuchenGetWindowInfo

Und was soll das bei ReleaseDC?
(nochein neues Handle besorgen nd dieses freigeben ... was ist mit dem anderen Handle? )

Dein Try-Except ist auch "toll" ... die Information, daß nicht gespeichert werden konnte ist ja nett, aber warum konnte es das nicht?
(diese Information hast du damit zerstört)
Abgesehn davon prüfst du nirgends, ob die Aufrufe der WinAPIs überhaupt erfolgreich waren.

KahPee 29. Jan 2010 14:39

Re: Screenshot von dem Clienten eines fremden Fensters mache
 
Den Quellcode hab ich übernommen :P.

Die Anfragen scheinen aber anzukommen, weil zumindest die obere linke ecke des Screenshots der oberen linken Ecke des Clienten entspricht. Im Prinzip stimmt nur die untere rechte Ecke des Screens und des Clienten noch nicht.

mfg Kahpee

Aphton 29. Jan 2010 15:09

Re: Screenshot von dem Clienten eines fremden Fensters mache
 
Heißt das nicht so?
Delphi-Quellcode:
    BitBlt(Canvas.Handle, 0, 0, iWidth, iHeight, GetWindowDC(h), left, top, SRCCOPY);

himitsu 29. Jan 2010 15:11

Re: Screenshot von dem Clienten eines fremden Fensters mache
 
stümmt ...

probier es mal so:

Delphi-Quellcode:
h2 := GetWindowDC(h);
iWidth := window.rcclient.right - window.rcClient.left + 1;
iHeight := window.rcclient.bottom - window.rcClient.top + 1;
left := window.rcWindow.Left - window.rcclient.Left;
top := window.rcwindow.Top - window.rcClient.top;
Width := iWidth;
Height := iHeight;
BitBlt(Canvas.Handle, left, top, left + iWidth - 1, top + iHeight - 1, h2, 0, 0, SRCCOPY);
...
ReleaseDC(h, h2);
[edit]
neee, müßte eigentlich die Breite sein. :gruebel:

KahPee 29. Jan 2010 18:58

Re: Screenshot von dem Clienten eines fremden Fensters mache
 
So funktioniert es. Diese Prozedur macht jetzt einen Screenshot vom Clienten und nicht vom Fenster!

Delphi-Quellcode:
// *** Erstellt von einem Clienten ein ScreenShot ***
function TForm1.FormularSaveScreenShot(FileName: String; h : hWnd): Boolean;
var
  Rec: TRect;
  iWidth, iHeight,left,top: Integer;
  window: TWindowInfo;

begin
  GetWindowInfo(h,window);


  with TBitmap.Create do try
    GetWindowRect(h, Rec);

    iWidth := window.rcclient.right-window.rcClient.left+1;
    iHeight := window.rcclient.bottom-window.rcClient.top+1;
    left:=window.rcWindow.Left-window.rcclient.Left;
    top:=window.rcwindow.Top-window.rcClient.top;
    Width := iWidth;
    Height := iHeight;

    BitBlt(Canvas.Handle, left, top, iWidth-left-1, iheight-top-1, GetWindowDC(h), 0, 0, SRCCOPY);
   
    Result := True;

    try SaveToFile(Filename) except Result := False end;
  finally
    ReleaseDC(h, GetWindowDC(h));
    Free;
  end;
end;
Der Hinweis von oben war gut.. der hat mich auf die richtige Spur gebracht


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:12 Uhr.

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