Странное поведение с UserControl, WndProc и focus

У меня есть UserControl-derived управление несколькими подэлементами управления (здесь: три закрепленных ярлыка). Чтобы реагировать на клик в любом месте UserControl, я override WndProc() и искать

WM_PARENTNOTIFY / WM_LBUTTONCLICK

- это было предложено на MSDN, и это работает хорошо.

Реакция на щелчок мышью пользователя заключается в открытии (модального) всплывающего диалога. Однако, когда я пытаюсь реализовать это, появляется странное поведение: иногда диалоговое окно мигает несколько раз, и появляется звук Windows. После закрытия диалогового окна пользователь должен щелкнуть в главном окне (содержащем UserControl), чтобы заново установить фокус. Иногда нет мерцания и звука, но основная форма также теряет фокус.

В отличие от этого кнопка рядом с UserControl также открывает это всплывающее диалоговое окно. Нет мерцания и звука, и после закрытия всплывающего окна главное окно автоматически снова фокусируется.

Что не так с конструкцией UserControl/WndProc?

Я включаю пример проекта (VS2008), чтобы проиллюстрировать поведение: ( через DropBox)

2 ответа

Решение

Попробуйте использовать BeginInvoke чтобы запустить событие после завершения метода WndProc:

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);
}

Это, вероятно, происходит, потому что вы открываете форму во время обработки события. В зависимости от времени и / или положения таймера событие ожидающего нажатия может быть вызвано для главной формы или для диалоговой формы.

Я предлагаю обходной путь.

После обнаружения щелчка запустите таймер, который открывает диалоговую форму через короткое время (50 мс или около того). Это отделяет обработку события щелчка от открытия формы. Этот прием помог мне решить эту проблему несколько раз.

Другие вопросы по тегам