Здравствуйте, Александр Шилоносов, Вы писали:
АШ>Статья:
АШ>Авторы:
АШ> Александр Шилоносов
АШ>Аннотация:
АШ>Cтатья описывает способы использования MFC-класса CHtmlView и технологии DHTML для создания web-интерфейса в MFC приложении.
В дополнение расскажу как мы реализовывали в CHtmlView аналог DoDataExchange механизма (как альтернатива использования OnBeforeNavigate2 в том контексте, в каком он описан в данной статье). Мы использовали переопределение интерфейса external у объекта window. Использовали Advanced Hosting Interfaces для его переопределения. Фактически external был сделан в WebBrowser именно для подобных целей. Например у IE через него можно работать с фаворитами (метод AddFavorites у external). Дополнительно есть еще несколько методов, специфичных для IE, именно IE, а не для WebBrowser. Нужно понимать эту разницу, потому как IE есть приложение, используещее WebBrowser для одной единственной задачи — броузинг в интернет. Я бы даже переименовал WebBrowser контрол как-нибудь по другому, чтобы не возникало путаницы между IE и WebBrowser. Задача ведь WebBrowser состоит всего лишь(!) в скачивании html страниц с некоторого адреса и их отображения, а уж под каким "соусом" они преподносятся — это дело того приложения, которое его использует, буть то IE, Norton Antivirus или ваше приложение.
В нашем случае, когда мы создаем свое приложение, используя WebBrowser, мы можем переопределить свойство
window.external. Задача external — возвращать некий
dispInterface. Для
DoDataExchange мы поступили следующим образом. Создали на базе класса
CCmdTarget обьект с поддержкой
Automation (CCmdTarget::EnableAutomation()). В классе определили dispatch map (DECLARE_DISPATCH_MAP()) с некоторым набором методов (один из них был
UpdateData(BOOL bUpdate)). Через
Advanced Hosting Interfaces по запросу WebBrowser мы отдавали ему указатель на наш обьект CCmdTarget —
m_pCmdTarget->GetIDispatch(TRUE). Т.е. когда в скрипте встречалась строка
window.external.<что-то>, происходил доступ к нашему CCmdTarget based объекту со стороны HTML. Например, по нажатию кнопки Ok на html странице мы вызывали
window.external.UpdateData(true). Сам UpdateData в CCmdTarget based классе просто вызывал стандартный UpdateData у CHtmlView. Таким образом мы просто задействовали стандартный подход, который реализован в MFC. Осталось только "разобраться" с самим DoDataExchange у нашего CHtmlView. Были написаны
DDX_* аналоги для работы со стандартными HTML объектами (edit'ы, combobox'ы и тому подобными). Вместо числовых ID_ значений мы использовали строковые аналоги, типа "1005", "password_field" (где password_field был как id у edit на html странице —
<edit id="password_field" ... ). Вообщем получили стандартный DoDataExchange механизм. Замечу, что писалось это несколько лет тому назад, когда еще не было MFC 7.0. Как потом обнаружилось, в седьмой версии нечто очень похожее было реальзовано.
Развивая эту механику, мы реализовали в нашей системе доступ к объектной модели проекта. Теперь все объекты в MFC приложении были доступны и из HTML, и как оказалось, было потом написано достаточно много логики приложения именно с использованием JScript (код имплементации выглядел намного проще и был выигрыш в сроках реализации).
Подытожу. Идея external в том, чтобы дать разработчику шлюз между HTML и неким внешним кодом, который использует WebBrowser (для нас это С++) и реализовывать свои методы и свойства со своими параметрами, а не использовать OnBeforeNavigate2, передавая параметры через navigate
Спасибо за внимание,
Николай Египко