55555555...自問自答 !
hf2:IHTMLFramesCollection2;
hf2:=doc.frames;
for i:=0 to hf2.length-1 do
begin
....
end;
有時會發現,無框架之網頁其 hf2.length 並不等於 0
這是為什麼呢!因為有些網頁使用了 iFrame 的技術,
而它也含在內,所以
在判斷時要加一步
if not SUCCEEDED(spDisp.QueryInterface(IHTMLIFrameElement ,iiFrameEle))then
來排除,...
可是又發現有的網頁卻能突破此封鎖,奇怪,
可惜只研究至此,就偷懶地
使用 try...except 來封鎖錯誤訊息了!
由於使用時大都利用 IDispatch,所以
寫個小程序將全部物件都放在一起,
不管有無框架都通吃,
不過還是有缺點,應該有方法可將它們
都放進一個 IHTMLElementCollection
這樣要用時再利用 OleVariant 來找就方便多了。
如
iec:IHTMLElementCollection;
item:OleVariant;
item:=all.item(pp,0); // pp 可為 index 或 name
看看高手是否願意再補述一番。
var
ObjList:array of IDispatch;
ObjListCount:integer;
procedure TForm1.UpdateObj;
var
doc:IHTMLDocument2;
begin
// 更新網頁上的物件至 ObjList
//
SetLength(ObjList,3000);
ObjListCount:=0;
doc:=web.Document as IHTMLDocument2;
if doc<>nil then
UpdateObj2(doc);
end;
procedure TForm1.UpdateObj2(doc:IHTMLDocument2);
var
tmpDoc:IHTMLDocument2;
all: IHTMLElementCollection;
spDisp:IDispatch;
i:integer;
HtmlWin:IHTMLWindow2;
iFrameB2:IHTMLFrameBase2;
iFramei:IHTMLIFrameElement;
iFrame:IHTMLFrameElement;
begin
//
all:=doc.Get_all;
for i := 0 to all.length-1 do
begin
application.ProcessMessages;
spDisp:=all.item(i,0);
ObjList[ObjListCount]:=spDisp;
inc(ObjListCount);
if (High(ObjList)-ObjListCount)<50 then
SetLength(objList,High(ObjList)+1000);
// Frame...
// 避開 iFrame 成員
if not SUCCEEDED(spDisp.QueryInterface(IHTMLIFrameElement ,iFramei))then
begin
if SUCCEEDED(spDisp.QueryInterface(IHTMLFrameElement ,iFrame)) and
SUCCEEDED(spDisp.QueryInterface(IHTMLFrameBase2 ,iFrameB2)) then
begin
spDisp:=iFrameB2.contentWindow;
if SUCCEEDED(spDisp.QueryInterface(IHTMLWindow2 ,HtmlWin))then
begin
if HtmlWin<>nil then
begin
try
if SUCCEEDED(HtmlWin.document.QueryInterface(IHTMLDocument2 ,tmpDoc)) then
begin
UpdateObj2(tmpDoc);
end;
except
end;
end;
end;
end;
end;
end; // for
end;