Здравствуйте Аноним, Вы писали:
А>Здравствуйте Faust, Вы писали:
F>>Еще как актуален!!!!!!!!!!!! F>>Скинь плиз — denis_@mailru.com
А>Сбросил на мыло, ответа пока неет. Поэтому дублирую здесь, в конференции
А>=================================================
А>Привет!
А>Ну раз актуален, тогда пожалуйста. Приятно что и я могу хоть кого-то чему-то А>научить — а то всё спрашиваю и спрашиваю. :-)
А>Основная идея такая: А>CHtmlView использует WebBrouser — это тот же самый Internet Explorer. А>IE предоставляет вещь под названием "объектная модель" — если ты писал под А>JavaScript, то наверняка знаешь её — если нет, то коротко так — любой HTML А>документ — это дерево объектов, у которых куча свойств. Достучаться до этих А>объектов и свойств можно используя семейство IHTML... интерфейсов. Их тоже А>очень много — практически на любую возможную мелочь.
А>Итак, цепочка действий для модификации HTML-кода такая: А>1 Обязательно загружаешь в CHtmlView любой документ (Navigate2) (Можно А>пустой, но он должен иметь тэг BODY) А>2 Получаешь интерфейс IHTMLDocument2 — я бы сказал, что он корневой. А>3 Затем от него получаешь интерфейс для управления нужным элементом А>документа. А>4 Через свойство put_innerHtml пишешь в него HTML-код
А>Напишу пример. За полную безошибочность кода не ручаюсь — выдираю куски кода А>из разных место своего проекта. Нет времени сделать тестовый проект для А>этого кода и отладить. А>-------------------------------------------------- А>1 Обязательно загружаешь в CHtmlView любой документ (Navigate2) (Можно и А>полностью пустой, но за это не ручаюсь. Лучше если, он будет иметь тэг А>BODY — у меня работало так.)
А>CHtmlView::Navigate2(sPath, 0); А>------------------------------------------------ А>2 Получаешь интерфейс IHTMLDocument2 — я бы сказал, что он корневой. А>Последующий код лучше всего загнать в OnNavigateComplete2 — эта функция А>вызывается, когда документ полностью загружен в IE и объектная модель А>документа полностью сформирована.
А> // пройти по цепочке интерфейсов и добраться до IHtmlDocument2 А> CComPtr<IWebBrowser2> pWB; А>CComPtr<IHTMLDocument2> m_pHtmlDoc А> LPDISPATCH pDisp1; А> CComPtr<IDispatch> pDisp2; А> // достукиваемся до коллекции элементов А> pDisp1 = GetApplication(); А> pDisp1->QueryInterface(IID_IWebBrowser2, (void**) &pWB); А> pWB->get_Document(&pDisp2); А> pDisp2->QueryInterface(IID_IHTMLDocument2, (void**) &m_pHtmlDoc);
А>Можно сделать то же самое через метод CHtmlView::GetHtmlDocument. Он вернет А>опять же LPDISPATCH, а от него — запросить IHTMLDocument2
А>------------------------------------
А>3 Затем от него получаешь интерфейс для управления нужным элементом. Как это А>делается? Каждый объект документа — это элемент коллекции внутри IE. На А>каждый HTML-тэг свой элемент, Можно добраться до этой коллекции, а затем от А>неё получать элементы либо по их ID (к примеру есть в документе абзац вида А><P ID="myparagraph">, значит к нему можно обратиться прямо по его имени - А>"myparagraph"). Либо можно последовательно перебирать все элементы А>коллекции — пока не доберешься до нужного. В моем примере я использую доступ А>прямой — по имени. Если придётся перебирать — посмотри методы А>IHTMLElementCollection.
А>CComPtr<IHTMLElementCollection> m_pEC; А> m_pHtmlDoc->get_all(&m_pEC); А> COleVariant varElementName; А> COleVariant varInd((long) 0, VT_I4); А> CComBSTR bstrHtml; А> CString sHtml(' ', CSTRINGBUFSIZE); А> // вставляем подопытный элемент А> CComPtr<IDispatch> pDisp4; А> CComPtr<IHTMLElement> pElement; А> // сначала создаем его HTML-код
А>........ — вырезано, в sHtml загоняется полное описание какого элемента А>(например — "<P id=\"test\"> Текст абзаца </P>")
А>bstrHtml = sHtml; А> m_pDivElement->put_innerHTML( (BSTR) bstrHtml); А>// m_pDivElement — это моя специфичная переменная типа CComPtr<IHTMLElement>, А>// указывает на <DIV> в который я и засовываю элементы А>// читаем его (только что добавленного HTML-элемента) размеры в пикселах А> if (pDataItem->m_sName == "") А> AfxMessageBox("Не смогу получить размер элемента, не зная его имени"); // А>у элемента нет имени — не смогу получить доступ А> varElementName = pDataItem->m_sName; А> m_pEC->item(varElementName, varInd, &pDisp4); А> pDisp4->QueryInterface(IID_IHTMLElement, (void**) &pElement);
А>//тут к примеру можно поглучить доступ к свойствам элемента: ширине, высоте, А>видимости, стилям .... и т.д. -
А> pElement->get_offsetHeight(&lHeight); А> pElement->get_offsetWidth(&lWidth); А> // удаляем подопытный элемент А> bstrHtml = CString(""); А> m_pDivElement->put_innerHTML( (BSTR) bstrHtml);
А>Что еще? Чтобы получше узнать структуру объектной модели, я в свое время А>потратил пару недель на DHTML — всё, что в нем есть имеет аналоги и в виде А>IHTML-интерфейсов.
А>Будут еще вопросы по этой теме — пиши, с удовольствием расскажу, что знаю.
А>Успехов, А>Кабаев Сергей
Это все понятно.............
А как получить документ до загрузки, например, указывая путь к файлу и счивая его, причем, иметь при этом такую же структуру которую предоставляют IHTML... интерфейсы?
Спасибо за заботу.....
Кстати, есть ли у тебя Platform SDK 2001?
Мне жуть как нужен заголовочный файл mshtml.h из этого комплекта. Если есть такая возможность, то буду очень благодарен.