Getting started with highlighting and indicators

Feb 7, 2008 at 8:27 PM
Hi,

I am trying to use scintillaNet as an editor similar to richtext control. I am using scintillaNet, because it has better handling of text background color, underlines, and so on. I will also have some kind of styling/lexing, but it will be not based on keywords. Also there are other features that I like (autocomplete, but I haven't tried it yet).

But there are problems. I found out how to use styling (if anyone asked, here is the code):
this.scintillaControl1.SetStyleBits(7); // I implemented this command myself in ScintillaControl.generated.cs, it allows to use more than 32 styles

this.scintillaControl1.StyleSetBack(2, 0xffff00); //lightblue
this.scintillaControl1.StyleSetFore(2, 0x0000ff); //red
this.scintillaControl1.StartStyling(0, 0xff);
this.scintillaControl1.SetStyling(20, 2);

But I can't figgure out how to use indicators. When I use the following code in this very old version of scintillaNet (0.61 from sourceforge), it works:

scintillaControl1.SetIndicStyle(1, 6);
scintillaControl1.SetIndicFore(1, 0x000000);
scintillaControl1.SPerform(SCI_SETINDICATORCURRENT, 1, 1);
scintillaControl1.SPerform(SCI_INDICATORFILLRANGE, 0, 10);

But with the latest version it does not work. I checked with debugger, that the calls to dll library are exactly the same for both versions. So what changed between these versions?
How to implement these indicators? What do I do wrong?

Another, more general question, why there are no implementations of commands like SCI_SETSTYLEBITS (I implemented myself as SetStyleBits), is there another way to execute these commands that I do not know of?
How is it done in HtmlControl (nativeMethods). I can't make sense of it.

Less important question: I am also wondering how to implement lexer (or rather pseudo lexer in my case?), which could colour some words starting with for example %, ! (these are psudo commands in my program), and also highlight grammar errors (I will handle grammar checking myself of course).
Is it possible for lexer to work this way?
Maybe that question should be for another post, when I get to know scintilla better, but I must also say that it is not easy to get started, so any help will be aprecciated.

Regards,
Bigg
Coordinator
Feb 8, 2008 at 4:26 AM
You might want to get the latest 2.0 version from the Source Code tab. While the main API is quite a departure from the 1.x version Indicators (new style Scintilla Indicators) are fully implemented. Use the SetIndicator Method of the Range object.
Feb 8, 2008 at 12:50 PM
I downloaded the code from "recent check-ins" (ScintillaNET-25322.zip, ScintillaNET-25561.zip, ScintillaNET-28189.zip, ScintillaNET-28317.zip, ScintillaNET-28319.zip) and also using Subversion, then started \Branches\2.0\ScintillaNET.sln, but none of theese seems to work.
Is it me or there is a bug? Do I download from the right location?

Everytime the same exception is thrown.

Exception details:

System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object."
Source="ScintillaNet"
StackTrace:
at ScintillaNet.SnippetChooser.setPosition() in E:\ScintillaNET-28319\Branches\2.0\ScintillaNET\Snippets\SnippetChooser.cs:line 81
at ScintillaNet.SnippetChooser.OnCreateControl() in E:\ScintillaNET-28319\Branches\2.0\ScintillaNET\Snippets\SnippetChooser.cs:line 69
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.ControlCollection.Add(Control value)
at Microsoft.VisualStudio.Tools.UserControlTestContainer.set_CurrentUserControl(UserControl value)
at Microsoft.VisualStudio.Tools.UserControlTestContainer.cbUserControls_SelectedIndexChanged(Object sender, EventArgs e)
at System.Windows.Forms.ComboBox.OnSelectedIndexChanged(EventArgs e)
at System.Windows.Forms.ComboBox.set_SelectedIndex(Int32 value)
at Microsoft.VisualStudio.Tools.UserControlTestContainer.LoadAssemblyFromFile(String fileName)
at Microsoft.VisualStudio.Tools.UserControlTestContainer.UserControlTestContainer_Load(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnLoad(EventArgs e)
at System.Windows.Forms.Form.OnCreateControl()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.WmShowWindow(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmShowWindow(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.SafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow)
at System.Windows.Forms.Control.SetVisibleCore(Boolean value)
at System.Windows.Forms.Form.SetVisibleCore(Boolean value)
at System.Windows.Forms.Control.set_Visible(Boolean value)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Microsoft.VisualStudio.Tools.UserControlTestContainer.Main(String[] args)
InnerException:
Feb 9, 2008 at 3:40 PM
Edited Feb 9, 2008 at 3:45 PM
Update!

I created new project in the solution, added Scintilla Control and it compiled.
To my surprise, now also Scide starts running without trhrowing any exception. Have no clue, why it didn't start previously.
Indicators and styling works (if anyone asked, here is the code):

Range r = new Range(0, 10, scintilla1);
Indicator ind = scintilla1.Indicators{5};
r.SetIndicator(ind.Number);

Style s = scintilla1.Styles{5};
s.BackColor = Color.HotPink;
r.SetStyle(s.Index);
Coordinator
Feb 11, 2008 at 7:34 PM
I'm glad it worked. One slight correction, instead of using the Range constructor (which I think is supposed to be protected internal) use the GetRange method of the Scintilla class. This makes your first line
Range r = scintilla1.GetRange(0, 10);
Feb 12, 2008 at 10:40 AM
I was playing with Scintilla control and I have one more question (or three).
1. If I apply styling and indicators to the range using the above code and insert a char inside this range, the following happens:
the char has indicator on it, but does not have style on it.
Is this different behaviour intended (I guess so, because you need a lexer to style your text)? Or maybe it something done by scintillaNet wrapper, or my (above) code does not take sth into account. I woud rather like the behaviour be the same one way or another...

2. As I understand Scintilla does not store style information in its undo/redo stack, so after undo/redo you need to style?

3. This I guess is Scintilla bug.
When I use the following code:
scintilla1.WhiteSpace.BackColor = Color.Chocolate;
scintilla1.LineWrap.Mode = WrapMode.Word;
and I enter text (white color) and then spaces (until the line with spaces wraps) strange things happen - sometimes spaces have chocolate color, sometimes not. When in Scintilla there is a text like this:

Scintilla1
//spaces
only these spaces that are not under "Scintilla1" are coloured.
This is probably Scintilla bug (?), but how can I make Scintilla recolorise its contents? Maybe this would help.
Coordinator
Feb 12, 2008 at 6:39 PM
1 and 2 are both innate behaviors to the native Scintilla, and they both relate to the way Scintilla is designed as a Source Code editing component.

As a general rich text editor all the styling information is really a part of the document. However in Scintilla really the style information is not considered part of the document because the style can always be recalculated based on the content (syntax coloring based on code). This is why styling isn't in the unde/redo stack. All changes to the document text need to be styled. If a lexer is used it will automatically style the text for you based on it's syntax coloring rules. In using it as a general rich text component you have to style each insertion into the document yourself and handle the StyleNeeded event to style text the user has added.

The reason indicators automatically apply to inserted text is because indicators were originally intended for use as compiler warnings/errors or spellcheck indicators.

Unfortunately for you I can't control these behaviors and I can almost guarantee you won't get the Scintilla project to change these behaviors. In the end Scintilla may not be the appropriate control for what you're looking to do.

For the whitespace bug I wasn't able to reproduce this, could you please create a full working example that demonstrates this? You can email it to me at rickard234@gmail.com.
Feb 13, 2008 at 4:11 PM
I kind of knew that styling and indicator behaviour is integral part of Scintilla, but I wanted to be sure.
I already solved some problems with styling so that it behaves as a rich text control. This is done by changing SnippetManager.Scintilla_TextInserted functon to the following:
Style s;
if (e.Position > 0) if ((e.Text != " ") && (e.Text != "\t") && (e.Text != "\r\n") && (e.Text != "\n") && (e.Text != "\u0000"))
{
s = Scintilla.StylesScintilla.Styles.GetStyleAt(e.Position - (int)1);
Range r = new Range(e.Position, e.Position + e.Length, Scintilla);
r.SetStyle(s.Index);
}
It just sets styles for the newly inserted text using style of neighbouring text.
And that is behaviour that I need for the non-command part of the text.
But there are also commands between the text or I should rather say there is text between commands.
Colouring these commands is slow and causes flickering... And there is no other free rich text control which behaves better than original rich text box.
So after a few adjustments, it looks like scintilla will suit my needs.

I am sending you .cs files that you need to reproduce the problem. The bug is visible after selecting menu item.
1. Selected spaces should all be blue (as selection color is). Now brown spaces are after selecting brown and white-colored spaces are blue.
2. When there is no text selection all whitespaces should be brown-colored.. Now whitespaces are partly brown, partly white.
Coordinator
Feb 15, 2008 at 2:52 AM
OK I've confirmed it now and I'm pretty sure this is a Scintilla bug. I've submitted it to the Scintilla Project https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1894195&group_id=2439. Now you're going to have to cross your fingers that Neil will take it because he doesn't seem too fond of the word wrap feature. Otherwise someone else in the community will have to take it.
Coordinator
Feb 15, 2008 at 5:40 PM

Bigg wrote:
...
Everytime the same exception is thrown.

Exception details:

System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object."
Source="ScintillaNet"
StackTrace:
at ScintillaNet.SnippetChooser.setPosition() in E:\ScintillaNET-28319\Branches\2.0\ScintillaNET\Snippets\SnippetChooser.cs:line 81
...


About this: It happens when ScintillaNET is the Startup project. One of the things that doesn't get committed to source control is which project is the startup in the solution. And thus the default is whichever happens to be highlighted in the Solution Explorer. If ScintillaNET is set as startup (which it isn't designed to be, it's a control library) VS will a display control test app, in which 1 of each kind of class that inherits from Control is instanciated. Well some controls like SnipperChooser don't work by themselves and aren't intended to be instantiated by anything outside the Scintilla control context. They have to be hooked up to a Scintilla control, hence the NullReferenceException (no Scintilla).
Aug 5, 2008 at 1:04 AM
Hi

I have been having similar problems getting indicators to work. I found this post and was able to correctly apply style to a range, however I have not had the same success with indicators.
I have tried the example Bigg posted with a new Win Forms app and the following code in the form constructor:

    Scintilla scintilla1 = new Scintilla();
    scintilla1.Dock = DockStyle.Fill;
    Controls.Add( scintilla1 );

    scintilla1.Styles.Default.BackColor = Color.White;

    scintilla1.Text = @"Test
Test
This is a Test
";

    IList<Range> ranges = scintilla1.FindReplace.FindAll( "test" );

    // This works
    //Style s = scintilla1.Styles[5];
    //s.BackColor = Color.HotPink;
    //ranges.ToList().ForEach( r => r.SetStyle( s.Index ) );

    Indicator i = scintilla1.Indicators[5];
    ranges.ToList().ForEach( r => r.SetIndicator( i.Number ) );

Is there some thing I am missing?

Thanks

BTW this is a great control, I have been using it in one of my projects for a couple of years, thanks.


Coordinator
Aug 5, 2008 at 1:59 AM
Hmm... It works for me, the words get underlined. Perhaps if you want to send me a full working example (rickard234@gmail.com) I can take a look.
Aug 5, 2008 at 3:41 AM
Thanks, knowing that it worked for you was enough for me to track it down to an old version of the scintilla.dll in WINDOWS/Sysem32. I have updated that dll and the SciLexer.dll files from version 1.6.2 to 1.7.6 and it worked first go.
Coordinator
Aug 5, 2008 at 4:02 AM
I'm glad you got it to work. The indicator system changed in Scintilla 1.74, and ScintillaNET only supports the "modern" indicator system.