AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Screenshot - Verständnisfrage
Thema durchsuchen
Ansicht
Themen-Optionen

Screenshot - Verständnisfrage

Ein Thema von hans ditter · begonnen am 27. Feb 2012 · letzter Beitrag vom 27. Feb 2012
Antwort Antwort
hans ditter

Registriert seit: 25. Jun 2010
Ort: Niedersachsen
263 Beiträge
 
Turbo Delphi für Win32
 
#1

Screenshot - Verständnisfrage

  Alt 27. Feb 2012, 15:02
Hallo alle zusammen!

Da hab ich mich letztens dumm und dämlich gesucht nach einem funktionierenden Screenshotcode und da stand er doch direkt vor meiner Nase in dem dicken Delphischmöker...

Der Code funktioniert auch prima... nur leider weiß ich nicht genau warum...

Hier erstmal der Code:
Delphi-Quellcode:
procedure ScreenshotBook(bmp: THandle);stdcall;
var ScreenDC, CompDC: HDC;
    ScreenBitmap: HBitmap;
    h: THandle;
begin
  ScreenDC := GetDC(0); //DC des gesamten Bildschirm abfragen
  CompDC := CreateCompatibleDC(ScreenDC); //einen neuen DC anlegen, der gleich dem DC vom Bildschirm ist??
  ScreenBitmap := CreateCompatibleBitmap(ScreenDC,
                  GetDeviceCaps(ScreenDC,HORZRES),
                  GetDeviceCaps(ScreenDC,VERTRES)); //hä? ein Bitmap wird angelegt ... und dann?
  h := SelectObject(CompDC,ScreenBitmap); //das versteh ich auch nicht so genau...
  BitBlt(CompDC,0,0,GetDeviceCaps(ScreenDC,HORZRES),
         GetDeviceCaps(ScreenDC,VERTRES),ScreenDC,0,0,SRCCOPY); //klar, hier wird der Inhalt aus ScreenDC in CompDC kopiert
  BitBlt(bmp,0,0,300,300,compDC,0,0,SRCCOPY); //Inhalt von CompDC in ein mitgeliefertes Handle

  DeleteObject(SelectObject(CompDC,h)); //?? und vor allem: warum selectObject in deleteObject??
  DeleteDC(CompDC); //künstlich erzeugtes DC freigeben
  ReleaseDC(0,ScreenDC); //Freigeben des abgefragten Bildschrim-DCs
end;
Erstens frage ich mich, ob das wirklich so umständlich sein muss?! Warum frage ich den Bildschirm-DC ab, erzeuge dann ein neuen DC und kopier aus dem Bildschirm-DC den Inhalt in den neuen DC um den da dann wieder rauszukopieren? Das ist doch irgendwie doppelt gemoppelt!

Und dann versteh ich die Schritte mit SelectObject und CreateCompatibleBitmap nicht, geschweige denn das DeleteObject(SelectObject()).

Ich hoffe ihr könnte mir helfen!

LG; hans ditter

//EDIT:

Ach ja, und eine Frage hätte ich noch: Warum geht das nur mit Form.Canvas.Handle bzw. Paintbox.Canvas.Handle nicht aber mit Image1.Picture.Bitmap.Handle (vlt wegen HBITMAP?) oder Image.Picture.Bitmap.Canvas.Handle?
RudiRüsselSeineSocketKomponente - SirRufo (--> Chat mit PM)

Delphi Programming is the best one!

Geändert von hans ditter (27. Feb 2012 um 15:15 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#2

AW: Screenshot - Verständnisfrage

  Alt 27. Feb 2012, 15:14
Du kannst auch einfach nur per Canvas arbeiten
Delphi-Quellcode:
procedure Screen2Canvas(DestCanvas:TCanvas;DestRect:TRect);
var
 C:TCanvas;

begin
 C:=TCanvas.Create;
 C.Handle := GetDC(0);
 try
   DestCanvas.CopyRect(DestRect,C,DestRect);
 finally
   ReleaseDC(0,C.Handle);
   c.Free;
 end;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
   Screen2Canvas(Image1.Canvas,Rect(0,0,Screen.Width,Screen.Height));
end;
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
hans ditter

Registriert seit: 25. Jun 2010
Ort: Niedersachsen
263 Beiträge
 
Turbo Delphi für Win32
 
#3

AW: Screenshot - Verständnisfrage

  Alt 27. Feb 2012, 15:19
@Bummi: Danke für die Antwort. Sieht ehrlich einfacher aus... aber ich glaube, das war auch eine der Varianten, die ich schon ausprobiert hatte und die nicht geklappt hat.
Und irgendwas muss ja den Mehraufwand bei meiner Methode rechtfertigen... was ist daran besser?

Zu deiner Methode: Funktioniert die auch, wenn man die in eine DLL auslagert? Das hab ich nämlich, vlt lag's daran?
RudiRüsselSeineSocketKomponente - SirRufo (--> Chat mit PM)

Delphi Programming is the best one!
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#4

AW: Screenshot - Verständnisfrage

  Alt 27. Feb 2012, 16:07
Ein wenig aus der deutschen OH

Zitat:
Die Funktion CreateCompatibleDC erzeugt einen Speichergerätekontext, der mit dem angegebenen Gerät kompatibel ist.

Eine Anwendung muß einem Speichergerätekkontext ein Bitmap zuordnen. Dieser Gerätekontext kann dann verwendet werden, um Bilder im Speicher aufzubereiten, bevor sie auf die gerätekompatible Bildschirmoberfläche kopiert werden.
Zitat:
Die Funktion CreateCompatibleBitmap erzeugt ein Bitmap, das mit einem angegebenen Gerät kompatibel ist.
Zitat:
Die Funktion SelectObject wählt ein Objekt in den angegebenen Gerätekontext. Das neue Objekt ersetzt das vorherige Objekt gleichen Typs.
Zitat:
Die Funktion BitBlt kopiert ein Bitmap von einem angegebenen Gerätekontext auf einen Zielgerätekontext.
Zitat:
Die Funktion DeleteObject löscht einen virtuellen Stift, Pinsel, Bitmap, einen Bereich, Schrift oder Farbpalette durch Freigabe des zugehörigen Systemspeichers.
Zitat:
Die Funktion DeleteDC löscht den angegebenen Gerätekontext.
Zitat:
Die Funktion ReleaseDC hebt einen Gerätekontext auf und gibt ihn zur Benutzung durch andere Anwendungen frei.
  Mit Zitat antworten Zitat
hans ditter

Registriert seit: 25. Jun 2010
Ort: Niedersachsen
263 Beiträge
 
Turbo Delphi für Win32
 
#5

AW: Screenshot - Verständnisfrage

  Alt 27. Feb 2012, 16:53
Hey, das hört sich schonmal gut an!

Aber mir ist noch nicht klar, wofür SelectObject gut ist. Das hört sich für mich so an, alls wenn dort ein Obejkt durch ein anderes ersetzt wird. Aber das ist ja nicht der Sinn dahinter, oder?

Und dann ist mir auch noch unklar, warum bei DeleteObject erst noch SelectObject(CompDC,h) in den Klammern steht. Kannst du mir da auch nochmal helfen?
RudiRüsselSeineSocketKomponente - SirRufo (--> Chat mit PM)

Delphi Programming is the best one!
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#6

AW: Screenshot - Verständnisfrage

  Alt 27. Feb 2012, 17:17
Unabhängig der Bedeutung

function SelectObject(DC: HDC; hObject: THandle): THandle; gibt das Handle des ersetzten Objekts. In diesem Fall

h := SelectObject(CompDC,ScreenBitmap); die der Bitmap.

DeleteObject(SelectObject(CompDC,h)); löscht die virtuelle Bitmap.

Warum aber SelectObject in DeleteObject? SelectObject ersetzt nur das Objekt.

Der einzige Grund der mir auf die Schnelle einfällt ist, dass SelectObject zur Sicherheit eingesetzt wurde, denn hier wird nur ersetzt, d. h. es kommt ein Handle zurück, oder Null oder Error. Ist das zurückgegebene Handle nicht gültig, wird auch nichts gelöscht. Man kann mit den Aufruf nichts verlieren aber evtl. etwas gewinnen. (meine unfachmännische Meinung)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Screenshot - Verständnisfrage

  Alt 27. Feb 2012, 17:22
Zitat:
An application should always replace a new object with the original, default object after it has finished drawing with the new object.
So, in h steht das Originalobjekt. Dasjenige, das h ersetzt hat, wird durch den inneren Aufruf von SelectObject ermittelt, dabei wird das Original (also h) wiederhergestellt. Da das temporäre Objekt (also das soeben ermittelte) nicht mehr gebraucht wird, wird es mit DeleteObject freigegeben.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#8

AW: Screenshot - Verständnisfrage

  Alt 27. Feb 2012, 17:48
So langsam ergibt es einen Sinn.

Delphi-Quellcode:
procedure ScreenshotBook(bmp: THandle);stdcall;
var ScreenDC, CompDC: HDC;
    ScreenBitmap: HBitmap;
    h: THandle;
begin
  ScreenDC := GetDC(0); //DC des gesamten Bildschirm abfragen
  CompDC := CreateCompatibleDC(ScreenDC); //einen neuen DC anlegen, der gleich dem DC vom Bildschirm ist??
  ScreenBitmap := CreateCompatibleBitmap(ScreenDC,
                  GetDeviceCaps(ScreenDC,HORZRES),
                  GetDeviceCaps(ScreenDC,VERTRES)); //hä? ein Bitmap wird angelegt ... und dann?
  h := SelectObject(CompDC,ScreenBitmap); //das versteh ich auch nicht so genau...
  BitBlt(CompDC,0,0,GetDeviceCaps(ScreenDC,HORZRES),
         GetDeviceCaps(ScreenDC,VERTRES),ScreenDC,0,0,SRCCOPY); //klar, hier wird der Inhalt aus ScreenDC in CompDC kopiert
  BitBlt(bmp,0,0,300,300,compDC,0,0,SRCCOPY); //Inhalt von CompDC in ein mitgeliefertes Handle

  DeleteObject(SelectObject(CompDC,h)); //?? und vor allem: warum selectObject in deleteObject??
  DeleteDC(CompDC); //künstlich erzeugtes DC freigeben
  ReleaseDC(0,ScreenDC); //Freigeben des abgefragten Bildschrim-DCs
end;
Ok, GetDC ermittelt das Handle für einen Gerätekontext, CreateCompatibleDC erzeugt einen kompatiblem Gerätekontext, CreateCompatibleBitmap erzeugt eine Bitmap die für SelectObject Voraussetzung ist. BitBlt kopiert dann alles an die richtige Stelle. Zuletzt wird aufgeräumt.

Ob das alles nötig ist, weiß ich nicht, es ist aber, soweit ich es beurteilen kann, ist es so wie es sein soll.
  Mit Zitat antworten Zitat
Antwort Antwort


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 05:13 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