2012-07-25 65 views
5

Điều này làm nổi bật toàn bộ chiều rộng của mỗi dòng bằng cách vẽ màu trong suốt làm màu nền trên dòng hiện tại. Khi đường chuyển mạch, màu nền gốc được khôi phục.Đánh dấu dòng hiện tại của RichTextBox

Vì vậy, những gì chúng tôi muốn làm là:

  1. Xác minh hình chữ nhật trước đó và hiện tại không phù hợp, do đó, không để sơn cùng một khu vực hai lần
  2. Thay thế nổi bật dòng cuối cùng bằng cách sử dụng các điều khiển backcolor
  3. Highlight dòng hiện tại sử dụng một màu trong suốt
  4. Set mLastHighlight với chỉ số và hình chữ nhật cho mỗi dòng áp dụng

Tuy nhiên, khi xóa phần đánh dấu, văn bản sẽ được tô màu. Điều này không xảy ra khi áp dụng tô sáng.

Một giải pháp sẽ là vẽ lại văn bản trên điều khiển sau khi đặt lại màu sau. mặc dù định dạng văn bản, màu sắc lựa chọn, kiểu phông chữ, siêu liên kết, v.v. sẽ tẻ nhạt để lọc. Không phải rất thanh lịch.

Điều này dẫn đến giải pháp đơn giản hơn, làm mới bộ điều khiển. Mặc dù điều đó sẽ gây ra nhấp nháy lớn. Không chấp nhận được.

Có giải pháp thanh lịch không? Tôi hoàn toàn bối rối vì sao điều này xảy ra.

EDIT: Đã chỉnh sửa để phản ánh phản hồi của Code Gray.

using System; 

public class RTBHL : RichTextBox 
{ 
    private LastHighlight mLastHighlight = new LastHighlight(0, Rectangle.Empty); 

    private class LastHighlight 
    { 
     public int mCharIndex; 
     public Rectangle mRectangle; 

     public LastHighlight(int index, Rectangle r) 
     { 
      mCharIndex = index; 
      mRectangle = r; 
     } 
    } 

    public void PaintLineHighlight() 
    { 
     using (Graphics g = this.CreateGraphics) 
     { 
      // highlight color 
      Color c = Color.Beige; 
      // current pen color 
      Pen cp = new Pen(Color.Beige); 
      // color for removing highlight 
      Pen lp = new Pen(this.BackColor); 
      // brush for removing highlight 
      SolidBrush lb = new SolidBrush(this.BackColor); 
      // brush for applying highlight 
      SolidBrush cb = new SolidBrush(Color.FromArgb(64, c.R, c.G, c.B)); 
      // index of the current line 
      int index = this.GetFirstCharIndexOfCurrentLine; 
      // rectangle to specify which region to paint too 
      Rectangle r = new Rectangle(); 

      // specify dimensions 
      r.X = 0; 
      r.Y = this.GetPositionFromCharIndex(index).Y; 
      r.Width = this.HorizontalScrollBarWidth; 
      r.Height = Convert.ToInt32(this.Font.Height * this.ZoomFactor); 

      // this will always be true unless the current line remains the same 
      if (!(mLastHighlight.mCharIndex == index) && !(mLastHighlight.mRectangle == r)) 
      { 
       // remove the last highlight. regardless of the brush specified, white is always applied, and the text is painted over 
       g.DrawRectangle(lp, mLastHighlight.mRectangle); 
       g.FillRectangle(lb, mLastHighlight.mRectangle); 
       // apply highlight to the current line 
       g.DrawRectangle(cp, r); 
       g.FillRectangle(cb, r); 
      } 

      mLastHighlight = new LastHighlight(index, r); 
     } 
    } 

#region RichScrollBars 
    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    private static extern bool GetScrollInfo(IntPtr hWnd, int fnBar, ref SCROLLINFO si); 

    [StructLayout(LayoutKind.Sequential)] 
    public class SCROLLINFO 
    { 
     public int cbSize; 
     public int fMask; 
     public int nMin; 
     public int nMax; 
     public int nPage; 
     public int nPos; 
     public int nTrackPos; 
     public SCROLLINFO() 
     { 
      this.cbSize = Marshal.SizeOf(typeof(SCROLLINFO)); 
     } 

     public SCROLLINFO(int mask, int min, int max, int page, int pos) 
     { 
      this.cbSize = Marshal.SizeOf(typeof(SCROLLINFO)); 
      this.fMask = mask; 
      this.nMin = min; 
      this.nMax = max; 
      this.nPage = page; 
      this.nPos = pos; 
     } 
    } 

    private const int SIF_ALL = 0X17; 
    private const int SB_HORZ = 0; 
    private const int SB_VERT = 1; 

    public int HorizontalScrollBarWidth() 
    { 
     SCROLLINFO si = new SCROLLINFO() {fMask = SIF_ALL}; 
     GetScrollInfo(this.Handle, SB_HORZ, si); 

     return Math.Max(si.nMax, this.Width); 
    } 

    public int VerticalScrollBarHeight() 
    { 
     SCROLLINFO si = new SCROLLINFO() {fMask = SIF_ALL}; 
     GetScrollInfo(this.Handle, SB_VERT, si); 

     return Math.Max(si.nMax, this.Height); 
    } 
#endregion 
} 

Trả lời

3

Vấn đề ở đây là mã bạn đang sao chép được thiết kế cho Scintilla. Các hằng số SCI_* được xác định nội bộ bởi các tiêu đề Scintilla và các thông điệp mà chúng đề cập chỉ có ý nghĩa đối với các điều khiển Scintilla.

Gửi những thư đó tới bộ điều khiển chỉnh sửa gốc của Win32 sẽ không làm gì vì nó không được thiết kế để xử lý các thư đó. (Hoặc tệ hơn, một hoặc nhiều của SCI_* hằng xảy ra xung đột với một hoặc nhiều các định danh thông điệp mà những người giàu có chỉnh sửa kiểm soát không nhận, sản xuất một số hành vi có khả năng hấp dẫn.)

Trừ khi bạn đang thực sự sử dụng một Scintilla chỉnh sửa kiểm soát trong dự án của bạn (mà bạn nói rằng bạn không muốn làm), mã đó sẽ không làm bất cứ điều gì thú vị. Nó không được viết cho điều khiển chỉnh sửa phong phú Win32, nó được viết để giao diện với điều khiển Scintilla.

Điều khiển Scintilla không chỉ là một trình bao bọc xung quanh điều khiển chỉnh sửa phong phú Win32. Nó phải làm một bản vẽ tùy chỉnh để làm cho phép thuật của nó và tất cả mã đó khó có thể tự làm được. Đó là lý do tại sao rất nhiều người sử dụng Scintilla ngay từ đầu. Nếu bạn cần bộ tính năng của nó, tôi khuyên bạn nên làm theo.

Dù sao, tôi thực sự không biết liệu điều này có thể thực hiện được với điều khiển chỉnh sửa phong phú Win32 hay không. Tôi không nghĩ là vậy, nhưng tôi không thể thề với sự thật đó. Tôi đoán bạn có thể hack nó bằng cách thiết lập màu sắc lựa chọn, nhưng điều đó không có vẻ giống như một giải pháp rất tốt. Một cái gì đó như Daniel suggests here. Tôi không phải là một chuyên gia Scintilla, nhưng với đôi mắt chưa được đào tạo của tôi, điều này có vẻ giống như đạo đức tương đương với mã Scintilla của bạn, nhưng được viết cho điều khiển chỉnh sửa phong phú Win32 (thông qua.NET WinForms wrapper của chúng).

+0

Cảm ơn câu trả lời của bạn và xóa thanh toán đó. Tôi đã nghĩ nhiều như vậy sau một vài suy nghĩ. Tuy nhiên, đề xuất Daniels không tô màu toàn bộ dòng. Tôi đã chỉnh sửa mã của mình để bao gồm một nỗ lực nhằm đạt được điều này. –

Các vấn đề liên quan