마우스가 전체 양식 및 하위 컨트롤 내부에 있는지 감지하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/986529

문제

사용자가 폼과 모든 하위 컨트롤 위로 마우스를 이동하는 시점과 폼에서 나가는 시점을 감지해야 합니다.나는 MouseEnter 그리고 MouseLeave Form의 이벤트를 시도했습니다. WM_MOUSEMOVE & WM_MOUSELEAVE 그리고 WM_NCMOUSEMOVE & WM_NCMOUSELEAVE Windows 메시지 쌍이 있지만 원하는 대로 작동하지 않는 것 같습니다...

내 양식의 대부분은 다양한 종류의 하위 컨트롤로 채워져 있으며 표시되는 클라이언트 영역이 많지 않습니다.즉, 마우스를 매우 빠르게 움직이면 마우스가 양식 내부에 있어도 마우스 움직임이 감지되지 않습니다.

예를 들어, 아래쪽과 데스크탑과 TextBox 사이에 도킹된 TextBox가 있는데 아주 작은 테두리만 있습니다.마우스를 아래쪽에서 TextBox로 빠르게 이동하면 마우스 움직임이 감지되지 않지만 마우스는 TextBox 내부에 있으므로 Form 내부에 있습니다.

나에게 필요한 것을 어떻게 달성할 수 있나요?

도움이 되었습니까?

해결책

메인 메시지 루프 및 전처리/후 처리/사후 처리 (WM_MOUSEMOVE) 메시지를 원하는 내용을 연결할 수 있습니다.

public class Form1 : Form {
    private MouseMoveMessageFilter mouseMessageFilter;
    protected override void OnLoad( EventArgs e ) {
        base.OnLoad( e );

        this.mouseMessageFilter = new MouseMoveMessageFilter();
        this.mouseMessageFilter.TargetForm = this;
        Application.AddMessageFilter( this.mouseMessageFilter );
    }

    protected override void OnClosed( EventArgs e ) {
        base.OnClosed( e );

        Application.RemoveMessageFilter( this.mouseMessageFilter );
    }

    class MouseMoveMessageFilter : IMessageFilter {
        public Form TargetForm { get; set; }

        public bool PreFilterMessage( ref Message m ) {
            int numMsg = m.Msg;
            if ( numMsg == 0x0200 /*WM_MOUSEMOVE*/) {
                this.TargetForm.Text = string.Format( "X:{0}, Y:{1}", Control.MousePosition.X, Control.MousePosition.Y );
            }

            return false;
        }

    }
}

다른 팁

어떻게 이점도 : 양식의 onload에서 재귀 적으로 모든 어린이 통제 (및 자녀)를 통해 마우스 센터 이벤트를 연결하십시오.

그런 다음 마우스가 자손에 들어갈 때마다 이벤트 핸들러가 호출됩니다. 마찬가지로 MouseMove 및/또는 Mouseleave 이벤트를 연결할 수 있습니다.

protected override void OnLoad()
{
   HookupMouseEnterEvents(this);
}

private void HookupMouseEnterEvents(Control control)
{
   foreach (Control childControl in control.Controls)
   {
      childControl.MouseEnter += new MouseEventHandler(mouseEnter);

      // Recurse on this child to get all of its descendents.
      HookupMouseEnterEvents(childControl);
   }
}

사용자 컨트롤에서 이와 같은 컨트롤(또는 다른 이벤트 유형)에 대한 마우스오버 이벤트를 만듭니다.

private void picBoxThumb_MouseHover(object sender, EventArgs e)
{
    // Call Parent OnMouseHover Event
    OnMouseHover(EventArgs.Empty);
}

UserControl을 호스팅하는 WinFrom에서는 UserControl이 Designer.cs에서 MouseOver를 처리하도록 합니다.

this.thumbImage1.MouseHover += new System.EventHandler(this.ThumbnailMouseHover);

WinForm에서 이 메서드를 호출합니다.

private void ThumbnailMouseHover(object sender, EventArgs e)
{

    ThumbImage thumb = (ThumbImage) sender;

}

ThumbImage는 usercontrol 유형입니다.

빠르고 더러운 솔루션 :

private bool MouseInControl(Control ctrl)
{
    return ctrl.Bounds.Contains(ctrl.PointToClient(MousePosition));
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top