|
Any word on this and whether there is a later version of the code that provides a fix for this problem?
thanks
|
|
|
|
|
You are correct that there is a bug in Uri's code concerning close tokens that are the same as the open token I just used the control today (thanks, Uri ) for highlighting some C# code, so I fixed the problem. Replace the 'case' shown here and you should be in business:
case DescriptorType.ToCloseToken:
{
int closeStart = i + hd.Token.Length;
while((line.IndexOf(hd.CloseToken, closeStart) == -1) && (lineCounter < lines.Length))
{
sb.Append(line.Remove(0, i));
lineCounter++;
if (lineCounter < lines.Length)
{
AddNewLine(sb);
line = lines[lineCounter];
i = closeStart = 0;
}
else
i = closeStart = line.Length;
}
int closeIndex = line.IndexOf(hd.CloseToken, closeStart);
if (closeIndex != -1)
{
sb.Append(line.Substring(i, closeIndex + hd.CloseToken.Length - i) );
line = line.Remove(0, closeIndex + hd.CloseToken.Length);
tokenCounter = 0;
tokens = mCaseSensitive ? line.Split(separators) : line.ToUpper().Split(separators);
SetDefaultSettings(sb, colors, fonts);
i = 0;
}
break;
}
|
|
|
|
|
Thanks for the reply Ken.
I haven't had a close look at the code yet (I don't know much c# unfortunately) but I'm going to see if I can fix the performance problems that someone else mentioned.
When dealing with large amounts of text, performance slows down. I suspect that the whole document is being parsed when perhaps it would only be necessary to parse the current line that the cursor is on.
|
|
|
|
|
I have applied the fix you showed, but it still doesn't seem to work.
How do you define the HighlightDescriptor for string literals?
|
|
|
|
|
Strange - that fixed the problem for me. It's in that one case where the bug was - it wasn't skipping past the open token before searching for the close token, so if they were the same it would treat the open also as a close.
Anyway, it works for me now. Here's an example of using it for double & single quotes:
textBox.HighlightDescriptors.Add(new HighlightDescriptor("\"", "\"", Color.Maroon, null, DescriptorType.ToCloseToken, DescriptorRecognition.StartsWith, false));
textBox.HighlightDescriptors.Add(new HighlightDescriptor("'", "'", Color.Olive, null, DescriptorType.ToCloseToken, DescriptorRecognition.StartsWith, false));
|
|
|
|
|
Got it! I had added ' and " as separators, and that apparently broke the highlight descriptors.
|
|
|
|
|
Great job, but i've got a one problem with this code. If you escape the the " or ' like "this \"is\" a string" or 'this \'is\' a string' the color shouldn't stop at the word is.
|
|
|
|
|
Great Solution! Thank you.
It worked peferct!
chabber
|
|
|
|
|
Hi,
is it possible to do something like:
class1.method1
class1.method2
class1.method2
i want to enter "class1." and then a list with methods 1-3 should be displayed.
Is it possible?
regards, h2
|
|
|
|
|
Can not input Chinese characters.
How solve?
thks
不能输入中文。
如何解决
|
|
|
|
|
try to define your charset in method
protected override void OnTextChanged(EventArgs e)
Look into StringBuilder creation.
For RTF file format look here:
http://www.biblioscape.com/rtf15_spec.htm
hsmishka
|
|
|
|
|
can you teach me how to user Chinese characters?
吴建明
|
|
|
|
|
For Eeas Asian People, Micrsoft provide special support(?).
You have to change two parts of this control codes.
(As I am Korean, so I write for Koreans. Sorry for that, but you can find
yours in RTF Specification)
1) OnTextChanged
original: sb.Append(@"{\rtf1\fbidis\ansi\ansicpg1255\deff0\deflang1037{\fonttbl{");
Korean Version: sb.Append(@"{\rtf1\fbidis\ansi\ansicpg949\deff0\deflang1042\deflangfe1042{\fonttbl{");
- ansicpg1255, deflang1037 means Hebrew(949,1042 means Korean)
- For EastAsian, you must add deflang + langnumber(in my case
deflangfe1042), otherwise RichTextBox cann't control double byte
characters
But, still your text in this control looks weird. That's why you have something to do next.2) AddFontToTable
original: sb.Append(@"\f").Append(counter).Append(@"\fnil\fcharset0").Append(font.Name).Append(";}");
Korean Version: sb.Append(@"\f").Append(counter).Append(@"\fnil\fcharset1").Append(font.Name).Append(";}");
- fcharset0 means ANSI
- fcharset1 means default
- fcharset129 means Korean
I don't know the difference between 1 and 129.
Both works fine.
Have a good luck
Walk Everyday give you a healthy living.
|
|
|
|
|
Get your C# game up and make the tab key work properly or at least functional.
|
|
|
|
|
Can you say what's wrong with the TAB key in your opinion, or at least tell me how to reproduce the problem?
|
|
|
|
|
I think he means the tab-key behavior of Visual Studio. There the tab-key is used to select an item and close the listbox.
regards h2
|
|
|
|
|
NO, thats not what I mean.
Quantum Quinn Inc.
|
|
|
|
|
I didn't understand what you mean, but try this
SyntaxHighlightingTextBox shtb = new SyntaxHighlightingTextBox();
shtb.AcceptsTab = true;
Regards,
|
|
|
|
|
The tab problem i have is, assume that SELECT is a keyword and it is supposed to highlight in blue.
if i use tab character along with SELECT (before or after the word SELECT), the coloring is gone.i believe if a word is padded with tab characters in front or at the back. it fails to recogonise as keyword
|
|
|
|
|
i found the solution too.. just add Seperators.Add('\t'); which represents tab character.. sorry for the earlier post
|
|
|
|
|
it IS fast, but adding all the keywords in the source code seems crazy.
any chance to support syntax file?
Regards,
unruledboy@hotmail.com
|
|
|
|
|
It would be good to have that.
In the mean time if you need to add many keywords, use a text edit which support macro (such as PFE or Textpad) to write code for you.
|
|
|
|
|
Hi All!!
I have used next code:
private void LoadSettings()
{
ScriptHighLightSettings.Separators = new char[] {
' ', '\r', '\n', ',', '*', '/'
,'.', '-', '+', ':', '(', ')'
,';'
};
ScriptHighLightSettings.KeyWords = new StringCollection();
ScriptHighLightSettings.ExtKeyWords = new StringCollection();
try
{
// Create an instance of StreamReader to read from a file.
// The using statement also closes the StreamReader.
using (StreamReader sr = new StreamReader("scredkeywords"))
{
String line;
String parsingMode = String.Empty;
// Read and display lines from the file until the end of
// the file is reached.
while ((line = sr.ReadLine()) != null)
{
if(parsingMode == String.Empty)
{
if(line == "[KEYWORDS]")
{
parsingMode = line;
}
if(line == "[EXTKEYWORDS]")
{
parsingMode = line;
}
Console.WriteLine(line);
continue;
}
if(line == "")
{
parsingMode = String.Empty;
}
switch (parsingMode)
{
case "[KEYWORDS]":
{
ScriptHighLightSettings.KeyWords.Add(line);
Console.WriteLine(line);
break;
}
case "[EXTKEYWORDS]":
{
ScriptHighLightSettings.ExtKeyWords.Add(line);
Console.WriteLine(line);
break;
}
default:
{
parsingMode = String.Empty;
break;
}
}
}
}
}
catch (Exception e)
{
// Let the user know what went wrong.
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
ScriptHighLightSettings.CommentsColor = Color.Green;
ScriptHighLightSettings.ErrorsColor = Color.Red;
ScriptHighLightSettings.KeyWordsColor = Color.Blue;
ScriptHighLightSettings.ExtKeyWordsColor = Color.Purple;
ScriptHighLightSettings.NumbersColor = Color.LightPink;
ScriptHighLightSettings.StringsColor = Color.LightSeaGreen;
}
My "scredkeywords" file:
[KEYWORDS]
function
if
then
end
nil
local
table
[EXTKEYWORDS]
vec3f
vec2f
camera
Game
SceneManager
NodeGraph
That's all
|
|
|
|
|
RichTextBox is generally broke with drag & drop and multible undo not really working. Implementing syntax highlighting in RichTextBox is a hack that hardly can work without being painful slow and flickering. I would rather use the rock solid Scintilla. With the help of scide which is very mature and Reflector looking at the WinForms code I made a simple Scintilla control, it lacks seriously features, currently I don't need more features for myself.
<br />
Imports System<br />
Imports System.Runtime.InteropServices<br />
Imports System.IO<br />
Imports System.ComponentModel<br />
Imports System.Text<br />
<br />
Imports Stax<br />
Imports Stax.UI<br />
Imports Stax.Win32<br />
<br />
Namespace UI<br />
Public Class Scintilla<br />
Inherits Control<br />
<br />
Private ScintillaHandle As IntPtr<br />
Private DirectPointer As Integer<br />
Private Initialized As Boolean<br />
<br />
Public Sub New()<br />
Dim path As String = CommonDirs.Startup + "SciLexer.dll"<br />
<br />
If File.Exists(path) Then<br />
MyBase.SetStyle(ControlStyles.UserPaint, False)<br />
MyBase.SetStyle(ControlStyles.UseTextForAccessibility, False)<br />
MyBase.SetStyle((ControlStyles.StandardDoubleClick Or ControlStyles.StandardClick), False)<br />
<br />
LoadLibrary("SciLexer.dll")<br />
<br />
ScintillaHandle = CreateWindowEx(0, "Scintilla", "", _<br />
WS.CHILD Or WS.VISIBLE Or WS.TABSTOP, 0, 0, _<br />
Width, Height, Handle, 0, IntPtr.Zero, Nothing)<br />
<br />
DirectPointer = CInt(SlowPerform(2185, 0, 0))<br />
SPerform(2037, CType(65001, UInt32), 0) 'Unicode<br />
<br />
Application.AddMessageFilter(New MessageFiler(AddressOf MessageCallback))<br />
<br />
Initialized = True<br />
Else<br />
BackColor = Color.White<br />
End If<br />
End Sub<br />
<br />
Private Sub MessageCallback(ByRef m As Message, ByRef cancel As Boolean)<br />
If m.HWnd = ScintillaHandle Then<br />
Select Case m.Msg<br />
Case WM.LBUTTONDOWN, WM.RBUTTONDOWN<br />
If Not Focused Then<br />
FindForm.ActiveControl = Me<br />
End If<br />
Case 256, 257, 258, 260, 261 'implements all key event<br />
If CType(GetType(Control).InvokeMember("ProcessKeyMessage", _<br />
Reflection.BindingFlags.Instance Or _<br />
Reflection.BindingFlags.InvokeMethod Or _<br />
Reflection.BindingFlags.NonPublic, _<br />
Nothing, Me, New Object() {m}), Boolean) Then<br />
<br />
cancel = True<br />
End If<br />
End Select<br />
End If<br />
End Sub<br />
<br />
Protected Overrides Function IsInputKey(ByVal keyData As Keys) As Boolean<br />
If (keyData And Keys.Alt) <> Keys.Alt Then<br />
Dim data As Keys = keyData And Keys.KeyCode<br />
<br />
If data <> Keys.Tab Then<br />
Select Case data<br />
Case Keys.Prior, Keys.Next, Keys.End, Keys.Home, _<br />
Keys.Left, Keys.Up, Keys.Right, Keys.Down<br />
<br />
Return True<br />
End Select<br />
Else<br />
Return ((keyData And Keys.Control) = Keys.None)<br />
End If<br />
End If<br />
<br />
Return MyBase.IsInputKey(keyData)<br />
End Function<br />
<br />
#Region " Properties "<br />
Private ReadOnlyValue As Boolean<br />
<br />
<Category("Scintilla"), DefaultValue(False)> _<br />
Public Property [ReadOnly]() As Boolean<br />
Get<br />
If Initialized Then<br />
Return SPerform(2140, 0, 0) <> 0<br />
Else<br />
Return ReadOnlyValue<br />
End If<br />
End Get<br />
Set(ByVal value As Boolean)<br />
ReadOnlyValue = value<br />
<br />
If Initialized Then<br />
If value Then<br />
SPerform(2171, CType(1, System.UInt32), 0)<br />
Else<br />
SPerform(2171, CType(0, System.UInt32), 0)<br />
End If<br />
End If<br />
End Set<br />
End Property<br />
<br />
Public ReadOnly Property Length() As Integer<br />
Get<br />
Return CInt(SPerform(2006, 0, 0))<br />
End Get<br />
End Property<br />
<br />
Private TextValue As String = ""<br />
<br />
Public Overrides Property Text() As String<br />
Get<br />
If Initialized Then<br />
Dim buffer As Byte() = New Byte(Length) {}<br />
Dim ptr As IntPtr = Marshal.AllocHGlobal(buffer.Length)<br />
SPerform(2182, CType(buffer.Length, UInt32), CType(ptr, UInteger))<br />
Marshal.Copy(ptr, buffer, 0, buffer.Length)<br />
Marshal.FreeHGlobal(ptr)<br />
Return UTF8Encoding.UTF8.GetString(buffer, 0, buffer.Length)<br />
End If<br />
<br />
Return TextValue<br />
End Get<br />
Set(ByVal value As String)<br />
TextValue = value<br />
<br />
If Initialized Then<br />
If value Is Nothing Then<br />
value = ""<br />
End If<br />
<br />
Dim buffer As Byte() = UTF8Encoding.UTF8.GetBytes(value + ChrW(0))<br />
Dim ptr As IntPtr = Marshal.AllocHGlobal(buffer.Length)<br />
Marshal.Copy(buffer, 0, ptr, buffer.Length)<br />
SPerform(2181, 0, CType(ptr, UInteger))<br />
Marshal.FreeHGlobal(ptr)<br />
End If<br />
End Set<br />
End Property<br />
<br />
Protected Overrides ReadOnly Property CreateParams() As CreateParams<br />
Get<br />
Dim ret As CreateParams = MyBase.CreateParams<br />
ret.ExStyle = ret.ExStyle Or CInt(WS.EX_CLIENTEDGE)<br />
Return ret<br />
End Get<br />
End Property<br />
#End Region<br />
<br />
#Region " Focus Management "<br />
Private Function GetScintillaFocus() As Boolean<br />
'Debug.WriteLine("GetScintillaFocus")<br />
<br />
If Initialized Then<br />
Return SPerform(2381, 0, 0) <> 0<br />
End If<br />
End Function<br />
<br />
Private Sub SetScintillaFocus(ByVal focus As Boolean)<br />
If Initialized Then<br />
If focus Then<br />
'Debug.WriteLine("SetScintillaFocus true")<br />
SPerform(2380, CType(1, System.UInt32), 0)<br />
Else<br />
'Debug.WriteLine("SetScintillaFocus false")<br />
SPerform(2380, CType(0, System.UInt32), 0)<br />
End If<br />
End If<br />
End Sub<br />
<br />
Protected Overrides Sub OnGotFocus(ByVal e As EventArgs)<br />
'Debug.WriteLine("OnGotFocus")<br />
SetScintillaFocus(SetFocus(ScintillaHandle) <> IntPtr.Zero)<br />
End Sub<br />
<br />
Protected Overrides Sub OnLostFocus(ByVal e As EventArgs)<br />
'Debug.WriteLine("OnLostFocus")<br />
SetScintillaFocus(False)<br />
End Sub<br />
<br />
Public Overrides ReadOnly Property Focused() As Boolean<br />
Get<br />
'Debug.WriteLine("Focused")<br />
Return GetScintillaFocus()<br />
End Get<br />
End Property<br />
#End Region<br />
<br />
#Region " Native Functions "<br />
<DllImport("kernel32")> _<br />
Private Shared Function LoadLibrary(ByVal lpLibFileName As String) As IntPtr<br />
End Function<br />
<br />
<CLSCompliant(False), DllImport("user32")> _<br />
Private Shared Function CreateWindowEx(ByVal dwExStyle As UInteger, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As UInteger, ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer, ByVal hWndParent As IntPtr, ByVal hMenu As Integer, ByVal hInstance As IntPtr, ByVal lpParam As String) As IntPtr<br />
End Function<br />
<br />
<CLSCompliant(False), DllImport("user32.dll")> _<br />
Private Shared Function SendMessage(ByVal hWnd As Integer, ByVal msg As UInt32, ByVal wParam As Integer, ByVal lParam As Integer) As Integer<br />
End Function<br />
<br />
<DllImport("user32.dll")> _<br />
Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As Integer, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As Integer) As Integer<br />
End Function<br />
<br />
<CLSCompliant(False), DllImport("scilexer.dll", EntryPoint:="Scintilla_DirectFunction")> _<br />
Private Shared Function Perform(ByVal directPointer As Integer, ByVal message As UInt32, ByVal wParam As UInt32, ByVal lParam As UInt32) As Integer<br />
End Function<br />
<br />
<CLSCompliant(False)> _<br />
Private Function SlowPerform(ByVal message As UInt32, ByVal wParam As UInt32, ByVal lParam As UInt32) As UInt32<br />
Return CType(SendMessage(CInt(ScintillaHandle), message, CInt(wParam), CInt(lParam)), UInt32)<br />
End Function<br />
<br />
<CLSCompliant(False)> _<br />
Private Function SPerform(ByVal message As UInt32, ByVal wParam As UInt32, ByVal lParam As UInt32) As UInt32<br />
Return CType(Perform(DirectPointer, message, wParam, lParam), UInt32)<br />
End Function<br />
<br />
<DllImport("user32.dll")> _<br />
Public Shared Function SetFocus(ByVal hwnd As IntPtr) As IntPtr<br />
End Function<br />
#End Region<br />
<br />
#Region " Event Handlers "<br />
Private Sub Scintilla_Resize(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Resize<br />
If Initialized Then<br />
SetWindowPos(ScintillaHandle, 0, ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height, 0)<br />
End If<br />
End Sub<br />
#End Region<br />
<br />
End Class<br />
End Namespace<br />
|
|
|
|
|
I downloaded Scintilla/SciTE, it supports many syntax, very interesting indeed.
Try to use your code and found that you have the following imports
Imports Stax
Imports Stax.UI
Imports Stax.Win32
What are they?
It would be great if the author/someone convert the Scintilla to .net managed code.
|
|
|
|
|