I understand that a RichEdit component is supposed to display a RTF file. I
saved a Word document containing images and other objects as an RTF file.
However when I load the file into a RichEdit component using the
Lines.LoadFromFile method, I get the formatted text but the embedded images
and objects are omitted. Can anyone advise whether there is a way to set up
the RichEdit component to enable it to handle embedded objects? I note that
the Win32 API help files state that
"The text can be assigned character and paragraph formatting, and can
include embedded OLE objects."
I am also considering using HTML instead of RTF for the formatted document.
Is there a native Delphi Win32 vcl component that can display HTML files,
and fetch them from a directory directly without using an internet server?
Thanks,
Enquiring Mind
> Hi,
Hi!
> I understand that a RichEdit component is supposed to display a RTF
> file. I saved a Word document containing images and other objects as
> an RTF file. However when I load the file into a RichEdit component
> using the Lines.LoadFromFile method, I get the formatted text but the
> embedded images and objects are omitted. Can anyone advise whether
> there is a way to set up the RichEdit component to enable it to
> handle embedded objects? I note that the Win32 API help files state
> that "The text can be assigned character and paragraph formatting,
> and can include embedded OLE objects."
I guess the VCL RichEdit do not support RTF V2, that supports embedded
images. I suggest you to use the Jedi JVCL RichEdit as a Free solution
or use other from other component vendor, I had used Infopower in the
past and if a need today Ill use the Jedi one.
> I am also considering using HTML instead of RTF for the formatted
> document. Is there a native Delphi Win32 vcl component that can
> display HTML files, and fetch them from a directory directly without
> using an internet server?
TWebBrowser
--
[]s
Cesar Romero
> I guess the VCL RichEdit do not support RTF V2, that supports embedded
> images. I suggest you to use the Jedi JVCL RichEdit as a Free solution
> or use other from other component vendor, I had used Infopower in the
> past and if a need today Ill use the Jedi one.
>
I guess that because TRichEdit wraps the Windows native RichEdit component,
the full functionality of the Windows component should be accessible (under
Windows XP SP2 or later versions), because it's the Windows component that's
doing the work of rendering the data. Now if I open the RTF file containing
images and equations that I mentioned in my previous post using Wordpad, the
images and equations are correctly rendered. I don't know whether or not
Wordpad uses the Windows RichEdit component to render an RTF file, but the
very basic nature of the user interface would seem to suggest so.
> TWebBrowser
Thanks for that.
Regards,
EM
> > I guess the VCL RichEdit do not support RTF V2, that supports
> > embedded images. I suggest you to use the Jedi JVCL RichEdit as a
> > Free solution or use other from other component vendor, I had used
> > Infopower in the past and if a need today Ill use the Jedi one.
> >
> I guess that because TRichEdit wraps the Windows native RichEdit
> component, the full functionality of the Windows component should be
> accessible (under Windows XP SP2 or later versions), because it's the
> Windows component that's doing the work of rendering the data. Now if
> I open the RTF file containing images and equations that I mentioned
> in my previous post using Wordpad, the images and equations are
> correctly rendered. I don't know whether or not Wordpad uses the
> Windows RichEdit component to render an RTF file, but the very basic
> nature of the user interface would seem to suggest so.
Nope, this is RTF version issue, WInXp have nothing to do with that
case.
I use this solition since win98.
--
[]s
Cesar Romero
Dave Baldwin at pbear.com has one.
> I guess that because TRichEdit wraps the Windows native RichEdit component,
> the full functionality of the Windows component should be accessible (under
> Windows XP SP2 or later versions), because it's the Windows component that's
> doing the work of rendering the data. Now if I open the RTF file containing
> images and equations that I mentioned in my previous post using Wordpad, the
> images and equations are correctly rendered. I don't know whether or not
> Wordpad uses the Windows RichEdit component to render an RTF file, but the
> very basic nature of the user interface would seem to suggest so.
Up until XP SP2 Wordpad used the same as TRichedit, a standard Class1
Richedit. They have somewhat differing capabilities, depending on which DLLs
are present, which in turn depends on the Windows version and what other
software you installed. Basically, whatever Wordpad could do TRichedit could
do, and whatever one could not do the other couldn't.
Additional functionality could be added by creating a component wrapping
Class3 Richedit.. but you won't ever get *all* the functionality of Word!
As a separate issue you can write a component with OLE enabled based on
either the Class1 or Class3; which allows pictures to be shown. The code to
enable OLE was published by Brian Long years ago. Most if not all 3rd party
replacement Richedits are OLE enabled class3's so a look at the source for
any of these should show you how it is done.
Now we come to XP SP2. In this, Wordpad uses a different DLL, MSFTEdit.DLL
which contains Class4 Richedit (Classnames are RICHEDIT50A and RICHEDIT50W).
So Wordpad can do Multiline tables as well!
Of course, once you learned to write a class3 richedit component you can
soon create a class4 too armed with just the information in the above
paragraph. <g>
I see that on SP2, Wordpad's richedit is OLE enabled; apart from being able
to show pictures you can also embed sounds in it, if you can think of any
practical reason to want to do this.
>
>
> Up until XP SP2 Wordpad used the same as TRichedit, a standard Class1
> Richedit. They have somewhat differing capabilities, depending on which
> DLLs
> are present, which in turn depends on the Windows version and what other
> software you installed. Basically, whatever Wordpad could do TRichedit
> could
> do, and whatever one could not do the other couldn't.
>
> Additional functionality could be added by creating a component wrapping
> Class3 Richedit.. but you won't ever get *all* the functionality of Word!
>
> As a separate issue you can write a component with OLE enabled based on
> either the Class1 or Class3; which allows pictures to be shown. The code
> to
> enable OLE was published by Brian Long years ago. Most if not all 3rd
> party
> replacement Richedits are OLE enabled class3's so a look at the source for
> any of these should show you how it is done.
>
Thanks for the detailed guidance.
So if I understand you correctly, for images (and any other embedded
objects) to be rendered, the component wrapping the native Windows RichEdit
control must call API functions to set up the native Windows control as
OLE-enabled. When the method RichEdit1.Lines.LoadFromStream/LoadFromFile is
executed, the RTF binary data file is loaded into memory, but presumably
any embedded objects are skipped in the reading process if the Windows
RichEdit control has not been set up as OLE-enabled. Similarly, when a block
of RTF data containing embedded objects is copied from the clipboard to a
TRichEdit component, any embedded object data is skipped if the component
hasn't been OLE-enabled.
From a cursory glance at the Windows SDK that comes with D7 I found the
following possibly relevant items:
- IRichEditOle
- IRichEditOleCallback
- EM_SETOLEINTERFACE
To make the Windows RichEdit control OLE-enabled, can a client component use
implementations of the 2 interfaces provided by the Windows system, or must
it provide implementations of these interfaces itself, and then pass the
interface object to the Windows RichEdit control?
I couldn't find a reference to the Class of the Rich Edit control in the
SDK.
Can you indicate where I can find the source for setting up an OLE-enabled
Class 3 RichEdit component?
> Now we come to XP SP2. In this, Wordpad uses a different DLL, MSFTEdit.DLL
> which contains Class4 Richedit (Classnames are RICHEDIT50A and
> RICHEDIT50W).
> So Wordpad can do Multiline tables as well!
> Of course, once you learned to write a class3 richedit component you can
> soon create a class4 too armed with just the information in the above
> paragraph. <g>
>
Quite!<g>
> I see that on SP2, Wordpad's richedit is OLE enabled; apart from being
> able
> to show pictures you can also embed sounds in it, if you can think of any
> practical reason to want to do this.
It would be nice if the VCL were to extend the TRichEdit component class,
which to me seems to be very rudimentary, not to say incomplete! One
enhancement would be to add a property OLEEnabled: Boolean, that does the
dirty work of making the appropriate API settings. Another would be to add
properties for the cursor position, and for controlling scrolling behaviour.
EM
> Thanks for the detailed guidance.
>
> So if I understand you correctly, for images (and any other embedded
> objects) to be rendered, the component wrapping the native Windows RichEdit
> control must call API functions to set up the native Windows control as
> OLE-enabled.
Yes.
> When the method RichEdit1.Lines.LoadFromStream/LoadFromFile is
> executed, the RTF binary data file is loaded into memory, but presumably
> any embedded objects are skipped in the reading process if the Windows
> RichEdit control has not been set up as OLE-enabled. Similarly, when a block
> of RTF data containing embedded objects is copied from the clipboard to a
> TRichEdit component, any embedded object data is skipped if the component
> hasn't been OLE-enabled.
Yes. Generally if a richedit comes across any tags it doesn't support it
ignores them (that is stated in the RTF spec), and if it then saves its
contents the resulting rtf will have lost the tags.
(except, there are some tags explicitly described by MS as round-tripped,
that don't do anything to the screen but do get preserved.
> From a cursory glance at the Windows SDK that comes with D7 I found the
> following possibly relevant items:
> - IRichEditOle
> - IRichEditOleCallback
> - EM_SETOLEINTERFACE
These two are the ones.
> To make the Windows RichEdit control OLE-enabled, can a client component use
> implementations of the 2 interfaces provided by the Windows system,
I didn't know Windows provided them.
I doubt they can be used, or why would all the component writers write their
own implementation.. that all look suspiciously similar to each other ..
> or must
> it provide implementations of these interfaces itself, and then pass the
> interface object to the Windows RichEdit control?
Your subclassed component performs EM_SETOLECALLBACK passing your callback
as param 3
> I couldn't find a reference to the Class of the Rich Edit control in the
> SDK.
Look at the VCL source.
Particularly, the call to CreateSubClass.
VCL creates class Richedit.
But you can create other classes if you know their names, and see also the
loadlibrary call, which you change to the lib that contains the class you
want to create.
> Can you indicate where I can find the source for setting up an OLE-enabled
> Class 3 RichEdit component?
Any third-party richedit replacement.
Jedi comes with source doesn't it?
>> Now we come to XP SP2. In this, Wordpad uses a different DLL, MSFTEdit.DLL
>> which contains Class4 Richedit (Classnames are RICHEDIT50A and
>> RICHEDIT50W).
>> So Wordpad can do Multiline tables as well!
>> Of course, once you learned to write a class3 richedit component you can
>> soon create a class4 too armed with just the information in the above
>> paragraph. <g>
>>
> Quite!<g>
>
>> I see that on SP2, Wordpad's richedit is OLE enabled; apart from being
>> able
>> to show pictures you can also embed sounds in it, if you can think of any
>> practical reason to want to do this.
>
> It would be nice if the VCL were to extend the TRichEdit component class,
> which to me seems to be very rudimentary, not to say incomplete! One
> enhancement would be to add a property OLEEnabled: Boolean, that does the
> dirty work of making the appropriate API settings. Another would be to add
> properties for the cursor position, and for controlling scrolling behaviour.
SelStart is a property for 'cursor position' you know!
Most of the 3rd party ones add a bunch of properties, to encapsulate the
extra functions that a class 3 can do.
I didn't bother with my own component.
I don't mind coding a perform EM_whatever, or wrapping one in a method call
as apppropriate.
>> It would be nice if the VCL were to extend the TRichEdit component class,
>> which to me seems to be very rudimentary, not to say incomplete! One
>> enhancement would be to add a property OLEEnabled: Boolean, that does the
>> dirty work of making the appropriate API settings. Another would be to
>> add
>> properties for the cursor position, and for controlling scrolling
>> behaviour.
> SelStart is a property for 'cursor position' you know!
I was referring to cursor coordinates within the the text page, i.e. line
number and character position within the line.
> Most of the 3rd party ones add a bunch of properties, to encapsulate the
> extra functions that a class 3 can do.
> I didn't bother with my own component.
> I don't mind coding a perform EM_whatever, or wrapping one in a method
> call
> as apppropriate.
That's because you're obviously comfortable with low level Windows
programming. But IMHO, the user of a high level language system should have
no need to descend to calling API functions like SendMessage or its Delphi
counterpart Perform, just to utilize the basic functionality of a visual
control. The functionality should be wrapped by class methods and properties
of the high-level VCL component. What's curious is that the Rich Edit sample
application that ships with Delphi includes some short functions containing
such low level API calls, for example to extract the text coordinates of the
cursor. Wouldn't it have been better to make these functions, appropriately
generalized, methods/properties of the TRichEdit class, so that they become
more reusable, and covered by the Delphi on-line help? (To understand the
API calls, one has to refer to the Windows SDK help)
Regards,
EM
In article <478888f5$1...@newsgroups.borland.com>, "Enquiring Mind"
<Enquiri...@nospam.btopenworld.com> wrote:
> That's because you're obviously comfortable with low level Windows
> programming. But IMHO, the user of a high level language system should have
> no need to descend to calling API functions like SendMessage or its Delphi
> counterpart Perform, just to utilize the basic functionality of a visual
> control. The functionality should be wrapped by class methods and properties
> of the high-level VCL component. What's curious is that the Rich Edit sample
> application that ships with Delphi includes some short functions containing
> such low level API calls, for example to extract the text coordinates of the
> cursor. Wouldn't it have been better to make these functions, appropriately
> generalized, methods/properties of the TRichEdit class,
There's an awful lot of EM_ messages.
To have them all as properties would mean that your programs would have code
to do all of them, even if you only ever called a few of them.
Whereas my programs don't include to do stuff I don't need to do, (unless I
seriously think I *will* need to do them soon).
Also, if I can do it myself I think I'd rather the Borland team got on with
something I can't do for myself..
I seem to remember once reading somewhere that the Delphi linker only links
in non-virtual methods that are actually called, so all the methods that are
not actually used should not bloat one's application.
> Also, if I can do it myself I think I'd rather the Borland team got on
> with
> something I can't do for myself..
I agree in general with this philosophy, but I would like to see:
a) a clear separation between the domains of application programming and
systems programming- application programs should to my mind be platform
independent, unless an application or component is doing intrinsically
system-dependent tasks like interprocess communication. So a component like
TRichEdit should provide an abstract interface to a RTF file viewer/editor
that can be mapped to either a Windows Rich Edit control, or to equivalent
components from the Linux and Apple operating systems.
b) the Borland team making continuous incremental improvements to the
existing foundations of Delphi (adhering to the ideals of Pascal) as well as
continuing to add new storeys to the edifice, such as new application
frameworks. That means making improvements to complex VCL components like
grid components, the RichEdit component, etc., where the existence of third
party replacement components would suggest that the native Delphi components
have some significant shortcomings.
c) the Borland team refraining from introducing features of C-like
languages into the Delphi language or the interface of the VCL components
unless absolutely necessary. Those that prefer the C style of language are
free to use Borland C-like language products. The problem with having to use
API functions in a high level program to accomplish something which is not
OS-specific is that one is forced to use a C-style of programming for these
functions. To my mind C-style programming is only marginally better in
clarity and style than Fortran-4 or assembly programming.
> I seem to remember once reading somewhere that the Delphi linker only links
> in non-virtual methods that are actually called, so all the methods that are
> not actually used should not bloat one's application.
True, but I'm not sure if that's the case for public property getters and
setters. Aren't there ways to find these through RTTI that means that you
can call them non-explicitly? so they have to be available regardless.
Anyway I've been writing a bit of Richedit code today and its reminded me
why I hate properties.
prev:=RI.SelStart;
RI.Selstart:=RI.Selstart+1;
{Cannot inc() a property :( }
if RI.SelStart=prev then begin
{How can this possibly be ??
.. because the damned property has silently refused to add 1, it might
be because it is at a CR-LF pair and won't go between them, or it could be
because the Selection is already at the end. Or maybe something else, who
knows .. :((((((( OK I can differentiate the two I know about..}
RI.selstart:=RI.selstart+2;
if RI.Selstart=prev then EndTextProcessing
else DoNextLine;
> Anyway I've been writing a bit of Richedit code today and its reminded me
> why I hate properties.
>
> prev:=RI.SelStart;
> RI.Selstart:=RI.Selstart+1;
> {Cannot inc() a property :( }
> if RI.SelStart=prev then begin
> {How can this possibly be ??
> .. because the damned property has silently refused to add 1, it might
> be because it is at a CR-LF pair and won't go between them, or it could be
> because the Selection is already at the end. Or maybe something else, who
> knows .. :((((((( OK I can differentiate the two I know about..}
> RI.selstart:=RI.selstart+2;
> if RI.Selstart=prev then EndTextProcessing
> else DoNextLine;
I agree that Properties often seem to be counterintuitive. Although they
masquerade as fields, they can't be passed as var parameters to subroutines,
or be used freely in expressions. When abstract data types were first
promoted in languages like Modula-2, it was recommended that the state of an
abstract data variable should be changed by calling procedures/functions
rather than by setting the value of a field. Then Properties came along to
simulate the deprecated practice of setting fields directly. I therefore
personally often prefer to omit the property definition and just call the
Getter and Setter routines. However when a property constitutes an interface
to a simple field that needs to be read-only, or which is required to
trigger a sequence of actions when its value is changed, it is obviously a
useful construct.
In your example, I do not think that the property SelStart is well
implemented if the statement RI.Selstart:=RI.Selstart+1 fails to throw an
exception when the value assigned to RI.SelStart goes out of range. The
logic would be better along the lines
CurrPosn:= RI.SelStart;
if CurrPosn<RI.GetTextLength then
begin
{End of document not yet reached, so move cursor forward:}
Inc(CurrPosn);
RI.SelStart:= CurrPosn;
end
else
begin
{Act on end of text condition, say move cursor to beginning of
document};
CurrPosn:= 0;
RI.SelStart:= CurrPosn;
end;
> That's a good point. If the Delphi compiler translates all property
> references into calls of the Getter or setter methods, then the linker could
> presumably determine whether or not a specific Getter or Setter method has
> actually been called, and include it or not accordingly. Therefore if a
> particular property is never referenced within an application, hopefully the
> property's Getter and Setter methods should not be included in the
> executable. I haven't understood the RTTI point. Perhaps you could explain.
Using RTTI you can query a component to find out what properties it has. You
do not need to consult the name, having obtained the info you can just set
the properties (RTTI also reveals the addresses of the property getter and
setter).
So these methods *must* be compiled into the app.
.. To make it even more anonymous you could loop the componentlist and for
each component found, call getpropinfo, and, say, set, every integer
property to 42, without even typing the name of any component let alone the
property name.
Both these are Windows RichEdit independent.