2011-02-18 116 views
0

因此,我正在为我喜欢的语言编写简单的代码编辑器。我有语法高亮进行得非常好。 问题是,如果我在我已经写好的文本之前回过头来,它会把我整个指针上的所有事情都挂起来。 这里是我的代码,我的道歉张贴了这么多:C#编写代码编辑器问题

public partial class Form1 : Form 
{ 
    public string MainFontName = "Courier New"; 
    public int MainFontSize = 12; 
    public Color MainFontColor = Color.Black; 

    [DllImport("user32.dll")] // import lockwindow to remove flashing 
    public static extern bool LockWindowUpdate(IntPtr hWndLock); 


    public Regex codeFunctions = new Regex("draw_line|draw_rectangle|draw_circle"); 
    public Regex codeKeywords = new Regex("and|for|while|repeat|or|xor|exit|break|case|switch|if|then|with|true|false"); 

    public Form1() 
    { 
     InitializeComponent(); 

     CodeInput.Font = new Font(MainFontName, MainFontSize, FontStyle.Regular); 
    } 

    private void CodeInput_TextChanged(object sender, EventArgs e) 
    { 
     CodeInput.Font = new Font(MainFontName, MainFontSize, FontStyle.Regular); 
     try 
     { 
      LockWindowUpdate(CodeInput.Handle); 

      int selPos = CodeInput.SelectionStart; 

      CodeInput.Select(0, CodeInput.TextLength); 
      CodeInput.SelectionFont = new Font(MainFontName, MainFontSize, FontStyle.Regular); 
      CodeInput.SelectionColor = Color.Black; 
      CodeInput.SelectionLength = 0; 
      CodeInput.SelectionStart = selPos; 

      //Match the functions 
      foreach (Match keyWordMatch in codeFunctions.Matches(CodeInput.Text)) 
      { 

       CodeInput.Select(keyWordMatch.Index, keyWordMatch.Length); 
       CodeInput.SelectionColor = Color.Red; 

       CodeInput.SelectionStart = selPos; 
       CodeInput.SelectionColor = MainFontColor; 

       CodeInput.SelectionLength = 0; 
      } 
      // Match the keywords 
      foreach (Match keyWordMatch in codeKeywords.Matches(CodeInput.Text)) 
      { 

       Font oFont = new Font(MainFontName, MainFontSize, FontStyle.Bold); 
       Font nFont = new Font(MainFontName, MainFontSize, FontStyle.Regular); 

       CodeInput.Select(keyWordMatch.Index, keyWordMatch.Length); 
       CodeInput.SelectionColor = Color.Blue; 
       CodeInput.SelectionFont = oFont; 

       CodeInput.SelectionStart = selPos; 
       CodeInput.SelectionColor = MainFontColor; 
       CodeInput.SelectionFont = nFont; 

       CodeInput.SelectionLength = 0; 
      } 
     } 
     finally 
     { 
      LockWindowUpdate(IntPtr.Zero); 
     } 
    } 
} 

感谢您的帮助。

+2

指针和win32 API调用停止闪烁?不暂停工作? – 2011-02-18 02:42:05

回答

0

你几乎在正确的轨道上,但尝试阻止WM_PAINT而不是使用API​​调用,我已经在这种类型的项目上工作并成功地实现了语法高亮,其原始源代码如下;

///RadonCodeEditor is the name of Project 
    /// <summary> 
    /// Gets or sets a value whether RadonTextEditor should repaint itself. 
    /// </summary> 
    public bool Repaint = true; 
cKeyword=Color.Blue; 
cComment=Color.Green; 

    /// <summary> 
    /// A Windows generated message send to a control that needs repainting. 
    /// </summary> 
    const short WM_PAINT = 0x00f; 

    /// <summary> 
    /// Contains creation data to call RadonTextEditor. 
    /// </summary> 
    public RadonTextEditor() 
    { 
     SetStyle(ControlStyles.OptimizedDoubleBuffer, true);//Reduces flickering. 
    } 

    /// <summary> 
    /// Overrides default WndProc and handles WM_PAINT message to remove flickering. 
    /// </summary> 
    /// <param name="m">The message in message queue.</param> 
    protected override void WndProc(ref Message m) 
    { 
     if (m.Msg == WM_PAINT)//If the message in the message queue is WM_PAINT. 
     { 
      switch (Repaint) 
      { 
       case true://When we want RadonTextEditor to repaint. 
        base.WndProc(ref m); 
        break; 

       case false://When we don't want RadonTextEditor to repaint. 
        m.Result = IntPtr.Zero; 
        break; 
      } 
     } 
     else//If the message in the message queue is anything else but not WM_PAINT. 
     { 
      base.WndProc(ref m); 
     } 
    } 
//Import namespace System.Text.RegularExpressions 
/// <summary> 
    /// Checks the input text for any contained comments using a defined Regular Expression. 
    /// </summary> 
    /// <param name="Text">The text to check.</param> 
    /// <param name="FirstCharIndex">The first character index of current line.</param> 
    /// <param name="CaretPosition">The position of caret.</param> 
    /// <param name="rtb">The handle to RichTextBox for highlighting.</param> 
    /// <returns>If the input text contains any text the return value is true otherwise false.</returns> 
    public void IsComment(string Text, int FirstCharIndex, int CaretPosition, RichTextBox rtb) 
    { 
     rComment = new Regex(@"\/\/.*$", RegexOptions.Compiled); 
     MatchCollection Matches = rComment.Matches(Text); 
     foreach (Match match in Matches) 
     { 
      rtb.Select(match.Index + FirstCharIndex, match.Length); 
      rtb.SelectionColor = cComment; 
      rtb.DeselectAll(); 
      rtb.SelectionStart = CaretPosition; 

     } 
     rMultiComment = new Regex(@"/\*.*?\*/", RegexOptions.Multiline); 
     MatchCollection Matches2 = rMultiComment.Matches(Text); 
     foreach (Match match2 in Matches2) 
     { 
      rtb.Select(match2.Index + FirstCharIndex, match2.Length); 
      rtb.SelectionColor = cComment; 
      rtb.DeselectAll(); 
      rtb.SelectionStart = CaretPosition; 
     } 
    } 

    /// <summary> 
    /// Checks the input text for any contained keywords using a defined Regular Expression. 
    /// </summary> 
    /// <param name="Text">The text to check.</param> 
    /// <param name="FirstCharIndex">The first character index of current line.</param> 
    /// <param name="CaretPosition">The position of caret.</param> 
    /// <param name="rtb">The handle to RichTextBox for highlighting.</param> 
    /// <returns>If the input text contains any text the return value is true otherwise false.</returns> 
    public void IsKeyword(string Text, int FirstCharIndex, int CaretPosition, RichTextBox rtb) 
    { 
     rKeyword = new Regex(@:\bint\b|\bdouble\b|\bstring\b", RegexOptions.Compiled); 
     MatchCollection Matches = rKeyword.Matches(Text); 
     foreach (Match match in Matches) 
     { 
      rtb.Select(match.Index + FirstCharIndex, match.Length); 
      rtb.SelectionColor = cKeyword; 
      rtb.DeselectAll(); 
      rtb.SelectionStart = CaretPosition; 
     } 
    } 

就是这样,请致电TextChange事件处理函数和由注释所传递所需的函数的参数(我知道这是一个有点乱,因为我有直接粘贴从我有项目的源代码。)如果还有什么问题,我很乐意帮助你。