Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Bildschirmfoto knipst nicht alles (https://www.delphipraxis.net/196531-bildschirmfoto-knipst-nicht-alles.html)

KodeZwerg 29. Mai 2018 00:15

Bildschirmfoto knipst nicht alles
 
Liste der Anhänge anzeigen (Anzahl: 1)
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 Anhang 49152
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;

Zacherl 29. Mai 2018 00:51

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von KodeZwerg (Beitrag 1403258)
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.

KodeZwerg 29. Mai 2018 01:03

AW: Bildschirmfoto knipst nicht alles
 
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!

Zacherl 29. Mai 2018 01:15

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von KodeZwerg (Beitrag 1403263)
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.

KodeZwerg 29. Mai 2018 01:19

AW: Bildschirmfoto knipst nicht alles
 
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!

KodeZwerg 29. Mai 2018 01:34

AW: Bildschirmfoto knipst nicht alles <GELÖST>
 
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.

EWeiss 29. Mai 2018 05:52

AW: Bildschirmfoto knipst nicht alles
 
Verdammt noch mal :wall: :duck: 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

KodeZwerg 29. Mai 2018 07:55

AW: Bildschirmfoto knipst nicht alles
 
Du kannst es ja mit FullWindow = False mal probieren.

Zacherl 29. Mai 2018 13:42

AW: Bildschirmfoto knipst nicht alles
 
Bitte bitte :) Du solltest deinen Code allerdings noch um ein
Delphi-Quellcode:
Bitmap.Canvas.Lock
vor dem
Delphi-Quellcode:
PrintWindow
und ein
Delphi-Quellcode:
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.

EWeiss 29. Mai 2018 14:33

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von Zacherl (Beitrag 1403319)
Bitte bitte :) Du solltest deinen Code allerdings noch um ein
Delphi-Quellcode:
Bitmap.Canvas.Lock
vor dem
Delphi-Quellcode:
PrintWindow
und ein
Delphi-Quellcode:
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

KodeZwerg 29. Mai 2018 15:19

AW: Bildschirmfoto knipst nicht alles
 
Zum einen, ich Zeichne nichts ich knipps und Speicher. Es ist mittlerweile eine Tray-App ohne Fenster, nur Popupmenu.
Ok das ist etwas gelogen, es erscheint eine Prozess-Liste mit allem was ich knippsen könnte.

Was ich wollte macht es, ich wollte ein Window knippsen und mit FullWindow steuert man ob mit Fenster-Rahmen oder ohne, Du wirst da keinen Unterschied feststellen da Deine SkinEngine kein Windows-Rahmen besitzt.

Ich übersetze mal Dein Code nach Delphi und lasse mich Überraschen. Danke dafür!:thumb:

Das Lock/Unlock habe ich einfach mal mit integriert, Danke Zacherl für den Hinweis!:thumb:

Zitat:

Zitat von EWeiss (Beitrag 1403328)
Weil es nur mit einem Fenster richtig funktioniert in dem auch alle dafür benötigten Messagen korrekt verarbeitet werden.

Ich weiß nicht so genau wie Du das mit Messages meinst, könntest Du das bitte ein wenig Erläutern oder eine Quelle zum nachlesen angeben, Danke!

EWeiss 29. Mai 2018 15:28

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Ich weiß nicht so genau wie Du das mit Messages meinst, könntest Du das bitte ein wenig Erläutern oder eine Quelle zum nachlesen angeben, Danke!
Was für eine Quelle?
Die Quelle ist meine Erfahrung..

Und was Windows Messagen sind muss dir doch klar sein.
Google mal nach WM_PRINT und WM_PRINTCLIENT zum Beispiel in Verbindung mit AnimateWindow ;)

gruss

Zacherl 29. Mai 2018 15:35

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von EWeiss (Beitrag 1403350)
Google mal nach WM_PRINT und WM_PRINTCLIENT zum Beispiel in Verbindung mit AnimateWindow ;)

Wenn MSDN-Library durchsuchenAnimateWindow verwendet wird, muss das Fenster MSDN-Library durchsuchenWM_PRINTCLIENT eigenständig implementieren. Ansonsten ist das alles kein Problem, da MSDN-Library durchsuchenWM_PRINT bei Standardeinstellungen von der MSDN-Library durchsuchenDefWindowProc abgearbeitet wird. Der Entwickler muss hierfür nicht wirklich etwas Eigenes implementieren.

Dennoch ist die Desktop Duplication API wie gesagt sowohl dieser Methode als auch dem Kopieren des DC Inhaltes jederzeit vorzuziehen. Wenn man noch kein Windows 8 verwendet, steht diese halt leider noch nicht zur Verfügung.

KodeZwerg 29. Mai 2018 15:46

AW: Bildschirmfoto knipst nicht alles
 
Da schau an, nun weiß ich was Dir dabei im Kopf rumgeflattert ist, das gibt mir Anlass das ganze nochmal zu Überdenken, bei Deiner Roten Schrift Post dachte ich so etwas in der Richtung:
Wenn eine Applikation kein WM_PRINT o.ä. anbietet dann wird nichts aus Foto. Da meine Eigenen Programm diese Msg bis jetzt noch nie verwendet haben, testete ich es und knippsen ging. Der Nebel ist auf jedenfall gelichtet, many thanks!:thumb::thumb:

Was mir jetzt wiederum durch den Kopf spukt, bei meinem ersten Post, da kopiere ich ja das DC und erhalte Bilder wo halt Sachen fehlen, nicht generell aber mal hier mal da. Wenn das kompilat mit Deiner Methode nicht zu groß ist, könntest Du es bitte zu Testzwecken bereitstellen, da seh ich ja gleich was mich erwartet und das wichtigste, ob es den Inhalt tatsächlich so knippst wie ich ihn aufm Desktop sehe. Siehe erster Post das Bilder-Knipps-Problem.

Nun bin ich ehrlich gesagt mehr als verwirrt.....

EWeiss 29. Mai 2018 16:02

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Was mir jetzt wiederum durch den Kopf spukt, bei meinem ersten Post, da kopiere ich ja das DC und erhalte Bilder wo halt Sachen fehlen,
Du kopierst aber genau das sollst du nicht tun..
Es hat damit zu tun weil du WM_PAINT zum zeichnen verwendest und nicht das zur Verfügung gestellte DC in WParam..
Wenn du WM_PRINT verwendest must du kein extra DC erstellen denn es ist vorhanden.

Zitat:

Wenn AnimateWindow verwendet wird, muss das Fenster WM_PRINTCLIENT eigenständig implementieren.
genau das mag unter VCL seine Bestimmung haben aber nicht unter Win32 glaube es mir schließlich habe ich die AnimateWindow Funktion in
meine NONVCL Lib integriert und das ist kein Spielchen.

Aber gut sei's drum.
https://msdn.microsoft.com/de-de/lib...(v=vs.85).aspx

gruss

Zacherl 29. Mai 2018 16:29

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von EWeiss (Beitrag 1403358)

Hast du ja Recht im Falle von
Delphi-Quellcode:
WM_PRINTCLIENT
. Die normale
Delphi-Quellcode:
WM_PRINT
braucht man aber explizit nicht selbst implementieren.
Delphi-Quellcode:
PW_CLIENTONLY
könnte demnach Probleme machen, die Variante mit Rahmen allerdings nicht.

EWeiss 29. Mai 2018 16:32

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von Zacherl (Beitrag 1403364)
Zitat:

Zitat von EWeiss (Beitrag 1403358)

Hast du ja Recht im Falle von
Delphi-Quellcode:
WM_PRINTCLIENT
. Die normale
Delphi-Quellcode:
WM_PRINT
braucht man aber explizit nicht selbst implementieren.
Delphi-Quellcode:
PW_CLIENTONLY
könnte demnach Probleme machen, die Variante mit Rahmen allerdings nicht.

Korrekt!
Solange man nicht mit NonVcl Arbeitet denn da gibt es nur das man explizit definiert. :)
Das ist in C++ genauso wenn du kein WM_PRINT in deiner Winproc einbindest tut sich da auch nichts.

gruss

Zacherl 29. Mai 2018 16:47

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von EWeiss (Beitrag 1403366)
wenn du kein WM_PRINT in deiner Winproc einbindest tut sich da auch nichts

Sicher? Bin etwas verwirrt von dem MSDN Auszug hier:
Zitat:

Unlike WM_PRINT, WM_PRINTCLIENT is not processed by DefWindowProc
Das verstehe ich so, dass
Delphi-Quellcode:
WM_PRINT
auch ohne eigene Behandlung von MSDN-Library durchsuchenDefWindowProc abgearbeitet wird. Letztere sollte man ja meines Wissens nach immer Aufrufen, wenn man keine eigene Behandlung für eine Message implementiert.

EWeiss 29. Mai 2018 16:54

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von Zacherl (Beitrag 1403368)
Zitat:

Zitat von EWeiss (Beitrag 1403366)
wenn du kein WM_PRINT in deiner Winproc einbindest tut sich da auch nichts

Sicher? Bin etwas verwirrt von dem MSDN Auszug hier:
Zitat:

Unlike WM_PRINT, WM_PRINTCLIENT is not processed by DefWindowProc
Das verstehe ich so, dass
Delphi-Quellcode:
WM_PRINT
auch ohne eigene Behandlung von MSDN-Library durchsuchenDefWindowProc abgearbeitet wird. Letztere sollte man ja meines Wissens nach immer Aufrufen, wenn man keine eigene Behandlung für eine Message implementiert.

Es nutzt dir nur nichts.
Es kann abgearbeitet werden nur wenn du mit dem DC von wParam nichts tust und sogar im gleichen Kontext noch WM_PRINT verwendest dann ist es sinnlos.
Ich habe alles durch und bestimmt 3 Tage gebraucht um AnimateWindow unter NonVcl ans laufen zu bringen.

Wenn ich dies Message nicht zu meinem eigenen Window schicke passiert gar nichts.
Mein Window ist in diesen Fall schwarz.

Delphi-Quellcode:
procedure TSkinEngine.PaintDoubleBuffer(WinHandle: hWnd; imgHdc: HDC);
var
  lP: longint;
begin
  if not Composited(WinHandle) then
  begin
    PaintBackground(WinHandle, False);
    // Bei Fehler PRF_CLIENT deaktivieren
    lP := PRF_CHILDREN or PRF_CLIENT or PRF_NONCLIENT or PRF_CHECKVISIBLE;
    SendMessageW(WinHandle, WM_PRINT, GetPaintDC(WinHandle), lP);
  end;
  PaintToScreen(WinHandle, imgHdc, 0, 0, 0);

end;
gruss

KodeZwerg 29. Mai 2018 17:18

AW: Bildschirmfoto knipst nicht alles
 
Kurze Rückmeldung dann könnt ihr ja weiter machen, ich les euch gerne weil ich dabei gut lerne.

Zwischenbilanz mit PrintWindow:
Viele non-VCLs von Luckie kompiliert und geknippst = null problemo
Viele VCLs, auch non-Delphi, knippsen = null probleme
Hardwarebeschleunigter MediaPlayerClassic während Wiedergabe geknippst = null problemo
DirectX/OpenGL = Je nach Anwendung, das DX/GL ClientRect bleibt leer (nicht schwarz sondern so als ob man ne leere große Form hat.) Zumindest wird der Rahmen korrekt geknippst falls einer da ist und ichs aktiviert hab (FullWindow = True)

Was mich nun interessieren würde wäre ein Example wo es Probleme bereitet. Da ihr zwei Euch so gut in der Materie auskennt da habt ihr doch bestimmt ein kleines Dingens rumliegen was ich nicht knippsen könnte, oder?

EWeiss 29. Mai 2018 17:25

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von KodeZwerg (Beitrag 1403376)
Kurze Rückmeldung dann könnt ihr ja weiter machen, ich les euch gerne weil ich dabei gut lerne.

Zwischenbilanz mit PrintWindow:
Viele non-VCLs von Luckie kompiliert und geknippst = null problemo
Viele VCLs, auch non-Delphi, knippsen = null probleme
Hardwarebeschleunigter MediaPlayerClassic während Wiedergabe geknippst = null problemo
DirectX/OpenGL = Je nach Anwendung, das DX/GL ClientRect bleibt leer (nicht schwarz sondern so als ob man ne leere große Form hat.) Zumindest wird der Rahmen korrekt geknippst falls einer da ist und ichs aktiviert hab (FullWindow = True)

Was mich nun interessieren würde wäre ein Example wo es Probleme bereitet. Da ihr zwei Euch so gut in der Materie auskennt da habt ihr doch bestimmt ein kleines Dingens rumliegen was ich nicht knippsen könnte, oder?

Versuch einfach mal ein LayeredWindow zu knipsen. ;)
https://social.msdn.microsoft.com/Fo...forum=winforms

gruss

Zacherl 29. Mai 2018 18:06

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von KodeZwerg (Beitrag 1403376)
Was mich nun interessieren würde wäre ein Example wo es Probleme bereitet. Da ihr zwei Euch so gut in der Materie auskennt da habt ihr doch bestimmt ein kleines Dingens rumliegen was ich nicht knippsen könnte, oder?

Das würde mich ebenfalls interessieren, aber wir reden irgendwie ein wenig aneinander vorbei :-D
Delphi-Quellcode:
PrintWindow
mit
Delphi-Quellcode:
WM_PRINT
funktioniert meines Verständnisses nach halt immer (auch bei NonVCL), solange man am Ende in seiner WndProc die
Delphi-Quellcode:
DefWindowProc
aufruft (was man immer machen sollte). Aber gut, ich bin da sicherlich nicht so weit drinnen in der Materie wie Emil. Wobei KodeZwergs Tests ja eigentlich für sich sprechen.

Was Probleme geben könnte ist wie gesagt alles, was
Delphi-Quellcode:
WM_PRINTCLIENT
verwendet (was wiederrum laut Doku ja nur der Fall ist, wenn man bei
Delphi-Quellcode:
PrintWindow
das
Delphi-Quellcode:
PW_CLIENTONLY
setzt).

Das LayeredWindow würde mich tatsächlich aber auch mal interessieren. Zumindest auf einem halbwegs aktuellen Windows. Einige dieser Limitierungen sind seit spätestens 8.1 nämlich komplett obsolet.

KodeZwerg 29. Mai 2018 18:21

AW: Bildschirmfoto knipst nicht alles
 
Rückmeldung, habe nun ein non-Vcl (das berühmte 2 Fenster Demo von Luckie) so abgeändert:
Delphi-Quellcode:
  {Fenste 1 erzeugen und hWnd1 zuweisen}
  hWndMain := CreateWindowEx(0, ClassName1, Window1Name, WS_VISIBLE or
    WS_EX_LAYERED,
    LPARAM(CW_USEDEFAULT), LPARAM(CW_USEDEFAULT), Window1Width, Window1Height, 0, 0, hInstance,
    nil);
Ich kann es ohne Probleme knipsen, aber wie Zacherl bestimmt Richtig vermutet bin ich irgendwo anders nur nicht bei dem worüber Ihr redet.

EWeiss 29. Mai 2018 18:39

AW: Bildschirmfoto knipst nicht alles
 
Nur weil du das Fenster mit dem Style WS_EX_LAYERED erstellst ist es nicht transparent. ;)
Es fehlen die Attribute es fehlt die BLENDFUNCTION es fehlt UpdateLayeredWindow und, und, und :)
Ganz so einfach ist es dann doch nicht.
Such doch mal hier im Forum nach einem Projekt welches WS_EX_LAYERED korrekt verwendet.

http://www.nuonsoft.com/blog/2009/05...layeredwindow/

btw.. was sagt mein OTTB kannst du es rendern ? Knipsen?
Du solltest eigentlich ein schwarzes Window erhalten wenn du es aufnimmst.
OTTB ist ein Layered Window.

gruss

KodeZwerg 29. Mai 2018 19:25

AW: Bildschirmfoto knipst nicht alles
 
Ja danke nein, ich fange jetzt bestimmt nicht an mich in layered reinzulesen nur damit ich ein example erschaffen kann das ich nicht knipsen kann.

Zu OTTB, genau das war so ein example was ich meinte :thumb::thumb::thumb:
PrintWindow generiert ein schwarzes Bild, vollkommen Richtig! Danke Emil!
Nun hab ich ja eine "Anti-Knips" Applikation, sobald ich das gelöst habe meld ich wieder.... kann dauern -_-

Am Rande, meine profi Screenshot-Freeware-Software knipst das Perfekt ohne Desktop Hintergrund

ich schau mal ob ich heraus finde wie die das machen, ich leg jetzt auf:coder2:

edit
Das Freeware Tool gibts hier und lautet Screenshot Captor.

EWeiss 29. Mai 2018 19:48

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

PrintWindow generiert ein schwarzes Bild, vollkommen Richtig! Danke Emil!
Und das sorry ich sage es nochmal wirst du nicht beheben können das ist die Unart von PrintWindow wenn WM_PRINT und WM_PRINTCLIENT nicht korrekt behandelt werden.
Alle Fenster die DirectX, LayeredWindow, Tollbars usw.. mit LayeredWindow verwenden werden dir an den stellen wo sie Transparent sind
ein schwarzes Feld zeigen da kannst du nichts machen.

Vergiss die API PrintWindow einfach ;) (Zumindest unter Win7) danach "Win7 up" können auch Child Windows Transparent gesetzt werden und das ganze könnte sich anders verhalten ;)
Ich mache lang genug mit Grafik da kannst du mir ruhig glauben es ist vertane Liebesmüh damit weiter rumzuspielen.

Zitat:

Das Freeware Tool gibts hier und lautet Screenshot Captor.
Ich installiere kein Apps ohne vernünftige Deinstallationsroutine (.exe)

Zu dem habe ich SnagIt gekauft das tut alles was ich will.
Trotzdem Danke.

gruss

KodeZwerg 29. Mai 2018 20:20

AW: Bildschirmfoto knipst nicht alles
 
Ja klar, ohne die Print Api, nun dank Example weiß ich was Du meintest und kann es Nachvollziehen, ich werds schon irgendwie hinbekommen, hab ja nun ein neues Forschungsprojekt "Knipps mit Delphi OTTB", ein paar Ansätze habe ich dazu schon aber die sind dann nicht so effektiv. (über OpenGL/DirectX Api Bildpuffer eventuell...)
Bei Erfolgen melde ich mich Zurück.

Ps: Das Tool hat einen UnInstaller und sollte mir nur als Beispiel dienen das es klappt.

KodeZwerg 29. Mai 2018 21:55

AW: Bildschirmfoto knipst nicht alles
 
Habs geschafft! Das einzige was nicht klappt ist das der Desktop Hintergrund nicht rausgefiltert wird, ansonsten klappts mit dem OTTB zu 100%, also Anti-Knips ist nicht mehr. Ich bin übers Canvas direkt rangegangen.

Ich teste nun wieder den Rest Test-Parcour durch, bei Erfolg oder Interesse Post ich mein noch nicht ganz fertigen Code.

edit
Erste Zwischenbilanz, es knippst OpenGL/DirectX (!), ich teste mal weiter aber ich glaube das kann ich mir sparen.

Luckie 29. Mai 2018 23:07

AW: Bildschirmfoto knipst nicht alles
 
Wie "Hintergrund herausfiltern"? Wenn du mit dem DC von dem betreffenden Fenster arbeitest, sollte auch nur das Fenster in das Bitmap kopiert werden.

KodeZwerg 29. Mai 2018 23:46

AW: Bildschirmfoto knipst nicht alles
 
Hallo Luckie,
Ich seh schon, Du hast mein Trick noch nicht durchschaut obwohl der Hinweis mit Hintergrund recht deutlich war. Um tatsächlich alles zu knipsen =
Delphi-Quellcode:
DC:=GetDC(0);
. Arbeite ich mit DC von Fenster hab ich Probleme, siehe erste Post.
Deswegen kann ich tatsächlich nun alles knipsen, mit dem Hintergrund Nachteil aber alles. Auch ein AnimateWindow kann nichts dagegen machen. Alle meine Tests wurden mehr oder minder gut bestanden.
Die minder guten Dinge sind noch bugs wo mir grad der Kopf dröhnt da ich komplett bei null mal wieder angefangen habe um mir dieses Anti-Knips-Egal Konzept zu entwickeln.

edit
Der erste Satz soll nicht hochnäsig oder angeberisch sein, Bitte Entschuldige mein Schreibstil

ps: über
Delphi-Quellcode:
CopyRect()
hol ich mir den Inhalt, die Positionen dafür ermittle auf ähnlich weise wie im ersten Post, diesmal habe ich aber alle Schritte getrennt.

Über die Unit Clipbrd glaube ich könnte man auch gehen um ans Ziel zu gelangen, da es jetzt im Grunde schon Einsatzbereit ist habe ich da noch nicht weiter nachgeforscht.

Ich überdenke mir gerade nochmal alles, ich glaube ich habe im Kopf schon die Lösung und muss Sie nur noch umsetzen.
Die Theorie:
Da ich jetzt weiß wie ich an Bild-Daten gelange, per
Delphi-Quellcode:
DC:=GetDC(0);
,
und den ganzen anderen Rest der dazu gehört bis das Image gespeichert ist (erste Post verrät fast alles),
Hier meine Idee,
Da wo ich knipsen will male ich kompletten Bereich Schwarz,
dann hole ich mir Ziel App wieder in den Vordergrund,
knipse und kille schwarzes Rechteck, so müsste es funktionieren denke ich.

EWeiss 30. Mai 2018 05:37

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Auch ein AnimateWindow kann nichts dagegen machen.
Ist mir jetzt schleierhaft was das aufnehmen eines Hintergrund in irgendeiner Form mit AnimateWindow zu tun hat.
Zitat:

ps: über CopyRect() hol ich mir den Inhalt
Es wäre vielleicht ratsam erst einen Rahmen um das entsprechende Objekt zu zeichnen und erst dann aufzunehmen.
So kannst du sehen wo du dich gerade befindest.
Siehe Pic.

Aber!

Wie Luckie schon sagt!
Überdenke nochmal dein Konzept.
Delphi-Quellcode:
DC:=GetDC(0);
Was glaubst du wessen DC du da in Anspruch nimmst?
Und warum du den Desktop nicht ignorieren kannst bei der Aufnahme?
Zudem GetDC(0) für eine ScreenShot Anwendung ist eine schlechte Wahl.

Mitunter wäre es ein einfaches.. dir das Bitmap direkt vom DC zu holen ohne den ganzen Umweg über CopyRect, ClipBord, Hintergrund schwarz machen und die anderen Sache die du dir so ausdenkst.
Und wenn du Qualität haben möchtest kommst du nicht Drumherum vorher ein 32BItDC zu erstelle.
Es ich schön mit unter vorgefertigte Schnipsel zu verwenden und einfach... aber du lernst nichts dabei.
Du weist nicht warum mache ich dies oder das welche Auswirkung kann dies oder jenes haben.
Sorry du stellst hier fragen bekommst Antworten aber du Entwickelst dein Projekt nicht auf dieser Basis und du verstehst nicht wirklich was du da tust oder hast
du dir jede Definition, Funktion, Variable einmal angeschaut welche Auswirkung diese haben?
Wenn ja dann habe ich nichts gesagt.
Wenn nicht tja dann hast du nichts dabei gelernt.

Beim ganzen Thread habe ich eigentlich nicht verstanden um was es dir eigentlich geht.
Du willst den Desktop knipsen ok.. kein Problem das ist ein 4 Zeiler an Code.
Du willst den Clientbereich knipsen? Ist auch nicht mehr an aufwand.
Insgesamt verstehe ich deine Probleme nicht.

gruss

KodeZwerg 30. Mai 2018 07:26

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von EWeiss (Beitrag 1403405)
Delphi-Quellcode:
DC:=GetDC(0);
Was glaubst du wessen DC du da in Anspruch nimmst?

Zitat:

If this value is NULL, GetDC retrieves the DC for the entire screen.
Dieses.
Zitat:

Zitat von EWeiss (Beitrag 1403405)
Es wäre vielleicht ratsam erst einen Rahmen um das entsprechende Objekt zu zeichnen und erst dann aufzunehmen.

Das probierte ich zu beschreiben dass das meine nächsten Schritte sind.
Zitat:

Zitat von EWeiss (Beitrag 1403405)
Wie Luckie schon sagt! Überdenke nochmal dein Konzept.

Kein Scherz, ich sehe bei mir keine Nachricht von Luckie, wo soll er sowas geschrieben haben?
Hab Verstanden was Du meinst aber da bin ich dann wieder beim Source von Post #1 was ja nicht klappt.
Falls selber noch nicht getestet, beim Post #1 ist die Umsetzung so:
Kompiliere und starte es, öffne das Fenster was Du knipsen willst, zurück zu mein Ding und auf knipsen klicken.
Ja sehr unzuverlässig aber nun habe ich eine Prozessliste, sehr zuverlässig.
Zitat:

Zitat von EWeiss (Beitrag 1403405)
Beim ganzen Thread habe ich eigentlich nicht verstanden um was es dir eigentlich geht.

Es geht mir nicht ums Kekse backen, ich will ein Fenster fotographieren so wie es mir auch der Desktop präsentiert.
Unabhängig ob das Fenster irgendwelche Tricks anwendet so das ein Knipsen erschwert wird.
Beispiele: Dein OTTB Layered oder was auch immer für DirectX/OpenGL Overlays, alles soll klappen.


Bin bald fertig.
Ps: Ja das Du das was ich in sehr vielen Zeilen mit nur einem Befehl hinbekommst weil Du weißt was Du tust ist mir klar, da mir die Erfahrung fehlt und ich keine Ahnung davon habe mache ich es nunmal so wie ich es mache.
Ich finde es für mich da es Neuland ist ein nettes Freizeitprojekt.

edit
Ps: Frage: Wenn Du selbst Dein OTTB mit deiner selbstgebackenen Knipsmethode knipst und da nen Rahmen malst, wo issn der Rahmen dann?

EWeiss 30. Mai 2018 08:11

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Dieses.
Nein.. Es gibt das DC des Virtuellen Bildschirm (Screen) zurück.
Und was machst du nun wenn du mehrere Monitore verwendest du glaubst das es dann immer noch funktioniert?
Wenn du also mit mehreren Monitoren arbeitern willst solltest du das verwenden.
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Zitat:

Kein Scherz, ich sehe bei mir keine Nachricht von Luckie, wo soll er sowas geschrieben haben?
Er sagte nicht das du dein Konzept überdenken sollst.
Zitat:

Wie "Hintergrund herausfiltern"? Wenn du mit dem DC von dem betreffenden Fenster arbeitest, sollte auch nur das Fenster in das Bitmap kopiert werden.
Das sagte Ich. Denn ich verstehe deine Herangehensweise leider auch nicht.
Es reicht wenn man sich das Bitmap direkt vom DC holt
Da muss man nix rausfiltern.
Delphi-Quellcode:
HBitmap(GetCurrentObject(DC, OBJ_BITMAP));
Zitat:

Es geht mir nicht ums Kekse backen, ich will ein Fenster fotographieren so wie es mir auch der Desktop präsentiert.
Aha.. OK ein vier\fünf Zeiler also.
1. GetDesktopWindow
2. GetDC\CreateDC
3. GetWindowRect
4. StretchBlt via BitBlt.
5. ReleaseDC

Das knipst alles incl. die Videos in meinem Player(DirectX) und Layered Windows.
Zitat:

da mir die Erfahrung fehlt und ich keine Ahnung davon habe mache ich es nunmal so wie ich es mache.
Zitat:

Frage: Wenn Du selbst Dein OTTB mit deiner selbstgebackenen Knipsmethode knipst und da nen Rahmen malst, wo issn der Rahmen dann?
Wo er hingehört um OTTB.

Sorry! Ich wollte dir nicht zu nahe treten, mach wie du willst.
Bin erste mal raus. (Dachte du wolltest etwas dabei lernen)

gruss

KodeZwerg 30. Mai 2018 08:26

AW: Bildschirmfoto knipst nicht alles
 
Och menno, Ok, Danke auf jeden fall für die korrekte heran gehens weise, ich versuche es so wie Du es beschreibst umzusetzen.

edit
Ich habe gerade dein update mit Bild gesehen, da ist doch auch Desktop Hintergrund, das meinte ich mit rausfiltern bei obiger Aussage.

EWeiss 30. Mai 2018 08:34

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von KodeZwerg (Beitrag 1403412)
Och menno, Ok, Danke auf jeden fall für die korrekte heran gehens weise, ich versuche es so wie Du es beschreibst umzusetzen.

edit
Ich habe gerade dein update mit Bild gesehen, da ist doch auch Desktop Hintergrund, das meinte ich mit rausfiltern bei obiger Aussage.

OK dies Antwort noch.
Dann hole dir doch direkt das Bitmap vom DC was gibt es da raus zu filtern.
Habe dir doch gezeigt wie es geht.
Delphi-Quellcode:
HBitmap(GetCurrentObject(DC, OBJ_BITMAP));

Aber ehrlich? Frage mich was es dir bringen soll ob ich nun den Hintergrund des Desktop im Bereich von OTTB sehe
oder aber nachher anstelle dessen einen weißen\schwarzen oder was auch immer Hintergrund habe ist gehüpft wie gesprungen.

Das einzige was du dann noch machen könntest das Bild als PNG kopieren und den schwarzen\weißen Hintergrund dann ausschneidest.
Aber das ist wieder höhere Mathematik :)

gruss

KodeZwerg 30. Mai 2018 08:45

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von EWeiss (Beitrag 1403414)
Habe dir doch gezeigt wie es geht.
Delphi-Quellcode:
HBitmap(GetCurrentObject(DC, OBJ_BITMAP));

Ja ich bin da noch nicht so fit, bedankt habe ich mich bereits und versuche es umzusetzen. Für Dich ist das alles so selbstverständlich weil Du so tief in der Materie drinnen steckst, ich muss das alles nun Sinnvoll umsetzen und natürlich hier und da MSDN lesen wie/womit/ausgabe etc ich aufrufe damit am Ende das rauskommt was ich wollte, ein Bild vom Fenster mit egal was für Content. Du hast ja heran gehens weise nun sehr deutlich beschrieben, ich bin dabei.
Danke nochmals!:thumb:

Mavarik 30. Mai 2018 09:57

AW: Bildschirmfoto knipst nicht alles
 
emm

Zitat:

Zitat von KodeZwerg (Beitrag 1403258)

Delphi-Quellcode:
BitBlt(Bmp.Canvas.Handle, 0, 0, Width, Height, DC, 0, 0, SRCCOPY);


Delphi-Quellcode:
BitBlt(Bmp.Canvas.Handle, 0, 0, Width, Height, DC, 0, 0, SRCCOPY or CAPTUREBLT);

mit

Delphi-Quellcode:
Const
   CAPTUREBLT = $40000000;
Grüsse Mavarik

EWeiss 30. Mai 2018 10:13

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von Mavarik (Beitrag 1403426)
emm

Zitat:

Zitat von KodeZwerg (Beitrag 1403258)

Delphi-Quellcode:
BitBlt(Bmp.Canvas.Handle, 0, 0, Width, Height, DC, 0, 0, SRCCOPY);


Delphi-Quellcode:
BitBlt(Bmp.Canvas.Handle, 0, 0, Width, Height, DC, 0, 0, SRCCOPY or CAPTUREBLT);

mit

Delphi-Quellcode:
Const
   CAPTUREBLT = $40000000;
Grüsse Mavarik

Zitat:

Includes any windows that are layered on top of your window in the resulting image. By default, the image only contains your window. Note that this generally cannot be used for printing device contexts.
Kann da keinen besonderen Vorteil drin erkennen.
Habe ich noch nie verwendet.

https://stackoverflow.com/questions/...y-of-the-targe
Denke das kann man getrost weglassen.

gruss

Mavarik 30. Mai 2018 10:32

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von EWeiss (Beitrag 1403430)
Kann da keinen besonderen Vorteil drin erkennen.
Habe ich noch nie verwendet.
Denke das kann man getrost weglassen.

Bei einem "Foto" des eigenen Fensters ggf. ja, aber wenn man z.B. die Gadgets vom Vista-Bildschirm auch im Image haben möchte, geht es nicht ohne...

Keine Ahnung ob das auch für andere Inhalte gilt, hab ich noch nicht getestet.

Mavarik

EWeiss 30. Mai 2018 10:35

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von Mavarik (Beitrag 1403435)
Zitat:

Zitat von EWeiss (Beitrag 1403430)
Kann da keinen besonderen Vorteil drin erkennen.
Habe ich noch nie verwendet.
Denke das kann man getrost weglassen.

Bei einem "Foto" des eigenen Fensters ggf. ja, aber wenn man z.B. die Gadgets vom Vista-Bildschirm auch im Image haben möchte, geht es nicht ohne...

Keine Ahnung ob das auch für andere Inhalte gilt, hab ich noch nicht getestet.

Mavarik

Ja das habe ich gelesen wenn es um Sprite auf dem Window geht (Widget)
Aber bei mir werden die auch ohne diese Flag aufgenommen.. siehe Shot.

Nun gut versuchen kann er es ja mal.. Nachteile wird er dadurch nicht habe.
Danke!

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:27 Uhr.
Seite 1 von 2  1 2      

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