Извлечь содержимое iframe в TWebBrowser из Delphi

У меня есть компонент TWebBrowser, и я загружаю URL-адрес расширенного текстового редактора. После редактирования я хотел бы получить HTML-код текста (со всей его разметкой).

Взглянув на отладчик браузера, я вижу, что редактор сохраняет текст в iframe:

Я могу получить iframe с помощью этого:

  NodeName := 'htmleditor_ifr';
  BodyIframe := (WebBrowser1.Document as IHTMLDocument3 ).getElementById(NodeName);

Но я не знаю, как получить внутренний документ.

Какие-нибудь советы?

содержаниеДокумент
Olivier 22.12.2020 12:44

@ Оливье, я вижу, ваш ответ для JavaScript, я работаю с Delphi.

Héctor C. 22.12.2020 13:12

Мой ответ для DOM, с которым вы работаете. getElementById() также является DOM, если вы не знаете.

Olivier 22.12.2020 13:15

В Delphi есть метод getElementById, но нет метода contentDocument, поэтому, к сожалению, я не могу использовать этот подход.

Héctor C. 22.12.2020 13:23

Попробуйте привести возвращаемый элемент к IHTMLIFrameElement3, и тогда вы сможете получить доступ к свойству contentDocument.

Olivier 22.12.2020 13:44

Я использую Delphi 7. Я могу найти IHTMLIFrameElement или IHTMLIFrameElement2, но не могу найти IHTMLIFrameElement3.

Héctor C. 22.12.2020 13:45

Тогда вы можете вместо этого привести элемент к IHTMLFrameBase2 и получить доступ к свойству contentWindow?

Olivier 22.12.2020 14:02

В этой версии Delphi нет ни IHTMLFrameBase2, ни IHTMLIFrameBase2. Я также не могу найти интерфейс с методом contentWindow.

Héctor C. 22.12.2020 16:59

Вы можете попытаться привести его к IUnknown и поместить результат в variant, чтобы использовать позднюю привязку для доступа к свойству contentWindow...

R. Hoek 22.12.2020 23:07

@ Оливье, я только что узнал, как добавить все те определения, которых мне не хватало.

Héctor C. 23.12.2020 09:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
10
517
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это мое решение для Delphi 7.

В моей версии Delphi не было реализации IHTMLIFrameElement3, но IDE предлагает способ добавить его в ваш проект:

Компонент меню > Импорт элемента управления ActiveX

В этом диалоговом окне вы можете сгенерировать новый модуль, содержащий все определения, отсутствующие в установке Delphi 7:

  CLASS_HTMLFrameElement: TGUID = '{3050F314-98B5-11CF-BB82-00AA00BDCE0B}';
  IID_IHTMLIFrameElement: TGUID = '{3050F315-98B5-11CF-BB82-00AA00BDCE0B}';
  IID_IHTMLIFrameElement2: TGUID = '{3050F4E6-98B5-11CF-BB82-00AA00BDCE0B}';
  IID_IHTMLIFrameElement3: TGUID = '{30510433-98B5-11CF-BB82-00AA00BDCE0B}';
  DIID_DispHTMLIFrame: TGUID = '{3050F51B-98B5-11CF-BB82-00AA00BDCE0B}';
  CLASS_HTMLIFrame: TGUID = '{3050F316-98B5-11CF-BB82-00AA00BDCE0B}';

[...]

// *********************************************************************//
// Interface: IHTMLIFrameElement3
// Flags:     (4416) Dual OleAutomation Dispatchable
// GUID:      {30510433-98B5-11CF-BB82-00AA00BDCE0B}
// *********************************************************************//
  IHTMLIFrameElement3 = interface(IDispatch)
    ['{30510433-98B5-11CF-BB82-00AA00BDCE0B}']
    function Get_contentDocument: IDispatch; safecall;
    procedure Set_src(const p: WideString); safecall;
    function Get_src: WideString; safecall;
    procedure Set_longDesc(const p: WideString); safecall;
    function Get_longDesc: WideString; safecall;
    procedure Set_frameBorder(const p: WideString); safecall;
    function Get_frameBorder: WideString; safecall;
    property contentDocument: IDispatch read Get_contentDocument;
    property src: WideString read Get_src write Set_src;
    property longDesc: WideString read Get_longDesc write Set_longDesc;
    property frameBorder: WideString read Get_frameBorder write Set_frameBorder;
  end;

// *********************************************************************//
// DispIntf:  IHTMLIFrameElement3Disp
// Flags:     (4416) Dual OleAutomation Dispatchable
// GUID:      {30510433-98B5-11CF-BB82-00AA00BDCE0B}
// *********************************************************************//
  IHTMLIFrameElement3Disp = dispinterface
    ['{30510433-98B5-11CF-BB82-00AA00BDCE0B}']
    property contentDocument: IDispatch readonly dispid -2147413992;
    property src: WideString dispid -2147413991;
    property longDesc: WideString dispid -2147413990;
    property frameBorder: WideString dispid -2147413989;
  end;

// *********************************************************************//
// DispIntf:  DispHTMLIFrame
// Flags:     (4112) Hidden Dispatchable
// GUID:      {3050F51B-98B5-11CF-BB82-00AA00BDCE0B}
// *********************************************************************//
  DispHTMLIFrame = dispinterface
    ['{3050F51B-98B5-11CF-BB82-00AA00BDCE0B}']
    procedure setAttribute(const strAttributeName: WideString; AttributeValue: OleVariant;
                           lFlags: Integer); dispid -2147417611;
    function getAttribute(const strAttributeName: WideString; lFlags: Integer): OleVariant; dispid -2147417610;
    function removeAttribute(const strAttributeName: WideString; lFlags: Integer): WordBool; dispid -2147417609;
    property _className: WideString dispid -2147417111;
    property id: WideString dispid -2147417110;
    property tagName: WideString readonly dispid -2147417108;

 // more

Получив это, я последовал советам @Olivier:

  NodeName := 'htmleditor_ifr';
  BodyIframe := (WebBrowser1.Document as IHTMLDocument3 ).getElementById(NodeName);
  ContentHTML := (((BodyIframe as IHTMLIFrameElement3 ).contentDocument) as IHTMLDocument2 );
  Body := ContentHTML.body.innerHTML;

Другие вопросы по теме