Отключить контекстное меню в WebBrowser .NET CF 3.5

#c# #windows-mobile #webbrowser-control #windows-ce #.net-cf-3.5

#c# #windows-mobile #webbrowser-управление #windows-ce #.net-cf-3.5

Вопрос:

Я использую элемент управления WebBrowser в .NET CF 3.5 для приложения на устройстве Windows CE, и по соображениям безопасности необходимо отключить контекстное меню. Я пробовал множество вещей, ни одна из которых, похоже, не работает для мобильных устройств с .NET CF 3.5:

  1. Я попытался поместить PictureBox поверх WebBrowser и сделать его прозрачным. К сожалению, прозрачность не работает, и в итоге получается белое поле над моим браузером.

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

  3. Я пытался отредактировать элемент OnContextMenu в html, безуспешно.

  4. Я попытался переопределить параметры CreateParams, чтобы создать прозрачный PictureBox поверх браузера, отмеченный как одно из приведенных здесь решений.

Кажется, в Интернете есть много решений для этого, но ни одно из них, похоже, не работает для Windows CE с .NET CF 3.5. Я полагаю, это потому, что WebBrowser имеет гораздо более простую реализацию, чем полный .NET 3.5. Итак, мой вопрос таков: есть ли какой-либо способ отключить контекстное меню для элемента управления WebBrowser?

Ответ №1:

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

Комментарии:

1. ого, это выглядит как чушь собачья (у меня не так много опыта разработки под Windows). Я все же попробую!

2. Итак, я выделил веб-браузер в подкласс, исходя из руководства Microsoft здесь: msdn.microsoft.com/en-us/library/ms229669.aspx Я пробовал как отключить сообщения WM_NOTIFY, так и WM_CONTEXTMENU, ни одно из которых, похоже, не работает. Как только я захожу в новый webbrowser, ничего не меняется. Кажется, что сообщение перехватывается неправильно, потому что обработчик никогда не вызывается при отладке. Возможно ли, что значения signed-int уведомлений отличаются? У меня есть 0x4E для WM_NOTIFY и 0x007B для WM_CONTEXTMENU.

3. Итак, путем подкласса я обнаружил, что на самом деле не было способа перехватить и удалить всплывающее окно контекстного меню. Мое решение состояло в том, чтобы подключиться к сообщению WM_CONTEXTMENU (аналогично подключению сообщения TreeView от Microsoft по ссылке выше) и открыть окно сообщения, как только событие прошло. Окно сообщений отвлекало от контекстного меню до того, как пользователь мог навести на него какой-либо фокус или щелкнуть по нему, предоставляя мне приемлемое решение. Спасибо!

Ответ №2:

На самом деле не так уж сложно использовать собственный HTML Control API (не IWebBrowser2 и др.), предварительно вызвав его из C #, если вы чувствуете, что недостаточно отвечаете за управляемый веб-браузер.

Если вы пойдете этим путем, то вы можете либо

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

или

  • полностью отключите контекстное меню, отправив ему DTM_ENABLECONTEXTMENU с FALSE.

Был там, сделал это, оба работают.

Редактировать:

В этом случае возможны 3 уровня сложности:

  1. Если HTML-элемент управления не создан с использованием стиля окна HS_CONTEXTMENU, по умолчанию контекстное меню будет отключено. Итак, если все, что вы когда-либо хотели сделать, это отключить его, то встроенная CreateWindowEx — единственная необходимая встроенная функция Win32 API для P / Invoke.
  2. С другой стороны, если вы действительно хотите включать и отключать контекстное меню во время выполнения, вы можете P / Invoke SendMessage с помощью DTM_ENABLECONTEXTMENU и TRUE / FALSE .
  3. И, наконец, если вы хотите получить максимальный контроль над меню или сделать что-то совершенно произвольное, когда HTML-элемент управления хочет отобразить меню, вам нужно P / Invoke SetWindowLong для подкласса родительского элемента и прослушивания NM_CONTEXTMENU и решить там, продолжать ли показывать меню или нет, или сделать что-то совершенно другое.

Комментарии:

1. Знаете ли вы какие-либо хорошие примеры для выполнения этого онлайн? Я погуглил, но я не совсем уверен, что влечет за собой P / Invoking. Я действительно не знаю, как бы я использовал собственный HTML Control API. Спасибо.

2. @John: Вы имеете в виду примеры P / Invoking в целом или выполнение этого в данном конкретном случае? Для общего случая, я думаю msdn.microsoft.com/en-us/library/aa446536.aspx это нормальное вступление. В этом конкретном случае вам нужно было бы, на мой взгляд, просто вызвать встроенную функцию Win32 API CreateWindowEx (для создания элемента управления HTML с управляемым окном по вашему выбору в качестве родительского) в простейшем сценарии.

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

4. Спасибо за ваш ответ! К счастью, мне удалось создать обходной путь без использования P / Invoke. Я обязательно воспользуюсь этой информацией, хотя мне нужно изучить использование P / Invoke для отключения меню параметров SIP (по несвязанной проблеме). Еще раз спасибо!

Ответ №3:

Ни один из этих возможных ответов не работает. Итак, я отказался от попыток скрыть контекстное меню и просто добавил обработчик события для события навигации и отменяю навигацию, если это не тот URL, на который я его изначально отправил. Он по-прежнему отображает контекстное меню, но нажатие на что-либо не отправит его на другую страницу

 void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e) {
    //don't let users go anywhere else
    if (e.Url != webBrowser1.Url) {
        e.Cancel = true;
    }
}
  

Комментарии:

1. Если вы прочтете мой комментарий к принятому ответу, вы увидите, что вы правы, ни один из этих ответов не сработал для меня, но я смог найти приемлемое альтернативное решение из одного из ответов. Ваше решение по-прежнему допускает контекстное меню, что оставило бы дыру в безопасности, о которой я беспокоился, открытой. Однако спасибо за информацию!

Ответ №4:

Не содержит ли реализация WebBrowser control в .NET CF свойства IsWebBrowserContextMenuEnabled ?

Комментарии:

1. нет, в нем нет никаких методов, переменных или событий, связанных с contextmenu.

Ответ №5:

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