2010-07-06 21 views
8

Ich muss ein Formular (Delphi 2007) als Bild in die Zwischenablage kopieren, um einzufügen, was der Benutzer in einem Word-Dokument sehen kann. Der Zwischenablage-Teil ist nicht wirklich ein Problem. Die Frage ist, wie man eine Bitmap für das Formular bekommt.Wie kopiere ich ein Formular als Bild in die Zwischenablage

Die Suche hat mehrere Optionen aufgetaucht.

Alle diese Optionen scheinen verschiedene Probleme zu haben. Die meisten Informationen, die ich finde, scheinen überholt zu sein. Ich kann keine gute Quelle sein, die die verschiedenen Optionen mit genügend Details vergleicht, um eine Entscheidung zu treffen. Irgendwelche Tipps, mit welcher Option man gehen kann.

Ich habe diese auf meinem Formular versucht und sie scheinen alle zu funktionieren OK, ich versuche nur, Probleme auf der Straße zu vermeiden. Irgendwelche Tipps zu welcher Lösung?

Update: Welche potenziellen Probleme mit GetFormImage?
Andreas fragte, was das Problem mit GetFormImage ist. Hoffentlich nichts mehr, das ist Teil von dem, was ich versuche, eine Antwort zu bekommen. Was mich beunruhigt, ist, dass so viele meiner Suchergebnisse kreative Alternativen zur Verwendung von GetFormImage vorschlagen. Ich hatte gehofft, dass die Antworten die Wasser ein wenig klären würden.

Ich wäre wirklich glücklich mit einer Antwort, die viele Stimmen bekommen hat, die gesagt haben - GetFormImage hatte einige Probleme, aber es gibt keinen Grund, es jetzt nicht zu verwenden. :-)

In Bezug auf das eigentliche Problem mit GetFormImage. Ein Problem für einige Benutzer bestand darin, dass nur der sichtbare Teil des Formulars im Bild angezeigt wurde (d. H., Sie können ein verborgenes oder überlappendes Fenster nicht erfassen). Das ist nicht wirklich ein Problem für mich, da meine gesamte Form sichtbar ist.

1) Die größeren Probleme betreffen die spezifische Unterstützung, die von den Steuerelementen in Ihrem Formular benötigt wird. Die Delphi 4 Fixes and Known issues page Liste hat diesen Eintrag (beachten Sie, dass es als "Auf den nächsten verschoben" aufgeführt ist). Ich konnte kein QC Eintrag finden, dieses Problem gelöst zeigte:

Gebiet: vcl \ core vcl Klassen

Referenznummer: 1088 (Published: 12/16/98)
Status: Latente auf Next
Rel Datum des Berichts: 8/6/98 Schweregrad: häufig anzutreffTyp: Basic
Funktionalität Failure Problem:

Das Problem ist mit den meisten GetFormImage Nest Fenster Steuerelemente wie Comboboxen usw. sind leer gezogen.

2) Ich verwende auch die DevExpress-Steuerungen.Auf einmal ihre Kontrollen (behoben am Ende des Jahres 2006) did not support the PaintTo Nachrichten, die GetFormImage verwendet wurde. Dies ist in der DevExpress-Version behoben, die ich verwende, aber es wirft andere Probleme mit mir auf, was ist die Chance, dass andere Kontrolle, die ich verwende, möglicherweise nicht richtig funktioniert?

3) Hier ist eine neuere (2010) post on the Embarcadero Groups. Der Benutzer hatte Probleme, GetFormImage zu verwenden, wenn ein Teil des Diagramms, das auf dem Bildschirm angezeigt wurde, nicht im endgültigen Bild angezeigt wurde. Sie benötigten auch die Formularbeschriftung (die ich nicht) und sie nahmen den Canvas.CopyRect Ansatz outlined in this post.

4) Hier ist das Zitat von der TExcellentImagePrinter Seite. Ich hätte kein Problem, ihr Produkt bei Bedarf zu kaufen. Die Komponente sieht so aus, als ob sie 2002 zuletzt aktualisiert wurde (es gibt jedoch eine Delphi 2007-Testversion). Ich kann nicht sagen, ob ich wirklich in diese Richtung gehen muss oder nicht.

können Sie versuchen, GetFormImage oder Form.Print verwenden. Versuchen Sie, eine ComboBox in einem Formular zu löschen, und rufen Sie dann GetFormImage oder Form.Print auf. Wenn Sie einen Ausdruck erhalten, sehen Sie den Text in der ComboBox? Nein? Weder tut jemand sonst! Dies ist nur ein kleines Beispiel für die Probleme, die auftreten, wenn Drucken von VCL-Formularen.

Sie können auch versuchen, Borlands TI-3155 "Eine bessere Möglichkeit, eine Form zu drucken". Ich habe den TI geschrieben, als ich bei Borland als Stop-Gap-Maßnahme arbeitete . Während es die Combobox Text drucken, es wird auf vielen Druckern fehlschlagen, kann es nicht das gesamte Formular drucken, wenn Ihr Benutzer hat Größe geändert das Formular, und es kann keine Formulare, die aus Sicht ausgeblendet oder sind teilweise vom Bildschirm entfernt. Der Code erzeugt grundsätzlich einen Screenshot, und um ein Bild zuverlässig zu drucken, würden Sie sich wahrscheinlich unseres TExcellentImagePrinter Produkts ansehen! Warum? Einfach gesagt, kann es eine paar tausend Zeilen Low-Level- Grafik-Code erfordern, Bitmaps zum Drucken gut unter Windows zu bekommen.

+4

Was genau ist das Problem mit GetFormImage? –

+0

Ich habe die Frage aktualisiert, um meine Bedenken mit GetFormImage genauer zu beschreiben. –

+0

Ich kämpfe derzeit die Probleme von GetFormImage, Canvas.CopyRect (und alle BitBlt/StretchBlt-Variante) und PrintWindow: keiner von ihnen bekommen die tatsächlichen Sachen auf dem Formular gezeichnet. Mein Formular ist in einigen Bereichen benutzerdefiniert, und in vielen Fällen wird es ein anderes Fenster haben, so dass ich es auch im Capture finde. Wenn es mir gelingt, eine Lösung zu finden, werde ich eine Antwort posten. Beachten Sie jedoch, dass in bestimmten Szenarien, wenn Ihr Zielformular ausgeblendet, ausgeblendet oder von einem anderen Fenster verdeckt ist, keine der oben genannten Lösungen ordnungsgemäß funktioniert. – ciuly

Antwort

8

Ich weiß nicht, was das Problem mit GetFormImage ist, aber eine Option, die Sie nicht versucht haben (zumindest nicht explizit) ist

procedure TForm1.FormClick(Sender: TObject); 
var 
    bm: TBitmap; 
begin 

    bm := TBitmap.Create; 
    try 
    bm.SetSize(ClientWidth, ClientHeight); 
    BitBlt(bm.Canvas.Handle, 0, 0, ClientWidth, ClientHeight, Canvas.Handle, 0, 0, SRCCOPY); 
    Clipboard.Assign(bm); 
    finally 
    bm.Free; 
    end; 

end; 

In fast allen Fällen würde ich dies zu produzieren erwarten das gleiche Ergebnis wie

Clipboard.Assign(GetFormImage); 

obwohl. (Auch das Canvas.CopyRect Verfahren employes StretchBlt, die ich erwarten würde das gleiche Ergebnis wie BitBlt zu erzeugen, wenn keine Dehnung angewendet wird.)

Methode 2

Sie immer Print Screen verwenden können:

procedure TForm1.FormClick(Sender: TObject); 
begin 
    keybd_event(VK_SNAPSHOT, 1, 0, 0); 
end; 

Dies erfasst auch den Rahmen und die Titelleiste.Wenn Sie nur den Kundenbereich erhalten möchten, können Sie das Bild beschneiden:

procedure TForm1.FormClick(Sender: TObject); 
var 
    bm, bm2: TBitmap; 
    DX, DY: integer; 
begin 
    Clipboard.Clear; 
    keybd_event(VK_SNAPSHOT, 1, 0, 0); 
    repeat 
    Application.ProcessMessages; 
    until Clipboard.HasFormat(CF_BITMAP); 
    bm := TBitmap.Create; 
    try 
    bm.Assign(Clipboard); 
    bm2 := TBitmap.Create; 
    try 
     bm2.SetSize(ClientWidth, ClientHeight); 
     DX := (Width - ClientWidth) div 2; 
     DY := GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYSIZEFRAME); 
     BitBlt(bm2.Canvas.Handle, 0, 0, ClientWidth, ClientHeight, bm.Canvas.Handle, DX, DY, SRCCOPY); 
     Clipboard.Assign(bm2); 
    finally 
     bm2.Free; 
    end; 
    finally 
    bm.Free; 
    end; 
end; 
+0

Andreas, es gibt einige großartige Möglichkeiten, aber es lässt mich immer noch mit der Frage, welche spezifische Option zu verwenden. Da diese alle in einer Antwort sind, kann ich nicht sagen, welche Option die meisten Stimmen erhält. –

+2

Sie sollten die einfachste Methode wählen, die * für Sie * funktioniert. Wenn * Sie * in Ihrem Projekt keine Probleme mit 'GetFormImage' haben, dann verwenden Sie es auf jeden Fall! –

+0

GetFormImage funktioniert in Delphi 10.1 Berlin immer noch nicht richtig. Z.B. TRichEdit-Komponenten in meinem Formular werden nicht erfasst – DaveBoltman

Verwandte Themen