1

UserControl-derivedいくつかのサブコントロールを持つコントロールがあります(ここでは、3つのドッキングされたラベル)。UserControlの任意の場所をクリックすると反応するために、私override WndProc()

WM_PARENTNOTIFY / WM_LBUTTONCLICK

--これはMSDNで提案されており、うまく機能します。

ユーザーのマウスクリックに対する反応は、(モーダル)ポップアップダイアログを開くことです。ただし、これを実装しようとすると、奇妙な動作が表示されます。ダイアログが数回点滅し、Windowsのサウンドが発生することがあります。ダイアログを閉じた後、ユーザーはメインウィンドウ(UserControlを含む)をクリックしてフォーカスをリセットする必要があります。ちらつきや音が出ないこともありますが、メインフォームもフォーカスを失います。

これとは対照的に、UserControlの横にあるボタンもそのポップアップダイアログを開きます。ちらつきや音はなく、ポップアップを閉じると、メインウィンドウに自動的にフォーカスが戻ります。

UserControl / WndProc構造の何が問題になっていますか?

動作を説明するためのサンプルプロジェクト(VS2008)を含めています:( DropBox経由

4

2 に答える 2

1

BeginInvokeWndProcメソッドが終了した後、を使用してイベントを開始してみてください。

protected override void WndProc(ref Message m) {
  //0x210 is WM_PARENTNOTIFY
  if (m.Msg == 0x210 && m.WParam.ToInt32() == 513)    //513 is WM_LBUTTONCLICK
    {
    Console.WriteLine("## MouseClick on UserControl1 ");
    this.BeginInvoke(new Action(() => UserControlClicked(this, new EventArgs())));
    return;
  }
  /*
  else if (m.Msg == 0x2a1) // WM_MOUSEHOVER
      TTrace.Debug.Send("## WMsg " + m.Msg + " / WParam " + m.WParam.ToInt32());
  */
  base.WndProc(ref m);
}
于 2013-02-04T18:19:52.580 に答える
0

これはおそらく、イベントの処理中にフォームを開いているために発生します。タイマーのタイミングや位置によっては、メインフォームまたはダイアログフォームで保留中のクリックイベントがトリガーされる場合があります。

回避策を提案します。

クリックを検出した後、短時間(50ミリ秒程度)後にダイアログフォームを開くタイマーを開始します。これにより、クリックイベント処理がフォームの開始から切り離されます。このトリックは、この種の問題を何度か解決するのに役立ちました。

于 2013-02-04T18:09:42.913 に答える