1. 結論
書式設定をするだけでもTextChanged
イベントが発生する。
2. 実験
2.1 実験用コード
using System;
using System.Drawing;
using System.Windows.Forms;
class RichTextBoxTest:Form
{
RichTextBox rtxt;
RichTextBoxTest()
{
ClientSize = new Size(400,300);
Controls.Add( rtxt = new RichTextBox() {
Multiline = true,
Location = new Point(0,0),
Size = new Size(400,270),
});
Button btn;
Controls.Add( btn = new Button() {
Location = new Point(0,270),
Size = new Size(400,30),
Text = "SetColor",
});
rtxt.TextChanged += Rtxt_TextChanged;
btn.Click += (s,e)=>{SetColor();};
}
void Rtxt_TextChanged(object sender, EventArgs e)
{
Console.WriteLine("TextChanged called.");
}
void SetColor()
{
Console.WriteLine("setting SelectionBackColor.");
rtxt.SelectionBackColor = Color.Yellow;
Console.WriteLine("setting SelectionColor.");
rtxt.SelectionColor = Color.Blue;
Font fontForTest = new Font("MS ゴシック", 12);
Console.WriteLine("setting SelectionFont.");
rtxt.SelectionFont = fontForTest;
Console.WriteLine("end of UpdateColor.");
}
[STAThread]
public static void Main(string[] args)
{
Application.Run(new RichTextBoxTest());
}
}
2.2. 実行結果
RichTextBoxにテキストを1文字入力して、全選択し、ボタンを押した結果。
TextChanged called.
setting SelectionBackColor.
TextChanged called.
setting SelectionColor.
TextChanged called.
setting SelectionFont.
TextChanged called.
end of UpdateColor.
RichTextBoxの以下のいずれのプロパティに対しても、設定時に TextChanged
イベントが発生しています。
SelectionBackColor
SelectionColor
SelectionFont
3. 内部仕様調査
3.1. 仕様記載
仕様記載上は、そのようには読み取れない。
Control.TextChanged Event (System.Windows.Forms) | Microsoft Docs
Occurs when the Text property value changes.
3.2. 内部コード
dotnet451\Source\ndp\fx\src\WinForms\Managed\System\WinForms
public Color SelectionColor {
get {
省略
}
set {
ForceHandleCreate();
NativeMethods.CHARFORMATA cf = GetCharFormat(true);
cf.dwMask = RichTextBoxConstants.CFM_COLOR;
cf.dwEffects = 0;
cf.crTextColor = ColorTranslator.ToWin32(value);
// set the format information
UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), RichTextBoxConstants.EM_SETCHARFORMAT, RichTextBoxConstants.SCF_SELECTION, cf);
}
}
明示的にTextChangedイベントを発火させている処理は見当たらない。
SendMessage
が要因っぽい予感。
WindowsのMessageを処理してTextChanged
イベントを発火しているのは、継承元のTextBoxBase
クラスのよう。
private void WmReflectCommand(ref Message m) {
if (!textBoxFlags[codeUpdateText] && !textBoxFlags[creatingHandle]) {
if (NativeMethods.Util.HIWORD(m.WParam) == NativeMethods.EN_CHANGE && CanRaiseTextChangedEvent) {
OnTextChanged(EventArgs.Empty);
}
省略
}
}
確証が持てないが、
UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), RichTextBoxConstants.EM_SETCHARFORMAT, RichTextBoxConstants.SCF_SELECTION, cf);
が
NativeMethods.Util.HIWORD(m.WParam) == NativeMethods.EN_CHANGE
を満たすメッセージを発火しているのではないか。
3.3. Window Messageを監視してみる
3.3.1. テストコード
RichTextBox
を、下記に置き換えてRichTextBox
のWindowメッセージを監視してみた。
public class MyRichTextBox:RichTextBox
{
protected override void WndProc(ref Message m)
{
long wparam = m.WParam.ToInt64();
long lparam = m.LParam.ToInt64();
Console.Write( "Msg:0x" + m.Msg.ToString("X08"));
Console.Write(" Wparam:0x" + wparam.ToString("X08"));
Console.Write(" Lparam:0x" + lparam.ToString("X08"));
Console.WriteLine();
base.WndProc(ref m);
}
}
3.3.2. 結果
setting SelectionBackColor.
Msg:0x00000444 Wparam:0x00000001 Lparam:0x00D3E460
Msg:0x00002111 Wparam:0x030007CC Lparam:0x000707CC
TextChanged called.
setting SelectionColor.
Msg:0x0000043A Wparam:0x00000001 Lparam:0x00D3E440
Msg:0x00000444 Wparam:0x00000001 Lparam:0x00D3E4B0
Msg:0x00002111 Wparam:0x030007CC Lparam:0x000707CC
TextChanged called.
setting SelectionFont.
Msg:0x00000444 Wparam:0x00000001 Lparam:0x00D3E470
Msg:0x00002111 Wparam:0x030007CC Lparam:0x000707CC
TextChanged called.
end of UpdateColor.
UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), RichTextBoxConstants.EM_SETCHARFORMAT, RichTextBoxConstants.SCF_SELECTION, cf);
が
NativeMethods.Util.HIWORD(m.WParam) == NativeMethods.EN_CHANGE
を満たすメッセージを発火しているのではないか。
内部コードをみると、
-
EM_SETCHARFORMAT
は0x444
. -
EN_CHANGE
は0x0300
.
に対して、結果として、
Msg:0x00000444 Wparam:.......... Lparam:........
Msg:.......... Wparam:0x0300.... Lparam:........
が得られているため、推測の裏どりが取れた。