WPF WebBrowser控件放大/缩小支持?

WPF WebBrowser control zoom in/out support?

对于WPF WebBrowser控件,是否可以复制Internet Explorer的缩放功能?

换句话说,Internet Explorer具有菜单"视图">"缩放">" 75%",该菜单以75%的比例显示网页。有没有办法使嵌入在WPF应用程序中的Web浏览器控件执行相同的操作?

我看过这篇文章:
WPF WebBrowser-如何缩放内容?

但是它似乎只能缩放页面,而不能缩放页面内容。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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 { }

    }

}


这是我的做法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 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);
}

由于WPF WebBrowser控件不会直接公开ActiveX,因此所有服务提供者的资料都公开了ActiveX。除此之外,它与alexei的解决方案几乎相同。


这不是一个确切的答案,因为它用于WinForms控件,但是如果您决定在WindowsFormsHost中而不是WPF控件中使用它,则可能会有用。

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

1
2
3
4
5
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程序集的引用
  • 仅在加载文档后命令才能成功
  • 可以通过OLECMDID_GETZOOMRANGE检索pvaIn的范围
  • 命令参考列表在MSDN上
  • 我遇到了这种奇怪的现象,似乎仅在非96 dpi时才发生。启动时,呈现的文本大小与OLECMDID_ZOOM状态下存储的文本大小不对应。将值设置为任何值并不能解决差异:渲染的大小仍然看起来像[存储的大小2]。当光学变焦设置为100%时,文本大小的差异消失了(缩放到100%后,文本大小明显缩小了)。在IE中并没有发生这种情况,也许这只是我所处环境中的一个怪异产物,但仅仅是fyi。

在使用其他解决方案时,我总是会收到类似的错误

HRESULT: 0x80040100
DRAGDROP_E_NOTREGISTERED

我在此页面上找到了一个对我有用的解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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。