C # - захват колеса CTRL-Mouse в элементе управления WebBrowser - PullRequest
2 голосов
/ 19 октября 2010

Я занимаюсь разработкой приложения для Windows Forms на C # со встроенным элементом управления WebBrowser для «фиктивного» (то есть отключения контекстных меню, кнопки «Назад», бесплатной навигации и т. Д.) Доступа к стороннему веб-приложению.

Прямо сейчас я пытаюсь добавить функцию масштабирования в свой браузер.У меня работают комбинации клавиш (CTRL + и CTRL - сделать правильные вызовы OLE для базового объекта ActiveX WebBrowser), но среди других неприятных вещей, связанных с WebBrowser, с которыми мне приходилось иметь дело, я не могу показатьсячтобы понять, как захватить колесо CTRL-Mouse для имитации функции Zoom, как это делает IE.Я искал повсюду, чтобы найти решение этой проблемы, но безрезультатно.

Чтобы попытаться выяснить это, я создал пустую форму, содержащую только элемент управления WebBrowser, и обнаружил следующее:

  1. CTRL-MouseWheel всегда запускает событие MouseWheel, когда родительская форма имеет фокус, а курсор мыши находится над верхней частью окна (например, над заголовком приложения) или когдакурсор мыши находится над элементом управления WebBrowser, когда кажется, что он не имеет фокуса, даже если родительская форма имеет фокус.
  2. CTRL-MouseWheel никогда не запускает событие MouseWheel, когда курсор мыши находится над элементом мыши.У элемента управления WebBrowser и WebBrowser есть фокус, и, похоже, эффекта нет.
  3. Использование колесика мыши без CTRL прокручивает содержимое окна WebBrowser, но не вызывает событие MouseWheel до тех пор, покавертикальная полоса прокрутки полностью достигла верхней или нижней части.
  4. Перехват Message для WM_MOUSEWHEEL путем переопределения WndProc и DefWndProc как для выборочного класса, унаследованного от WebBrowser, так и для родительской формы, применяется только для вышеуказанных условий (с wParam, правильно обозначающими MK_CONTROL).
  5. Событие PreviewKeyDown срабатывает при нажатии клавиши CTRL, как и ожидалось, но все равно ничего не делает в унисон с колесом мыши.

Так что я думаюMessage обрабатывается ниже родительской формы и уровня управляемого управления и не поднимается там, где я могу его перехватить или даже обработать.Есть ли способ сделать это или какой-то другой способ имитировать увеличение и уменьшение масштаба с помощью CTRL-MouseWheel?

Спасибо за чтение!

Ответы [ 5 ]

4 голосов
/ 10 октября 2013

Сначала приведите WebBrowser.Document.DomDocument к нужному интерфейсу в пространстве имен mshtml, например mshtml.HTMLDocumentEvents2_Event, затем вы можете обрабатывать (и отменять) события колесика мыши. Я не уверен, но я думаю, что вам нужно подключать обработчик событий каждый раз, когда документ изменяется, поэтому я делаю это для события WebBrowser.DocumentCompleted. Я также не уверен, нужно ли вам освобождать какие-либо COM-объекты.

Это было достаточно разочаровывающим, что я заставил его работать и перестал заботиться ...

Вот как минимум один документ, объясняющий основы: Как обрабатывать события документа в приложении Visual C # .NET

Для вашего конкретного случая просто условно сдавить событие onmousewheel, в зависимости от того, нажата ли клавиша CTRL.

private void webBrowser_DocumentCompleted(object sender,
                                         WebBrowserDocumentCompletedEventArgs e)
{
    if (webBrowser.Url.ToString() == "about:blank")
        return;
    var docEvents = (mshtml.HTMLDocumentEvents2_Event)webBrowser.Document.DomDocument;
    docEvents.onmousewheel -= docEvents_onmousewheel; //may not be necessary?
    docEvents.onmousewheel += docEvents_onmousewheel;
}

bool docEvents_onmousewheel(mshtml.IHTMLEventObj pEvtObj)
{
    if (pEvtObj.ctrlKey)
    {
        pEvtObj.cancelBubble = true; //not sure what this does really
        pEvtObj.returnValue = false;  //this cancels the event
        return false; //not sure what this does really
    }
    else
        return true; //again not sure what this does
} 

Теперь, если вам нужно узнать Дельта Колеса (количество прокрутки), вам нужно привести объект событий к еще одному интерфейсу.

bool docEvents_onmousewheel(mshtml.IHTMLEventObj pEvtObj)
{
    var wheelEventObj = (mshtml.IHTMLEventObj4)pEvtObj;
    var delta = wheelEventObj.wheelDelta;
    [...]
}
0 голосов
/ 07 мая 2014

Я не смог заставить что-либо из них работать надежно, поэтому после некоторых (разочаровывающих) экспериментов я получил производную от ответа, опубликованного TCC.Мой веб-браузер управления размещен в пользовательском контроле.Основное различие заключается в том, что я использую переменную уровня класса для HTMLDocumentEvents2_Event, чтобы успешно отписаться от подписки, и для mshtml.IHTMLEventObj pEvtObj.Returnvalue установлено значение true.

0 голосов
/ 13 ноября 2013

Это код, который я использовал для отключения ctrl + shift:
Вам нужно изменить поведение WndProc в самом глубоком элементе управления "Internet Explorer_Server",
Сделайте это после того, как ваш веб-браузер будет готов:

IntPtr wbHandle = Win32.FindWindowEx(this.wbMain.Handle, IntPtr.Zero, "Shell Embedding", String.Empty);
wbHandle = Win32.FindWindowEx(wbHandle, IntPtr.Zero, "Shell DocObject View", String.Empty);
wbHandle = Win32.FindWindowEx(wbHandle, IntPtr.Zero, "Internet Explorer_Server", String.Empty);
WbInternal wb = new WbInternal(wbHandle);

class WbInternal : NativeWindow
    {
        public WbInternal(IntPtr handle)
        {
            this.AssignHandle(handle);
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_MOUSEWHEEL)


            {
                if (((int)m.WParam & 0x00FF) == MK_SHIFT)
                {
                    return;
                }
            }
            base.WndProc(ref m);
        }
    }

Вы можете найти больше сообщений о WM_MOUSEWHEEL от MSDN.
Я нахожу это из MSDN.Но я забыл ссылку, Как только найду, добавлю сюда.

0 голосов
/ 12 февраля 2012

Для того, чтобы решить эту проблему, вы должны слушать и обрабатывать эти сообщения:

  • OLECMDID_GETZOOMRANGE

Они отправляются Internet Explorer.См. замечания по MSDN .

0 голосов
/ 04 января 2011

Возможно, использование SetWindowsHookEx для поиска этих событий может работать для вас. Это то, что я использовал для получения событий колеса прокрутки поверх элемента управления ActiveX MapPoint.

Имейте в виду, что в Windows 7 есть некоторые причуды, которые могут потребовать некоторых изменений. Для получения дополнительной информации выполните поиск SetWindowsHookEx в Windows 7 на форумах MSDN.

...