Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   TWebBrowser obtener HTML de un frame cargado. (https://www.clubdelphi.com/foros/showthread.php?t=85555)

QuiqueSalamanca 31-03-2014 14:00:04

TWebBrowser obtener HTML de un frame cargado.
 
Hola a todos:

Primero daros las gracias porque este foro me ha sido de muy gran ayuda desde hace más de 4 años, aquí he encontrado muchas soluciones a problemas varios, otra vez gracias.

Ahora os expongo el que después de varias semanas buscando y rebuscando por internet (y por el foro también) no he encontrado solución.

Os explico: necesito traerme el HTML que me muestra un frame (que está dentro de otros tantos frames) para obtener un valor que me pinta una función de JavaScript en el HTML.

He probado varias cosas desde traerme el HTML con un TIdHTTP (como no se ejecuta el JSP no me devuelve el valor que necesito pero sí me devuelve el HTML correcto).

De ahí he pasado al componente IHTMLDocument2 que ofrecía éste foro, del usuario kotai.

Os pongo el código de kotai donde yo solo he modificado un par de cosas:
Código:

//******************************************************************************

function GetBrowserForFrame(Doc: IHTMLDocument2; nFrame: Integer): IWebBrowser2;
var
  pContainer: IOLEContainer;
  enumerator: ActiveX.IEnumUnknown;
  nFetched: PLongInt;
  unkFrame: IUnknown;
  hr: HRESULT;
begin
    Result := nil;
    nFetched := nil;
    // Cast the page as an OLE container
    pContainer := Doc as IOleContainer;
    // Get an enumerator for the frames on the page
    hr := pContainer.EnumObjects(OLECONTF_EMBEDDINGS or OLECONTF_OTHERS, enumerator);
    if hr <> S_OK then
    begin
          pContainer._Release;
          Exit;
    end;
    // Now skip to the frame we're interested in
    enumerator.Skip(nFrame);
    // and get the frame as IUnknown
    enumerator.Next(1,unkFrame, nFetched);
    // Now QI the frame for a WebBrowser Interface - I'm not  entirely
    // sure this is necessary, but COM never ceases to surprise me
    unkframe.QueryInterface(IID_IWebBrowser2, Result);
end;

//******************************************************************************

function GetFrameSource(WebDoc: iHTMLDocument2): string;
  //returns frame HTML and scripts as a text string
var
  re: integer;
  HTMLel: iHTMLElement;
  HTMLcol: iHTMLElementCollection;
  HTMLlen: Integer;
  ScriptEL: IHTMLScriptElement;
begin
    Result := '';
    if Assigned(WebDoc) then
    begin
        HTMLcol := WebDoc.Get_all; //Me devuelve NIL y por lo tanto en la siguiente linea cruje
          HTMLlen := HTMLcol.Length;
          for re := 0 to HTMLlen - 1 do
          begin
              HTMLel := HTMLcol.Item(re, 0) as iHTMLElement;
              if HTMLEl.tagName = 'HTML' then
                  Result := Result + HTMLEl.outerHTML;
          end;
    end;
end;

//******************************************************************************

procedure TF_Principal.ObtenerHTML(Num:SmallInt);
var
  Webdoc, HTMLDoc: ihtmldocument2;
  framesCol: iHTMLFramesCollection2;
  FramesLen: integer;
  pickFrame: olevariant;
  p: integer;
  HTML : String;
  iFrame : IWebBrowser2;
begin
    if WB <> nil then
        try
          WebDoc := WB.Document as IHTMLDocument2;
          HTML := GetFrameSource(WebDoc);
          meHtml.Text := HTML;
          FramesCol := WebDoc.Get_frames;
          FramesLen := FramesCol.Get_length;
          if FramesLen > 0 then
              for p := 0 to FramesLen - 1 do
              begin
                  pickframe := p;
                  HTMLDoc  := WB.Document as iHTMLDocument2;
                  iFrame    := GetBrowserForFrame(HTMLDoc, pickframe);
                  if iFrame <> nil then
                  begin
                        WebDoc := iFrame.document as iHTMLDocument2;
                        if WebDoc <> nil then
                        begin
                            HTML := GetFrameSource(WebDoc);
                            // analizamos el HTML de este frame
                              meHtmlFrame.Text := HTML;
                        end;
                  end;
              end;
        except
        end;
end;

Ésta es la solución que más se me adecua.

Seguí buscando y apareció una documentación muy buena por cierto pero tras varios intentos sigo sin lograr traerme el HTML del frame con el valor...

Entonces pense si podría traerme el contenido del HTML una vez que se carga el frame y encontré éste código del usuario roman, (mil gracias porque eres un crack en ésto) y así controlaba cuando se ha cargado el frame:

Código:

procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
var
  Webdoc, HTMLDoc: ihtmldocument2;
  framesCol: iHTMLFramesCollection2;
  FramesLen: integer;
  pickFrame: olevariant;
  p: integer;
  HTML : String;
  iFrame : IWebBrowser2;
  CurWebrowser : IWebBrowser;
  TopWebBrowser: IWebBrowser;
  Document    : OLEvariant;
  WindowName  : string;
begin
{ TForm1.WebBrowser1DocumentComplete }
  CurWebrowser := pDisp as IWebBrowser;
  TopWebBrowser := (Sender as TWebBrowser).DefaultInterface;
  if CurWebrowser=TopWebBrowser then
  begin
    ShowMessage('Document is complete.');
    //FCambiandoDePag := FALSE;
  end
  else
  begin
    Document := CurWebrowser.Document;
    WindowName := Document.ParentWindow.Name;
    if windowname = 'frame_presentacion' then
    begin
      Webdoc := (CurWebrowser.Document );
      //Aquí necesito obtener el HTML
      ShowMessage('Frame ' + WindowName + ' is loaded.')
    end;
  end;
end;

Pero sigo sin ideas de como hacerlo, no sé ya me estoy volviendo un pelín loco.

¿Alguna idea?

Mil gracias!

PD: no me dejaba poner los enlaces...

Saludos,
Quique.

escafandra 31-03-2014 19:28:03

Quizás este ejemplo te ayude a organizar tus ideas.

Saludos.

QuiqueSalamanca 01-04-2014 09:44:50

Cita:

Empezado por escafandra (Mensaje 474613)
Quizás este ejemplo te ayude a organizar tus ideas.

Saludos.

Hola escafandra:

El problema es que me devuelve el html del index pero sin desplegar los frames.

Yo he identificado el frame (como veíais más arriba ponía frame_presentacion) el problema es que este frame es un JSP que devuelve el código en HTML y no es HTML puro...

Estoy por decirle al cliente que no se puede pero ya por cabezonería lo querría sacar...

Gracias!


La franja horaria es GMT +2. Ahora son las 01:18:28.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi