WPF WebBrowser控件支持缩放吗?

8
对于 WPF WebBrowser 控件,是否有一种方法来复制 Internet Explorer 的缩放功能?
换句话说,Internet Explorer 有菜单视图 -> 缩放 -> 75%,这将以 75% 的比例呈现网页。是否有办法使嵌入在 WPF 应用程序中的 web 浏览器控件做到这一点?
我看过这篇文章:WPF WebBrowser - How to Zoom Content?,但它似乎只能缩放页面而不是页面内容。
4个回答

7
public partial class TestWindow: UserControl
{
    public TestWindow()
    {
        InitializeComponent();

        browser.LoadCompleted += new LoadCompletedEventHandler(browser_LoadCompleted);
    }

    private void browser_LoadCompleted(object sender, NavigationEventArgs e)
    {
        try
        {

            FieldInfo webBrowserInfo = browser.GetType().GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);

            object comWebBrowser = null;
            object zoomPercent = 120;
            if (webBrowserInfo != null)
                comWebBrowser = webBrowserInfo.GetValue(browser);
            if (comWebBrowser != null)
            {
                InternetExplorer ie = (InternetExplorer)comWebBrowser;
                ie.ExecWB(SHDocVw.OLECMDID.OLECMDID_OPTICAL_ZOOM, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, ref zoomPercent, IntPtr.Zero);
            }
        }
        catch (Exception ex)
        {
        }
    }


    public void SetBrowser(string url)
    {
        browser.Navigate(url,null,null,null);

    }

    internal void Destroy()
    {
        try
        {
            if (browser.Parent != null)
            {
                ((Grid)browser.Parent).Children.Remove(browser);
                browser.Navigate("about:blank");
                browser.Dispose();
                browser = null;
            }
        }
        catch { }

    }

}

2
这个真救命 :) 你需要添加一个名为Microsoft Internet Controls的COM组件的引用。 - lanicor

4

这是我是如何做到的:

// Needed to expose the WebBrowser's underlying ActiveX control for zoom functionality
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
internal interface IServiceProvider
{
    [return: MarshalAs(UnmanagedType.IUnknown)]
    object QueryService(ref Guid guidService, ref Guid riid);
}

static readonly Guid SID_SWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");

private void ZoomListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    object zoomPercent; // A VT_I4 percentage ranging from 10% to 1000%
    switch(ZoomListBox.SelectedItem.ToString())
    {
        case "System.Windows.Controls.ListBoxItem: 200%":
            zoomPercent = 200;
            break;
        case "System.Windows.Controls.ListBoxItem: 100%":
            zoomPercent = 100;
            break;
        case "System.Windows.Controls.ListBoxItem: 50%":
            zoomPercent = 50;
            break;
        default:
            zoomPercent = 100;
            break;
    }

    // grab a handle to the underlying ActiveX object
    IServiceProvider serviceProvider = null;
    if (m_webView.Document != null)
    {
        serviceProvider = (IServiceProvider)m_webView.Document;
    }

    Guid serviceGuid = SID_SWebBrowserApp;
    Guid iid = typeof(SHDocVw.IWebBrowser2).GUID;
    SHDocVw.IWebBrowser2 browserInst = (SHDocVw.IWebBrowser2)serviceProvider.QueryService(ref serviceGuid, ref iid);

    // send the zoom command to the ActiveX object
    browserInst.ExecWB(SHDocVw.OLECMDID.OLECMDID_OPTICAL_ZOOM, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, ref zoomPercent, IntPtr.Zero);
}

所有服务提供商的东西都会暴露ActiveX,因为WPF WebBrowser控件不能直接暴露它。除此之外,这基本上与alexei的解决方案相同。


我从这个答案中摘取了一些片段来解决我的问题。这很好用。奇怪的是,IE缩放级别默认为Windows桌面控制面板-->Win 7上的显示不是1-1,所以你必须使用像这样的方程式才能使它正常工作。请参见此不同/但类似帖子上的答案,了解我是如何做到的:https://dev59.com/jFTTa4cB1Zd3GeqPurCj#11528480 - Daniel McQuiston

2

这并不是一个确切的答案,因为它适用于WinForms控件,但如果您决定在WindowsFormsHost中使用它而不是WPF控件,则可能会有所帮助,因为WPF控件暴露的内容太少了,无法提供足够的帮助。

您可以通过ActiveX实例上的ExecWB使用OLE命令:OLECMDID_ZOOM用于文本大小,OLECMDID_OPTICAL_ZOOM用于光学缩放。例如:

object pvaIn = 200; // A VT_I4 percentage ranging from 10% to 1000%
var browserInst = ((SHDocVw.IWebBrowser2)(browserContol.ActiveXInstance));
browserInst.ExecWB(SHDocVw.OLECMDID.OLECMDID_OPTICAL_ZOOM,
                   SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER,
                   ref pvaIn, IntPtr.Zero);

一些注意事项:

  • 需要引用Interop.SHDocVw程序集
  • 命令只有在文档加载后才能成功执行
  • pvaIn的范围可以通过OLECMDID_GETZOOMRANGE获取
  • 命令的参考列表在MSDN
  • 我遇到了一种奇怪的行为,似乎只发生在非96 dpi的情况下。启动时,呈现的文本大小与存储在OLECMDID_ZOOM状态中的大小不对应。将值设置为任何值都无法解决差异:呈现的大小仍然是类似于[存储大小+2]的样子。当光学缩放设置为100%时,文本大小的差异消失了(缩放到100%后,文本大小明显缩小)。这在IE中没有发生,也许那只是我的环境中的奇怪现象 - 但只是提供信息。

0

当使用其他解决方案时,我总是会遇到以下错误:

HRESULT: 0x80040100
DRAGDROP_E_NOTREGISTERED

我在this page上找到了一个适合我的解决方案:

var wb = webBrowser.ActiveXInstance.GetType();

object o = zoomPercentage; // Between 10 and 1000.

wb.InvokeMember(
    @"ExecWB", 
    BindingFlags.InvokeMethod, 
    null, 
    webBrowser.ActiveXInstance, 
    new[]
        {
            OLECMDID.OLECMDID_OPTICAL_ZOOM, 
            OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, 
            o, 
            o
        }); 

使用OLECMDID_OPTICAL_ZOOM为63和OLECMDEXECOPT_DONTPROMPTUSER为2。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接