Hallo,
ich habe eine Lösung für das Problem. Allerdings habe ich Sie bislang nicht gepostet, da sie nicht eben elegant ist. Ich habe lieber gewartet, weil ich dachte jemand anderes habe vielleicht eine bessere Lösung.
Nach dem Posting von Benjamin@vb habe ich jedoch beschlossen, meine Lösung hier zu posten.
Beim Testen bitte beachten, dass das Kontextmenü erst zur Verfügung steht, wenn das Dokument vollständig fertig geladen ist.
Vorgehensweise:
1. Eine Form erstellen und ein Webbrowsercontrol namens AxWebBrowser1 darauf positionieren.
2. Ein Kontextmenü mnuBrowser auf der Form platzieren mit einem Menuitem namens miBrItem01.
3. Eine private Variable myDoc für das HTML-Dokumentobjekt des Browsers deklarieren.
Private WithEvents myDoc As mshtml.HTMLDocumentClass 4. Zum DocumentComplete-Event des Webbrowsers folgenden Code schreiben:
Private Sub AxWebBrowser1_DocumentComplete( _
ByVal sender As Object, _
ByVal e As AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent) _
Handles AxWebBrowser1.DocumentComplete
myDoc = CType(AxWebBrowser1.Document, mshtml.HTMLDocumentClass)
End Sub 5. Anschließend den Code für das OnContextMenuEvent des Dokument-Objekts schreiben.
Private Function myDoc_HTMLDocumentEvents2_Event_oncontextmenu( _
ByVal pEvtObj As mshtml.IHTMLEventObj) _
As Boolean _
Handles myDoc.HTMLDocumentEvents2_Event_oncontextmenu
'ACHTUNG: der Event steht erst zur Verfügung, wenn das Dokument
'komplett geladen worden ist
Dim pt As Point
'Umrechnen der Mauskoordinaten des Contextmenu-Events in
' Fensterkoordinaten
'der Form auf der das Webbrowsercontrol ist
pt = PointFromHtmlEvent(pEvtObj)
'Nun das Kontextmenu anzeigen
mnuBrowser.Show(AxWebBrowser1.Parent, pt)
Return False
End Function ACHTUNG: Wenn man den Code automatisch vom Visual-Studio erzeugen lässt, indem man im Dropdownmenu in der IDE den Event auswählt, wird der Event-Code nicht richtig erzeugt. Statt einer Funktion, die einen bool’schen Wert zurückgibt, erhält man eine Sub. Man muss die Prozedur also zuerst umschreiben.
6. Nun noch eine Funktion einfügen, die die Koordinaten des ContextMenu-Events in Fensterkoordinaten umrechnet.
Private Function PointFromHtmlEvent(ByVal pEvtObj As mshtml.IHTMLEventObj) As _
Point
'rechnet die Koordinaten eines HtmlEvents in Fensterkoordinaten um
Dim x%, y%
Dim el As mshtml.IHTMLElement
Dim elBody As mshtml.HTMLBodyClass
Dim ptRet As Point
'Koordinaten relativ zum Source-Element, in dem das
'Ereignis stattgefunden hat ermitteln
x = pEvtObj.offsetX
y = pEvtObj.offsetY
'Die Koordinaten des Source-Elements relativ
'zum Body des HTML-Documents ermitteln
el = pEvtObj.srcElement
elBody = myDoc.body
Do
x = x + el.offsetLeft
y = y + el.offsetTop
el = el.offsetParent
If el Is Nothing Then
Exit Do
End If
Loop Until el Is elBody
'Wenn die Seite gescrollt ist, die Scroll-Weiten wieder
'von den Koordinaten abziehen
x = x - elBody.scrollLeft
y = y - elBody.scrollTop
'zum Schluss die Position des Browsercontrols hinzuaddieren
'jetzt hat man die Koordinaten relativ zu dem Control
'das der Container des Browser-Steuerelements ist
x = x + AxWebBrowser1.Left
y = y + AxWebBrowser1.Top
ptRet = New Point(x, y)
Return ptRet
End Function 7. Zum Schluss noch einen Ereignishandler für das MenuItem miBrItem02 des Contextmenüs schreiben
Private Sub miBrItem01_Click( _
ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles miBrItem01.Click
Dim mi As MenuItem = CType(sender, MenuItem)
MsgBox("Klick on " & mi.Text)
End Sub8. Anscheinend werden alle Events des Dokument-Objekts „verschluckt“. So funktioniert beispielsweise ein Klick auf einen Link nicht mehr. Deswegen muss man auch noch die anderen Dokument-Ereignisse implementieren. Z.B.
Private Function myDoc_HTMLDocumentEvents2_Event_onclick( _
ByVal pEvtObj As mshtml.IHTMLEventObj) _
As Boolean _
Handles myDoc.HTMLDocumentEvents2_Event_onclick
'Der Event muss rein, weil sonst Klickevents "verschluckt" werden
'gleiches gilt, so vermute ich, auch für alle anderen Events des
' Document-Objekts
Return True
End Function Hier sollte eigentlich der Code im Ganzen hin aber: "Ihre Nachricht zu lang. Bitte kürzen Sie die Nachricht." (sic)
Ciao
D. |