Создание браузера на c
Коротко суть проблемы: по умолчанию компонент WebBrowser работает под версией IE7. Сейчас 2020 год и уже давно последней версией Internet Explorer служит 11-я версия. Можно было бы использовать и старую версию, но с тех пор появились новые JavaScript-методы, например, GetElementsByClassName. Поэтому в старой версии IE7 современные сайты откроются с многочисленными ошибками JavaScript.
1. Отключение ошибок скриптов.
В первую очередь, Вы можете воспользоваться настройкой отключения отображения ошибок JavaScript:
Данный трюк поможет мало, так как для современных сайтов все же нужен IE более новой версии. Зато браузер перестанет сыпать MessageBox с ошибками.
2. Изменение User-Agent Вашего браузера.
Сайт определил Ваш браузер как IE7, так как браузер в отправленном GET-запросе добавил заголовок:
Данное значение User-Agent соответствует IE7.
Данный момент решается следующим образом: создадим статический класс IeMethods со следующим кодом:
Из кода программы перед выполнением перехода на сайт вызовем метод SetAnotherUserAgent класса IeMethods и передадим строку со значением необходимого User-Agent:
Решит ли данный способ проблему ? Скорее всего нет. Все дело в том, что сайт на основании полученного от Вас заголовка User-Agent сформирует необходимый HTML-код. Программисты при разработке могут заложить поддержку IE9, IE11, Chrome и других браузеров. Но вряд ли кто-то будет закладывать поддержку IE7, все-таки слишком старый движок.
3. Изменение версии эмуляции IE.
Итак, мы добрались до основного. Эмулировать мы можем любую версию Internet Explorer. Главное понимать, что если в Вашей ОС установлен IE10, то в нем не будет поддержки IE11 или если в ОС установлен IE8, то нельзя эмулировать более поздние версии ))) Правило простое.
Еще раз, зачем что-то эмулировать?
Компания Microsoft заложила следующий функционал в каждую свою версию IE - возможность эмулировать более старую свою версию из новой версии. И по умолчанию компонент WebBrowser открывает сайты не под той версией Internet Explorer, который установлен в Вашей ОС, а под версией IE7 (а это старый движок, как я написал в начале статьи).
Как эмулировать версию IE ? Вариант только один, создать в реестре ключ типа DWord в Current User по адресу:
// Для x64 приложений SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION // Для x32 приложений SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATIONИмя ключа - это имя Вашего приложения (пример: WindowsFormsApp1.exe)
Значение ключа - специальный код версии IE, который нужно ввести в десятичном формате. Пример для эмуляции IE11 используя код 11001:
Таблица кодов для разных версий IE:
11001 (0x2AF9) - Internet Explorer 11. Webpages are displayed in IE11 edge mode, regardless of the !DOCTYPE directive.
11000 (0x2AF8) - IE11. Webpages containing standards-based !DOCTYPE directives are displayed in IE11 edge mode. Default value for IE11.
10001 (0×2711) - Internet Explorer 10. Webpages are displayed in IE10 Standards mode, regardless of the !DOCTYPE directive
10000 (0×02710) - Internet Explorer 10. Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode. Default value for Internet Explorer 10.
9999 (0x270F) - Windows Internet Explorer 9. Webpages are displayed in IE9 Standards mode, regardless of the !DOCTYPE directive.
9000 (0×2328) - Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode. Default value for Internet Explorer 9.Important In Internet Explorer 10, Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
8888 (0x22B8) - Webpages are displayed in IE8 Standards mode, regardless of the !DOCTYPE directive.
8000 (0x1F40) - Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode. Default value for Internet Explorer 8Important In Internet Explorer 10, Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
7000 (0x1B58) - Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode. Default value for applications hosting the WebBrowser Control.
Пора сделать метод эмуляции в коде нашего приложения. В класс IeMethods добавим метод SetBrowserEmulation с возможностью передачи ему параметра version типа integer.
В коде формы нашего приложения вызовем этот метод и передадим ему код 11001. Метод необходимо вызвать до создания компонента WebBrowser, поэтому поместим его вызов перед InitializeComponent.
Чтобы добиться максимального результата, необходимо использовать все 3 перечисленных выше способа, а именно:
Мне очень захотелось написать свой браузер, со своими фишками и т.п. Так вот, пробовал использовать стандартный компонент WForms, но он использует ядро IE, так еще и устаревшнее.
Попробовал использовать CefSharp, который работает с Chromium, но кушает больше оперативки, чем хотелось бы.
Так вот, мне бы хотелось узнать как написать свое ядро, если вы знаете книги посвященные эти темы, какие-то примеры, статьи или уроки - буду вам чрезвычайно благодарен.
- Вопрос задан более трёх лет назад
- 9584 просмотра
Оценить 3 комментария
Народ, вы чего? Автор не говорил, что будет его кодить. Имхо, ему интересно как это делается. Я верно понял?
Чтобы сделать ядро для браузера надо идти от самого нуля:
* Анализатор html/css, рендер графики.
* Интерпретатор как минимум javascript
В итоге - свой браузер, это еще сложнее чем свой интерпретатор языка программирования. да. Поэтому если решились сделать свой браузер с нуля - лучше сделайте язык программирования :)))))))
Для того, чтобы создать браузер необходимо создать приложение Windows Forms, которое включает в себя элементы управления Button, TextBox, Panel и конечно WebBrowser. Конечный пользователь должен набрать адрес веб страницы, а наш браузер должен отобразить документ.
И так приведу список всех элементов.
Когда пользователь наберет адрес и нажмет <ENTER> WebBrowser извлечет запрошенную страницу и отобразит в своем поле. Код данного сектора выглядит следующим образом
private void txtAdress_KeyPress( object sender, KeyPressEventArgs e)
if ( e .KeyChar == ( char )13)
webBrowseMain.Navigate(txtAdress.Text);
>
>
Здесь каждое нажатие клавиш перехватывается обработчиком события txtAdress_KeyPress и если нажата клавиша <ENTER>, то в действие вступает WebBrowser, методу webBrowseMain.Navigate передается URL который пользователь набрал в элементе txtAdress.
При запуске кнопки Back, Forward и Stop должный быть недоступными, поскольку они не имеют смысла при первоначальной загрузки. Позднее можно сообщать приложению когда надо активировать кнопки Back и Forward исходя от того где находится пользователь в стеке страниц. Когда страница загружается было бы уместном активировать кнопку Stop, но при завершении запретить доступ к ней.
Запрограммируем функциональность кнопок.
private void btnGo_Click( object sender, EventArgs e)
string url = txtAdress.Text;
if (!url.StartsWith( "http://" ) &&
!url.StartsWith( "https://" ))
url = "http://" + url;
>
webBrowseMain.Navigate( new Uri (url));
>
private void btnBack_Click( object sender, EventArgs e)
webBrowseMain.GoBack();
>
private void btnStop_Click( object sender, EventArgs e)
webBrowseMain.Stop();
>
private void btnHome_Click( object sender, EventArgs e)
webBrowseMain.GoHome();
>
private void btnRefresh_Click( object sender, EventArgs e)
webBrowseMain.Refresh();
>
private void btnForward_Click( object sender, EventArgs e)
webBrowseMain.GoForward();
>
По имени обработчика можно понять который обработчик принадлежит которой кнопке.
Когда форма загружается первоначально, событие Form1_Load отключает к соответствующим кнопкам. Чтобы включать и отключать доступ к кнопкам, приходится обращаться к множеству событий. Для активации кнопки Stop в начале загрузки необходимо добавить обработчик события Navigating.
private void webBrowseMain_Navigating( object sender, WebBrowserNavigatingEventArgs e)
btnStop.Enabled = true ;
>
После загрузки снова доступ к кнопке Stop отключим.
private void webBrowseMain_DocumentCompleted( object sender, WebBrowserDocumentCompletedEventArgs e)
btnStop.Enabled = false ;
>
Доступность кнопок Back и Forward зависит от возможности перехода в перед или назад в стеке страниц. В этом нам помогут события CanGoForwardChanged и CanGoBackChanged. И так во время инициализации определяем данные события.
webBrowseMain.CanGoForwardChanged+= new EventHandler (webBrowseMain_CanGoForwardChanged);
webBrowseMain.CanGoBackChanged+= new EventHandler (webBrowseMain_CanGoBackChanged);
и после вписываем события
private void webBrowseMain_CanGoForwardChanged( object sender, EventArgs e)
if (webBrowseMain.CanGoForward)
btnForward.Enabled = true ;
else
btnForward.Enabled = false ;
>
private void webBrowseMain_CanGoBackChanged( object sender, EventArgs e)
if (webBrowseMain.CanGoBack)
btnBack.Enabled = true;
else
btnBack.Enabled = false;
>
Вот и все, у нас уже есть свой собственный Браузер.
Ссылка для демо-программы тут.
В одном из своих материалов мы сказали, что веб-браузер сделать легко. И сейчас мы это продемонстрируем в Borland C++ Builder v.6.0.
Без паники, в этом материале, свой движок писать не придется, мы воспользуемся готовым. От Internet Explorer.
Создаем форму распологаем на ней элемент CppWebBrowser с вкладки Internet. У нас он самый крайний справа. И добавим кнопку Button, и Edit, чтобы вводить адрес. Получаем подобное:
В большом белом прямоугольнике и будет появлятся страница сайта. Но сначала опишем события по клику на кнопке или можно в событии onEnter у Edit`а.
Кратко получилось. Но больше-то ничего и не надо. Повторимся, больше НИЧЕГО НЕ НАДО для начала.
Хотя если кто-то привык обходится без кнопок, то горячие клавиши действуют без дополнительных манипуляций. Например, по F5 - обновляется страница. Итак получили что-то вроде этого:
Код для кнопок приведен несколькими строками, но имей ввиду, на каждую кнопку приходится только одна(!) строка. Одна кнопка = одна функция. На всякий случай мы сделали пояснения.
Примечание: Автор не удосужился объяснить куда ведет кнопка Домашняя страница. А ведет она на ту которая прописана в свойствах твоего Internet Explorer в качестве домашней. Мелочь, но зато ты понял на 100%.
Исходный код и скомпилированный вариант получившегося ищи тут.
Теперь заменим компонент Edit на выпадающий список ComboBox, и будем записывать в него недавно открытые адреса.
Добавляем совсем немного строчек в обработчик события onKeyDown, элемента ComboBox:
if(Key==VK_RETURN)
CppWebBrowser1->Navigate(StringToOleStr(ComboBox1->Text)); //Загружаем страницы
ComboBox1->Items->Add(ComboBox1->Text); //Добавляем использованные адреса
>
Исходный код и скомпилированный вариант получившегося ищи тут.
Считай это вступлением. Мы просто не хотим перегружать твой мозг информацией. Наращивать на скелет можно очень и очень много, поэтому чтоб не терять нить рассуждений мы разделим наш материал на несколько частей.
Для себя мы уже нарисовали план развития этой задумки. Разумеется мы не планируем соревноватся с популярными веб-браузерами, нам просто интересно как это все устроено, пускай даже не на самописном ядре, а уже на готовом.
Читайте также: