Link to home
Start Free TrialLog in
Avatar of blue220
blue220

asked on

Adding Emoticons to a RichEdit

I know this question has been asked (and answered) before but  the methods I have seen will not work for me because I need to load the emoticons into  a ReadOnly richedit control which means any method that the requires the user to interact with it will not work for me.

If you have ever seen/used the archive feature of Yahoo Messenger then thats pretty much what I want to do. Give the users the ability to archive thier chats with all the formatting intact which includes the emotions.

I believe the only method that will work for me will be something of a custom StringReplace procedure that will add the emotions to the richedit control when the text is changed but I not the expert so thats why I came here to ask the experts for help. (code examples)

I am currently storing the emotions in an imagelist and I have installed the JvRichEdit  control from the JVCL group if this information helps in anyway.

Finally I hope I have explained my situation well enough but if not then I will do my best to clear up any questions you might have and thx in advance for your replies.

Avatar of paulb1989
paulb1989

If you already have a method that works when the richedit isn't read only, then why not simply use MyRichEdit.ReadOnly := False; before using your code then MyRichEdit.ReadOnly := True; after using it.
Avatar of blue220

ASKER

Thx for the reply and I should have made this more clear in my original post  but I don't have any methods at all. What I should have said is I read an article saying it would be possible but have never seen the code to actually try it out.

So to repharase my question what I am looking for is some code that will....

A.) Replace specific strings in a RichEdit control with images as the user is typing into it and ...

B.) Have those same strings automatically converted if a user loads text into it using the Richedit.Lines.LoadFromFile function.

Again I just want to say I currently DO NOT have a method to accomplish either of these task but I hope one of you might have already done this and would be willing to share your code with the rest of us.

Thx again for all replies in advance.
Avatar of blue220

ASKER

Ok in the JVCL examples folder I found a small messagner type app which had a procedure called AddImageToRichEdit which takes an image from an imagelist and insterts it into the RichEdit control which is want I am wanting to do BUT I can only get it to work when I press a button or something so my question now is    there anyway to incoporate the code below into a custom StringReplace procedure so that it will add the image to the richedit when the user is typing into it .

----------------------------------------------------------------------
 Begin Code
----------------------------------------------------------------------

procedure TForm1.AddImageToRichEdit(const AImageIndex: Integer);
var
  Bitmap: TBitmap;
begin
  Bitmap := TBitmap.Create;
  try
    ImageList1.GetBitmap(AImageIndex, Bitmap);
    JvRichEdit1.InsertBitmap(Bitmap, False);

    { Move cursor }
    with JvRichEdit1.GetSelection do
      JvRichEdit1.SetSelection(cpMin + 1, cpMin + 1, False);
  finally
    Bitmap.Free;
  end;
end;

------------------------------------------------------------------
 End Code
------------------------------------------------------------------

Thx again for your replies.
procedure TForm1.JvRichEdit1Change(Sender: TObject);
var
  p: Integer;
begin
  p := Pos(':)', JvRichEdit1.Lines.Text);
  while p > 0 do
  begin
    JvRichEdit1.SelStart := p - (JvRichEdit1.LineFromChar(p) + 1);
    JvRichEdit1.SelLength := 2;
    AddImageToRichEdit(0);
    p := Pos(':)', JvRichEdit1.Lines.Text);
  end;
end;
Avatar of blue220

ASKER

Thx for the reply again but I noticed a couple of things.

1. The code works fine as long as you are on the first line of the richedit control but once you go to the 2nd line you are left with the ":" character before the image so not sure why it's doing that and ...

2. This works for one image but what if I have more then one image ? (example plz)

Thx Again.
I'm not sure about the lines problem yet, but this should let you handle multiple images easier.

procedure TForm1.JvRichEdit1Change(Sender: TObject);

  procedure HandleImage(Str: String; Index: Integer);
  var
    p: Integer;
  begin
    p := Pos(Str, JvRichEdit1.Lines.Text);
    while p > 0 do
    begin
      JvRichEdit1.SelStart := p - 1;
      JvRichEdit1.SelLength := Length(Str);
      AddImageToRichEdit(Index);
      p := Pos(Str, JvRichEdit1.Lines.Text);
    end;
  end;

begin
  // Use this as many times as you need
  HandleImage(':)', 0);
  HandleImage(':(', 1);
end;
OK change the HandleImage procedure above to this and it will work on multiple lines:

  procedure HandleImage(Str: String; Index: Integer);
  var
    p: Integer;
  begin
    p := Pos(Str, JvRichEdit1.Lines.Text);
    while p > 0 do
    begin
      JvRichEdit1.SelStart := p - JvRichEdit1.CaretPos.Y - 1;
      JvRichEdit1.SelLength := Length(Str);
      AddImageToRichEdit(Index);
      p := Pos(Str, JvRichEdit1.Lines.Text);
    end;
  end;
Avatar of blue220

ASKER

Thx again but there still seems to be some problems.

Set the richedit controls width to 544 and put 2 buttons on the form and put the code below in each of the buttons OnClick events to see the result.

------------------------------------------------------------------
Code for button 1
------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
JvRichEdit1.Clear;
JvRichEdit1.Lines.Text := 'This is a typical richedit control with a twist. You can insert images in place of some text such as this :) but as you can see if the text is on the 2nd line or below then we encounter some problems so how can we fix it.';
end;

---------------------------------------------------------------------
Code for button 2
---------------------------------------------------------------------
procedure TForm1.Button2Click(Sender: TObject);
begin
JvRichEdit1.Clear;
JvRichEdit1.Lines.Text := 'Another example to show how it works now. Here is the :) again and look at the result this time.';
end;
OK its a little more complicatied than I first thought but the replace the HandleImage procedure with the below and it seems to work fine:

  procedure HandleImage(Str: String; Index: Integer);
  var
    p, l, i, start: Integer;
  begin
    for l := 0 to JvRichEdit1.Lines.Count - 1 do
    begin
      p := Pos(Str, JvRichEdit1.Lines[l]);
      while p > 0 do
      begin
        start := p + l - 1;

        for i := 0 to l-1 do
          start := start + Length(JvRichEdit1.Lines[i]);

        JvRichEdit1.SelStart := start;
        JvRichEdit1.SelLength := Length(Str);
        AddImageToRichEdit(Index);
        p := Pos(Str, JvRichEdit1.Lines[l]);
      end;
    end;
  end;
Avatar of blue220

ASKER

Sorry to keep saying this but it's still not working. Set the richedit  width and height like it is below and then type or copy & paste the text below into the richedit and see what  happens.

RichEdit Width = 433
RichEdit Height = 193

-------------------------------------------------------------------
Type or copy and paste this in the richedit control
-------------------------------------------------------------------
This is yet another example to show the problem we are having with the inserted images and the line wrapping problem. If the image is inserted on the first line then it seems to work fine but if once the text wraps around to the second line or above we start to have problems like this. Type the :) character and see what happens.
-------------------------------------------------------------------

Something I did notice is that in the AddImageToRichEdit  procedure there is some code that moves the cursor after the image is added which might be conflicting with the code your using Im not sure but here is the line from the procedure just incase.

    { Move cursor }
    with JvRichEdit1.GetSelection do
      JvRichEdit1.SetSelection(cpMin + 1, cpMin + 1, False);

Once again thx for your replies in advance.
Avatar of blue220

ASKER

Not sure if you have given up on the question or if your busy but Im still looking for some help on this one so if ANYONE wants to try and take a stab at it plz do.
Avatar of blue220

ASKER

To paulb1989

Well I found a way to do both of the things I need to do (it's dirty  but it works)

For the "as you type" part I used a FindLastWord function to grab the last word typed into the richedit control and then if it was the same as one of my "keywords"  it would replace the word with the emoticon and delete the word.

For the "automatic loading" part  I just used the saveToFile / LoadFromFile functions which works fine.

Since I came up with this solution on my own I am going to ask the moderators to delete this question but I will start another question and award you 200 points for your effort.

Thx Again.
Blue220
ASKER CERTIFIED SOLUTION
Avatar of Netminder
Netminder

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial