What I am aiming for here is simply a box to display
non-editable text to the user that they can scroll through.
I have an 3rd pary HTML viewer component that I might try using
instead of the TRichEdit or TMemo. Thanks again for the info.
The code using HideCaret only works with TEdit and TMemo. TRichedit
recreates the caret quite frequently, since it has to adjust its size
to the font of the text the caret sits in. So it's simply not practical
to hide the caret in a richedit.
> What I am aiming for here is simply a box to display
> non-editable text to the user that they can scroll through.
> I have an 3rd pary HTML viewer component that I might try using
> instead of the TRichEdit or TMemo. Thanks again for the info.
If you need some formatting then a HTML viewer is probably the best
approach.
--
Peter Below (TeamB)
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be
Look at the CreateCaret API function. It allows you to specify a bitmap that
is used to display the caret. Since the SDK docs make no mention that the
bitmap has to be monochrome i assume that you can use one with colors. Never
tried it, though.
Tried but, as you said, the RichEdit control seems to recreate the caret
as you move around the text. It's probably something stupid I did, but I
could not create a colored caret.
Thanks,
Ronaldo
A richedit is probably a lost cause anyway. But with any control that handles the
caret itself you have to choose the right spot to intervene in this process. A
standard edit control (TEdit, TMemo) will create the caret when it processes the
WM_SETFOCUS message and destroy it when it receives WM_KILLFOCUS. So you have to
make sure you modify the caret *after* the control has done its stuff, or your
change will not take. That means you have to trap WM_SETFOCUS (the OnEnter event
is fired from that message), pass it on to the control for processing, and *then*
do your caret manipulations.
The only likely place to do the same for a richedit would be the EN_SELCHANGE
notification, which fires the OnSelectionChange event. The timing is a bit more
tricky here since the event probably happens before the caret is recreated, so
one would have to delay the act of changing the caret by posting a user message
to the form and do the deed in the handler for that message. That is also the
simplest strategy for doing this, using the OnEnter event, for a memo or edit.
Hi,
I created a Trichedit descendant with an extra property ViewOnly,
When setting that property the richedit will not show the carrot anymore,
also the text will be non selectable, so you can use it nicely to only
display RTF text.
it also has limited autosize capability, and reacts to key messages for
scrolling.
hope you find it usefull
Best regards,
Mario van Zeist.
unit ELSRichEdit;
interface
uses
Windows,SysUtils,Messages, Classes, Controls, StdCtrls,
ComCtrls,Forms,RichEdit;
type
TCustomELSRichEdit = class(TCustomRichEdit)
private
FViewOnly: boolean;
Procedure WMSetFocus( Var msg: TWMSetFocus ); message WM_SETFOCUS;
Procedure WMKillFocus( Var msg: TWMKillFocus); message WM_KILLFOCUS;
procedure WMSetCursor(var Message: TWMSetCursor); message WM_SETCURSOR;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
procedure SetViewOnly(const Value: boolean);
protected
procedure WndProc(var Message: TMessage); override;
procedure RequestSize(const Rect: TRect); override;
procedure SetAutoSize(Value: boolean); override;
property AutoSize default False;
public
constructor Create(AOwner :TComponent); override;
property ViewOnly :boolean read FViewOnly write SetViewOnly default
False;
end;
TELSRichEdit = class(TCustomELSRichEdit)
published
property Align;
property Alignment;
property Anchors;
property BevelEdges;
property BevelInner;
property BevelOuter;
property BevelKind default bkNone;
property BevelWidth;
property BiDiMode;
property BorderStyle;
property BorderWidth;
property Color;
property Ctl3D;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Font;
property HideSelection;
property HideScrollBars;
property ImeMode;
property ImeName;
property Constraints;
property Lines;
property MaxLength;
property ParentBiDiMode;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PlainText;
property PopupMenu;
property ReadOnly;
property ScrollBars;
property ShowHint;
property TabOrder;
property TabStop default True;
property Visible;
property WantTabs;
property WantReturns;
property WordWrap;
property OnChange;
property OnContextPopup;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnMouseWheel;
property OnMouseWheelDown;
property OnMouseWheelUp;
property OnProtectChange;
property OnResizeRequest;
property OnSaveClipboard;
property OnSelectionChange;
property OnStartDock;
property OnStartDrag;
property ViewOnly;
property AutoSize;
end;
implementation
{ TCustomELSRichEdit }
constructor TCustomELSRichEdit.Create(AOwner: TComponent);
begin
inherited;
AutoSize:=False;
end;
procedure TCustomELSRichEdit.RequestSize(const Rect: TRect);
begin
inherited;
if AutoSize then
BoundsRect := Rect
end;
procedure TCustomELSRichEdit.SetAutoSize(Value: boolean);
begin
if AutoSize=Value then exit;
inherited SetAutoSize(Value);
if Value then
SendMessage (Handle, EM_REQUESTRESIZE, 0, 0)
end;
procedure TCustomELSRichEdit.SetViewOnly(const Value: boolean);
begin
if FViewOnly = Value then exit;
FViewOnly:=Value;
if not Value then
ShowCaret(Handle);
Invalidate;
end;
procedure TCustomELSRichEdit.WMKillFocus(var msg: TWMKillFocus);
begin
if ViewOnly then
ShowCaret(Handle);
inherited;
end;
procedure TCustomELSRichEdit.WMPaint(var Message: TWMPaint);
begin
inherited;
if ViewOnly then
HideCaret(Handle);
end;
procedure TCustomELSRichEdit.WMSetCursor(var Message: TWMSetCursor);
var P :TPoint;
begin
if ViewOnly then begin
Message.Result:=1;
GetCursorPos(P);
with PointToSmallPoint(P) do
case Perform(WM_NCHITTEST, 0, MakeLong(X, Y)) of
HTVSCROLL,
HTHSCROLL:
Windows.SetCursor(Screen.Cursors[crArrow]);
HTCLIENT:
Windows.SetCursor(Screen.Cursors[Cursor]);
end;
end else
inherited;
end;
procedure TCustomELSRichEdit.WMSetFocus(var msg: TWMSetFocus);
begin
inherited;
if ViewOnly then
HideCaret(Handle);
end;
procedure TCustomELSRichEdit.WndProc(var Message: TMessage);
procedure Scroll( msg, scrollcode: Integer );
begin
Perform( msg, scrollcode, 0 );
Perform( msg, SB_ENDSCROLL, 0 );
end;
begin
If not (csDesigning In ComponentState) and ViewOnly Then
Case Message.Msg Of
WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_LBUTTONDBLCLK,
WM_CHAR, WM_KEYUP: Begin
Message.Result := 0;
If Message.Msg = WM_LBUTTONDOWN Then
If not Focused Then
SetFocus;
Exit;
End;
WM_KEYDOWN: Begin
Case Message.WParam Of
VK_DOWN : Scroll( WM_VSCROLL, SB_LINEDOWN );
VK_UP : Scroll( WM_VSCROLL, SB_LINEUP );
VK_LEFT : Scroll( WM_HSCROLL, SB_LINELEFT );
VK_RIGHT: Scroll( WM_HSCROLL, SB_LINERIGHT );
VK_NEXT : Scroll( WM_VSCROLL, SB_PAGEDOWN );
VK_PRIOR: Scroll( WM_VSCROLL, SB_PAGEUP );
VK_HOME : Scroll( WM_VSCROLL, SB_TOP );
VK_END : Scroll( WM_VSCROLL, SB_BOTTOM );
End;
Message.Result := 0;
Exit;
End;
End;
inherited;
end;