Перехват событий мыши в элементе управления в пользовательском элементе управления - PullRequest
0 голосов
/ 17 июля 2010

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

Изменение кода для содержащегося элемента управления возможно, но только в крайнем случае.У автономного элемента управления есть окно, которым управляет неуправляемая библиотека.

FWIW. Я пытался добавить обработчики для событий мыши, содержащихся в элементе управления, но эти обработчики никогда не вызывались.Я подозреваю, что содержащийся в нем элемент управления потребляет события мыши.

Я подумывал добавить какое-то прозрачное окно поверх содержимого элемента управления, чтобы перехватывать события, но я все еще довольно новичок в Windows FormsМне интересно, есть ли лучший способ.

Ответы [ 3 ]

1 голос
/ 17 июля 2010

Ну, это технически возможно. Вы должны перенаправить сообщение мыши самостоятельно, что требует немного P / Invoke. Вставьте этот код в свой внутренний класс UserControl:

    protected override void WndProc(ref Message m) {
        // Re-post mouse messages to the parent window
        if (m.Msg >= 0x200 && m.Msg <= 0x209 && !this.DesignMode && this.Parent != null) {
            Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
            // Fix mouse position to be relative from parent's client rectangle
            pos = this.PointToScreen(pos);
            pos = this.Parent.PointToClient(pos);
            IntPtr lp = (IntPtr)(pos.X + pos.Y << 16);
            PostMessage(this.Parent.Handle, m.Msg, m.WParam, lp);
            return;
        }
        base.WndProc(ref m);
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern IntPtr PostMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

Кстати, этого лучше избегать. Родительский элемент управления, вероятно, должен просто подписаться на события мыши внутреннего элемента управления.

1 голос
/ 17 июля 2010

Если внутренний элемент управления не запечатан, вы можете создать его подкласс и переопределить методы, связанные с мышью:

protected override void OnMouseClick(MouseEventArgs e) {
    //if you still want the control to process events, uncomment this:
    //base.OnMouseclick(e)

    //do whatever
}

и т.д.

0 голосов
/ 17 июля 2010

Вот что я сделал:

Сначала я определил класс TransparentControl, который просто является прозрачным элементом управления и ничего не рисует.(Этот код благодаря http://www.bobpowell.net/transcontrols.htm.)

public class TransparentControl : Control
{
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
            return cp;
        }
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        // Do nothing
    }

    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
        // Do nothing
    }
}

Затем я поместил TransparentControl в свой пользовательский элемент управления поверх содержащегося пользовательского элемента управления и добавил обработчики для его событий мыши.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...