Fehlermeldung nach langer Benutzung von Screenshot-Funktion



  • Hi,

    mit folgendem Code lasse ich alle paar Sekunden einen Screenshot schießen und in ein Imagefeld packen.

    HWND handle = GetForegroundWindow();
    TCanvas* canvas = new TCanvas();
    canvas->Handle = GetWindowDC(handle);
    TRect Dest = Image1->ClientRect;
    TRect Source;
    GetWindowRect(handle, (LPRECT)&Source);
    Image1->Canvas->CopyRect(Dest, canvas, Source);
    delete canvas;
    

    (Hier im Forum gefunden)

    Wenn das kompilierte Programm allerdings ein paar Stunden am Stück läuft, kommt eine Fehlermeldung mit dem Inhalt: "Leinwand/Bild erlaubt kein"

    Hat jemand eine Idee woran das liegen kann und wo ein Lösungsansatz zu sehen ist?

    Danke im Voraus!

    Gruß
    ravel



  • Ich mach das so:

    HWND HWnd;
      HDC hdc;
      int cx,cy;
      Graphics::TBitmap *BM=new Graphics::TBitmap;
      HWnd=GetDesktopWindow();
      hdc=GetDC(HWnd);
      if (LockWindowUpdate(HWnd))
      {
        cx=GetSystemMetrics(SM_CXSCREEN);
        cy=GetSystemMetrics(SM_CYSCREEN);
        BM->Width=cx;
        BM->Height=cy;
        BitBlt(BM->Canvas->Handle,0,0,cx,cy,hdc,0,0,SRCCOPY);
        LockWindowUpdate(0);
        Image->Picture->Assign(BM);
      }
      ReleaseDC(HWnd,hdc);
      delete Pic;
      delete BM;
    

    PS: Du gibst ev. den Geraetzekontext nicht richtig frei???



  • Ich tippe auch auf das fehlende ReleaseDC.

    Aber warum erstellst du den ganzen Plunder laufend neu? Theoretisch sollte es doch reichen, lediglich CopyRect immer wieder aufzurufen.



  • Ich hab' mal gelesen, man soll nen Geraetekontext sobald als moeglich wieder freigeben - belegt Ressourcen. Bei Sekundenweise benutzen koennte mann das aber ev. weglassen. Erst beim Beenden freigeben?



  • Genau. Die Sachen, die laufend benötigt werden, werden einmal beim Programmstart erstellt und einmal am Programmende wieder freigegeben. Im OnTimer erfolgt lediglich der CopyRect-Aufruf.

    Ich bin zwar kein DeviceContext-Experte, bezweifle aber, dass man durch das "Festhalten" des einen DC andere Programme oder das System beeinträchtigt. Im Gegensatz zu Ravels ursprünglicher Version ist es ja eben nur einer und nicht tausende.



  • Ich denke mal das dein Prg. am hacken war und der DC nicht freigegeben
    wurde, aber der Timer erneut aufgerufen wurde und ein "gleiches" DC erstellen
    wollte.
    Timer->Enabled = false;
    dein Code;
    Timer->Enabled = true;

    könnte helfen

    Ich hatte das gleiche Problem, allerdings kamm bei mir die Fehlermeldung schneller, da der Timer auf 40 steht, und ich aus den Aufnahmen eine AVI
    erstellt habe (Als Dokumentationsvideo).

    Ich habe es später (durch mehr wissen) dann so gemacht, wie Jansen schon sagte,
    das der Zugriff nur einmal erfolgt und nur CopyRect ausgefürt wird, ich verwende
    aber keinen Timer mehr sondern eine Millisekunden berechnete Schleife, so ruckelts
    nicht im AVI, mein größter Testlauf war 14 Stunden ohne Probleme.

    gruß Micha



  • Hi,

    erstmal vielen Dank an Euch alle! Ich werde die Lösungen ausprobieren sobald ich Zeit habe und Euch über das Ergebnis informieren.

    promicha: War dein Problem denn schon behoben als Du nur den "Trick" mit dem Abschalten des Timers verwendet hast?

    Gruß
    ravel



  • promicha: War dein Problem denn schon behoben als Du nur den "Trick" mit dem Abschalten des Timers verwendet hast?

    Ich hatte gleichzeitig auch alles ausgelagert was ich auslagern konnte.
    Ich hatte mal die Zeit mitgeschrieben die mein Code im OnTimer benötigte,
    und die lag über 40ms wenn ich einige Prgs. geöffnet hatte.
    Nach dem Auslagern und ->Enabled false/true lief es und er kamm nur selten
    über 40ms. Ich habe es im Nachhinein stark optimiert und wie gesagt in einer
    Schleife gepackt. Mit der Timer Variante hatte ich glaub ich so ca. 30min.
    aufgezeichnet.

    gruß Micha


Log in to reply