This is the code that I am using. I have altered by your advice, and I have tested it. It works as good as what I had already been using. So I suppose that I can use it and be more modern.
However, I have gone back to compiler 2.0.10, and operating in 32 bit format, which does not choke on my older code nor your changes to it. Curiously, even compiler 2.0.12 chokes on my older code, so it might date when things have become so complicated.
//========================= begin: stream callback for Get/PutRTFselection
// by Peter Below (TeamB) < 100113.1...@compuserve.com >
// Stream Callback function
//
type
TEditStreamCallBack = function(dwCookie:PtrUInt; pbBuff:PByte; // PtrUInt = DWord = LongWord
cb:Longint; var pcb:Longint
):DWORD; stdcall;
// ):DWORD_Ptr or PtrUInt for ansistring *was* ):Longint for widestring
TEditStream = record
dwCookie:LongInt; // PtrUInt;
dwError:Longint;
pfnCallback:TEditStreamCallBack;
end;
// Callback function for EM_STREAMOUT ... by the TEAM
//
function EditStreamOutCallback(dwCookie:PtrUInt; pbBuff:PByte;
cb:Longint; var pcb:Longint):DWORD; stdcall;
// ):DWORD for ansistring *was* ):Longint for widestring
// TMemoryStream; // TStream;
begin
// This will write the contents of the Richmemo OUT to a TMemoryStream field.
//
// dwCookie is Application-defined, so we're passing the blob stream.
//
pcb:= TMemoryStream(dwCookie).Write(pbBuff^, cb); // TMemoryStream // TStream
Result:= 0;
end;
// Callback function for EM_STREAMIN
//
function EditStreamInCallback(dwCookie:PtrUInt; pbBuff:PByte;
cb:Longint; var pcb:Longint):DWORD; stdcall;
var // ):DWORD for ansistring *was* ):Longint for widestring
theStream: TMemoryStream; // try TMemoryStream instead of TStream.
begin
// This will write the contents of a TStream field IN to a Richmemo.
//
// dwCookie is Application-defined, so we're passing the stream containing
// the formatted text to be added.
//
theStream:= TMemoryStream(dwCookie);
Result:= 0;
with theStream do
begin
if (Size - Position) <= cb then
begin
pcb:= Size;
Read(pbBuff^, Size);
end
else begin
pcb:= cb;
Read(pbBuff^, cb);
end;
end;
end;
// copyout Stream from RichEdit: uses stream callback above
//
Procedure GetRTFSelection(Amemo:TRichMemo; IntoStream:TMemoryStream); // TStream);
Var EditStream: TEditStream;
Begin
with EditStream do
Begin
dwCookie:= Longint(IntoStream);
dwError:= 0;
pfnCallback:= @EditStreamOutCallBack; // get OUT FROM stream
end;
Amemo.Perform(EM_STREAMOUT, SF_RTF or SFF_SELECTION, longint(@EditStream));
End;
// Insert Stream into RichEdit: uses stream callback above
//
procedure PutRTFSelection(Amemo:TRichMemo; SourceStream:TMemoryStream); // TStream);
var EditStream: TEditStream;
begin
with EditStream do
begin
dwCookie:= Longint(SourceStream);
dwError:= 0;
pfnCallback:= @EditStreamInCallBack; // put IN to stream
end;
Amemo.Perform(EM_STREAMIN, SF_RTF or SFF_SELECTION, Longint(@EditStream));
end;
//=================================== end: stream callback for Get/PutRTFselection
How the code works is that I select anything or everything that is in an RTF document, and then call to MnuSaveSelectionClick(Sender: TObject).
procedure TCmdForm.SaveSelection; // PageMemo to New TabPage
var MS: TMemoryStream; // TMemoryStream;
// TMemoryStream is a TStream descendant that stores its data in memory.
// TMemoryStream self-handles all allocation and destroying of memory.
// When the stream is freed, all allocated memory will also be freed.
begin // PageMemo range must already be selected
MS:= TMemoryStream.create; // TMemoryStream.Create; //MS:= TStringStream.create;
try
GetRTFSelection(PageMemo,MS); // stores selection as MS
PageMemo.SelLength:= 0;
MS.Position:= 0;
btnNewClick(Self);
PageMemo.SetFocus;
PutRTFSelection(PageMemo,MS); // copy/paste MS to Untitled
PageMemo.SelLength:= 0; //PageMemo.SetFocus;
finally
MS.Free;
end;
end;
procedure TCmdForm.MnuSaveSelectionClick(Sender: TObject);
begin
if PageTabControl.PageCount>0 then
begin
if PageMemo.SelLength>0
then SaveSelection // ReportPageTab;
else showmessage('Nothing selected.');
end else showmessage('No active document.');
end;
This opens a new TabSheet and copies the selected to it. It is just a convenience for saving (on the fly) the content in a document that I have decided to edit. ie. rewrite. So that I can restore the section if my editing doesn't get me anywhere. It's a book.
Given all the trouble that I have encountered by upgrading to the latest compiler version, I may not reinstall it. There could be other 64bit problems that I don't know about yet. Meanwhile, I only want to get my work finished.
Unfortunately, even with version 2.0.10 I now have a problem importing images into the document ... because I am forced to use Online Package Manager to install RichMemo, instead of just installing from a disk package. It seems that graphic functions have been modified, and images are currently imported at too large of a scale (about double size).
Do you know anything about that? I would really like to get that fixed.
Rick