Special TRichEdit component for text chat software...

Hello All,

I need a special RichEdit for my text chat example...
RichEdit like Miranda-IM message window...

It means that I can select text when somebody sends me message and it will not lost focus and selected area.
I can moving text with vertical scroll bar and when message will be arrived it will not lost text which I was seeing
in this moment... When this richedit lost focus it still not move to bottom when text will be inserted...
But when I move scrollbar or cursor to bottom it will insert text and do auto scroll... etc...

Please see how work ICQ message window or Miranda message window...

Ok, if somebody know same component, please send URL...

Thanks,
Dan
DanDaemonAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

geobulCommented:
Hi,

I don't have a component but rather code using standard RichEdit. If the following doesn't fit your needs then I'm sorry for the long post.

Regards, Geo

// The following example adds colored lines to a RichEdit in a timer event.
// If the user has selected text or the vertical scroll bar is not at the bottom
// new lines are saved in a string list and are added when it's possible:
// 1. the mouse is up
// 2. and there is no selected text
// 3. and the vertical scrollbar is at the bottom

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    RichEdit1: TRichEdit;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure RichEdit1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure RichEdit1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  InSelection: boolean; // while mouse is down
  CantAdd: boolean; // do not add lines while true
  NewLines: TStringList; // add them here
  Colors: TStringList; // and their colors

  // the following two vars are for testing only
  count: integer; // line counter for showing
  col: TColor; // current color

implementation

{$R *.DFM}

uses richedit;

// returns true if the last line is visible
function IsLastLineVisible(re: TRichEdit): boolean;
var
  p: tpoint;
  LinesVisible: integer;
begin
  p := Point(1, re.ClientHeight);
  LinesVisible := re.Perform(EM_LINEFROMCHAR, re.Perform(EM_CHARFROMPOS, 0, Integer(@P)), 0);
  if LinesVisible >= re.Lines.Count
  then result := true
  else result := false;
end;

// used only by AddColoredLine procedure
// do not use it directly !!!
procedure AddOneColoredLine(re: TRichEdit; Line: string; c: TColor);
begin
  re.Lines.BeginUpdate;
  try
    re.SelStart := re.Perform(EM_LINEINDEX, re.Lines.Count - 1,0);
    re.Lines.Add(Line);
    re.SelLength := re.Perform(EM_LINEINDEX, re.Lines.Count - 1,0) - re.SelStart;
    re. SelAttributes.Color := c;
  finally
    re.Lines.EndUpdate;
  end;
  // move cursor at the end
  re.SelStart := re.Perform(EM_LINEINDEX, re.Lines.Count,0);
end;

// use this procedure for adding lines
procedure AddColoredLine(re: TRichEdit; Line: string; c: TColor);
var i: integer;
begin
  // determine if we can add new lines
  if (IsLastLineVisible(re)) and (not InSelection) then CantAdd := false
  else CantAdd := true;
  if re.SelLength > 0 then CantAdd := true;
  if CantAdd then begin
    // remember the line
    NewLines.Add(Line);
    Colors.Add(IntToStr(c));
  end else begin
    // add remembered lines if any
    for i := 0 to NewLines.Count - 1 do
      AddOneColoredLine(re, NewLines[i], StrToInt(Colors[i]));
    // clear the remembered lines
    NewLines.Clear;
    Colors.Clear;
    // add current line
    AddOneColoredLine(re, Line, c);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  NewLines := TStringList.Create;
  Colors := TStringList.Create;
  CantAdd := false;

  // for testing
  count := 1;
  col := clRed;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if Assigned(NewLines) then NewLines.Free;
  if Assigned(Colors) then Colors.Free;
end;

procedure TForm1.RichEdit1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  InSelection := true;
end;

procedure TForm1.RichEdit1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  InSelection := false;
end;

// test routine for changing three colors
procedure ChangeColor;
begin
  if col = clRed then col := clGreen
  else if col = clGreen then col := clBlue
  else col := clRed;
end;

// for testing
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  AddColoredLine(RichEdit1, 'Line '+IntToStr(count), col);
  Inc(count);
  ChangeColor;
end;

end.
0
geobulCommented:
BTW, you may use another hidden (not visible) TRichEdit component instead of NewLines stringlist. This way Colors stringlist will become redundant and one line can have more than one color and various styles in it.
0
DanDaemonAuthor Commented:
Hello geobul,

Thank you very much, your source code is very good, but I have one question,
why it stops add line when I select some lines? How can I fix it?
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

geobulCommented:
That is the way I've faked that behaviour. I don't add lines to the richedit but keep them in a stringlist and add them all at once when it becomes possible (i.e. when there is no selected text, the last line is visible and the left mouse button is up). If I add a line while there is some selected text up in the richedit everything goes ugly saving the info of the selection and repositioning after the new line is added. I'm not able to fix it in an elegant way. Sorry.
0
DanDaemonAuthor Commented:
yahh, thank you, but I do not need so :(
0
zoozalpCommented:
i suggest trichview as a richedit component. and trichviewactions. http://www.trichview.com/
0
zoozalpCommented:
there are some chat applications made by using richview on site...
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
zoozalpCommented:
thank you DanDaemon, i got my first 500 points ;-)
0
geobulCommented:
DanDaemon,

I'm just curious: can TRichView do exactly what you need? I'm asking because I might need that functionality in the near future.

Thanks.
0
DanDaemonAuthor Commented:
Hello Geobul,

I wrote wrapper for standard TRichEdit and got TRichEdit which works 100% as I need.
It does not lose focuse, selection area and so on...

Will add images and all :)
0
geobulCommented:
OK thanks. So, you haven't tried TRichView.
0
DanDaemonAuthor Commented:
No, I was using it as example for another my job :)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.