It'd probably be easiest to handle the
contextmenu event on the JS side instead, that way you avoid having to write more platform-specific code. It'd also be easier to get information on the DOM node target this way.
Still, if you want to go the Cocoa route, you can respond to the
WebUIDelegate's
webView:contextMenuItemsForElement:defaultMenuItems:, for example:
Code: Select all
EnableExplicit
;; Helpers
;; =======================================================
Procedure.s pbStringFromNSString(*string)
ProcedureReturn PeekS(CocoaMessage(0, *string, "UTF8String"), -1, #PB_UTF8)
EndProcedure
Procedure debugNSDictionary(*dict)
Protected count = CocoaMessage(0, *dict, "count")
Protected Dim values(count)
Protected Dim keys(count)
CocoaMessage(0, *dict, "getObjects:", @values(), "andKeys:", @keys(), "count:", count)
Define x
For x = 0 To count - 1
Debug " " + pbStringFromNSString(keys(x)) + " -> " + values(x)
Next x
EndProcedure
;; Setup a new WebUIDelegate class.
;; =======================================================
;{ class RVR_WebView_UIDelegate begin
ProcedureC delegate_webView__contextMenuItemsForElement__defaultMenuItems(*self, *cmd, *webView, *element, *defaultMenuItems)
Debug "Request for context-menu display:"
debugNSDictionary(*element)
Debug ""
EndProcedure
Define clsWebViewDelegate = objc_allocateClassPair_(objc_getClass_("NSObject"), "RVR_WebView_UIDelegate", 0)
class_addProtocol_(clsWebViewDelegate, objc_getProtocol_("WebUIDelegate"))
class_addMethod_(clsWebViewDelegate, sel_registerName_("webView:contextMenuItemsForElement:defaultMenuItems:"), @delegate_webView__contextMenuItemsForElement__defaultMenuItems(), "@@:@@@")
objc_registerClassPair_(clsWebViewDelegate)
;} end class RVR_WebView_UIDelegate
;; Main.
;; =======================================================
Define wnd = OpenWindow(#PB_Any, 0, 0, 600, 400, "WebGadget menu override", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Define webGad = WebGadget(#PB_Any, 0, 0, 600, 400, "")
SetGadgetItemText(webGad, #PB_Web_HtmlCode, "<html><body>Right click me.</body></html>")
CocoaMessage(0, GadgetID(webGad), "setUIDelegate:", CocoaMessage(0, clsWebViewDelegate, "alloc"))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
From the
delegate_webView__contextMenuItemsForElement__defaultMenuItems() procedure, you can extract element info from the *element NSDictionary, and accordingly return an NSArray of menu items or display a popup menu yourself with
DisplayPopupMenu(), etc.
For completion's sake, here's an example of the cross-platform, JS approach:
Code: Select all
EnableExplicit
;; Helpers.
;; =======================================================
Procedure webViewOnContextMenu(paramsJson.s)
Debug "Handle context menu: " + paramsJson
EndProcedure
;; Main.
;; =======================================================
Define html.s = "<html>" +
"<head><script>" +
"document.oncontextmenu = function(ev) { ev.preventDefault(); handleContextMenu(); }" +
"</script></head>" +
"<body>Right click anywhere.</body>" +
"</html>"
Define wnd = OpenWindow(#PB_Any, 0, 0, 600, 400, "WebGadget menu override", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Define webGad = WebViewGadget(#PB_Any, 0, 0, 600, 400)
SetGadgetItemText(webGad, #PB_WebView_HtmlCode, html)
BindWebViewCallback(webGad, "handleContextMenu", @webViewOnContextMenu())
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
I've used the
WebViewGadget (which should be preferred where possible) for simplicity in bridging JS<->PB, but this is adaptable to the IE
WebGadget as well by interfacing with the underlying
IWebBrowser2.