2015-02-04 13 views
2

일부 조사를 마친 후 Remove richtextbox SelectionBackColor과 같은 질문을하고 있다고 생각합니다. 나는 똑같은 문제를 겪었지만 질문이 명확하게 설명되지 않았기 때문에 그 실에서의 대답은 불충분하다고 믿는다. 아래를 참조하십시오 :C# RichTextBox 사용자 정의 SelectionBackColor 제거

RichTextBox, 나는 텍스트 (SelectionBackColor)의 모든 사용자 정의 일부에서 BackColor 있지만를를 제거 어떻게 그것을 제어 BackColor을지지 있도록 경우에도 그 BackColor 변화 미래?

텍스트를 강조 표시하고 을 SelectionBackColor으로 변경하는 방법이 있습니다. 전체 컨트롤의 BackColor을 변경하는 또 다른 방법이 있습니다. 이러한 이벤트는 독립적으로 발생할 수 있습니다.

SelectionBackColor을 "제거"하려면 SelectionBackColorColor.Transparent으로 설정하려고 할 수 있지만 흰색이됩니다. 내 RichTextBox현재BackColor이 흰색 인 경우 일시적으로 문제가 없습니다. SelectionBackColor을 현재 BackColor으로 설정하면 다른 방법에서 해당 BackColor가 변경 될 때까지 임시로 이됩니다.

RichTextBox.BackColor이 변경된 후에는 이전에 강조 표시되지 않은 텍스트와 같은 새 색상을 사용하는 대신 이전에 강조 표시된 모든 위치에 흰색 또는 이전 BackColor을 사용합니다.

텍스트 삭제 및 바꾸기를 시도했지만, 내 지식에 따라 텍스트의 다른 사용자 지정 서식을 유지할 수 없게됩니다. SelectionBackColor을 null로 설정하면 작동하지 않습니다.

하나 쉽게 나는 아래의 코드를 사용하는 방법에 대해 이야기하고있는 것을 볼 수 있습니다

protected override void OnLostFocus(EventArgs e) 
{ 
    base.OnLostFocus(e); 
    this.BackColor = Color.Gray; 
    if (SelectionLength > 0) 
    { 
     SelectionBackColor = Color.Yellow; 
    } 
} 

protected override void OnGotFocus(EventArgs e) 
{ 
    base.OnGotFocus(e); 
    this.ResetBackColor(); 
    if (SelectionLength > 0) 
    { 
     // The goal of this line is to "remove" the yellow. 
     // By assigning it any value, it seems to have lost 
     // the ability to use the control's BackColor normally. 
     SelectionBackColor = this.BackColor;// or Color.Transparent 
    } 
} 

입력 텍스트를 사용자 정의로 RichTextBox 객체를 코드로 위의 것은 그것의 작은 부분을 강조 표시 한 다음 상자를 잃는 초점. 강조 표시된 텍스트가 노란색으로 표시됩니다. 그런 다음 상자에 초점을 맞 춥니 다. 노란색 배경은 예상대로 사라질 것입니다. 그러나 텍스트에서 다른 위치로 캐럿을 이동하고 컨트롤의 초점을 다시 잃게되면 이전에 강조 표시된 텍스트가 회색 배경색으로 간주되지 않습니다.

+0

방법에 따라 작동하는 몇 가지 코드를 제공 어떻습니까? –

+0

다른 잠긴 작업 기계에서와 마찬가지로 원본 소스 코드를 사용할 수 없습니다. 위의 간단한 예제를 참조하십시오. – Matthew

+0

나는 이것이 가능하다고 생각하지 않는다. 색상은 텍스트 청크의 값이며 일부 공간에 대한 참조는 아닙니다. 따라서 모든 텍스트를 반복하여 색상을 변경해야합니다. 내가 의미하는 바를 알기 위해 rtf 코드를 들여다 볼 수 있습니다. (그리고 투명도는 어쨌든 실제 색상이 아니기 때문에 여기서는 도움이되지 않을 것입니다.) – TaW

답변

2

이것은 흥미 롭습니다. Windows 7/.Net 3.5에서 (내가 테스트 한 곳과 다른 곳에서) System.Windows.Forms.RichTextBox.SelectionBackColor에 선택 색상을 지우는 버그가있을 수 있습니다. source code을 수행합니다 당신이 발견 한 것처럼 richTextBox.BackColor로 설정하면

public Color SelectionBackColor { 
     set 
     { 
      //Note: don't compare the value to the old value here: it's possible that 
      //you have a different range selected. 
      selectionBackColorToSetOnHandleCreated = value; 
      if (IsHandleCreated) 
      { 
       NativeMethods.CHARFORMAT2A cf2 = new NativeMethods.CHARFORMAT2A(); 
       if (value == Color.Empty) 
       { 
        cf2.dwEffects = RichTextBoxConstants.CFE_AUTOBACKCOLOR; 
       } 
       else 
       { 
        cf2.dwMask = RichTextBoxConstants.CFM_BACKCOLOR; 
        cf2.crBackColor = ColorTranslator.ToWin32(value); 
       } 

       UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), RichTextBoxConstants.EM_SETCHARFORMAT, RichTextBoxConstants.SCF_SELECTION, cf2); 
      } 
     } 
    } 

이, 실제로 다시 색상을 취소하지 않습니다. RichTextBox.DefaultBackColor으로 설정하면 색상을 지우지 않으며 선택 영역의 색상을 기본 회색 조절 색상으로 설정하기 만합니다. 소스 코드가 인 것처럼 보입니다. Color.Empty으로 설정하면 선택 색상을 지우려고합니다.하지만 적어도 내 컴퓨터에서는 아무 것도하지 않습니다.

그러나 메시지를 보내기 전에 빈 색상으로 cf2.dwMask = RichTextBoxConstants.CFM_BACKCOLOR;을 설정하는 확장 방법을 만들면 SetSelectionBackColor(Color.Empty)이 작동합니다.hereherehereherehere에서 적응 상수와 클래스와

public static void SetSelectionBackColor(this RichTextBox richTextBox, Color value) 
    { 
     if (richTextBox.IsHandleCreated && value == Color.Empty) 
     { 
      var cf2 = new CHARFORMAT2(); 

      cf2.dwEffects = RichTextBoxConstants.CFE_AUTOBACKCOLOR; 
      cf2.dwMask = RichTextBoxConstants.CFM_BACKCOLOR; 
      cf2.crBackColor = ColorTranslator.ToWin32(value); 

      UnsafeNativeMethods.SendMessage(new HandleRef(richTextBox, richTextBox.Handle), RichTextBoxConstants.EM_SETCHARFORMAT, RichTextBoxConstants.SCF_SELECTION, cf2); 
     } 
     else 
     { 
      richTextBox.SelectionBackColor = value; 
     } 
    } 

전체에있어서,

public static class RichTextBoxConstants 
{ 
    // http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/RichTextBoxConstants.cs,31b52ac41e96a888 
    /* EM_SETCHARFORMAT wparam masks */ 
    internal const int SCF_SELECTION = 0x0001; 

    internal const int EM_SETCHARFORMAT = (NativeMethods.WM_USER + 68); 

    internal const int CFM_BACKCOLOR = 0x04000000; 

    /* NOTE: CFE_AUTOCOLOR and CFE_AUTOBACKCOLOR correspond to CFM_COLOR and 
     CFM_BACKCOLOR, respectively, which control them */ 
    internal const int CFE_AUTOBACKCOLOR = CFM_BACKCOLOR; 
} 

[StructLayout(LayoutKind.Sequential, Pack = 4)] 
public class CHARFORMAT2 
{ 
    // http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/NativeMethods.cs,acde044a28b57a48 
    // http://pinvoke.net/default.aspx/Structures/CHARFORMAT2.html 

    public int cbSize = Marshal.SizeOf(typeof(CHARFORMAT2)); 
    public int dwMask; 
    public int dwEffects; 
    public int yHeight; 
    public int yOffset; 
    public int crTextColor; 
    public byte bCharSet; 
    public byte bPitchAndFamily; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 
    public string szFaceName; 
    public short wWeight; 
    public short sSpacing; 
    public int crBackColor; 
    public int lcid; 
    public int dwReserved; 
    public short sStyle; 
    public short wKerning; 
    public byte bUnderlineType; 
    public byte bAnimation; 
    public byte bRevAuthor; 
    public byte bReserved1; 
} 

public static class NativeMethods 
{ 
    // http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/NativeMethods.cs,e75041b5218ff60b 

    public const int WM_USER = 0x0400; 

    public static void SetSelectionBackColor(this RichTextBox richTextBox, Color value) 
    { 
     if (richTextBox.IsHandleCreated && value == Color.Empty) 
     { 
      var cf2 = new CHARFORMAT2(); 

      cf2.dwEffects = RichTextBoxConstants.CFE_AUTOBACKCOLOR; 
      cf2.dwMask = RichTextBoxConstants.CFM_BACKCOLOR; 
      cf2.crBackColor = ColorTranslator.ToWin32(value); 

      UnsafeNativeMethods.SendMessage(new HandleRef(richTextBox, richTextBox.Handle), RichTextBoxConstants.EM_SETCHARFORMAT, RichTextBoxConstants.SCF_SELECTION, cf2); 
     } 
     else 
     { 
      richTextBox.SelectionBackColor = value; 
     } 
    } 
} 

public static class UnsafeNativeMethods 
{ 
    // http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/UnsafeNativeMethods.cs,0d546f58103867e3 
    // For RichTextBox 
    // 
    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, [In, Out, MarshalAs(UnmanagedType.LPStruct)] CHARFORMAT2 lParam); 
} 
+0

나는 Color.Empty를 시도했다는 것을 언급하지 않았다. XP 컴퓨터에서 .NET 4.0을 사용하고 있습니다 (잠긴 작업 컴퓨터를 기억하십시오). Color.Empty가 흰색으로 설정되어 나타납니다. 우리는 Windows 8로 마이그레이션 중이며 .NET 4.5에 액세스 할 수 있습니다. 바라건대이 문제는 마이 그 레이션 후 해결하기 위해 간단합니다. 감사합니다. 필자는 여전히 XP에서 솔루션을 통합하는 방법에 대해 살펴볼 것이며, 회사 정책을 전복하지 않고도이 모든 것을 얻을 수 있다고 가정합니다. – Matthew

+0

@Matthew - Win8/.Net 4.5에도 버그가 존재한다고 생각합니다. [참조 소스] (http://referencesource.microsoft.com/#System.Windows.Forms/) 이후로 버그가 수정되었습니다. winforms/Managed/System/WinForms/RichTextBox.cs, d0f4a24face1b591)은 .Net 및 Windows의 최신 버전에 해당합니다. 100 % 확실하지는 않지만 XP에서 작동 할 것입니다.하지만 시도해 볼 수는 있습니다. – dbc

+0

@Matthew - 참조 소스 및 pinvoke.net에서 블록의 상수를 복사했습니다. 그렇게해야한다면 5 또는 6 상수로 줄일 수 있습니다. – dbc