AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Bildschirmfoto knipst nicht alles
Thema durchsuchen
Ansicht
Themen-Optionen

Bildschirmfoto knipst nicht alles

Ein Thema von KodeZwerg · begonnen am 29. Mai 2018 · letzter Beitrag vom 5. Jun 2018
Antwort Antwort
Seite 1 von 7  1 23     Letzte »    
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#1

Bildschirmfoto knipst nicht alles

  Alt 29. Mai 2018, 01:15
Hi, ich probiere mich mal am Knipsen von Fenstern, es funktioniert ja eigentlich auch schon relativ gut.
Bei manchen Programmen die ich Knipse fehlt leider Bildinhalt, ich habe mal mit professioneller Screenshot-Software den Fehler geknipst damit ich es irgendwie besser Erklären kann.
Im Hintergrund mein geknipstes Bild in IrfanView, im Vordergrund das was ich Knipsen wollte da-fehlt-.jpg
Da sieht man das in der Menu-Leiste nicht alles vom Original aufgenommen wurde.
Das ist eines der Probleme, das andere, wenn ich OpenGL/DirectX Anwendungen starte und Knipse entstehen nur schwarze Bilder, gibts da ein Trick?

Mit diesem Code erstelle ich die Bilder.
Delphi-Quellcode:
procedure TForm1.Screenshot (const FullWindow: Boolean = True);
var
  Win: HWND;
  DC: HDC;
  Bmp: TBitmap;
  FileName: string;
  WinRect: TRect;
  Width: Integer;
  Height: Integer;
begin
  Form1.Label1.Caption := 'Error: No Handle!';
  Form1.Hide;
  try
    Application.ProcessMessages;
    Win := GetForegroundWindow;
    if Win = 0 then Exit;
    Form1.Label1.Caption := 'Error during save!';

    if FullWindow then
    begin
      GetWindowRect(Win, WinRect);
      DC := GetWindowDC(Win);
    end else
    begin
      Windows.GetClientRect(Win, WinRect);
      DC := GetDC(Win);
    end;
    try
      Width := WinRect.Right - WinRect.Left;
      Height := WinRect.Bottom - WinRect.Top;

      Bmp := TBitmap.Create;
      try
        Bmp.Height := Height;
        Bmp.Width := Width;
        BitBlt(Bmp.Canvas.Handle, 0, 0, Width, Height, DC, 0, 0, SRCCOPY);
        FileName := 'Screenshot_' +
          FormatDateTime('mm-dd-yyyy-hhnnss', Now());
        Bmp.SaveToFile(Format('.\%s.bmp', [FileName]));
      finally
        Form1.Label1.Caption := 'Saved!';
        Bmp.Free;
      end;
    finally
      ReleaseDC(Win, DC);
    end;
  finally
    Form1.Show;
  end;
end;
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: Bildschirmfoto knipst nicht alles

  Alt 29. Mai 2018, 01:51
wenn ich OpenGL/DirectX Anwendungen starte und Knipse entstehen nur schwarze Bilder, gibts da ein Trick?
Ob dein anderes Problem dadurch auch behoben würde (ich vermute stark, ja), kann ich nicht sagen, aber bezüglich Hardware-beschleunigter Grafik sollte die Desktop Duplication API Abhilfe schaffen. Das ist der vorgesehene Weg ab Windows 8, um den Monitorinhalt abzugreifen. Ist zwar nicht ganz unkompliziert, aber es gibt eine ausführliche Demo Anwendung.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Bildschirmfoto knipst nicht alles

  Alt 29. Mai 2018, 02:03
Das könnte ich einbauen mit OSVersion Kontrolle, aber ich selbst benutze Windows 7.
Hast Du da eventuell noch eine Api auf die ich zurückgreifen könnte?
Danke für den Tipp Zacherl!
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#4

AW: Bildschirmfoto knipst nicht alles

  Alt 29. Mai 2018, 02:15
Hast Du da eventuell noch eine Api auf die ich zurückgreifen könnte?
Vor der Desktop Duplication API ging der "korrekte" Weg über einen Mirror Driver. Für DirectX/GL bleibt dir ansonsten nur die Möglichkeit über Hooks (ist aber auch nur Murks). Ansonsten gibt es noch die MSDN-Library durchsuchenPrintWindow API. Hardware-beschleunigte Inhalte wirst du damit allerdings auch nicht screenshoten können.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Bildschirmfoto knipst nicht alles

  Alt 29. Mai 2018, 02:19
Ja ok, mit DX/GL das seh ich total ein und lass es mehr als außen vor.
PintWindow kenne ich auch noch nicht, da schau ich mal nach.
Ich glaube nicht das der TC hardwarebeschleunigung an den fehlenden Stellen macht, das muss eine andere Ursache haben.
Zacherl Danke nochmal, bei Problemem melde ich mich wieder!
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Bildschirmfoto knipst nicht alles <GELÖST>

  Alt 29. Mai 2018, 02:34
PrintWindow ist für mich DIE LÖSUNG!!! Vielen lieben Dank!
Habs bereits erfolgreich eingebaut und es knippst den TC ohne fehlenden Bildinhalt!

Frage: Funktioniert PrintWindow auch noch mit Windows 10?

Delphi-Quellcode:
function MyPrintWindow(const Win: HWND = 0; var Bmp: TBitmap; const FullWindow: Boolean = True): Boolean;
var
  rect: TRect;
begin
  Result := False;
  if Win = 0 then Exit;
  if FullWindow then
   GetWindowRect(Win, rect)
   else
   Windows.GetClientRect(Win, rect);
  bmp.Width := rect.Right - rect.Left;
  bmp.Height := rect.Bottom - rect.Top;
  Result := PrintWindow(Win, Bmp.Canvas.Handle, 0) ;
end;
Mini-Upgrade, so wirds bei Bedarf ohne Fenster-Rahmen geknippst.

Ps: Der erste Parameter sollte ein Prozess-Handle sein was ein Window besitzt.
Gruß vom KodeZwerg

Geändert von KodeZwerg (29. Mai 2018 um 09:26 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#7

AW: Bildschirmfoto knipst nicht alles

  Alt 29. Mai 2018, 06:52
Verdammt noch mal eigentlich bin ich ja zu blöd für so was.
Aber trotzdem bei mir knipst alles und ich kann es sogar noch etwas verschönern.

Sorry das musste sein!

gruss

Geändert von EWeiss (11. Jul 2019 um 16:51 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Bildschirmfoto knipst nicht alles

  Alt 29. Mai 2018, 08:55
Du kannst es ja mit FullWindow = False mal probieren.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#9

AW: Bildschirmfoto knipst nicht alles

  Alt 29. Mai 2018, 14:42
Bitte bitte Du solltest deinen Code allerdings noch um ein Bitmap.Canvas.Lock vor dem PrintWindow und ein Bitmap.Canvas.Unlock danach erweitern. Ansonsten kann es vorkommen, dass seltsame Effekte auftreten wie z.B., dass das Zielfenster unkontrolliert anfängt zu flackern, während der Screenshot erstellt wird.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#10

AW: Bildschirmfoto knipst nicht alles

  Alt 29. Mai 2018, 15:33
Bitte bitte Du solltest deinen Code allerdings noch um ein Bitmap.Canvas.Lock vor dem PrintWindow und ein Bitmap.Canvas.Unlock danach erweitern. Ansonsten kann es vorkommen, dass seltsame Effekte auftreten wie z.B., dass das Zielfenster unkontrolliert anfängt zu flackern, während der Screenshot erstellt wird.
PrintWindow ist eine sehr schlechte Lösung um Screen Shots zu erstellen.

Warum?

Weil es nur mit einem Fenster richtig funktioniert in dem auch alle dafür benötigten Messagen korrekt verarbeitet werden.
Wenn dem nicht so ist lass es lieber.

Die Messagen die du behandeln musst sind WM_PRINT, WM_PRINTCLIENT nur damit kannst du korrekt auf den bereitgestellten wParam DC Zeichnen.
WM_PAINT sollte dann komplett ignoriert werden.

Verwende lieber etwa auf dieser Art.
Code:
BOOL CaptureScreen(HBITMAP& hBitmap)
{
    HDC hDCScreen = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
    const int cx = ::GetDeviceCaps(hDCScreen, HORZRES);
    const int cy = ::GetDeviceCaps(hDCScreen, VERTRES);
    HDC hDCMem = ::CreateCompatibleDC(hDCScreen);
    hBitmap = ::CreateCompatibleBitmap(hDCScreen, cx, cy);
    HBITMAP hBmpOld = (HBITMAP)::SelectObject(hDCMem, hBitmap);

    // Note: CAPTUREBLT flag is required to capture layered windows
    DWORD dwRop = SRCCOPY | CAPTUREBLT;
    BOOL bRet = ::BitBlt(hDCMem, 0, 0, cx, cy, hDCScreen, 0, 0, dwRop);

    ::SelectObject(hDCMem, hBmpOld);
    ::DeleteDC(hDCMem);
    ::DeleteDC(hDCScreen);

    return bRet;
}
Zitat:
Du kannst es ja mit FullWindow = False mal probieren.
Sollte kein Problem sein.. warum auch ob ich nun den gesamten Screen kopiere oder nur den Teil der unter meiner Anwendung liegt spielt absolut keine rolle.
Es bleibt sich gleich.

gruss

Geändert von EWeiss (29. Mai 2018 um 15:42 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 7  1 23     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:52 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