2011-02-18 4 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 호출이 깜박임을 중지하겠습니까? 레이아웃 작업을 일시 중지하지 않습니까? –

+1

[미치 (Mitch)의 말] (http://msdn.microsoft.com/en-us/library/system.windows.forms.control.suspendlayout.aspx). –

+0

오, 나는 suspendlayout에 대해 들어 본 적이 없었습니다. 고마워요. 내 문제가 뭔지 생각해? – pajm

답변

0

거의 올바른 경로에 있지만 API 호출 대신 WM_PAINT를 차단하려고합니다.이 유형의 프로젝트에서 작업했으며 구문 강조 표시를 성공적으로 구현했습니다. 원본 소스 코드는 아래와 같습니다.

///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 이벤트 처리기에서 두 함수를 호출과 의견에 의해 설명 된 기능에 필요한 인수를 전달 (내가 직접 내가이 프로젝트의 소스 코드를 붙여 넣은 때문에 조금 지저분한 알고있다.) 그래도 뭔가 잘못되면 기꺼이 도와 드리겠습니다.