Screenshot anfertigen (war: timage)



  • hi,
    erstmal danke für die schnelle hilfe 🙂 wenn 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 hilfe 🙂 wenn 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 Problem

    Aber 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


Anmelden zum Antworten