Reputation: 15404
I am using OLE Search Replace to replace "placeholder tags" with content stored in db fields into a Word docuemnt. I use a technique similar to what disussed here.
THis works but of course it doesn't for rtf fields. I have db fields containing rtf data and if a do search replace I will get the full rtf code, so instead of seeing
Hello World
I see something like
{\rtf1\ansi\ansicpg1252\deff0\deflang1040 \viewkind4\uc1\pard\sa200\sl276\slmult1\lang16\b\f0\fs22 Hello \i World\b0\i0\par }
Did anyone already solved the problem? Searching on StackOverflow I found a trick that uses the clipboard. Note: I don't use bookmarks, this example uses bookmarks, I simply have my tags defined as plain text like '' and when I find '' in my search and replace loop I replace the text.
UPDATE: Do you see any prolem in this clipboard trick?
Do you have other ideas and can suggest other solutions?
Upvotes: 3
Views: 3666
Reputation: 125757
Here's a post I saved from ages ago. It was posted by Dr. Peter Below of TeamB to the old Borland Delphi newsgroups, but it's still applicable today. It shows how to use the EM_STREAMIN
and EM_STREAMOUT
messages and related callback to put RTF text into and copy out of a TRichEdit
.
Uses RichEdit;
Type
TEditStreamCallBack = function (dwCookie: Longint; pbBuff: PByte;
cb: Longint; var pcb: Longint): DWORD; stdcall;
TEditStream = record
dwCookie: Longint;
dwError: Longint;
pfnCallback: TEditStreamCallBack;
end;
function EditStreamInCallback(dwCookie: Longint; pbBuff: PByte;
cb: Longint; var pcb: Longint): DWORD; Stdcall;
var
theStream: TStream;
dataAvail: LongInt;
begin
theStream := TStream(dwCookie);
with theStream do begin
dataAvail := Size - Position;
Result := 0; {assume everything is ok}
if dataAvail <= cb then begin
pcb := Read(pbBuff^, dataAvail);
if pcb <> dataAvail then //couldn't read req. amount of bytes
result := E_FAIL;
end
else begin
pcb := Read(pbBuff^, cb);
if pcb <> cb then
result := E_FAIL;
end;
end;
end;
Function EditStreamOutCallback(dwCookie: Longint; pbBuff: PByte;
cb: Longint; var pcb: Longint): DWORD; stdcall;
var
theStream: TStream;
begin
theStream := TStream(dwCookie);
with theStream do begin
If cb > 0 Then
pcb := Write(pbBuff^, cb);
Result := 0;
end;
end;
Procedure GetRTFSelection( aRichEdit: TRichEdit; intoStream: TStream );
Var
editstream: TEditStream;
Begin
With editstream Do Begin
dwCookie:= Longint(intoStream);
dwError:= 0;
pfnCallback:= EditStreamOutCallBack;
end;
aRichedit.Perform( EM_STREAMOUT, SF_RTF or SFF_SELECTION, longint(@editstream));
End;
Procedure PutRTFSelection( aRichEdit: TRichEdit; sourceStream: TStream );
Var
editstream: TEditStream;
Begin
With editstream Do Begin
dwCookie:= Longint(sourceStream);
dwError:= 0;
pfnCallback:= EditStreamInCallBack;
end;
aRichedit.Perform( EM_STREAMIN, SF_RTF or SFF_SELECTION, longint(@editstream));
End;
Upvotes: 0
Reputation: 1364
I would suggest to use the Selection.InsertFile instead. Here is an example that shoud do what you want, it finds "placeholder" and inserts a rtf file. Save your rtf to a temp-file before...
procedure TForm1.Button1Click(Sender: TObject);
var
Fword,FDocument,FFindObject:OleVariant;
Filename:String;
begin
Filename := 'C:\temp\test.doc';
Fword := CreateOleObject('Word.Application');
FDocument := Fword.Documents.Add(Filename);
FFindObject := FDocument.ActiveWindow.Selection.Find;
Fword.visible := true;
FFindObject.ClearFormatting;
FFindObject.Replacement.ClearFormatting;
FFindObject.Text := 'placeholder';
FFindObject.Forward := True;
FFindObject.Replacement.Text := '';
FFindObject.Wrap := 1;
FFindObject.MatchCase := False;
FFindObject.MatchWholeWord := False;
FFindObject.MatchWildcards := False;
FFindObject.MatchSoundsLike := False;
FFindObject.MatchAllWordForms := False;
if FFindObject.Execute() then Fword.selection.InsertFile('C:\temp\test.rtf')
end;
Upvotes: 1