Событие MouseEnter не срабатывает при открытии панели меню.

У меня есть menuStrip с несколькими элементами и кнопка в другой части формы. Когда мышь входит в кнопку, она что-то делает (событие MouseEnter). Проблема, которую я получаю, заключается в том, что при открытии панели меню, если мышь входит в кнопку, событие MouseEnter не запускается. Есть ли способ стрелять, пока открыта меню?

Чтобы увидеть это графически, вот что я делаю:

введите описание изображения здесь

У меня есть меню, и для каждого родительского пункта меню есть кнопка. Кнопка будет над ним, поэтому единственной видимой частью меню будет контейнер с их дочерними элементами.

Теперь, когда мышь входит в кнопку, например «Система», она выполняет щелчок по пункту меню. Вот почему появляется контейнер. Но после открытия, если я хочу открыть любой другой контейнер других родителей, я должен сначала щелкнуть, чтобы потерять фокус. Затем я хочу сделать это, не щелкая мышью.

Я хочу, чтобы поведение было похоже на то, что есть в меню. Например, если система открыта, и мышь входит в список клиентов, она автоматически закрывает систему и открывает клиентов.

введите описание изображения здесь


person Andres    schedule 02.03.2013    source источник
comment
какой тип огня вы хотите такой ... нажатие клавиши, функциональной клавиши и так далее ????????????   -  person DOT.NET    schedule 03.03.2013
comment
Как событие сработает, когда в центре внимания ваше меню ??? Вы можете сосредоточить внимание на одном элементе управления за раз.   -  person Shaharyar    schedule 03.03.2013
comment
просто выберите menuStrip и нажмите функциональную клавишу f4 ... откройте диалоговое окно свойств ... перейдите к событию и выберите любой желаемый тип .......   -  person DOT.NET    schedule 03.03.2013
comment
Мне просто нужно такое же поведение, как когда мышь входит в другой родительский элемент меню. Он просто открывает один и закрывает остальные. Итак, когда мышь находится над кнопкой, я хочу закрыть все открытые элементы меню. Это потому, что кнопка будет той, которая открывает определенный пункт меню.   -  person Andres    schedule 03.03.2013
comment
Если вы можете показать изображения, чтобы мы могли лучше понять вашу проблему.   -  person Shaharyar    schedule 03.03.2013
comment
поделитесь своей частью кодирования, чтобы лучше понять   -  person DOT.NET    schedule 03.03.2013
comment
Добавлены ребята, надеюсь, теперь это легче понять.   -  person Andres    schedule 03.03.2013
comment
Мне кажется, что вам нужно реализовать IMessageFilter в своем приложении и перенаправить желаемое событие мыши. Мне пришлось сделать это с событиями MouseWheel, чтобы они не попадали в неотзывчивый элемент управления в Z-порядке.   -  person Pieter Geerkens    schedule 03.03.2013
comment
Спасибо @PieterGeerkens. У вас, кстати, нет примера кода, чтобы показать мне?   -  person Andres    schedule 03.03.2013
comment
Сейчас я боюсь, что меня накажут за размещение ссылок на другие веб-сайты (где я впервые это увидел), а также за размещение, возможно, комментариев, которые модераторы считают комментариями.   -  person Pieter Geerkens    schedule 03.03.2013


Ответы (1)


Посмотрим, верен ли это ответ:

#region IMessageFilter implementation
/// <summary> Redirect WM_MouseWheel messages to window under mouse.</summary>
    /// <remarks>Redirect WM_MouseWheel messages to window under mouse (rather than 
/// that with focus) with adjusted delta.
/// <see cref="http://www.flounder.com/virtual_screen_coordinates.htm"/>
/// Dont forget to add this to constructor:
///             Application.AddMessageFilter(this);
///</remarks>
    /// <param name="m">The Windows Message to filter and/or process.</param>
    /// <returns>Success (true) or failure (false) to OS.</returns>
    [System.Security.Permissions.PermissionSetAttribute(
        System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
    bool IMessageFilter.PreFilterMessage(ref Message m) {
        // Determine window and control at these coordinates.
  //var pos   = WindowsMouseInput.GetPointLParam(m.LParam);
        var hWnd  = WindowFromPoint( WindowsMouseInput.GetPointLParam(m.LParam) );
        var ctl   = Control.FromHandle(hWnd);
  if (hWnd != IntPtr.Zero  &&  hWnd != m.HWnd  &&  ctl != null) {
    switch(m.Msg) {
      default:  return false;
      case (int)WM.MOUSEWHEEL:
        DebugTracing.Trace(TraceFlag.ScrollEvents, true," - {0}.WM.MouseWheel: {1}", 
                                                    Host.Name, ((WM)m.Msg).ToString()); 
        if (ctl is MapPanel) {
          var keyState    = WindowsMouseInput.GetKeyStateWParam(m.WParam);
          var mult            = keyState.HasFlag(MouseKeys.Control) ? 5 : 1;
          keyState            = keyState &= ~MouseKeys.Control;
          var wheelDelta    = WindowsMouseInput.WheelDelta(m.WParam);
          // forward delta of +/- 30 instead of +/- 120; 30/120 == 1/4
          var newWparam   = WindowsMouseInput.WParam((Int16)(mult*wheelDelta/4), keyState);
          SendMessage(hWnd, m.Msg, newWparam, m.LParam);
          return true;
        } else if (ctl is MapFormOverview) {
          var keyState    = WindowsMouseInput.GetKeyStateWParam(m.WParam);
          var wheelDelta    =  WindowsMouseInput.WheelDelta(m.WParam);
          // forward delta of +/- 54 instead of +/- 120
          // 54 = 3 * 18 (default point height in pixels?); 54/120 == 9/20
          var newWparam   = WindowsMouseInput.WParam((Int16)(wheelDelta*9/20), keyState);
          SendMessage(hWnd, m.Msg, newWparam, m.LParam);
          return true;
        }
        break;
    }
  }
  return false;
    }
#region Extern declarations
/// <summary>P/Invoke declaration for user32.dll.WindowFromPoint</summary>
    /// <remarks><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/ms633558(v=vs.85).aspx"/></remarks>
    /// <param name="pt">(Sign-extended) screen coordinates as a Point structure.</param>
    /// <returns>Window handle (hWnd).</returns>
    [DllImport("user32.dll")]
    private static extern IntPtr WindowFromPoint(Point pt);
    /// <summary>P/Invoke declaration for user32.dll.SendMessage</summary>
    /// <param name="hWnd">Window handle</param>
    /// <param name="msg">Windows message</param>
    /// <param name="wp">WParam</param>
    /// <param name="lp">LParam</param>
    /// <returns></returns>
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
#endregion
#endregion
person Pieter Geerkens    schedule 02.03.2013
comment
Это ответ на кое-что, но не на этот вопрос. - person Hans Passant; 03.03.2013
comment
@Hans: OP попросил пример использования IMessageFilter. Это было у меня под рукой. - person Pieter Geerkens; 03.03.2013
comment
Да правда в том, что наконец-то я реализовал меню по-другому. Но все равно спасибо :) - person Andres; 05.03.2013