PrintWindow-Bitmap unterscheidet sich von PrintScreen Key-Bitmap

8

Wenn Sie ein Fenster manuell mit der Schlüsselkombination Print Screen + Alt erfassen, bekomme ich Folgendes:

Aber wenn ich versuche, es programmgesteuert zu tun, Windows API , bekomme ich das:

Warum die Diskrepanz? Wie bekomme ich das erste programmatisch?

Hier ist mein Code:

%Vor%

Aktualisierung: Es mit BitBlt macht das gleiche.

Hier ist Code von CodeProject gibt immer noch ein schwarz maskiertes Bild zurück:

%Vor%

Ich habe viele Kombinationen von CopyPixelOperation ausprobiert (irgendwo rund 15.000 von den 131.000), aber es funktioniert immer noch nicht.

Unter Windows 8 AMD Radeon HD 6870.

Update 2

Es scheint, dass das Fenster transparent ist und die blaue Farbe des Fensters durchbluten lässt. Wenn ich die Fensterfarbe in Schwarz ändere (mit dem Windows-Personalisierungsdialog), bekomme ich ungefähr etwas Ähnliches wie das zweite Fenster. Die Grenze fehlt allerdings noch.

Ich habe keine Lösung gefunden, aber es ist ein Einblick in das Problem.

    
Jason 03.05.2013, 03:16
quelle

3 Antworten

8

Der Grund, dass PrintWindow nicht funktioniert, ist, dass es auf die korrekte Handhabung von WM_PRINT Nachricht von der App. Viele Apps sind mit WM_PRINT flockig und implementieren es nicht richtig oder testen es nie. Es ist daher eine schlechte Idee, sich darauf zu verlassen, es sei denn, Sie verwenden es nur in bekannten und getesteten Apps.

Wenn Sie das Fenster, wie es auf dem Bildschirm angezeigt wird, aufnehmen möchten, blättern Sie es einfach über das Desktop-Fenster ( GetDesktopWindow () ) und nur das rect, das das Fenster enthält.

Transparenz ist ein Problem beim Fenstergreifen. Es ist unmöglich, moderne Windows OS-Fenster zu erfassen, da es keinen Bilddateityp gibt, der die Unschärfe unterstützt, wie das Verwischen der zugrunde liegenden Bilder. Es ist jedoch möglich, einfache Transparenz in eine PNG-Datei zu erfassen.

Seien Sie vorsichtig bei der Annahme, dass ein Fenster auf dem Bildschirm am besten aussieht. Abhängig davon, was darunter liegt, ist dies möglicherweise nicht wahr. Es kann auch eine schlechte Idee sein, das darunterliegende Bild zu kopieren, da es nicht gerechtfertigt ist, dass es im Bild erscheint, wie ein explizites Hintergrundbild, das in einer Geschäftspräsentation unter einem Screenshot von Excel erscheint.)

Wenn Sie vom Desktop aus blättern, kopieren Sie das, was Sie auf dem Bildschirm sehen, einschließlich aller überlagerten Fenster und darunter liegenden Fenster (wo transparent). Es wird normalerweise als "sauberer" angesehen, nur das Fenster zu greifen, wie bei PrintWindow, aber Sie können dies auf einem Hintergrund Ihrer Wahl, wie Weiß oder Blau, zusammensetzen. Wenn Sie vom Bildschirm bluten möchten, gibt es Möglichkeiten, Fenster, die Ihr Ziel überlagern, vorübergehend zu verstecken, aber es ist eine Menge Arbeit mit EnumWindows und so.

Das korrekt ist in Windows keine leichte Aufgabe und es gibt viele Screen-Grab-Apps, die miteinander konkurrieren, weil sie genau mit diesem Problem umgehen. Außerdem gibt es in Windows mehrere Möglichkeiten, um Bereiche von Fenstern transparent zu machen, und sie können auch zusammen verwendet werden.

Auch in Vista + gibt es die DWM-Miniatur-API , mit dem Sie eine Kopie eines App-Fensters auf Ihrem Fenster erhalten können. Eine Demo und eine Quelle finden Sie unter ShareX (früher zScreen).

Schließlich können Sie sich die Quelle der Open Broadcaster-Software ansehen, in der Direct3D zum Screen-Grabbing verwendet wird.

    
DDS 12.05.2013 00:44
quelle
3

Der Grund dafür, dass das Bild Alt+PrntScrn anders aussieht, ist, dass es nicht tatsächlich einen Schnappschuss des ausgewählten Fensters macht - es erstellt einen Schnappschuss von etwas wie dem Desktop-Fenster, aber schneidet den entsprechenden Teil aus.

Um dies zu beweisen, nehmen Sie ein Immer-oben-Fenster wie den Task-Manager und positionieren Sie es so, dass es das Fenster überlagert, das Sie als Snapshot erstellen. Sie werden sehen, dass beide Fenster im Snapshot enthalten sind. Während ein Aufruf von PrintWindow nur das angegebene Fenster zurückgibt.

Wenn Sie also Alt+PrntScrn exakt emulieren möchten, müssen Sie BitBlt vom Desktop ausführen. Etwas wie das:

%Vor%

Ich errate die Syntax hier anhand Ihres Beispielcodes. Die Raw-Windows-API-Aufrufe würden wie folgt aussehen:

%Vor%

Das funktioniert zumindest für mich. Wenn Sie Probleme haben, den Rest von hier herauszufinden, lassen Sie es mich in den Kommentaren wissen.

    
James Holderness 11.05.2013 22:02
quelle
1
  

"Warum die Diskrepanz? Wie bekomme ich die erste programmatisch?"

BitBlt vs PrintWindow

    
kero 05.05.2013 01:07
quelle

Tags und Links