それでは本題の冒頭に戻ります。System.Windows.Forms を使用してテキスト エディターを作成しています。デフォルトでは、テキスト ボックス コントロールは、含まれているテキストがダブルクリックされたときにイベントを受け入れ、テキスト行全体を強調表示します。この動作を別のものでオーバーライドしたかったのです。これには、このイベントを開始する Windows メッセージをインターセプトし、トリガーされないようにする必要があることがわかりました。これは、私がやっていることをほぼ逐語的に説明している Stackoverflow で見つけたリンクです。
しかし、この説明は不完全です!DoubleClickEvent は EventArgs を継承していることに注意してください。MouseEventArgs から継承する必要があります。これは、画面がクリックされた場所に関する Windows メッセージからの情報が PreviewDoubleClick に必要になるためです。それが私が達成するために着手したタスクです: doubleclick イベントをオーバーライドしますが、それでも Windows メッセージからすべてのクリック情報を送信します。
コードにブレークポイントを設定すると、情報がどこに保存されているかがわかるようになります。メッセージ m にはいくつかのプロパティが含まれており、そのうちの 1 つは LParam と呼ばれます。私が理解しているように、これは取得したいクリック情報へのポインターです。しかし、これは C++ ではありません...ポインタを逆参照することはできません。.NET は便利な Message.GetLParam メソッドを提供して、私を助けてくれます。このメソッドを機能させるのに問題があります。
これが私のコードです:
public class DoubleClickEventArgs : MouseEventArgs
{
public DoubleClickEventArgs(MouseButtons Button, int clicks, int x, int y, int delta) : base (Button, clicks, x, y, delta) { }
public bool Handled
{
get;
set;
}
}
public class NewTextBox : System.Windows.Forms.TextBox
{
public event EventHandler<DoubleClickEventArgs> NewDoubleClick;
private const int WM_DBLCLICK = 0xA3;
private const int WM_LBUTTONDBLCLK = 0x203;
protected override void WndProc(ref Message m)
{
if ((m.Msg == WM_DBLCLICK) || (m.Msg == WM_LBUTTONDBLCLK))
{
DoubleClickEventArgs e = (DoubleClickEventArgs) m.GetLParam(typeof(MouseEventArgs));
if (NewDoubleClick != null)
{
NewDoubleClick(this, e);
}
if (e.Handled)
{
return;
}
}
base.WndProc(ref m);
}
}
ご覧のとおり、サンプルとよく似ています。この行でコンパイルするために私が行ったクレイジーなキャスト DoubleClickEventArgs e = (DoubleClickEventArgs) m.GetLParam(typeof(MouseEventArgs)); 明らかにクラッシュを引き起こしています。エラーが表示されます: このオブジェクトにパラメーターなしのコンストラクターが定義されていません。
それは理にかなっている。DoubleClickEventArgs では、パラメーターを作成する必要があります。しかし、パラメーターは lParam ポインターによって定義されています...ここで少しガイダンスを教えてもらえますか? 私は苦労しています。