Переключение на Главную Страницу Страницы: [1] 2 3 ... 6 ОтправитьПечать
Очень популярная тема (более 25 ответов) Примеры и наработки по использованию WebBrowser ActiveX (число прочтений - 51910 )
maljaev
Senior Member
****
Отсутствует


Классический секс с 1С
надоел. Хочется изврата...

Сообщений: 405
Местоположение: Нижний Новгород
Зарегистрирован: 19. Октября 2006
Пол: Мужской
Примеры и наработки по использованию WebBrowser ActiveX
19. Сентября 2011 :: 18:37
Печать  
Открываю новую тему, в которой будем общаться относительно сабжа, как продолжение оффтопной темы http://www.1cpp.ru/forum/YaBB.pl?num=1315559526. Буду сюда скидывать свои наработки по использованию этого "чуда", надеюсь и активисты подтянутся, всё-таки коллективный разум это сила. Улыбка


1. ОС

Ближе к теме. Предыдущая попытка поделиться примером управления DOM-моделью HTML-документа потерпела фиаско по причине того, что Win7 и Win2008 более-менее сносно поддерживают управление узлами прямо из 1С, а вот WinXP и Win2003 можно сказать отвратительно, потому я как-то сразу и не подумал что готовое и работающее на стороне клиентов решение может у кого-то не работать. Далее буду продолжать тему в контексте WinXP, хотя и под более свежими ОС тоже будет работать.

2. DOM

Значит путем экспериментов выяснилось, что управлять нормально DOM напрямую из 1С нельзя, из MSScriptControl.ScriptControl получше но полноценно тоже нельзя, из javascript внутри HTML-документа (или приаттаченого) - управляется практически полноценно. Об этом свидетельствовали веб-страницы с активным содержимым, которые загружались и работали без проблем.

3. Скрипты

Значит нужно вынести весь функционал по управлению DOM в скрипты. Вопрос в том как вызывать эти скрипты, как передавать туда параметры и как возвращать результаты.

3.1. Вызов скриптов

Единственная возможность вызвать скрипты в окне WebBrowser - это через метод ExecScript родительского для WebBrowser объекта parentWindow.

Код
Выбрать все
Браузер.Объект.document.parentWindow.ExecScript(ТекстСкрипта,"JavaScript")
 



Оно работает, но есть одна фича которую нужно иметь ввиду: ExecScript - асинхронный метод, то есть управление в модуль 1С возвращается сразу после вызова скрипта, а не после его выполнения. А вот управление в форму не возращается, так что эта асинхронность как собаке пятая нога - только мешает. Но работать можно, только иметь ввиду данный факт при написании программ, чтобы не искать подолгу ошибки. В приведенном примере я специально расставил сообщения с _GetPerformanceCounter(), чтобы вы наглядно могли увидеть в каком порядке это происходит.

3.2. Передача параметров в скрипт

Так как ExecScript принимает в качестве параметра только строку, мы не можем передать в скрипт объекты напрямую, как в случае с MSScriptControl.ScriptControl.

Вы можете попробовать воспользоватся медом "Сериализовать" из класса "Система" 1С++, но вряд ли у вас выйдет что-то стабильное. Я попробовал, с одной стороны оно работает до поры до времени, с другой стороны асинхронность ExecScript приводит к тому что в какой-то момент по клику пользователя экземпляр "Системы" не готов вернуть объект и сначала скрипт выдает ошибку, а затем вываливается 1С. Если все-таки удастся решить эту проблему, я буду очень признателен.

А на данный момент можно либо усложнить себе жизнь, конвертируя объекты в JSON и обратно (еще поискать надо чем), либо просто конвертировать объекты в строку. ТЗ и списки конвертируются в строку с разделителями и в скрипте разворачиваются в виде массива (одномерного, двумерных в javascript нету, но это не очень мешает). В примере как раз реализована свертка и развертка двумерной ТЗ с помощью строки с разделителями. Работает стабильно.

3.2. Возврат результатов из скрипта, перехват событий

У нас есть один простой и надежный метод перехватывать события из WebBrowser - это событие BeforeNavigate2. В нем мы можем перехватить ссылку, по которой переходит пользователь, отменить переход, а взамен наделать кучу гадостей. Улыбка В ссылку можно запихнуть тоже довольно много, если этого будет мало - то придется обратиться к методу POST, куда можно засунуть на порядок больше. Но обычно из скрипта много передавать и не приходиться - идентификатор какой-нибудь, значение введенное в поле, наименование действия и т.д., а что еще?

Но с событием BeforeNavigate2 есть неприятные тонкости: возникает оно программно из скрипта, обрабатываем мы его тоже программно, и 1С не обновляет WebBrowser до тех пор пока обработка не завершиться. Ну скажем нельзя в окне браузера выводить прогресс-бар по мере добавления строк в таблицу, статус-текст и т.п. Из этой ситуации можно выкрутиться следующим образом - в обработчике события BeforeNavigate2 мы генерируем новое событие через класс "Сервис" FormEx, управление кратковременно передается в форму, потом в предопределенной процедуре формы "ОбработкаВнешнегоСобытия" мы уже выполняем действия над WebBrowser. В примере доступно показано как это делается.

Но даже когда мы меняем содержимое WebBrowser из обработчика внешнего события (а меняем мы его запуском скрипта), окно браузера не обновиться до тех пор пока не закончиться скрипт. Поэтому при разработке программ учитывайте, что лучше 1000 раз в цикле вызвать функцию скрипта, добавляющую одну строку, чем 1 раз вызвать функцию скрипта, добавляющую разом 1000 строк. В первом случае окно будет обновляться сразу после добавления каждой строки, а во втором только после того как всё выведется. Визуально первый вариант намного предпочтительнее. Зато второй быстрее.
« Последняя редакция: 20. Сентября 2011 :: 07:47 - maljaev »  

_______005.rar ( 10 KB | Загрузки )
Наверх
 
IP записан
 
maljaev
Senior Member
****
Отсутствует


Классический секс с 1С
надоел. Хочется изврата...

Сообщений: 405
Местоположение: Нижний Новгород
Зарегистрирован: 19. Октября 2006
Пол: Мужской
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #1 - 19. Сентября 2011 :: 18:38
Печать  
4. Контрол

На форме контрол всегда выводится с 3D-рамкой, способов убрать ее ни средствами объекта WebBrowser, ни средствами HTML/javascript не существует. Но есть обходной путь - смотрите в примере процедуру "ВыровнятьРеквизиты", результат - рамку контролу мы вообще убираем, а если оно нам надо - то обводим его картинкой с прозрачнымм фоном, у которой уже устанавливаем необходимую рамку (например простую как в примере).

5. HTML

По умолчанию в окне WebBrowser всегда выводится вертикальная полоса прокрутки, даже если она не нужна. Убрать ее можно, установив в CSS стиль:

Код
Выбрать все
html {overflow:auto;}
 



Это уберет скроллы до тех пор, пока они действительно не понадобятся. Если поставить overflow:none, то вообще скроллов не будет, тут надо либо создавать элементы со скроллами (например DIV), либо разруливать ситуацию самостоятельно с помощью скриптов или стилей.



Еще одна фича в том, что в WebBrowser (старых версий) не пашет метод getElementsByClassName, поэтому эмулируем его одноименной функцией (есть в примере).



Выполнить переход по ссылке (который мы потом ловим) можно либо в теге <a href="....">, либо в скрипте location.href="....." (есть в примере), или сразу по событию скажем onmouseover="location.href='.....'".



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

6. Прочее

Для тех, кто будет пытаться использовать "Сериализовать", есть еще одна фича - при попытке развернуть объект в скрипте будет выдаваться исключение браузера, чтобы этого не происходило - нужно в свойствах обозревателя в настройках безопасности для интранет-узлов сначала выставить самый низкий уровень безопасности, а затем открыть расширенные настройки и включить галку "Использование элементов управления ActiveX, не помеченных как безопасные для использования". На IE7 не знаю, а вот на IE8 и IE9 точно. Как бы еще один минус в пользу этого метода, ведь не будешь заставлять клиента делать это.
  
Наверх
 
IP записан
 
maljaev
Senior Member
****
Отсутствует


Классический секс с 1С
надоел. Хочется изврата...

Сообщений: 405
Местоположение: Нижний Новгород
Зарегистрирован: 19. Октября 2006
Пол: Мужской
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #2 - 20. Сентября 2011 :: 00:38
Печать  
Интерактивный фоновый отчет по документам

А вот наклепал я практически рабочий отчет, который в фоне выводит список всех документов базы. Можно при этом спокойно работать с другими окнами, можно щелкать по строкам формирующейся таблицы, прокручивать ее. А отчет всё формируется и формируется... Кому не понятен принцип получения/вывода данных - объясню позже, очень устал... Печаль

P.S. Примеры делал без гламурных красот типа картинок и прочего - эту хрень за 10 минут добавить можно если надо, в отличие от алгоритма.
  

_____________002.rar ( 14 KB | Загрузки )
Наверх
 
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #3 - 20. Сентября 2011 :: 01:19
Печать  
Супер! Особенно прмиер журнала!
  
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #4 - 20. Сентября 2011 :: 07:15
Печать  
Dmitry The Wing писал(а) 20. Сентября 2011 :: 01:19:
Супер! Особенно прмиер журнала!


+1

Вот с этим 3.2. Передача параметров в скрипт можно паработать.
Пример можешь подготовить, когда это невозможно сделать, чтоб ошибка выдавалась. Я посмотрю.
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #5 - 20. Сентября 2011 :: 10:12
Печать  
Ага.. примерчик зачетный.
  
Наверх
 
IP записан
 
maljaev
Senior Member
****
Отсутствует


Классический секс с 1С
надоел. Хочется изврата...

Сообщений: 405
Местоположение: Нижний Новгород
Зарегистрирован: 19. Октября 2006
Пол: Мужской
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #6 - 20. Сентября 2011 :: 10:31
Печать  
chessman писал(а) 20. Сентября 2011 :: 07:15:
[quote author=Wing link=1316457428/0#3 date=1316481542]Супер! Вот с этим 3.2. Передача параметров в скрипт можно паработать.
Пример можешь подготовить, когда это невозможно сделать, чтоб ошибка выдавалась. Я посмотрю.

Стёр я его, перепишу снова как время будет.

Общий смысл такой: объект "Система" объявлен в модуле, при клике в веб-форме мы формируем в 1С таблицу значений, сериализуем ее и передаем в скрипт, где происходит ее развертка. Так вот если не ждать 1-2 секунды пока таблица в скрипте обратно развернется и выведется, а упорно продолжать тыкать по кнопке "Добавить таблицу", то где-то на 10-15 тыке управление успевает получить 1С до того, как скрипт закончит работать с очередным экземпляром, и получается что новая таблица только еще сериализуется, а скрипт продолжает работать с предыдущим экземпляром (объект "Система"-то один на весь модуль), в результате скрипт не может получить очередное значение из таблицы и вываливает ошибку и валит заодно 1С. Говорю же что тут асинхронность сказывается, если только заводить по одному экземпляру "Системы" на каждую сериализацию, а потом удалять их по команде из скрипта.

P.S. Лучше JSON реализовать - посмотрел я, не так там всё и сложно, а возможности представления структур такие же как у XML, то есть можно хранить структуры любой сложности, а разворачивается структура из строки простым методом eval(str) в яваскрипте. Есть пример кодировки структур и объектов в JSON из 1С8, думаю можно и под 1С77 переписать: http://infostart.ru/public/59535/
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #7 - 20. Сентября 2011 :: 13:26
Печать  
+10
Пример из #2 заработал ( Win XP )
  
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #8 - 20. Сентября 2011 :: 13:41
Печать  
maljaev писал(а) 20. Сентября 2011 :: 10:31:
3.2. Передача параметров в скрипт


Вот это не поможет?

http://www.1cpp.ru/forum/YaBB.pl?num=1312576677/15#24

Сделай пример, где ТЗ передается без сериализации. В скрипте работай с ТЗ, как с обычным объектом 1С, только методы и наименования колонок используй английские.
Пускай 1С ругается, я дальше гляну, может взлетит.


Пример взял из "Журнала".
Эх, жаль, что на javascript все написано. На vbs'е было бы проще.  Улыбка
« Последняя редакция: 20. Сентября 2011 :: 14:54 - chessman »  
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #9 - 20. Сентября 2011 :: 15:38
Печать  
Как и предполагал, взлетело.

Я конечно там код несколько коряво написал, но главное результат.
Времени нет допилить сегодня, пока только сделал передачу ТЗ в скрипт и вызов "ВыбратьСтроку".


ЗЫ: использовал DynamicWrapperX + исправления в Blang.dll (на лету) для передачи ТЗ. Пока незнаю, как избавиться от предупреждения IE об АктивИксе. Если это невозможно отключить, то упс.


ЗЫ2: параметры в функцию скрипта можно передавать так:

Код
Выбрать все
Браузер.Объект.document.parentWindow.put_array(pCBLContext); 



  

Clipboard02_012.jpg ( 93 KB | Загрузки )
Clipboard02_012.jpg
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #10 - 20. Сентября 2011 :: 15:42
Печать  
Пример и класс DWX.Blang (просто создать 1 раз за сессию, он пропатчит Blang)
  

sample_001.zip ( 19 KB | Загрузки )
Наверх
 
IP записан
 
maljaev
Senior Member
****
Отсутствует


Классический секс с 1С
надоел. Хочется изврата...

Сообщений: 405
Местоположение: Нижний Новгород
Зарегистрирован: 19. Октября 2006
Пол: Мужской
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #11 - 20. Сентября 2011 :: 16:44
Печать  
В принципе я уже придумал, как то же самое сделать с помощью штатного "Сериализовать" класса "Система". С ТЗ всё работает.

Вопрос в другом: можно в скрипт экземпляр своего класса передать? С помощью сериализации или еще как, не важно, ведь можно будет тогда перейти на совсем другой уровень обработки событий и обмена данными.

P.S. Опа, оказывается функцию в модуле скрипта можно прямо через точку вызывать... я не знал...  Улыбка
  
Наверх
 
IP записан
 
maljaev
Senior Member
****
Отсутствует


Классический секс с 1С
надоел. Хочется изврата...

Сообщений: 405
Местоположение: Нижний Новгород
Зарегистрирован: 19. Октября 2006
Пол: Мужской
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #12 - 20. Сентября 2011 :: 17:24
Печать  
Ура, у меня получилась классная вещь! Оказывается можно сериализовать контекст формы!  Улыбка Вот что делаем:

Код
Выбрать все
Функция get_object(ИмяОбъекта)
	Возврат СоздатьОбъект(ИмяОбъекта);
КонецФункции

Процедура HTML_DocumentComplete()
	));
КонецПроцедуры
 



Код
Выбрать все
var object1C;

function initObject1C(obj) {

	object1C=GetObject(obj);

	var tz=object1C.get_object("ТаблицаЗначений");
	tz.ChooseLine(); // это работает !!!

	var myclass=object1C.get_object("МойКласс"); // это тоже работает !!!

}
 



И больше не нужно никаких обработчиков событий и т.д. - скрипт сам получает из 1С нужную информацию - заметьте любую, вплоть до пользовательских классов. Думаю что можно даже прямо к форме обратиться из скрипта, но не пробовал.

Единственная проблема - 1С вываливается тихо при закрытии обработки. Видимо надо какой-то деструктор для сериализованного контекста делать, chessman - может разберешься в чём дело?
  

___________________001.rar ( 8 KB | Загрузки )
Наверх
 
IP записан
 
maljaev
Senior Member
****
Отсутствует


Классический секс с 1С
надоел. Хочется изврата...

Сообщений: 405
Местоположение: Нижний Новгород
Зарегистрирован: 19. Октября 2006
Пол: Мужской
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #13 - 20. Сентября 2011 :: 17:34
Печать  
Вылет 1С поборол:

Код
Выбрать все
Процедура ПриЗакрытии()
	Браузер.Объект.document.parentWindow.object1C="";
	Система="";
КонецПроцедуры
 



Вот и всех делов... Улыбка

P.S. chessman, так как всё что хотелось и даже более того - получается с помощью штатного "Система.Сериализовать", то я не понимаю в чём фишка использования DynamicWrapperX?  Озадачен
  

__________________.rar ( 8 KB | Загрузки )
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Примеры и наработки по использованию WebBrowser ActiveX
Ответ #14 - 20. Сентября 2011 :: 17:45
Печать  
по моему надо при закрытии
Код
Выбрать все
Процедура ПриЗакрытии()
	Браузер.Уничтожить();
КонецПроцедуры
 


проверить не могу потому что у меня еще раньше валиться твой
тестовый пример.

ps Только что увидел твой код
Все равно к #13 надо добавить #14
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 3 ... 6
ОтправитьПечать