Autor |
Beitrag |
maniask
Hält's aus hier
Beiträge: 7
|
Verfasst: Mo 15.03.10 16:30
Hallo,
ich möchte gerne mit einer WPF-Anwendung einen Screenshot machen, allerdings ohne das oben liegende Programmfenster. Das Fenster soll dabei die ganze zeit sichtbar bleiben, also weder unsichtbar gemacht noch kurz minimiert werden. Hat jemand eine Idee wie das möglich ist? Vielleicht irgendwie über den Z-Index bzw. die Z-Order?
Danke schonmal!
|
|
JüTho
      
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Mo 15.03.10 16:51
Hallo,
da WPF eine andere Technologie verwendet, von der ich keine Ahnung habe, kann es sein, dass ich mit meiner Antwort daneben liege. Aber für Windows gilt eigentlich:
Ein Screenshot kann nur das aufnehmen, was auf dem Bildschirm gezeichnet wird. Was nicht sichtbar ist, muss von Windows nicht gezeichnet werden, kann also auch nicht im Screenshot enthalten sein. Das betrifft z.B. minimierte Fenster, Bereiche außerhalb des Screens, nicht sichtbare Teile eines Grids oder eben verdeckte Fenster.
Gruß Jürgen
|
|
bakachan
      
Beiträge: 503
Erhaltene Danke: 34
W7 (x64) Ultimate
C# / VB.NET (VS2010 Ultimate)
|
Verfasst: Mo 15.03.10 17:08
Ich denke er möchte einfach einen Screenshot machen ohne das sein Program in den Vordergrund kommt.
Allerdings kenne ich mich mit WPF/Silverlight nicht gut aus.
Für eine normale Win-Forms-Anwendung wäre das erste was mir auf Anhieb einfällt ein Global Hotkey.
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Mo 15.03.10 17:42
Hallo,
ich fand das Thema interessant und hab deshalb gegoogelt und bin auf den Artikel "Image aus einem WPF-Control erzeugen" gestoßen.
Ich denke das ist genau das was du benötigst. Bei mir funktioniert es einwandfrei
Gruß Daniel
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mo 15.03.10 19:22
Wie Jürgen schon sagte, hat das hier nichts mit WPF zu tun  . Und ich sage einfach mal, dass die Einschränkung maniask hat folgendes geschrieben : | Das Fenster soll dabei die ganze zeit sichtbar bleiben, also weder unsichtbar gemacht noch kurz minimiert werden. |
nicht erfüllt werden kann. Man könnte umständlich über WM_PRINT alle Fenster einzeln zeichnen, aber spätestens Aero schlägt einem dabei ein Schnippchen.
_________________ >λ=
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Mo 15.03.10 19:33
Naja, ich denke nicht, dass er einen Screenshot machen will, sondern eben den Inhalt des anderen Formulares abspeichern will. Deshalb den Ansatz über das FE rendern.
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Di 16.03.10 00:22
Falls ich etwas falsch interpretiert habe, entschuldige ich mich, aber für mich klingt das doch sehr danach, dass er einen Screenshot des Desktops exklusive der eigenen Anwendung machen will. Warten wir mal ab  .
_________________ >λ=
|
|
maniask 
Hält's aus hier
Beiträge: 7
|
Verfasst: Di 16.03.10 09:30
Erstmal danke für eure Antworten! Leider gab es hier wohl ein paar Missverständnisse.
Kha, du hast das eigentlich schon richtig verstanden, ich möchte
Kha hat folgendes geschrieben : | einen Screenshot des Desktops exklusive der eigenen Anwendung |
machen.
Ich denke es ist besser mein ganzes Problem genauer zu beschreiben, vielleicht kann man meinen Lösungsansatz mit dem Screenshot so ja gar nicht umsetzen.
Bei meiner WPF-Anwendung zieht man ein Fenster über den Bildschirm und lässt sich den dahinterliegenden Bildausschnitt mit einem Farbfilter umwandeln. Das umgewandelte Bild wird in einem Image im Fenster dargestellt. Das Programm läuft unter Windows XP ohne Probleme. Unter Windows Vista und Windows 7 erscheint in dem Fenster jedoch immer ein Bild vom vorherigen umgewandelten Bild. Ich habe das selbe nochmal mit WindowsForms programmiert, diese Anwendung läuft auch problemlos unter Vista und 7. Desweiteren habe ich herausgefunden, dass WPF-Anwendungen unter XP in einem WindowsForms-Container laufen und deshalb mein Problem dann auch nicht auftritt.
Unter diesem Aspekt denke ich übrigens auch, dass das Thema doch sehr viel mit WPF zu tun hat.
Ich habe auch schon versucht das Image in einem zweiten Thread während des "CopyFromScreen" unsichtbar zu machen, das führt allerdings zu unschönem Ruckeln, außerdem soll das Bild beim Verschieben ja sichtbar bleiben. Da hatte ich nur noch die Idee mit dem Screenshot hinter dem Fenster...
Es gibt doch auch Lupen oder ähnliches, die man über den Bildschirm ziehen kann und der dahinterliegende Ausschnitt wird problemlos umgewandelt.
Ich hoffe, dass mir jetzt jemand mit dieser etwas ausführlicheren Beschreibung besser helfen kann.
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Di 16.03.10 10:40
Der Punkt geht wohl (mal wieder) an Kha. Dann hab ich es wohl falsch verstanden, sorry.
Weiß dann auch nicht weiter, ... it's your turn 
|
|
maniask 
Hält's aus hier
Beiträge: 7
|
Verfasst: Di 16.03.10 12:54
Weiß denn vielleicht jemand welcher Unterschied zwischen WindowsForms und WPF dafür verantwortlich ist, dass es bei WindowsForms funktioniert und bei WPF nicht mehr?
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Di 16.03.10 19:31
maniask hat folgendes geschrieben : | Ich denke es ist besser mein ganzes Problem genauer zu beschreiben, vielleicht kann man meinen Lösungsansatz mit dem Screenshot so ja gar nicht umsetzen. |
Gut, so langsam kommen wir der Sache doch ein bisschen näher. Aber was mir noch nicht klar ist: Wie schaffst du es denn zumindest in der Winforms-Anwendung, an den vom Fenster verdeckten Bildausschnitt zu kommen?
_________________ >λ=
|
|
maniask 
Hält's aus hier
Beiträge: 7
|
Verfasst: Di 16.03.10 21:27
Das funktioniert komischerweise von ganz alleine.
Hier ein kleines Winforms Beispielprogramm, welches ich zum testen benutzt habe:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52:
| using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO;
namespace farbenTest { public partial class Form1 : Form {
private Bitmap _Bmp;
public Form1() { InitializeComponent(); }
private void ConvertScreenshot() {
GetBitmap(); _Image.Image = (Image)_Bmp; _Image.Visible = true;
}
private void GetBitmap() {
_Bmp = new Bitmap(Convert.ToInt32(_Image.Width), Convert.ToInt32(_Image.Height)); Graphics g = Graphics.FromImage(_Bmp); g.CopyFromScreen(Convert.ToInt32(Left), Convert.ToInt32(Top), 0, 0, new System.Drawing.Size(_Bmp.Width, _Bmp.Height));
}
private void Form1_LocationChanged(object sender, EventArgs e) { _Image.Visible = false; ConvertScreenshot(); }
}
} |
Wenn man das gleiche mit WPF programmiert gibt es wieder ein Bild im Bild im Bild....
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Di 16.03.10 22:02
Hm, ich nehme an, das sieht bei dir anders aus  ?
Ich glaube fast, du hattest bisher einfach "Glück", kannst dich auf dieses Verhalten aber nicht verlassen.
Einloggen, um Attachments anzusehen!
_________________ >λ=
|
|
maniask 
Hält's aus hier
Beiträge: 7
|
Verfasst: Mi 17.03.10 09:14
Nee, bei mir sieht das genauso aus, soll es ja auch. Das Image zeigt eben nur einmal das Fenster.
Das gleiche mit WPF würde so aussehen:
Fenster im Fenster im Fenster....
Das WindowsForms-Programm ist ja nur zum testen, zeigt also noch nichts sinnvolles an.
|
|
JüTho
      
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Mi 17.03.10 10:02
Ganz nebenbei:
C#-Quelltext 1:
| _Bmp = new Bitmap(Convert.ToInt32(_Image.Width), Convert.ToInt32(_Image.Height)); |
Wozu diese "Konvertierungen"? Mir liegt das Wort "Quatsch" auf der Zunge, denn Width und Height sind doch schon Integers. Also schreib bitte kürzer:
C#-Quelltext 1:
| _Bmp = new Bitmap(_Image.Width, _Image.Height); |
Dabei geht es mir nicht nur um "Schönheit" des Codes. Eine derart abwegige Verwendung von Convert deutet darauf hin, dass du über Datentypen und Typgenauigkeit überhaupt nicht nachdenkst oder es nicht verstanden hast. Da .NET aber genau auf die Typen achtet, musst du das auch. Insofern bitte ich meinen Änderungsvorschlag nicht als Beckmesserei zu verstehen, sondern als Anregung für eine sorgfältigere Arbeit.
Zur Sache selbst kann ich nicht mehr sagen als in meinem allerersten Beitrag, deshalb schweige ich dazu.
Gruß Jürgen
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Mi 17.03.10 11:04
Hallo Jürgen,
das passt in dem Fall nicht. Bei dem _image handelt es sich um das WPF Control Image und jedes WPF Control hat eine Höhe/Breite als double. Dementsprechend muss er an dieser Stelle die Konvertierung machen.
Gruß Daniel
|
|
maniask 
Hält's aus hier
Beiträge: 7
|
Verfasst: Mi 17.03.10 11:11
Ihr habt beide Recht! Hatte mir den Code nur aus meiner ursprünglichen WPF-Anwendung schnell zusammenkopiert. Bei der WPF-Imagegröße ist eine Konvertierung nötig, bei der WinForms-Anwendung nicht.
Ist aber jetzt eigentlich auch egal, darum geht es bei meinem Problem nämlich nicht.
Danke aber für den Hinweis! Da muss ich wohl meine Aufmerksamkeit noch ein wenig schulen, damit mir sowas auch sofort ins Auge springt. Ich sehe ein, dass solche Dinge auch in Testfällen wichtig sind.
|
|
JüTho
      
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Mi 17.03.10 11:40
@Daniel
Ach je, wenn die Controls bei gleichem Namen sich so unterschiedlich verhalten, dann sollte ich bei WPF auch keine allgemeinen Hinweise geben.
@maniask
Entschuldigung! Aber Convert stört mich generell; ich finde, dann sollte es wenigstens so aussehen:
C#-Quelltext 1:
| _Bmp = new Bitmap((int)_Image.Width, (int)_Image.Height); |
Das kann man zwar als Geschmackssache ansehen; aber wenn ich sehe, wie oft Convert falsch oder überflüssigerweise verwendet wird, bin ich animiert, das zu ändern - auch wenn ich (wie hier) danebenliege.
Aber jetzt habe ich euch lang genug vom eigentlichen Problem abgelenkt. Soll nicht wieder vorkommen! Jürgen
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mi 17.03.10 19:55
maniask hat folgendes geschrieben : | Nee, bei mir sieht das genauso aus, soll es ja auch. |
Jetzt verstehe ich gar nichts mehr  . Ich dachte, es geht darum, den Ausschnitt hinter dem Fenster und nicht das Fenster selbst aufzunehmen  Oder ist das Fenster dann unsichtbar und nur das Image sichtbar?
Wie auch immer, das war wohl tatsächlich reines Glück mit GDI, mit WPF+DWM wird es ohne Flimmern so wohl nicht funktionieren.
_________________ >λ=
|
|
maniask 
Hält's aus hier
Beiträge: 7
|
Verfasst: Do 18.03.10 09:00
Ich glaube auch, dass ich aufgeben muss. Nachdem ich nun das Intenet durchforstet habe, auf der Suche nach ähnlichen Programmen, z.B. diverse Bildschirmlupen, habe ich festgestellt, dass niemand dieses Problem lösen konnte. Bei vielen erscheint unter Windows 7 auch das blöde Bild im Bild, andere lassen sich von vornherein den Ausschnitt neben dem Fenster umwandeln, wieder andere machen beim aktivieren des Fensters einen Screenshot vom ganzen Bildschirm und lassen sich von diesem Bild Ausschnitte umwandeln. Bei der letzten Methode bleibt dann allerdings die Systemzeit stehen und wenn sich der Desktophintergrund ändert sieht es völlig gruselig aus etc..
Schade, dass es sich nicht so umsetzen lässt, wie ich mir das gewünscht hätte, nun bleibt mir nichts anderes übrig als die beste Alternative zu finden.
Vielen Dank für Eure nette Hilfe, ich denke ich werde jetzt öfters in diesem Forum vorbeischauen, vielleicht kann ich ja auch mal jemandem helfen.
Gruß Anna
|
|