C# “如何停用”;右键单击";在WPF Webbrowser控件上?
我似乎找不到答案。 有人知道吗C# “如何停用”;右键单击";在WPF Webbrowser控件上?,c#,wpf,webbrowser-control,C#,Wpf,Webbrowser Control,我似乎找不到答案。 有人知道吗 感谢来自内部WebBrowserSite类的: int UnsafeNativeMethods.IDocHostUIHandler.ShowContextMenu(int dwID, NativeMethods.POINT pt, object pcmdtReserved, object pdispReserved) { // Returning S_FALSE will allow the native control to do default pro
感谢来自内部WebBrowserSite类的:
int UnsafeNativeMethods.IDocHostUIHandler.ShowContextMenu(int dwID, NativeMethods.POINT pt, object pcmdtReserved, object pdispReserved)
{
// Returning S_FALSE will allow the native control to do default processing,
// i.e., execute the shortcut key. Returning S_OK will cancel the context menu
return NativeMethods.S_FALSE;
}
硬烘焙,您无法覆盖此。将Winforms WebBrowser放入WindowsFormsHost是一个解决办法,它有一个更智能的方法实现,使用IsWebBrowserContextMenuEnabled属性,并允许您创建自己的上下文菜单。下面是一个实用程序类的代码,该类允许您停用WPF的WebBrowser上下文菜单。它还允许您抑制脚本错误()并更改IE的 使用示例:
public partial class Player : Window
{
private WebBrowserHostUIHandler _wbHandler;
public Player()
{
InitializeComponent();
...
_wbHandler = new WebBrowserHostUIHandler(MyWebBrower);
_wbHandler.IsWebBrowserContextMenuEnabled = false;
}
}
公用事业代码:
public class WebBrowserHostUIHandler : Native.IDocHostUIHandler
{
private const uint E_NOTIMPL = 0x80004001;
private const uint S_OK = 0;
private const uint S_FALSE = 1;
public WebBrowserHostUIHandler(WebBrowser browser)
{
if (browser == null)
throw new ArgumentNullException("browser");
Browser = browser;
browser.LoadCompleted += OnLoadCompleted;
browser.Navigated += OnNavigated;
IsWebBrowserContextMenuEnabled = true;
Flags |= HostUIFlags.ENABLE_REDIRECT_NOTIFICATION;
}
public WebBrowser Browser { get; private set; }
public HostUIFlags Flags { get; set; }
public bool IsWebBrowserContextMenuEnabled { get; set; }
public bool ScriptErrorsSuppressed { get; set; }
private void OnNavigated(object sender, NavigationEventArgs e)
{
SetSilent(Browser, ScriptErrorsSuppressed);
}
private void OnLoadCompleted(object sender, NavigationEventArgs e)
{
Native.ICustomDoc doc = Browser.Document as Native.ICustomDoc;
if (doc != null)
{
doc.SetUIHandler(this);
}
}
uint Native.IDocHostUIHandler.ShowContextMenu(int dwID, Native.POINT pt, object pcmdtReserved, object pdispReserved)
{
return IsWebBrowserContextMenuEnabled ? S_FALSE : S_OK;
}
uint Native.IDocHostUIHandler.GetHostInfo(ref Native.DOCHOSTUIINFO info)
{
info.dwFlags = (int)Flags;
info.dwDoubleClick = 0;
return S_OK;
}
uint Native.IDocHostUIHandler.ShowUI(int dwID, object activeObject, object commandTarget, object frame, object doc)
{
return E_NOTIMPL;
}
uint Native.IDocHostUIHandler.HideUI()
{
return E_NOTIMPL;
}
uint Native.IDocHostUIHandler.UpdateUI()
{
return E_NOTIMPL;
}
uint Native.IDocHostUIHandler.EnableModeless(bool fEnable)
{
return E_NOTIMPL;
}
uint Native.IDocHostUIHandler.OnDocWindowActivate(bool fActivate)
{
return E_NOTIMPL;
}
uint Native.IDocHostUIHandler.OnFrameWindowActivate(bool fActivate)
{
return E_NOTIMPL;
}
uint Native.IDocHostUIHandler.ResizeBorder(Native.COMRECT rect, object doc, bool fFrameWindow)
{
return E_NOTIMPL;
}
uint Native.IDocHostUIHandler.TranslateAccelerator(ref System.Windows.Forms.Message msg, ref Guid group, int nCmdID)
{
return S_FALSE;
}
uint Native.IDocHostUIHandler.GetOptionKeyPath(string[] pbstrKey, int dw)
{
return E_NOTIMPL;
}
uint Native.IDocHostUIHandler.GetDropTarget(object pDropTarget, out object ppDropTarget)
{
ppDropTarget = null;
return E_NOTIMPL;
}
uint Native.IDocHostUIHandler.GetExternal(out object ppDispatch)
{
ppDispatch = Browser.ObjectForScripting;
return S_OK;
}
uint Native.IDocHostUIHandler.TranslateUrl(int dwTranslate, string strURLIn, out string pstrURLOut)
{
pstrURLOut = null;
return E_NOTIMPL;
}
uint Native.IDocHostUIHandler.FilterDataObject(IDataObject pDO, out IDataObject ppDORet)
{
ppDORet = null;
return E_NOTIMPL;
}
public static void SetSilent(WebBrowser browser, bool silent)
{
Native.IOleServiceProvider sp = browser.Document as Native.IOleServiceProvider;
if (sp != null)
{
Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E");
object webBrowser;
sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out webBrowser);
if (webBrowser != null)
{
webBrowser.GetType().InvokeMember("Silent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.PutDispProperty, null, webBrowser, new object[] { silent });
}
}
}
}
internal static class Native
{
[ComImport, Guid("BD3F23C0-D43E-11CF-893B-00AA00BDCE1A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IDocHostUIHandler
{
[PreserveSig]
uint ShowContextMenu(int dwID, POINT pt, [MarshalAs(UnmanagedType.Interface)] object pcmdtReserved, [MarshalAs(UnmanagedType.Interface)] object pdispReserved);
[PreserveSig]
uint GetHostInfo(ref DOCHOSTUIINFO info);
[PreserveSig]
uint ShowUI(int dwID, [MarshalAs(UnmanagedType.Interface)] object activeObject, [MarshalAs(UnmanagedType.Interface)] object commandTarget, [MarshalAs(UnmanagedType.Interface)] object frame, [MarshalAs(UnmanagedType.Interface)] object doc);
[PreserveSig]
uint HideUI();
[PreserveSig]
uint UpdateUI();
[PreserveSig]
uint EnableModeless(bool fEnable);
[PreserveSig]
uint OnDocWindowActivate(bool fActivate);
[PreserveSig]
uint OnFrameWindowActivate(bool fActivate);
[PreserveSig]
uint ResizeBorder(COMRECT rect, [MarshalAs(UnmanagedType.Interface)] object doc, bool fFrameWindow);
[PreserveSig]
uint TranslateAccelerator(ref System.Windows.Forms.Message msg, ref Guid group, int nCmdID);
[PreserveSig]
uint GetOptionKeyPath([Out, MarshalAs(UnmanagedType.LPArray)] string[] pbstrKey, int dw);
[PreserveSig]
uint GetDropTarget([In, MarshalAs(UnmanagedType.Interface)] object pDropTarget, [MarshalAs(UnmanagedType.Interface)] out object ppDropTarget);
[PreserveSig]
uint GetExternal([MarshalAs(UnmanagedType.IDispatch)] out object ppDispatch);
[PreserveSig]
uint TranslateUrl(int dwTranslate, [MarshalAs(UnmanagedType.LPWStr)] string strURLIn, [MarshalAs(UnmanagedType.LPWStr)] out string pstrURLOut);
[PreserveSig]
uint FilterDataObject(IDataObject pDO, out IDataObject ppDORet);
}
[StructLayout(LayoutKind.Sequential)]
internal struct DOCHOSTUIINFO
{
public int cbSize;
public int dwFlags;
public int dwDoubleClick;
public IntPtr dwReserved1;
public IntPtr dwReserved2;
}
[StructLayout(LayoutKind.Sequential)]
internal struct COMRECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[StructLayout(LayoutKind.Sequential)]
internal class POINT
{
public int x;
public int y;
}
[ComImport, Guid("3050F3F0-98B5-11CF-BB82-00AA00BDCE0B"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ICustomDoc
{
[PreserveSig]
int SetUIHandler(IDocHostUIHandler pUIHandler);
}
[ComImport, Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IOleServiceProvider
{
[PreserveSig]
uint QueryService([In] ref Guid guidService, [In] ref Guid riid, [MarshalAs(UnmanagedType.IDispatch)] out object ppvObject);
}
}
[Flags]
public enum HostUIFlags
{
DIALOG = 0x00000001,
DISABLE_HELP_MENU = 0x00000002,
NO3DBORDER = 0x00000004,
SCROLL_NO = 0x00000008,
DISABLE_SCRIPT_INACTIVE = 0x00000010,
OPENNEWWIN = 0x00000020,
DISABLE_OFFSCREEN = 0x00000040,
FLAT_SCROLLBAR = 0x00000080,
DIV_BLOCKDEFAULT = 0x00000100,
ACTIVATE_CLIENTHIT_ONLY = 0x00000200,
OVERRIDEBEHAVIORFACTORY = 0x00000400,
CODEPAGELINKEDFONTS = 0x00000800,
URL_ENCODING_DISABLE_UTF8 = 0x00001000,
URL_ENCODING_ENABLE_UTF8 = 0x00002000,
ENABLE_FORMS_AUTOCOMPLETE = 0x00004000,
ENABLE_INPLACE_NAVIGATION = 0x00010000,
IME_ENABLE_RECONVERSION = 0x00020000,
THEME = 0x00040000,
NOTHEME = 0x00080000,
NOPICS = 0x00100000,
NO3DOUTERBORDER = 0x00200000,
DISABLE_EDIT_NS_FIXUP = 0x00400000,
LOCAL_MACHINE_ACCESS_CHECK = 0x00800000,
DISABLE_UNTRUSTEDPROTOCOL = 0x01000000,
HOST_NAVIGATES = 0x02000000,
ENABLE_REDIRECT_NOTIFICATION = 0x04000000,
USE_WINDOWLESS_SELECTCONTROL = 0x08000000,
USE_WINDOWED_SELECTCONTROL = 0x10000000,
ENABLE_ACTIVEX_INACTIVATE_MODE = 0x20000000,
DPI_AWARE = 0x40000000
}
参考mshtml
using mshtml;
然后,您可以通过访问文档来执行此操作:
MainBrowser.Navigate("https://www.domain.com");
MainBrowser.LoadCompleted += (o, args) =>
{
var doc = (HTMLDocumentEvents2_Event) MainBrowser.Document;
doc.oncontextmenu += obj => false;
};
这是一个老问题,但我有一个独特的问题,我想/需要在.Net Core SDK中使用较新的CSProj文件格式,但它有一个无法引用扩展库(如mshtml)的问题。因此,我最终找到了一个不需要参考mshtml的解决方案 一些灵感来自于用户将
WebBrowser.Document
属性转换为dynamic
假设webView是WebBrowser
控件的名称,连接LoadCompleted
事件,如下所示:
private void webView\u LoadCompleted(对象发送方,导航目标)
{
动态文档=webView.document;
document.oncontextmenu+=新函数(()=>false);
}
似乎在挖坟墓,但是
例如,根据此处的答案获取IWebBrowser2
接口,然后获取DWebBrowserEvents2\u事件接口,并将处理程序附加到DocumentComplete事件
SHDocVw.DWebBrowserEvents2_Event wbEvents = (SHDocVw.DWebBrowserEvents2_Event)myWebBrowser2;
wbEvents.DocumentComplete += new SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(OnWebBrowserDocumentComplete);
(上述操作只能在WebBrowser LoadCompleted事件上执行一次,因此添加一些逻辑以仅在第一个事件上运行)
然后在此处理程序中,运行sone JavaScript将事件侦听器附加到文档,并附加到文档中的iframe
private void OnWebBrowserDocumentComplete(object pDisp, ref object URL)
{
/* try-catch wrap this if you get e.g. DISP_E_EXCEPTION */
MyBrowser.InvokeScript("execScript", new Object[]
{
"document.addEventListener('contextmenu', function(e){ e.preventDefault(); }, false);" +
"var frm = document.getElementById('frm');" +
"frm.onload = function() { frm.contentDocument.body.addEventListener('contextmenu', function(e){ e.preventDefault(); }, false); };",
"JavaScript"
});
}
即使iframe内容发生更改,这也会起作用。我将其用于在WPF WebBrowser中运行的DITA WebHelp classic
而且不需要mshtml参考。这对我在Windows 10(WPF web浏览器)上很有用。应该标记为答案。漂亮的解决方案,只是当WebBrowser处于用户控件(WPF)中时,它似乎崩溃了。实际上,不仅在用户控件中,see工作得很好:)不幸的是,一旦您选择了一些文本,上下文菜单又回来了。这对System.Windows.Controls.WebBrowser有效吗?我这边给出的是:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException“System.\uu ComObject”不包含“oncontextmenu”的定义。有什么想法吗?谢谢。我已经很久没有看这个了,但我相信它是System.Windows.Controls.WebBrowser
。您是否将WebBrowser
或文档
属性强制转换为动态
?