AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Bildschirmfoto knipst nicht alles

Bildschirmfoto knipst nicht alles

Ein Thema von KodeZwerg · begonnen am 29. Mai 2018 · letzter Beitrag vom 4. Jun 2018
Antwort Antwort
Seite 6 von 7   « Erste     456 7   
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#51

AW: Bildschirmfoto knipst nicht alles

  Alt 31. Mai 2018, 16:31
Zitat:
da auch noch nicht so ganz gecheckt habe wieso einer Methode a) nimmt und anderer Methode b)
Solange du nur einen Monitor unterstützen willst wäre die zweite Methode angebracht.
Willst du Multimonitor unterstützen dann die erste.

gruss
Wie kommst Du auf diese Aussage?
Bei Invalidate wird Windows mitgeteilt, dass das Fenster neu gezeichnet werden soll. In dem Fall das Image.

Blick in die Source von refresh:

das ruft Repaint auf
Repaint:

Delphi-Quellcode:
Invalidate
Update;
Im Normalfall ist es so das ein Invalidate ausreichen sollte. Windows kümmert sich dann darum, wann das Zeichnen passieren soll. WM_PAINT wird mit einer geringeren Priorität ausgelöst.

https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

kommt also immer darauf an was Du erwartest.
Bei Refresh und co ist die Systemlast höher, da immer sofort gezeichnet wird.

Aber mit Multimonitor hat das rein gar nichts zu tun
Fritz Westermann
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#52

AW: Bildschirmfoto knipst nicht alles

  Alt 31. Mai 2018, 17:03
Zitat:
Bei Invalidate wird Windows mitgeteilt, dass das Fenster neu gezeichnet werden soll. In dem Fall das Image.
Es hat niemand über Invalidate gesprochen.

Sondern darüber welche Funktion er verwenden soll.
Die erste oder die zweite Methode.

Methode A:
Delphi-Quellcode:
Function CaptureScreen(var hbmp: HBITMAP): Boolean;
var
   hDCScreen, hDCMem : HDC;
   cx, cy: Integer;
   hBmpOld: HBITMAP;
   dwRop: DWORD;
begin
   hDCScreen := CreateDC('DISPLAY', 0, 0, 0);
   cx := GetDeviceCaps(hDCScreen, HORZRES);
   cy := GetDeviceCaps(hDCScreen, VERTRES);
   hDCMem := CreateCompatibleDC(hDCScreen);
   hbmp := CreateCompatibleBitmap(hDCScreen, cx, cy);
   hBmpOld := SelectObject(hDCMem, hbmp);
   dwRop := SRCCOPY or CAPTUREBLT;
   Result := BitBlt(hDCMem, 0, 0, cx, cy, hDCScreen, 0, 0, dwRop);
   SelectObject(hDCMem, hBmpOld);
   DeleteDC(hDCMem);
   DeleteDC(hDCScreen);
end;
Methode B:
1. GetDesktopWindow
2. GetDC\CreateDC
3. GetWindowRect
4. StretchBlt via BitBlt.
5. ReleaseDC

Was hat das jetzt mit Invalidate zu tun?

Das!
Zitat:
Oder warum benutzt einer nach knipsen ein image.invalidate und ein anderer image.refresh.. all solche Sachen da muss ich noch viel blättern damit ich die zusammenhänge Verstehe bzw was Überhaupt die Unterschiede sind, für mich ists irgendwie das selbe.
Ist wieder eine andere Frage worauf ich aber nicht geantwortet habe.
Du musst das schon auseinander halten.

gruss

Geändert von EWeiss (31. Mai 2018 um 17:08 Uhr)
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#53

AW: Bildschirmfoto knipst nicht alles

  Alt 31. Mai 2018, 17:10
Zitat:
Oder warum benutzt einer nach knipsen ein image.invalidate und ein anderer image.refresh
Da habe ich wohl die lokalen Variablen a und b falsch initialisiert....
Sorry, nix für Ungut, dann kennt er jetzt zumindest den Unterschied zwischen I und R:
Fritz Westermann
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#54

AW: Bildschirmfoto knipst nicht alles

  Alt 31. Mai 2018, 17:11
Zitat:
Oder warum benutzt einer nach knipsen ein image.invalidate und ein anderer image.refresh
Da habe ich wohl die lokalen Variablen a und b falsch initialisiert....
Sorry, nix für Ungut, dann kennt er jetzt zumindest den Unterschied zwischen I und R:
Dito! Danke.

gruss
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

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

AW: Bildschirmfoto knipst nicht alles

  Alt 31. Mai 2018, 18:11
Hallo Ihr Lieben,
um die Frage "wie wirds bei mir momentan Angezeigt" zu beantworten, so: screenshot-31_05.jpg mit invalidate zum aktualisieren.
Die Anzeige hat aber nichts mit dem Bild gemeinsam was gespeichert wird, das liegt noch im Rohformat rum so wie ichs ausgelesen habe und kann an mehreren Stellen freigegeben werden.

Alles noch totale Early Alpha Phase.

Vielen Dank für Erklärungen für beide Fragezeichen die ich so hatte, es hat beides gefruchtet

Jetzt mach ich erstmal das was Emil sagte, ich besuche erstmal das MSDN und speicher mir alle Infos zu allen Befehlen damit ich von vorne beginnen kann aber diesmal Richtig, den Methode b) Weg.

Danke auch für Vorwarnung mit MultiMonitor, das es da Unterschiede gibt werde wusste ich nicht einmal, gut mitgedacht danke, da werde ich viel zu tun haben, auch Danke für diese Erklärungen und auch das ich ein 32bit Bild erzeugen sollte, darauf wäre ich alleine nie gekommen, ich werde all diese Hinweise aufsaugen inhalieren und langsam verdauen
Gruß vom KodeZwerg

Geändert von KodeZwerg (31. Mai 2018 um 18:20 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#56

AW: Bildschirmfoto knipst nicht alles

  Alt 31. Mai 2018, 18:16
Wird schon
Wenn man die einzelnen schritte einmal verewigt hat ist das die Basis welche man für alle Bildmanipulationen verwenden kann.

Zitat:
und auch das ich ein 32bit Bild erzeugen sollte
Ich meinte einen 32BitDC der quasi alle Rohdaten schon enthält um ein Aufgenommenes 32Bit Bild aufzunehmen ohne das Daten verloren gehen.
Also quasi ein MyBitmap.canvas auf 32Bit Bilddaten ausgerichtet.

Aber das später ist jetzt für den Anfang nicht so wichtig.

PS:
Mit der VCL ist das einfach siehe
Image.PixelFormat := pf32bit; Das war's dann schon.

gruss

Geändert von EWeiss (31. Mai 2018 um 18:27 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

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

AW: Bildschirmfoto knipst nicht alles

  Alt 31. Mai 2018, 18:31
Genau
Am Rande.....
Und was man im Bild nicht sieht, ich habs so gemacht:
App startet und holt sich alle Window Handles die es für mich verarbeiten könnte,
selektiert man einen Eintrag erscheint die Vorschau und Kamera wird aktiviert,
drückt man Kamera wird der Eigentliche Screenshot erstellt und Speichern ermöglicht.

Ist das Ok oder sollte ich da nochmal was überdenken?

Nachtrag
Danke für Nachtrag
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#58

AW: Bildschirmfoto knipst nicht alles

  Alt 31. Mai 2018, 18:32
Genau
Am Rande.....
Und was man im Bild nicht sieht, ich habs so gemacht:
App startet und holt sich alle Window Handles die es für mich verarbeiten könnte,
selektiert man einen Eintrag erscheint die Vorschau und Kamera wird aktiviert,
drückt man Kamera wird der Eigentliche Screenshot erstellt und Speichern ermöglicht.

Ist das Ok oder sollte ich da nochmal was überdenken?
Hört sich gut an mache es einfach so.. und gut ist.
Nachher kannst immer noch etwas feilschen.

gruss
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

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

AW: Bildschirmfoto knipst nicht alles

  Alt 1. Jun 2018, 00:24
Zwischenstand:

Ich habe nun wieder probiert es hinzubekommen, komplett von vorne bis zum Ende ohne bei Methode b) abzugucken aber mit den Infos von Post 1 angefangen, so das ich theoretisch weiß was ich da mache. Hier stoße ich wieder auf das Layered Problem aber der Rest macht alles Prima. Ist sozusagen ein BestOf ohne Layered support.
Das ist sozusagen Methode c).... da diese Methode nicht klappt fange ich nun an Methode b) umzusetzen, ich sagte ja, alleine bin ich noch nicht im Stande und ich habe mir wirklich Mühe gegeben MSDN da zu Verstehen und Richtig einzusetzen aber eure Infos zu Layered für Methode b) vorbehalten/reserviert.
OTTB = Geht damit nicht von daher muss ich an dieser Stelle aufgeben mit Methode c)
Delphi-Quellcode:
Function Knipse(const Win: HWND; var tbmp: TBitmap; const FullWindow: Boolean): Boolean;
const
  CAPTUREBLT = $40000000;
var
  hDCScreen: HDC;
  rec: TRect;
begin
  Result := False;
  if Win = 0 then Exit;
  try
    begin
      if FullWindow then
       begin
         hDCScreen := GetWindowDC(Win);
         Windows.GetWindowRect(Win, rec)
       end else
       begin
         hDCScreen := GetDC(Win);
         Windows.GetClientRect(Win, rec);
       end;
      tbmp.PixelFormat:=pf32bit;
      tbmp.Width := Rec.Right - Rec.Left;
      tbmp.Height := Rec.Bottom - Rec.Top;
      tbmp.Canvas.Lock;
      StretchBlt(tbmp.Canvas.Handle, 0, 0,
                 tbmp.Width, tbmp.Height,
                 hDCScreen, 0, 0,
                 tbmp.Width, tbmp.Height,
                 SRCCOPY or CAPTUREBLT);
      tbmp.Canvas.Unlock;
    end;
  finally
    ReleaseDC(0, hDCScreen);
    Result := True;
  end;
end;
Und nicht das ihr denkt ich lese nicht alles, ich arbeite alles halt nur langsamer ab da es Neuland ist,
hier ist meine Interpretation einer WM_PRINT -> ClipBoard -> HBITMAP Variante, irgendwie alles falsch da ich kein Bild erhalte. Also Versucht habe ich es. Das hier steht allerdings nicht zur Debatte, nur zur Illustration wie man es nicht machen sollte
Delphi-Quellcode:
function MyWM_PRINT(const Win: HWND): HBITMAP;
var
  rect: TRECT;
  hBmp: HBITMAP;
  hOld: HGDIOBJ;
  hDCMem, hDCScreen: HDC;
begin
  hDCMem := CreateCompatibleDC(0);
  GetWindowRect(Win, rect);
  hBmp := 0;
  hDCScreen := GetDC(Win);
  hBmp := CreateCompatibleBitmap(hDCScreen, rect.right - rect.left, rect.bottom - rect.top);
  ReleaseDC(Win, hDCScreen);
  hOld := SelectObject(hDCMem, hBmp);
  SendMessage(Win, WM_PRINT, WPARAM(hDCMem), PRF_CHILDREN or PRF_CLIENT or PRF_ERASEBKGND or PRF_NONCLIENT or PRF_OWNED);
  SelectObject(hDCMem, hOld);
  DeleteObject(hDCMem); // ich glaub das wär falsch oder?
  DeleteDC(hDCMem); // oder doch so? me stupid
  OpenClipboard(Win);
  EmptyClipboard();
  SetClipboardData(CF_BITMAP, hBmp);
  Result := hBmp;
  CloseClipboard();
end;
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#60

AW: Bildschirmfoto knipst nicht alles

  Alt 1. Jun 2018, 00:36
Delphi-Quellcode:
      tbmp.Canvas.Lock;
       StretchBlt(tbmp.Canvas.Handle, 0, 0,
                  tbmp.Width, tbmp.Height,
                  hDCScreen, 0, 0,
                  tbmp.Width, tbmp.Height,
                  SRCCOPY or CAPTUREBLT);
       tbmp.Canvas.Unlock;
Lock, Unlock ist nicht von nöten.
StretchBlt auf der Basis auch nicht.

StretchBlt ist nur sinnvoll wenn der Source und Destination sich in der weite, Höhe unterscheiden.
So macht ein Stretch keinen sinn bei gleichen ausmaßen.
Du kannst hier also getrost BitBlt verwenden.

Zitat:
DeleteObject(hDCMem); // ich glaub das wär falsch oder?
Definitiv!
Denn ein HDC ist kein Object.
DeleteObject(hBmp);
wäre korrekt wenn du es nicht noch brauchen würdest.

Result := True;
Warum?
Du weist doch gar nicht ob StretchBlt erfolgreich war.
Wenn schon dann so.
Result := StretchBlt(bla, bla,

gruss

Geändert von EWeiss ( 1. Jun 2018 um 00:51 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 06:06 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