Screenshot anfertigen (war: timage)
-
hi,
ich bin ein totaler cpp newbie und habe daher ein paar fragen
1. wie kann ich ein screenshot machen
2. wie kann ich ein screenshot von nur einem bestimmten fenster oder allen ohne dem aktuellen fenster bzw. dem formular machen?
3. wie kann ich diesen screenshot dann in ein timage laden und das wiederrum speichern?
ich hoffe ihr könnt mir helfen
schonmal danke im *******cu cppnewbie
[ Dieser Beitrag wurde am 01.06.2002 um 19:55 Uhr von Jansen editiert. ]
-
1.mit PSP ab V6.0
2. dito
3. Image1->Picture->LoadFromFile("Filename.bmp");Junix, wo bleibt deine Antwort?
-
Original erstellt von maloo:
Junix, wo bleibt deine Antwort?Ich weiss nicht genau was du meinst? War grad unterwegs *g*
http://www.c-plusplus.net/ubb/cgi-bin/ultimatebb.cgi?ubb=get_topic&f=2&t=006805 Schau mal hier... oder gleichauch in der FAQ, weil ichs jetzt da hin schiebe (:-junix
-
Allgemein etwas zur Screenshot-Darstellung in einem TImage: Du musst dir das Handle des Fensters holen, das du im Screenshot darstellen willst. Das kannst du entweder per FindWindow() machen oder, wenn das Fenster eine Form ist, durch die Eigenschaft "Handle" von TForm. Das Handle des Desktops bekommst du übrigens über GetDesktopWindow(). Hilfe zu jeder Funktion bekommst du, wenn du den Cursor in dem Wort platzierst und F1 drückst. Wenn du also das Handle des Fensters hast, von dem du den Screenshot machen willst, kannst du folgendes schreiben (vorausgesetzt ist ein Button und ein Image auf der Form):
void __fastcall TForm1::Button1Click(TObject *Sender) { TCanvas* canvas = new TCanvas(); canvas->Handle = GetWindowDC([Fensterhandle]); TRect Dest = Image1->ClientRect; TRect Source; GetWindowRect([Fensterhandle], (LPRECT)&Source); Image1->Canvas->CopyRect(Dest, canvas, Source); delete canvas; }
-
@junix
Mein Gott, ist das viel Code. Meiner ist kürzer und leichter verständlich. Gibt's denn einen Vorteil deines Codes gegenüber meinem?@<cppnewbie>
Ist es nicht besser, den Screenshot zu speichern ohne ihm in ein Image zu laden - also so, dass man ihn nicht sieht?[ Dieser Beitrag wurde am 01.06.2002 um 18:48 Uhr von WebFritzi editiert. ]
-
hi,
erstmal danke für die schnelle hilfewenn es möglich ist, den screenshot direkt zu speichern, ohne ihn erst in ein timage zu laden, dann wäre das natürlich noch besser. aber ich bin davon ausgegangen dass man das eben erst in ein timage laden muss, um es zu speichern. werde mir erstmal eure codes anschauen. nochmals danke für die hilfe
-
Stimmt. Ist wirklich kürzer.... hmm was war das nur? Wenn ich mich richtig erinnere, werden bei meiner Variante auch noch die Paletten-Konfigurationen berücksichtig oder sowas. Kann mich nichtmehr erinnern.
Wie schon da steht: Ich hatte diese Funktion in den Borland-News-Groups via Usenet (groups.google.com) gefunden.
-junix
-
Original erstellt von cppnewbie:
erstmal danke für die schnelle hilfewenn es möglich ist, den screenshot direkt zu speichern, ohne ihn erst in ein timage zu laden, dann wäre das natürlich noch besser.
Erstelle vor der Funktion eine Instanz von TBitmap. Wenn du dir die Methoden von TBitmap anschaust, wirst du auch eine finden, die dich das Ganze dann speicher lässt.
delete nicht vergessen am ende der Funktion! (:
-junix
-
@junix und <cppnewbie>
Mein Code war falsch. Das ging nur mit dem Desktop. Lag an dem TRect Source. Mit folgender Überarbeitung klappt's:void __fastcall TForm1::MakeScreenShot(HWND handle, TImage* image) { TCanvas* canvas = new TCanvas(); canvas->Handle = GetWindowDC(handle); TRect Dest = Image1->ClientRect; TRect Source; GetWindowRect(handle, (LPRECT)&Source); Source = Rect(0, 0, Source.Right - Source.Left, Source.Bottom - Source.Top); image->Canvas->CopyRect(Dest, canvas, Source); delete canvas; }
Das muss dann nur so aufgerufen werden:
MakeScreenShot([Fensterhandle], Image1);
[ Dieser Beitrag wurde am 01.06.2002 um 19:36 Uhr von WebFritzi editiert. ]
-
danke für eure Hilfe, es hat geklappt
-
Mal wieder ne n00b Frage von mir.
Was muss ich alles machen um es in mein Programm einzu binden?? (ich will Screnns vom ganzen Desktop bzw von einem Game machen)
die Function habe ich einfach so rein kopiert wie sie da ist aber dann bekomme ich den Fehler
C++ Fehler] main.cpp(39): E2316 '_fastcall TForm1::MakeScreenShot(void *,TImage *)' ist kein Element von 'TForm1'So und so habe ich es bei einem Button deklariert klappt aber auch nicht
MakeScreenShot(GetDesktopWindow(), "bla");
[C++ Fehler] main.cpp(62): E2268 Aufruf der undefinierten Funktion 'MakeScreenShot'
[C++ Fehler] main.cpp(62): E2451 Undefiniertes Symbol 'bla'Könnt ihr mir sagen was ich anderes machen muss??
besten Dank
wdsl
-
Ja, du musst statt Bal ein TImage einbinden und dann einfach und ohne Anführungszeichen Image1 oder wie dein Image auch immer heißen mag in der Funktion angeben und die Funktion vor der Definition, ganz am Anfang des Codes noch prozedur schreiben.
-
TForm1::MakeScreenShot() bedeutet, dass es sich um eine Memberfunktion der Klasse TForm1 handelt. Du musst die Funktion also im Header von Form1 zB. unter private: deklarieren.
void __fastcall MakeScreenShot(HWND handle, TImage* image);
Und dann solltest du dich unbedingt nochmal mit den C++-Grundlagen, insbesondere mit dem Umgang mit Klassen beschäftigen.
-
@Jandsen Sorry habe ich vergessen.
Aber ich habe noch ein ProblemAber ich habe noch ein Problem wie kann ich es machen, dass der Screenshot in der normalen Bildschirm auflösung abgespeichert wir??
Ich kann das TImage Feld ja nicht so gr0ß Ziehen das es so groß wird und wenn ich den Sreen nachher vergrößert hat er keine Auflöung mehr.
mfg
wdsl
-
das sollte automatisch klappen, denn anzeigen!=abspeichern, er zeigt dir zwar vielleicht 800x600 an, is aber 1024x768 groß (wenn das image 800x600 groß ist und du eine auflösung von 1024x768 hast)
-
Erstelle innerhalb der Funktion eine TBitmap-Instanz in den Abmessungen von Source. Statt auf das Image zeichnest du dann direkt auf das Bitmap und weist dieses am Schluss per Assign dem Image zu. Nicht vergessen, das Bitmap wieder zu löschen.
Beim Image sollte natürlich die StretchDraw-Property aktiviert sein.
-
Ups sorry habe nicht gesehen das du schon geantwortet hast ich Editir mal schnell meinen Beitrag weil ich ein Problem habe. Jetzt ist zwar das bild 800x600 aber der Screen ist genauso groß nur das Ausenrum alles Weis ist was habe ich jetzt schon wieder falsch gemacht??
void __fastcall TForm1::MakeScreenShot(HWND handle, TImage* image) { TCanvas* canvas = new TCanvas(); TJPEGImage *jpg = new TJPEGImage(); Graphics::TBitmap *bmp = new Graphics::TBitmap(); bmp->Height = 800; bmp->Width = 600; canvas->Handle = GetWindowDC(handle); TRect Dest = Image1->ClientRect; TRect Source; GetWindowRect(handle, (LPRECT)&Source); Source = Rect(0, 0, Source.Right - Source.Left, Source.Bottom - Source.Top); bmp->Canvas->CopyRect(Dest, canvas, Source); bmp->SaveToFile("Bla.bmp"); delete canvas; }
-
Da hast die Zielgrösse Dest auf die Grösse des Images gesetzt anstatt auf die Grösse des Bitmaps. Da Quell- und Zielgrösse identisch sein sollen kann man sich das Dest-Rect aber auch komplett sparen.
void __fastcall TForm1::MakeScreenShot(HWND hwnd, TImage *img) { TCanvas *canvas = new TCanvas(); canvas->Handle = GetWindowDC(hwnd); TRect Source; GetWindowRect(hwnd, (LPRECT)&Source); Source = Rect(0, 0, Source.Right - Source.Left, Source.Bottom - Source.Top); Graphics::TBitmap *bmp = new Graphics::TBitmap(); bmp->Width = Source.Width(); bmp->Height = Source.Height(); bmp->PixelFormat = pf24bit; bmp->Canvas->CopyRect(Source, canvas, Source); img->Picture->Assign(bmp); delete bmp; delete canvas; }
-
Sehr vielen herzlichen Dank