WPF WIN32 hwndhost WM_MOUSEMOVE WM_MOUSEHOVER

У меня есть приложение WPF с пользовательским элементом управления, содержащим HwndHost. HwndHost создается следующим образом:

  hwndHost = CreateWindowEx(0, "static", "",
                            WS_CHILD | WS_VISIBLE,
                            0, 0,
                            hostHeight, hostWidth,
                            hwndParent.Handle,
                            (IntPtr)HOST_ID,
                            IntPtr.Zero,
                            0);

  hwndControl = CreateWindowEx(0, "Static", "",
                                WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN
                                  ,
                                0, 0,
                                hostHeight, hostWidth,
                                hwndHost,
                                (IntPtr)PICTUREBOX_ID,
                                IntPtr.Zero,
                                0);

Затем я подключаюсь к насосу сообщений с помощью HwndSourceHook, и приходит множество сообщений.

Кроме тех, которые я хочу, то есть WM_MOUSEMOVE, WM_MOUSEHOVER, WM_LBUTTONDOWN и WM_LBUTTONUP

Кроме того, событие OnMouseLeftButtonDown не запускается в коде WPF в главном окне или элементе управления, я полагаю, потому что окна захватывают его и выбрасывают.

Кто-нибудь знает, как я могу заставить их пройти, с использованием или без использования оконных сообщений WIN32?


person Neil B    schedule 25.03.2010    source источник
comment
Обновление: OnMouseLeftButtonUp срабатывает в WPF, но не OnMouseLeftButtonDown. Потеряли plot.com?   -  person Neil B    schedule 25.03.2010


Ответы (3)


Вам нужно обработать WM_NCHITTEST. Пока вы этого не сделаете, он не будет отправлять вам сообщения мыши.

// C++/CLI implementation of HwndHost.WndProc().
virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, bool% handled) override
{
    switch (msg)
    {
        case WM_NCHITTEST:
        {
            handled = true;
        return IntPtr(HTCLIENT);
        }
    }

    return IntPtr::Zero;
}
person Tom P.    schedule 10.11.2010

Похоже, что элемент Border в WPF предотвращает выброс OnMouseLeftButtonDown. Мое временное решение, пока я не найду лучшее, - это изменить границу WPF на кнопку WPF, после чего запускаются все события мыши.

Не идеально для большинства людей, но поскольку я использую его для рендеринга 3D, не имеет значения, что находится под ним.

person Neil B    schedule 14.04.2010

Почему бы вам не зарегистрировать WndClass и не получать сообщения, доставляемые в ваш собственный WndProc, вместо того, чтобы подключать насос сообщений? Я подозреваю, что результаты будут намного лучше.

person i_am_jorf    schedule 25.03.2010
comment
Я подключаюсь к WndProc, я думал, что это даст мне каждое отправленное сообщение. Вы знаете, могу ли я зарегистрировать WndClass в WPF? - person Neil B; 25.03.2010
comment
Я не уверен, что вы делаете не так, но может быть, вы не в нужном месте в цепочке WndProc? Я недостаточно знаком с WPF, чтобы сказать, как бы вы это сделали, но если вы можете вызвать CreateWindowEx (), я не понимаю, почему вы не можете вызвать RegisterClass (). - person i_am_jorf; 25.03.2010
comment
Хорошо, спасибо, я посмотрю. Я подозреваю, что есть что-то еще, что мешает, например, движок Ogre3D, которому я передаю Hwnd, чтобы он мог отображать в моем окне. - person Neil B; 30.03.2010
comment
Вы должны иметь возможность использовать Spy ++, чтобы увидеть цепочку окон и места исчезновения сообщений. - person i_am_jorf; 30.03.2010