Увеличение масштаба веб-страницы с помощью элемента управления WebBrowser .NET

В IE7 есть встроенная функция масштабирования (отображается в строке состояния), позволяющая увеличивать масштаб до 400%. Я использую элемент управления WebBrowser .NET в демонстрационном/симуляционном приложении, и мне нужно увеличить масштаб веб-страницы. Это вообще возможно?

(Я не хочу просто сфотографировать страницу и увеличить ее, так как мне нужно использовать ссылки и кнопки на странице).

Я использую .NET 2.0, если это имеет значение.


person Jon B    schedule 10.04.2009    source источник


Ответы (6)


Похоже, решение есть на странице IE Zoom, который включает переопределение AttachInterfaces и DetachInterfaces в WebBrowser для получения интерфейса IWebBrowser2, а затем вызов ExecWB с OLECMDID_OPTICAL_ZOOM.

Я попробовал его пример кода, и он работает; (сокращенный) соответствующий класс выглядит следующим образом:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace ZoomBrowser
{
    public partial class MyBrowser : WebBrowser
    {
        #region enums
        public enum OLECMDID
        {
            // ...
            OLECMDID_OPTICAL_ZOOM = 63,
            OLECMDID_OPTICAL_GETZOOMRANGE = 64,
            // ...
        }

        public enum OLECMDEXECOPT
        {
            // ...
            OLECMDEXECOPT_DONTPROMPTUSER,
            // ...
        }

        public enum OLECMDF
        {
            // ...
            OLECMDF_SUPPORTED = 1
        }
        #endregion

        #region IWebBrowser2
        [ComImport, /*SuppressUnmanagedCodeSecurity,*/
         TypeLibType(TypeLibTypeFlags.FOleAutomation | 
                     TypeLibTypeFlags.FDual |       
                     TypeLibTypeFlags.FHidden), 
         Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E")]
        public interface IWebBrowser2
        {
            [DispId(100)]  void GoBack();
            [DispId(0x65)] void GoForward();
            [DispId(0x66)] void GoHome();
            [DispId(0x67)] void GoSearch();
            [DispId(0x68)] void Navigate([In] string Url, 
                                         [In] ref object flags, 
                                         [In] ref object targetFrameName, 
                                         [In] ref object postData, 
                                         [In] ref object headers);
            [DispId(-550)] void Refresh();
            [DispId(0x69)] void Refresh2([In] ref object level);
            [DispId(0x6a)] void Stop();
            [DispId(200)]  object Application 
                           { [return: 
                              MarshalAs(UnmanagedType.IDispatch)] get; }
            [DispId(0xc9)] object Parent 
                           { [return: 
                              MarshalAs(UnmanagedType.IDispatch)] get; }
            [DispId(0xca)] object Container 
                           { [return: 
                              MarshalAs(UnmanagedType.IDispatch)] get; }
            [DispId(0xcb)] object Document 
                           { [return: 
                              MarshalAs(UnmanagedType.IDispatch)] get; }
            [DispId(0xcc)] bool TopLevelContainer { get; }
            [DispId(0xcd)] string Type { get; }
            [DispId(0xce)] int Left { get; set; }
            [DispId(0xcf)] int Top { get; set; }
            [DispId(0xd0)] int Width { get; set; }
            [DispId(0xd1)] int Height { get; set; }
            [DispId(210)]  string LocationName { get; }
            [DispId(0xd3)] string LocationURL { get; }
            [DispId(0xd4)] bool Busy { get; }
            [DispId(300)]  void Quit();
            [DispId(0x12d)] void ClientToWindow(out int pcx, out int pcy);
            [DispId(0x12e)] void PutProperty([In] string property, 
                                             [In] object vtValue);
            [DispId(0x12f)] object GetProperty([In] string property);
            [DispId(0)] string Name { get; }
            [DispId(-515)] int HWND { get; }
            [DispId(400)] string FullName { get; }
            [DispId(0x191)] string Path { get; }
            [DispId(0x192)] bool Visible { get; set; }
            [DispId(0x193)] bool StatusBar { get; set; }
            [DispId(0x194)] string StatusText { get; set; }
            [DispId(0x195)] int ToolBar { get; set; }
            [DispId(0x196)] bool MenuBar { get; set; }
            [DispId(0x197)] bool FullScreen { get; set; }
            [DispId(500)] void Navigate2([In] ref object URL, 
                                         [In] ref object flags, 
                                         [In] ref object targetFrameName, 
                                         [In] ref object postData, 
                                         [In] ref object headers);
            [DispId(0x1f5)] OLECMDF QueryStatusWB([In] OLECMDID cmdID);
            [DispId(0x1f6)] void ExecWB([In] OLECMDID cmdID, 
                                        [In] OLECMDEXECOPT cmdexecopt, 
                                        ref object pvaIn, IntPtr pvaOut);
            [DispId(0x1f7)] void ShowBrowserBar([In] ref object pvaClsid, 
                                                [In] ref object pvarShow, 
                                                [In] ref object pvarSize);
            [DispId(-525)] WebBrowserReadyState ReadyState { get; }
            [DispId(550)] bool Offline { get; set; }
            [DispId(0x227)] bool Silent { get; set; }
            [DispId(0x228)] bool RegisterAsBrowser { get; set; }
            [DispId(0x229)] bool RegisterAsDropTarget { get; set; }
            [DispId(0x22a)] bool TheaterMode { get; set; }
            [DispId(0x22b)] bool AddressBar { get; set; }
            [DispId(0x22c)] bool Resizable { get; set; }
        }
        #endregion

        private IWebBrowser2 axIWebBrowser2;

        public MyBrowser()
        {           
        }

        protected override void AttachInterfaces(
            object nativeActiveXObject)
        {
            base.AttachInterfaces(nativeActiveXObject);
            this.axIWebBrowser2 = (IWebBrowser2)nativeActiveXObject;
        }

        protected override void DetachInterfaces()
        {
            base.DetachInterfaces();
            this.axIWebBrowser2 = null;
        }

        public void Zoom(int factor)
        {
            object pvaIn = factor;
            try
            {
                this.axIWebBrowser2.ExecWB(OLECMDID.OLECMDID_OPTICAL_ZOOM,
                   OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, 
                   ref pvaIn, IntPtr.Zero);
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}
person Daniel LeCheminant    schedule 10.04.2009
comment
Есть ли способ, чтобы горизонтальные полосы прокрутки не появлялись, а текст перетекал на следующую строку. - person Priyank Bolia; 08.06.2009
comment
Спасибо за ответ. Кажется, что настройка разрешена только в том случае, если браузер в данный момент не загружает документ, поэтому не забудьте проверить свойство IsBusy перед установкой коэффициента масштабирования. - person MartinStettner; 30.01.2010
comment
Если вы продолжаете получать сообщение об ошибке DRAGDROP_E_NOTREGISTERED и не знаете, почему, убедитесь, что масштабирование IE не отключено в реестре. Проверьте, есть ли у вас значение ZoomDisabled=1 в разделе HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Zoom, и если да, удалите его. Может сэкономить вам время. - person dkozl; 26.02.2015
comment
ссылка на исходную статью: http://web.archive.org/web/20111228094455/http://slingkid.blogsome.com/2007/04/13/ie-zoom - person Charley Rathkopf; 07.10.2015
comment
Есть ли способ получить коэффициент масштабирования вместо его установки? - person Kyle Delaney; 11.06.2018

Легкий совет:

//Zoom IN
webBrowser1.Focus();
SendKeys.Send("^{+}"); // [CTRL]+[+]

//Zoom OUT
webBrowser1.Focus();
SendKeys.Send("^-"); // [CTRL]+[-]

//Zoom 100%
webBrowser1.Focus();
SendKeys.Send("^0"); // [CTRL]+[0]
person Gloupi    schedule 09.01.2013
comment
Это дает мне ошибку в WPF/WinForms SendKeys не может работать внутри этого приложения, потому что приложение не обрабатывает сообщения Windows. - person firebellys; 30.10.2015

Это работает для меня:

int zoomFactor = 300;
((SHDocVw.WebBrowser)webBrowser1.ActiveXInstance).ExecWB(SHDocVw.OLECMDID.OLECMDID_OPTICAL_ZOOM,
    SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, zoomFactor, IntPtr.Zero);

Кажется, это можно сделать только после загрузки документа.

person bdrajer    schedule 16.10.2012
comment
Также необходимо добавить ссылку COM на C:\Windows\System32\shdocvw.dll. - person Der_Meister; 25.03.2014
comment
Вместо этого добавьте ссылку на Microsoft Internet Controls. - person bluedog; 13.05.2014
comment
Я получаю сообщение об ошибке, когда пытаюсь это сделать. Попытка отозвать незарегистрированную цель перетаскивания (исключение из HRESULT: 0x80040100 (DRAGDROP_E_NOTREGISTERED)) - person firebellys; 30.10.2015
comment
Я получил DRAGDROP_E_NOTREGISTERED при попытке применить масштабирование сразу после настройки документа. Он хорошо работает, если вызывается в обработчике событий для DocumentCompleted (WinForms). - person bgx; 05.12.2016

Вы можете использовать CSS:

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        webBrowser1.Document.Body.Style = "zoom:50%";
    }
person QHNPROF    schedule 21.04.2015
comment
Это было самое простое решение. Очень хорошо. Просто добавьте обработчик события к событию DocumentCompleted и добавьте стиль. Работает как шарм. Спасибо QHNPROF - person KonaRin; 22.08.2017
comment
Не перезапишет ли это любой существующий стиль? - person Kyle Delaney; 11.06.2018
comment
Кроме того, WebBrowser.Document является object. Как вы получаете доступ к Body? - person Kyle Delaney; 11.06.2018

Обратите внимание, что значение коэффициента, которое вы передаете функции масштабирования, предполагает, что значение 100 соответствует «нормальному» размеру веб-страницы. Более высокие значения коэффициента означают, что вы «увеличиваете масштаб», поэтому страница выглядит больше. Меньшие значения коэффициента означают, что вы «уменьшаете масштаб», поэтому страница выглядит меньше. Я обнаружил, что разумным шагом между факторами является 10.

person RogerInHawaii    schedule 08.04.2011

Для всех, кто сталкивается с той же проблемой, что и я, вот модификация ответа Gloupi, которая должна работать в более международных системах, где клавиши плюс и минус находятся в разных местах с помощью клавиш со знаком цифровой клавиатуры. Это также исправляет увеличение и уменьшение масштаба макетов дворака.

// zoom in
webBrowser1.Focus();
SendKeys.Send("^{ADD}");

// zoom out
webBrowser1.Focus();
SendKeys.Send("^{SUBTRACT}");

// zoom reset
webBrowser1.Focus();
SendKeys.Send("^0");
person Polynomial    schedule 30.01.2017
comment
webBrowser1 не содержит определения для focus. Так что этот ответ неверен. - person Mark; 24.08.2018
comment
Вместо этого вы должны использовать webBrowser1.Select() - person Mark; 24.08.2018
comment
@Mark Код скопирован из производственного приложения. Вероятно, проблема с версией, я думаю? - person Polynomial; 26.08.2018
comment
Да, я так думаю - похоже, что Focus() устарело в пользу Select() для определенных элементов управления. Не совсем уверен, в какой версии .NET это произошло, но тем не менее :D - person Mark; 29.08.2018
comment
В вопросе указано, что .NET 2.0 является справедливым, и я уверен, что это правильно. Я опубликовал этот ответ только для того, чтобы указать на использование ^{ADD} и ^{SUBTRACT} вместо ^{+} и ^- в идентичном ответе Gloupi выше, поскольку последний не работает на некоторых раскладках клавиатуры, отличных от английского и QWERTY. - person Polynomial; 30.08.2018
comment
Ты прав. Должно быть, я пропустил .NET 2.0. Пожалуйста, не обращайте внимания на мою глупость. - person Mark; 30.08.2018