웹에 널려 있는 GetIEFromHWND() 함수가 제대로 안되어서 새로 구했음.

 

 

클래스명이 Internet Explorer_Server 인 윈도우의 핸들은 알아서 구하는 걸로 가정.

 

 

 

// 사용예

 

uses

  IE;

var

  hIE: HWND;

  sHTML: String;

 

begin

  // 어떻게 Internet Explorer_Server 윈도우의 핸들을 가져옴

  hIE:=GetIEHandle(~~);

  // 가져온 핸들을 이용해 HTML 소스를 받아옴

  sHTML:=GetHTML(hIE);

end;

 

 

// 스트링 리스트에 모든 프레임의 HTML 들을 받아오는 함수

function GetHTML(hIE: HWND): String;

var sList: TStringList;

begin

  Result:='';

 

  sList:=TStringList.Create;

  try

    GetIEHTMLSources(hIE, sList);

    Result:=sList.Text;

  finally

    FreeAndNil(sList);

  end;

end;

 

 

 

 

unit IE;

 

interface

 

uses

    Windows, SysUtils, ComObj, Forms, Variants, SHDocVw, OleCtrls, MsHTML, ActiveX, Classes;

 

function GetFrameSource(iDoc: IHTMLDocument2): String;

function GetHTMLDocument(hIE: HWND): IHTMLDocument2;

function GetIEHTMLSource(hIE: HWND): String;

procedure GetIEHTMLSources(hIE: HWND; SourceList: TStringList);

 

 

implementation

 

 

// IHTMLDocument2 -> HTML 소스

function GetFrameSource(iDoc: IHTMLDocument2): String;

var

  i: Integer;

  elem: IHTMLElement;

  collection: IHTMLElementCollection;

  lenHTML: Integer;

begin

  Result:='';

 

  if (Assigned(iDoc)) then begin

    collection:=iDoc.Get_all;

    lenHTML:=collection.Length;

    for i:=0 to lenHTML-1 do begin

      elem:=collection.item(i, 0) as IHTMLElement;

      if elem.tagName='HTML' then Result:=Result+elem.outerHTML;

    end;

  end;

end;

 

// HWND -> IHTMLDocument2

procedure GetDocumentPtrFromWnd(Wnd: HWND; var pDoc: IHTMLDocument2);

type

  TObjectFromLResult=function(LRESULT: LRESULT; const IID: TGUID; wParam: WPARAM; out PObject): HRESULT; stdcall;

var

  GetDocPtr: TObjectFromLResult;

  hModule: THandle;

  Msg: Cardinal;

  lRes: Cardinal;

begin

  hModule:=LoadLibrary('OLEACC.DLL');

  try

    if hModule <> 0 then begin

      GetDocPtr:=GetProcAddress(hModule, 'ObjectFromLresult');

      if @GetDocPtr <> nil then begin

        Msg:=RegisterWindowMessage('WM_HTML_GETOBJECT');

        SendMessageTimeout(Wnd, Msg, 0, 0, SMTO_ABORTIFHUNG, 1000, lRes);

        if GetDocPtr(lRes, IID_IHTMLDocument2, 0, pDoc) <> S_OK then begin

          pDoc:=nil;

        end;

      end;

    end;

  finally

    FreeLibrary(hModule);

  end;

end;

 

// HWND -> IHTMLDocument2

function getHTMLDocument(hIE: HWND): IHTMLDocument2;

var

   pDoc: IHTMLDocument2;

begin

  Result:=nil;

  GetDocumentPtrFromWnd(hIE, pDoc);

  Result:=pDoc;

end;

 

// HWND -> HTMLSource

function GetIEHTMLSource(hIE: HWND): String;

begin

  Result:=GetFrameSource(GetHTMLDocument(hIE));

end;

 

// IHTMLDocument2 -> IWebBrowser2 (fIdx번째 프레임의 IWebBrowser2)

function GetBrowserForFrame(pDoc: IHTMLDocument2; fIdx: Integer): IWebBrowser2;

var

  pContainer: IOleContainer;

  Enumerator: ActiveX.IEnumUnknown;

  nFetched: PLongInt;

  UnknownFrame: IUnknown;

  hr: HResult;

begin

  Result:=nil;

  nFetched:=nil;

 

  pContainer:=pDoc as IOleContainer;

  hr:=pContainer.EnumObjects(OLECONTF_EMBEDDINGS or OLECONTF_OTHERS, Enumerator);

  if hr <> S_OK then begin

    pContainer._Release;

    Exit;

  end;

 

  Enumerator.Skip(fIdx);

  Enumerator.Next(1, UnknownFrame, nFetched);

  UnknownFrame.QueryInterface(IID_IWebBrowser2, Result);

end;

 

// HWND -> HTML소스 (프레임이 있을 경우 프레임의 소스까지 - depth는 1단계만)

procedure GetIEHTMLSources(hIE: HWND; SourceList: TStringList);

var

  pDoc, tmpDoc: IHTMLDocument2;

  fCol: IHTMLFramesCollection2;

  lenFrames: Integer;

  ov: OleVariant;

  i: Integer;

begin

  try

    pDoc:=GetHTMLDocument(hIE);

    SourceList.Add(GetFrameSource(pDoc));

 

    fCol:=pDoc.Get_Frames;

    lenFrames:=fCol.Get_Length;

    if lenFrames > 0 then begin

      for i:=0 to lenFrames-1 do begin

        ov:=i;

        tmpDoc:=pDoc;

        pDoc:=GetBrowserForFrame(tmpDoc, ov).Document as IHTMLDocument2;

        if pDoc<>nil then SourceList.Add(GetFrameSource(pDoc));

      end;

    end;

  except on E:Exception do

    SourceList.Add(E.Message);

  end;

end;

 

 

 

 

 

 

 

 

 

 

 

 

Posted by bloodguy
,