2011-02-18 117 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事件處理函數和由註釋所傳遞所需的函數的參數(我知道這是一個有點亂,因爲我有直接粘貼從我有項目的源代碼。)如果還有什麼問題,我很樂意幫助你。