Delphi-PRAXiS
Seite 6 von 7   « Erste     456 7      

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)

Fritzew 31. Mai 2018 16:31

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von EWeiss (Beitrag 1403525)
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

EWeiss 31. Mai 2018 17:03

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

Fritzew 31. Mai 2018 17:10

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

EWeiss 31. Mai 2018 17:11

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von Fritzew (Beitrag 1403533)
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

KodeZwerg 31. Mai 2018 18:11

AW: Bildschirmfoto knipst nicht alles
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Ihr Lieben,
um die Frage "wie wirds bei mir momentan Angezeigt" zu beantworten, so: Anhang 49187 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 :thumb:

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

EWeiss 31. Mai 2018 18:16

AW: Bildschirmfoto knipst nicht alles
 
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
Delphi-Quellcode:
Image.PixelFormat := pf32bit;
Das war's dann schon.

gruss

KodeZwerg 31. Mai 2018 18:31

AW: Bildschirmfoto knipst nicht alles
 
Genau:thumb:
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:stupid:

EWeiss 31. Mai 2018 18:32

AW: Bildschirmfoto knipst nicht alles
 
Zitat:

Zitat von KodeZwerg (Beitrag 1403547)
Genau:thumb:
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

KodeZwerg 1. Jun 2018 00:24

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

EWeiss 1. Jun 2018 00:36

AW: Bildschirmfoto knipst nicht alles
 
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.
Delphi-Quellcode:
DeleteObject(hBmp);

wäre korrekt wenn du es nicht noch brauchen würdest.

Delphi-Quellcode:
Result := True;

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


gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:08 Uhr.
Seite 6 von 7   « Erste     456 7      

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