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 : |