Othuna
Othuna

Reputation: 129

c# - inserting smileys in RichTextBox inserts some and ignores others

I have a code to replace symbols in the richtextbox to smileys, this is the code:

private void add_smileys(RichTextBox addin)
        {
            try
            {
                while (addin.Text.Contains(":)"))
                {
                    addin.SelectionStart = addin.Find(":)", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_smile;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(">:("))
                {
                    addin.SelectionStart = addin.Find(">:(", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 3;

                    Image img = Resources.in_angry;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":D"))
                {
                    addin.SelectionStart = addin.Find(":D", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_lol;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":'("))
                {
                    addin.SelectionStart = addin.Find(":'(", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 3;

                    Image img = Resources.in_cry;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":("))
                {
                    addin.SelectionStart = addin.Find(":(", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_sad;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(";)"))
                {
                    addin.SelectionStart = addin.Find(";)", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_wink;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains("xD"))
                {
                    addin.SelectionStart = addin.Find("xD", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_laugh;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":P"))
                {
                    addin.SelectionStart = addin.Find(":P", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_tongue;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":|"))
                {
                    addin.SelectionStart = addin.Find(":|", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_neutral;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains("^^"))
                {
                    addin.SelectionStart = addin.Find("^^", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_happy;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains("o.O"))
                {
                    addin.SelectionStart = addin.Find("o.O", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 3;

                    Image img = Resources.in_dizzy;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":S"))
                {
                    addin.SelectionStart = addin.Find(":S", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_confused;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":O"))
                {
                    addin.SelectionStart = addin.Find(":O", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_omg;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
            }
            catch (Exception e)
            {
              MessageBox.Show(e.Message);
            }
        }

This is the output: enter image description here

As you see, some symbols are replaced with smileys and some aren't. moreover, I get this exception:

enter image description here

What is the cause of this error? How do I fix it?

Upvotes: 2

Views: 3004

Answers (1)

NightOwl888
NightOwl888

Reputation: 56859

I get this exception: enter image description here

enter image description here

What is the cause of this error? and how do I fix it?

The Find method returns -1 when the string it is looking for doesn't exist. This value is not valid for addin.SelectionStart.

You should first check to ensure the result of the Find is greater than -1 method before attempting to use the value.

var selectionStart = addin.Find(":)", RichTextBoxFinds.WholeWord);
if (selectionStart > -1)
{
    addin.SelectionStart = selectionStart;
    addin.SelectionLength = 2;
}

And your Contains and Find check are redundant. For some reason when you get to "^^" they are returning different results, which is why you are getting the error. But to remove the redundancy, you should use the Find method in your loop instead of Contains.

while (true)
{
    var selectionStart = addin.Find(":)", RichTextBoxFinds.WholeWord);
    if (selectionStart > -1)
    {
        addin.SelectionStart = selectionStart;
        addin.SelectionLength = 2;
    }
    else
    {
        break;
    }
}

I also think that your approach is not very clean. You could use a Dictionary<string, Image> to do all of your replacing in a simpler, more maintainable way. You should also use the @ symbol to escape your strings.

private void add_smileys(RichTextBox addin)
{
    var smileys = new Dictionary<string, Image>()
    {
        { @":)", Resources.in_smile },
        { @">:(", Resources.in_angry },
        { @":D", Resources.in_lol },
        { @":'(", Resources.in_cry },
        { @":(", Resources.in_sad },
        { @";)", Resources.in_wink },
        { @"xD", Resources.in_laugh },
        { @":P", Resources.in_tongue },
        { @":|", Resources.in_neutral },
        { @"^^", Resources.in_happy },
        { @"o.O", Resources.in_dizzy },
        { @":S", Resources.in_confused },
        { @":O", Resources.in_omg },
    };

    foreach (var smiley in smileys)
    {
        add_smiley(addin, smiley.Key, smiley.Value);
    }
}

private void add_smiley(RichTextBox addin, string token, Image smiley)
{
    while (true)
    {
        var selectionStart = addin.Find(token, RichTextBoxFinds.WholeWord);
        if (selectionStart < 0) break;

        try
        {
            addin.SelectionStart = selectionStart;
            addin.SelectionLength = token.Length;

            Clipboard.SetImage(smiley);
            addin.Paste();
        }
        catch (Exception ex)
        {
            MessageBox.Show(e.Message);
            break;
        }
    }
}

Upvotes: 2

Related Questions