Solved

Special TRichEdit component for text chat software...

Posted on 2004-10-27
210 Views
Last Modified: 2010-04-05
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
0
Question by:DanDaemon
    12 Comments
     
    LVL 17

    Expert Comment

    by:geobul
    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
     
    LVL 17

    Expert Comment

    by:geobul
    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
     

    Author Comment

    by:DanDaemon
    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
     
    LVL 17

    Expert Comment

    by:geobul
    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
     

    Author Comment

    by:DanDaemon
    yahh, thank you, but I do not need so :(
    0
     

    Expert Comment

    by:zoozalp
    i suggest trichview as a richedit component. and trichviewactions. http://www.trichview.com/
    0
     

    Accepted Solution

    by:
    there are some chat applications made by using richview on site...
    0
     

    Expert Comment

    by:zoozalp
    thank you DanDaemon, i got my first 500 points ;-)
    0
     
    LVL 17

    Expert Comment

    by:geobul
    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
     

    Author Comment

    by:DanDaemon
    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
     
    LVL 17

    Expert Comment

    by:geobul
    OK thanks. So, you haven't tried TRichView.
    0
     

    Author Comment

    by:DanDaemon
    No, I was using it as example for another my job :)
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    IT, Stop Being Called Into Every Meeting

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
    Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
    In this Experts Exchange video Micro Tutorial, I'm going to show how small business owners who use Google Apps can save money by setting up what is called a catch-all email address in their Gmail accounts. By using the catch-all feature, small busin…
    Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

    884 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    21 Experts available now in Live!

    Get 1:1 Help Now