Disabling the context menu in the .Net CF WebBrowser Control
Posted by anoriginalidea on December 31, 2007
Although initially impressive, the WebBrowser control in the .NET Compact Framework 2.0 lacks the ability to be customised in a few important areas. An obvious one that people are asking about seems to be the ability to remove the default context menu.
None of the obvious solutions , such as setting the ContextMenu property to null seem to work.
The Problem
The internal PIE control that the WebBrowser control wraps has a COM property to disable it, but this is not exposed.
So how can we set the property?
The .NET CF 2.0 provides the answer. It introduced some new features that allows straight forward interaction with COM objects and controls.
Doing this with the WebBrowser control involves sending a special windows message (DTM_BROWSERDISPATCH) to the windows handle of the control to retrieve a pointer to the IDispatch interface, converted into an object (using the GetObjectForIUnknown call) , which is then cast to a marked up interface with the appropriate identifiers. These are found webvw.h which is part of the Compact Framework SDK.
This technique will only work for Windows Mobile (not Smartphone) based devices. For my own projects I use a compiler directive to screen avoid the COM calls on the Smartphone platform.
The Solution
I have cut down the solution to it’s bare essentials and encapsulated it in the class WebBrowserContactMenu. You should be able to reuse this class, unaltered in your own project.
Warning: Currently this solution WILL ONLY WORK FOR Windows Mobile 2003! It is supposed to work for WM5 and above also (it all seems correct) but for some reason the SendMessage to DTM_BROWSERDISPATCH is not working at all. I have researched the problem but as yet cannot find a workaround. I will update this article if I do. Any suggestions are welcome.
Imports System.Runtime.InteropServices
Imports System.Runtime.CompilerServices
Public Class WebBrowserContextMenu
Private moWebBrowser As WebBrowser
Public Sub New(ByVal control As WebBrowser)
moWebBrowser = control
End Sub
Const WM_USER As Integer = &H400
Const DTM_BROWSERDISPATCH As Integer = (WM_USER + 124)
Declare Function SendMessageLongRef Lib “Coredll” Alias “SendMessageW” (ByVal HWND As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByRef lParam As Integer) As Integer
Public Property Enabled() As Boolean
Get
Return mGetBrowserInterface.ContextMenuEnabled
End Get
Set(ByVal value As Boolean)
mGetBrowserInterface.ContextMenuEnabled = value
End Set
End Property
Private Function mGetBrowserInterface() As IBrowserBareEssentials
Dim liPtr As Integer = 0
SendMessageLongRef(moWebBrowser.Handle.ToInt32, DTM_BROWSERDISPATCH, 0, liPtr)
Return CType(System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(CType(liPtr, IntPtr)), IBrowserBareEssentials)
End Function
<ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIDispatch), Guid(”698E3FC9-70C3-11D0-81E8-00A0C90AD20A”)> _
Public Interface IBrowserBareEssentials
<DispId(185)> Property ContextMenuEnabled() As Boolean
End Interface
End Class
In the example project, a simple WebBrowser application hosts this class, instantiating it and using radio buttons to toggle the button. Here’s what the form code looks like:
Public Class Form1
Private moContextMenu As WebBrowserContextMenu
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
WebBrowser1.Navigate(New Uri(txtUrl.Text))
moContextMenu = New WebBrowserContextMenu(WebBrowser1)
End Sub
Private Sub cmdGo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdGo.Click
WebBrowser1.Navigate(New Uri(txtUrl.Text))
End Sub
Private Sub optEnabled_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles optEnabled.Click
moContextMenu.Enabled = optEnabled.Checked
End Sub
Private Sub optDisabled_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles optDisabled.Click
moContextMenu.Enabled = optEnabled.Checked
End Sub
End Class
Download the sample project. (14K)
Conclusion
The purpose of this article was to provide a direct solution to the context menu problem. I have by no means an exhaustive description of using COM with WebBrowser, but this may help as an introduction. At a future date I will share other uses for this technique.
| Share this post : |
This entry was posted on December 31, 2007 at 11:54 pm and is filed under .net Framework, Pocket PC Development, VB.Net. Tagged: .NET CF, Compact Framework, WebBrowser, Windows Messages. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.


Sirlizium said
I have tried your solution without any changes on my Windows Mobile 5 device, (Compact Framework 2 SP1 installed), but it doesn’t work. When I try to disable the ContextMenu at runtime I always get the an ArgumentNullException for ‘mGetBrowserInterface()’ in Line
“Return CType(System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(CType(liPtr, IntPtr)), IBrowserBareEssentials)”.
Seems like the IUnknown-Interface of the Browserobject is not found… ???
David said
Same problem for me, Windows Mobile 5.
Erik said
The same for me, under windows ce 2003 it works perfect, under windows mobile 5 throws the same exception as sirlizium says. Has anyone solved it?
Nuno said
yeah, i have the same problem, i’m using windows mobile 6 with cf 2.0 and when i try to disable the context menu at runtime i get a lot of errors… Someone can help me?
Best way to do this? said
[...] found this, it may be worth the reaading… __________________ Paulo Gomes Porto, Portugal PC: Dual-Core [...]
programmervb said
great code
Thank’s
Mobile Development : Disable WebBrowser's Context-Menu in NETCF applications said
[...] one developer I’ve worked with pointed me to this link, which describes a possible way to disable NETCF’s WebBrowser’s context-menu, which worked only on [...]
Raffaele Limosani said
Hi, pls check the following for a possible approach on WM5\6\6.1: http://blogs.msdn.com/raffael/archive/2009/01/08/disable-webbrowser-s-context-menu-in-netcf-applications.aspx.
HTH,
~raffaele