PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C#: Automatische Screenshots


Tom Servo
2003-10-10, 18:59:28
Hallo,

möchte von meinem Programm eine Reihe von Screenshots automatisch anfertigen, welche verschiedene Zustände des Programms darstellen.

Wollte es über eine interne Funktion machen, welche die GUI entsprechend einstellt und dann einen Shot macht. Das Problem ist nur, die Shots nicht zu früh zu machen, wenn die GUI noch nicht alle Änderungen darstellt. Ich denke man müsste einen Teil des Codes über Events aufrufen. Mit meinem jetztigen Code bekomme ich oft Screenshots die die GUI mitten im Umbau zeigen.

Wie könnte man das am einfachsten synchronisieren?



void dev_make_screenshots() {
Image img;

tabCtrl.SelectedTab = tab_main;
img = GetScreenShot(this);
img.Save("shot_main.png", System.Drawing.Imaging.ImageFormat.Png);

tabCtrl.SelectedTab = tab_extra_d3d;
img = GetScreenShot(this);
img.Save("shot_extra3d.png", System.Drawing.Imaging.ImageFormat.Png);

tabCtrl.SelectedTab = tab_extra_ogl;
img = GetScreenShot(this);
img.Save("shot_extra_ogl.png", System.Drawing.Imaging.ImageFormat.Png);

tabCtrl.SelectedTab = tab_summary;
img = GetScreenShot(this);
img.Save("shot_extra_summ.png", System.Drawing.Imaging.ImageFormat.Png);

tabCtrl.SelectedTab = tab_clocking;
img = GetScreenShot(this);
img.Save("shot_extra_clocking.png", System.Drawing.Imaging.ImageFormat.Png);
}

ethrandil
2003-10-10, 19:23:21
ich kann zwar nur c#, aber in java würd ich einfach etwas warten, bis der aufbau abgeschlossen ist ...
(evtl. mit nem timer)

Tom Servo
2003-10-10, 19:38:20
Danke für die Antwort.

Wollte ich auch erst so machen. Einfaches Warten geht leider nicht, weil die Forms-GUI single threaded ist (STA).

Vielleicht mit einer speziellen Wartefunktion, aber mit dem normalen Thread.Sleep() passiert während der Wartezeit nichts.

Das mit dem Timer ginge wohl, aber wäre dann fast so kompliziert wie gleich die richtigen Events zu nehmen. Leider weiss ich nicht, welchen Event ich da nehmen müsste.

Demirug
2003-10-10, 21:39:13
Das mit Sleep nichts passiert ist logisch. Aufgrund des Sleeps wird ja die Nachrichtenwarteschlange nicht weiter abgearbeitet. Sleep sollte man deswegen grundsätzlich nicht in einem Thread benutzten welcher das User Interface bearbeitet.

Ein Timer ist auch nicht unbedingt das richtige weil der Zeitpunkt des Events etwas unbestimbar ist.

Das was du brauchst ist eine Methode welche an einem beliebigen Punkt innerhalb des Programms die Nachrichtenwarteschlange abarbeitet und damit die UI aktualisierst. Schau mal unter Application.DoEvents nach.

Tom Servo
2003-10-10, 22:42:16
Vielen Dank, hat geklappt. Kann ich jetzt mehrsrpachige Screenshots auf meine Webseite machen und die aktuell halten ohne nennenswerten Zeitaufwand. :)

DoEvents() funktioniert wunderbar. Damit spare ich mir eine Menge Experimente und der Code ist auch optimal, da alles in einer Funktion ohne Callbacks. Warum es mit Thread.Sleep() nicht ging, war schon klar, aber man kann m.E. Application.DoEvents() auch als spezielle Wartefunktion ansehen.

Die Nachteile des Timers sind klar, aber wenn es damit deutlich einfacher gewesen wäre, dann hätte man es unter Aufsicht trotzdem nutzen können.


void dev_make_screenshots() {
Image img;

tabCtrl.SelectedTab = tab_main;
Application.DoEvents();
img = GetScreenShot(this);
img.Save("shot_main.png", System.Drawing.Imaging.ImageFormat.Png);

tabCtrl.SelectedTab = tab_extra_d3d;
Application.DoEvents();
img = GetScreenShot(this);
img.Save("shot_extra3d.png", System.Drawing.Imaging.ImageFormat.Png);

tabCtrl.SelectedTab = tab_extra_ogl;
Application.DoEvents();
img = GetScreenShot(this);
img.Save("shot_extra_ogl.png", System.Drawing.Imaging.ImageFormat.Png);

tabCtrl.SelectedTab = tab_summary;
Application.DoEvents();
img = GetScreenShot(this);
img.Save("shot_extra_summ.png", System.Drawing.Imaging.ImageFormat.Png);

tabCtrl.SelectedTab = tab_clocking;
Application.DoEvents();
img = GetScreenShot(this);
img.Save("shot_extra_clocking.png", System.Drawing.Imaging.ImageFormat.Png);
}