question

sharonglipman-9594 avatar image
0 Votes"
sharonglipman-9594 asked Viorel-1 commented

How can I make sure that it will highlight the specific chars only if typing them once each time in the TextChanged event?

 private void richTextBox2_TextChanged(object sender, EventArgs e)
         {
             if ((richTextBox2.Text != "" && textBoxRootDirectory.Text != "" &&
                 Directory.Exists(textBoxRootDirectory.Text)) || richTextBox2.Text != "")
             {
                 startButton.Enabled = true;
                 Properties.Settings.Default["Setting2"] = richTextBox2.Text;
                 Properties.Settings.Default.Save();
             }
             else
             {
                 startButton.Enabled = false;
             }
    
             if (IsColouring) return;
    
             IsColouring = true;
    
             try
             {
                 if (richTextBox2.Text.Length > 1 && !richTextBox2.Text.Substring(0,2).StartsWith(",,")) 
                 {
                     Highlight(richTextBox2);
                 }
             }
             finally
             {
                 IsColouring = false;
             }
         }

And

 void Highlight(RichTextBox richTextBox)
         {
             const int WM_SETREDRAW = 0x000B;
    
             SendMessage(richTextBox.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
    
             var sel_start = richTextBox.SelectionStart;
             var sel_len = richTextBox.SelectionLength;
    
             richTextBox.SelectAll();
             richTextBox.SelectionColor = Color.Black;
    
             int p = 0;
             while ((p = richTextBox.Find(",,", p, RichTextBoxFinds.None)) >= 0)
             {
                 richTextBox.SelectionStart = p;
                 richTextBox.SelectionLength = 2;
                 richTextBox.SelectionColor = Color.Red;
    
                 p += 1;
             }
    
             richTextBox.SelectionStart = sel_start;
             richTextBox.SelectionLength = sel_len;
    
             SendMessage(richTextBox.Handle, WM_SETREDRAW, new IntPtr(1), IntPtr.Zero);
             richTextBox.Invalidate();
         }
    
         [DllImport("user32")]
         private extern static IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

The problem is in case I type for example in the richTExtBox2 :

Hello World,,,,,,,,

It will color in red all the ,, chars but I want that it will color the first two ,, in red and if I keep typing ,, after it than the next ,, will be in black. only if there is a space between the ,,,,, or letters or other chars color the ,, in red.

The goal is to color each time only two ,, in red and if there is more than two ,, in a row than color only the first two in red the rest in black.

,,,,,,
^
This two in red the rest should be in black

,,hello,,hi,,,,,,
^ ^ ^ ^ ^
red red black



I will add a screenshot image to explain better :

The chars ,, are for separate.

So in this screenshot image : The chars in the end ,,,,,,,,,,,, they are all red but they should not be red but black.
Because only if I type two ,, and than a letter or something other chars it should keep the two in red and the rest the next in black.
But if I didn't type any letters or other chars after two ,, than the two ,, should become black with the rest ,, so all this ,,,,,,,,,,,, in the end should be black.

The separate rule is to separate only between words letters or chars that are not two or more ,, in a row.

So Hello,,World make the two ,, in red but Hellow,,World,,,,,,,,,, make all the ,,,,,, in the end after the World in black because there is nothing to separate it's all ,,,,,,,,,,


127261-mysep1.jpg


dotnet-csharpwindows-forms
mysep1.jpg (10.2 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

Viorel-1 avatar image
0 Votes"
Viorel-1 answered sharonglipman-9594 commented

Check this adjustment:

 void Highlight( RichTextBox richTextBox )
 {
    const int WM_SETREDRAW = 0x000B;
    
    SendMessage( richTextBox.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero );
    
    var sel_start = richTextBox.SelectionStart;
    var sel_len = richTextBox.SelectionLength;
    
    richTextBox.SelectAll( );
    richTextBox.SelectionColor = Color.Black;
    
    for( int y = 0; y < richTextBox.Lines.Length; y++ )
    {
       string s = richTextBox.Lines[y];
       int x = richTextBox.GetFirstCharIndexFromLine( y );
    
       foreach( Match m in Regex.Matches( s, @"(?<!^)(?<=[^,])(?<sep>,,),*?[^,]" ) )
       {
          richTextBox.SelectionStart = x + m.Groups["sep"].Index;
          richTextBox.SelectionLength = 2;
    
          richTextBox.SelectionColor = Color.Red;
       }
    }
    
    richTextBox.SelectionStart = sel_start;
    richTextBox.SelectionLength = sel_len;
    
    SendMessage( richTextBox.Handle, WM_SETREDRAW, new IntPtr( 1 ), IntPtr.Zero );
    richTextBox.Invalidate( );
 }

· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Viorel- 1 it's close but not yet working as expected.

127271-notworkingyet3.jpg



The problem is that if I typed many ,,,,,,, then letters after it it will color in red the two first ,, in the row of many ,,,,,,, but it should not.
It should color in red only if between two letters or other chars there is only two ,,

like for example : Hello World,,Hi color in red the two ,, but Hellow World,,,,Hi don't color in red anything.

The separate should be only if there is two ,, between letters or other chars.

0 Votes 0 ·
notworkingyet3.jpg (16.7 KiB)
Viorel-1 avatar image Viorel-1 sharonglipman-9594 ·

For this new details, try adjusting the above foreach line:

 foreach( Match m in Regex.Matches( s, @"(?<=[^,])(?<sep>,,)(?=[^,])" ) )

1 Vote 1 ·