Das Notes Forum

Domino 9 und frühere Versionen => Entwicklung => Thema gestartet von: TMC am 30.03.04 - 22:03:33

Titel: RenderToRTItem in Zwischenablage
Beitrag von: TMC am 30.03.04 - 22:03:33
Hi,

ich suche eine einigermaßen elegante Möglichkeit, den kompletten Dok-Inhalt aus einer Ansicht heraus oder bei geöffnetem Dokument in die Zwischenablage zu kopieren.

Schön wäre es dabei, die RenderToRTItem - Methode benutzen zu können.

Also:

Call doc.RenderToRTItem( Clipboard )

Allerdings soll der Inhalt in der Zwischenablage landen, und per Ctrl+V in ein beliebiges RT-Feld kopierbar sein.

Ich könnte mir auch vorstellen man muss so über ein temporäres Dokument arbeiten, dort in ein RTItem den Inhalt kopieren und dann den RT-Item in die Zwischenablage (per API??) ?

Any idea?

Danke,
Matthias
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: Glombi am 30.03.04 - 22:07:11
Am einfachsten so:

@Command([EditSelectAll]);
@Command([EditCopy]);

Du musst dafür sorgen, dass das Dokument geöffnet ist. Wenn Du ansagt, aus welchem Kontext das gestartet wird, kann man den Code erweitern.
Es wird alles in die Zwischenablage kopiert, was "sichtbar für die Zwischenablage" ist.

Andreas
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: TMC am 30.03.04 - 22:12:38
Danke Andreas, daran hab ich auch schon gedacht, da müsste aber ein Forward in meinem Fall vorgeschalten werden. Also nicht sehr elegant.....

Kontext:
Z.B. klassisches Mailfile oder jede andere DB:

User markiert ein Dokument (oder eben das aktuell geöffnete), klickt auf einen Button, und hat den Inhalt in der Zwischenablage (nicht das Dok, sondern eben den Inhalt von RenderToRTItem).

Daher meine Idee, das per Script umzusetzen.

Matthias
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: TMC am 30.03.04 - 22:21:56
Nachtrag:
Mir würde auch schon eine Methodik reichen, wie ich (wohl dann per API) den Inhalt eines RT-Feldes ins Clipboard bekomme.

Für ein reines Textfeld nutze ich immer folgende Sub:
Code
Const GMEM_MOVEABLE = &H40
Const GMEM_ZEROINIT = &H2
Const CF_TEXT = &H01
Const SRCCOPY = &HCC0020

Declare Function OpenClipboard Lib "user32" Alias "OpenClipboard" (Byval hwnd As Long) As Long
Declare Function CloseClipboard Lib "user32" Alias "CloseClipboard" () As Long
Declare Function EmptyClipboard Lib "user32" Alias "EmptyClipboard" () As Long
Declare Function SetClipboardData Lib "user32" Alias "SetClipboardData" (Byval wFormat As Long, Byval hMem As Long) As Long
Declare Function GlobalAlloc Lib "kernel32" Alias "GlobalAlloc" (Byval wFlags As Long, Byval dwBytes As Long) As Long
Declare Function GlobalLock Lib "kernel32" Alias "GlobalLock" (Byval hMem As Long) As Long
Declare Function GlobalUnlock Lib "kernel32" Alias "GlobalUnlock" (Byval hMem As Long) As Long
Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (Byval lpString1 As Long, Byval lpString2 As String) As Long
Declare Function NEMGetCurrentSubprogramWindow Lib "nnotesws.dll" () As Long

Sub SetClipboardText(text As String)
   Dim hwnd As Long
   Dim hGlobalMemory As Long
   Dim lpGlobalMemory As Long
   Dim ret As Variant
   On Error Goto error_handler
   hwnd = NEMGetCurrentSubProgramWindow()
   If hwnd Then
      hGlobalMemory = GlobalAlloc(Clng(GMEM_MOVEABLE Or GMEM_ZEROINIT), Clng(Len(text)+1))
      If hGlobalMemory Then
         lpGlobalMemory = GlobalLock(hGlobalMemory)
         If lpGlobalMemory Then
            ret = lstrcpy(lpGlobalMemory, text)
            Call GlobalUnlock(hGlobalMemory)
            If OpenClipboard(hwnd) Then
               ret = EmptyClipboard()
               ret = SetClipboardData(CF_TEXT, hGlobalMemory)
               ret = CloseClipboard()
            End If
         Else
            Msgbox "Can't allocated global memory pointer.", 32, "Error"
         End If
      Else
         Msgbox "Can't allocated global memory handle.", 32, "Error"
      End If
   Else
      Msgbox "Can't get window handle.", 32, "Error"
   End If
   Exit Sub
error_handler:
   Print "Error: " + Error$(Err)
   Resume Next
End Sub
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: Glombi am 30.03.04 - 22:24:22
Wenn ich es richtig verstehe, willst Du den Inhalt eines Dokuments in die Zwischenablage kopieren. Das geht mit dem 2-zeiler, den ich gepostet habe.
Wenn Du in einer Ansicht bist, müsste das Dokument geöffnet werden -

@Command([EditDocument];"0");
@Command([EditSelectAll]);
@Command([EditCopy]);
@Command([FileCloseWindow])

Ein Forward brauchst Du nicht.

Amdreas
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: TMC am 30.03.04 - 22:27:43
Andreas, aber das kopiert nur das Body-RTFeld.

Z.B. bei einer Mail hätte ich gerne den auch den Header (Logo, An, Von, Subject, etc.). Daher war RenderToRTItem meine Idee.....

In einer anderen DB eben auch diese Felder etc.


Matthias
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: animate am 30.03.04 - 22:29:43
das ist easy, wenn du den Namen des RTFelds weißt - vor der Laufzeit.
Du brauchst ne Maske, auf der nur ein RTFeld mit diesem Namen drauf ist.
Dann machst du ne Dialogbox auf (@Dialogbox, oder so ähnlich).
Dann das, was Glombi schon geschrieben hat (Select All & Copy) und die Box wieder schließen.
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: animate am 30.03.04 - 22:32:20
mein Post bezog sich auf das eine RTFeld.
evtl geht sowas auch mit Script und mehr sophisticated.
BackendDoc erzeugen, RenderToRTItem, Dialogbox auf, Kopieren, dialogbox zu
Theoretisch auch ganz einfach. Theoretisch
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: animate am 30.03.04 - 22:34:13
Zitat
@Command([EditDocument];"0");
@Command([EditSelectAll]);
@Command([EditCopy]);
@Command([FileCloseWindow])

ich kann mich dunkel daran erinnern, dass es bei dieser Methode an bestimmten Stellen zum Absturz kam wegen eines Notes Bugs. Deshalb musste ich anno dazumal den Umweg über eine Dialogbox gehen.
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: Semeaphoros am 30.03.04 - 22:34:26
Uhm, Deine Lösung geht schon, ist sogar raffiniert, da macht man genau den von Matthias angezogenen RenderToRTItem in ein temporäres Dokument, macht dann genau das, was Du sagst und entsorgt am Schluss das temporäre Dok. Da kommt dann die gesamte Darstellung mit
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: Glombi am 30.03.04 - 22:35:44
Habe es auf die Schnelle getestet - so ginge es:

@Command([MailForward]);
@Command([EditGotoField];"Body");
@Command([EditSelectAll]);
@Command([EditCopy]);
@Command([FileCloseWindow])

Es kommt nur die eigene Signature dazu, wenn man Weiterleitet. Das kann stören.

Andreas
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: TMC am 30.03.04 - 22:39:47
Hmm, danke.

Mein Ziel ist es eigentlich, nur einen Code zu haben (z.B. in einem Agenten). Und diesen Agenten kann ich dann sowohl in einem Mailfile einsetzen (ohne eine zusätzliche Maske reinzukopieren) als auch in anderen DB's.

Daher würde ich das ganze gerne ohne weitere Masken machen.

Hintergrund:
Z.B. von einem Mailfile (MailIn) aus sollen Mail-Dokumente in andere DBs übernommen werden. Dies mache ich, indem ich Buttons bzw. Agenten zur Verfügung stelle, um Items von Mails in neue Doks in anderen DBs rüberzuschaufeln. Allerdings sind manchmal Mails dabei, für die es nicht lohnt, extra solche Skripts aufzubauen. Daher soll User einen Button haben, um die Mail so zu kopieren (mit Empfänger, Absender, Richtext  etc.), um diese dann manuell in die DB seiner Wahl in ein RTFeld zu kopieren.

Bisherige Vorgehensweise vom User: Klick auf Weiterleiten, Klicken ins Body-Feld, Strg+A, Strg+C.
Ist 1. nicht elegant, und 2. ist immer die oberste Zeile mit dabei (Diese Zeile "Forwarded on....by.... usw.".

Das ganze würde ich gerne ohne Maske realisieren, um einen Copy&Paste fähigen Code auch für andere DBs zu haben.....

Matthias
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: TMC am 30.03.04 - 22:43:18
Man soll nicht zwischenzeitlich was anderes machen....

Mein letztes Posting war bezogen auf Thomas, Datum/Zeit: Heute um 22:29:43

Matthias

Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: TMC am 30.03.04 - 22:47:28
Fazit: Erst mal danke Euch allen für die Hilfe.

Was ich gerne hätte:

Wie bekomme ich den Richtext (mit Anhängen etc.) eines RT-Items in die Zwischenablage?

Das Richtextfeld würde ich via RenderToRTItem füllen......

M.E. würde ich nur dadurch vermeiden dass
a) eine zusätzliche Maske benötigt wird
b) (wenn ich @Formel einsetze): Signatur und "Forward by...." erscheint

Sorry dass ich mich oben wohl nicht klar ausgedrückt habe.

Matthias
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: Glombi am 30.03.04 - 23:10:16
Das ist knifflig.

Ich habe es versucht mit

Dim session As New NotesSession
   Dim workspace As New NotesUIWorkspace
   Dim db As NotesDatabase
   Dim uidoc As NotesUIDocument
   Dim docA As NotesDocument
   Dim docB As NotesDocument
   Dim rtitem As NotesRichTextItem
   Dim success As Variant
   Set db = session.CurrentDatabase
   Set uidoc = workspace.CurrentDocument
   Set docA = uidoc.Document
   Set docB = New NotesDocument( db )
   Set rtitem = New NotesRichTextItem( docB, "Body" )
   docB.Form = "Memo"
   docB.Subject = "It's a picture of the document"
   Call docB.Save( True, True )                                         ' Ein oder Ausschalten
   success = docA.RenderToRTItem( rtitem )
   
   Set uidoc = workspace.EditDocument( True, docB )
   Call uidoc.GotoField("Body")
   
   Call uidoc.SelectAll
   Call uidoc.Copy   


aber es sieht zumindest unter R6 blöd aus...
Mit Call docB.Save( True, True )   wird die Signatur nicht eingesetzt, ohne schon.
Ausserdem wird mit Save immer das Dokument gespeichert.

Man könnte sich noch überlegen, eine extra DB zu erstellen, in der das Dokument gerendert wird. Dort dann keine "Schweinereien" wie Signatrue oder dergleichen einbauen...

Sorry, aber mir fällt da momentan nichts mehr ein.

Andreas
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: TMC am 30.03.04 - 23:13:57
Danke Andreas, das ist ja schon mal ein Ansatz.

Zitat
Mit Call docB.Save( True, True )  wird die Signatur nicht eingesetzt, ohne schon.

Aha, interessant.....

Werde ich morgen mal ausgiebiger testen....
Wäre ja schön, das ganze ohne API lösen zu können.

Zitat
aber es sieht zumindest unter R6 blöd aus...
RenderToRTItem sieht übrigens auch unter R5 nicht perfekt toll aus (wenn Du das meinst) aber erfüllt seinen Zweck.


Matthias
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: Glombi am 31.03.04 - 10:03:44
Wegen der Signatur. Die wird nur dann gesetzt, wenn es ein neues Dokument ist. Wenn das Dokument bereits (im Backend) gespeichert wurde, wird diese nicht mehr gesetzt.
Nachteil: Es geistern immer Dokumente herum, die man eigentlich nur temporär benötigt. Die kann man aber mit doc.Remove(true) wieder löschen - sofern man Löschrecht hat. Das muss berücksichtigt werden! Also keine Leser oder User ohne Löschrecht.

Andreas
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: TMC am 31.03.04 - 21:26:21
Danke, Andreas.

Leider existiert noch ein Bug in R5:
http://www.atnotes.de/index.php?board=7;action=display;threadid=12514;start=0

Beim Ausführen Deines Codes - auch noch einiges von mir modifiziert (u.a. auch ein erneutes save nach docA.RenderToRTItem( rtitem )) stürzt der Client ab mit der RBOD.

Problem ist, dass der Cursor im Betreff stehen bleibt.

Ich denke, es bleibt wohl wirklich nur Deine Formel:
@Command([MailForward]);
@Command([EditGotoField];"Body");
@Command([EditSelectAll]);
@Command([EditCopy]);
@Command([FileCloseWindow])


Grüße,
Matthias
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: Glombi am 01.04.04 - 08:01:13
Ich hatte es nur in R6 probiert, da ist der Bug offenbar behoben...
Allerdings sah das Ergebnis unschön aus, daher mein Hinweis.

Andreas
Titel: Re:RenderToRTItem in Zwischenablage
Beitrag von: TMC am 01.04.04 - 21:29:04
Jo, ich hatte auch im Web recherchiert, aber ohne Erfolg.

RenderToRTItem kann von der Logik her auch nicht direkt ins Windows Clipboard erfolgen (logisch: mit den Daten kann Windows so nix anfangen - da muss der Umweg über ein Item gewählt werden).

Und Zeilen von einem Richtextfeld einfach so zu entfernen (also Sig, "---- forwarded .... ----" etc.) ist wohl auch ohne 3rd Party nicht möglich.

Ich hake das jetzt mal als "wäre zwar schick gewesen, aber geht nicht so einfach" ab.

Grüße,
Matthias