问大虾能否遍历所有的框架中的doc(200分)

  • 主题发起人 主题发起人 cyberwalker
  • 开始时间 开始时间
C

cyberwalker

Unregistered / Unconfirmed
GUEST, unregistred user!
如果没有框架(frame),网页的doc:IHtmlDocumet2很容易获得,但是如果有框架,只能得到主框架的doc,问大虾能否遍历所有的框架中的doc
// 有一个VC例子,供参考
//find doc in all frames

int MyApp::DoWorkOnFrames(IHTMLDocument2 *pDoc)
{
int hr;

IHTMLWindow2* pWindow2 = NULL;
IHTMLWindow2* pFrameWindow2 = NULL;
IHTMLDocument2* pFrameDoc = NULL;
IHTMLFramesCollection2* pFrameColl = NULL;

long cFrames;

hr = pDoc->get_parentWindow(&pWindow2);
ASSERT(SUCCEEDED(hr) && pWindow2);

pWindow2->get_frames(&pFrameColl);

if (SUCCEEDED(hr = pFrameColl->get_length( &cFrames )))
{
for ( int i=0; i < cFrames ; i++ )
{
VARIANT vIndex;
vIndex.vt = VT_UINT;
vIndex.lVal = i;
VARIANT var2 = { 0 };
LPDISPATCH pDisp;
VARIANT frame;

if (SUCCEEDED(hr = pFrameColl->item( &vIndex, &frame ))){
hr = frame.pdispVal->QueryInterface(IID_IHTMLWindow2, (void**)&pFrameWindow2);
hr = pFrameWindow2->get_document(&pFrameDoc);
DoWorkOnDoc(pFrameDoc);
DoWorkOnFrames(pFrameDoc);
}

}
}
}

//请大虾看看上面的程序,把它翻译成Delphi
 
IHTMLWindow2* pWindow2 = NULL;
IHTMLWindow2* pFrameWindow2 = NULL;
IHTMLDocument2* pFrameDoc = NULL;
IHTMLFramesCollection2* pFrameColl = NULL;
这些都是初始化相关窗体和文档的指针

hr = pDoc->get_parentWindow(&pWindow2);
ASSERT(SUCCEEDED(hr) && pWindow2);
查找文档的父窗体,并验证是否存在(指针是否有)


pWindow2->get_frames(&pFrameColl);

if (SUCCEEDED(hr = pFrameColl->get_length( &cFrames )))
{
for ( int i=0; i < cFrames ; i++ )
{
VARIANT vIndex;
vIndex.vt = VT_UINT;
vIndex.lVal = i;
VARIANT var2 = { 0 };
LPDISPATCH pDisp;
VARIANT frame;

这些都是得到Frame的信息

if (SUCCEEDED(hr = pFrameColl->item( &vIndex, &frame ))){
hr = frame.pdispVal->QueryInterface(IID_IHTMLWindow2, (void**)&pFrameWindow2);
hr = pFrameWindow2->get_document(&pFrameDoc);
DoWorkOnDoc(pFrameDoc);
DoWorkOnFrames(pFrameDoc);
在Frame里面查找符合要求的文档

程序怎么写你自己想了[:)]
 
doc:Frames[Index]可以获得每一个框架,并且实现了IHTMLWindow2接口(通过QueryInterface
就可以得到).
在得到的IHTMLWindow2接口中又有doc,此时通过doc得到的就是框架内的代码.
 
在Delphi中比较麻烦, 因为要取得Frame的IHtmlDocumet2比较困难,调用相应的方法返回
的是OleVariant。
不过如果你只是为了取得Frame的outerHTML之类的文本却是很简单的。
 
procedure TForm1:WorkOnFrame(doc, IHtmlDocument2)
var
framewin2,win2:IHtmlWindow2;
framedoc:IHtmlDocument2;
frameCol:IHtmlFramesCollection2;
i:Integer;
vi,frame:OleVariant;

begin
win2:=doc.parentWindow;
frameCol:=win2.Frames;
for i:=0 to frameCol.Length-1 do
begin
vi:=i;
frame:=frameCol.Item(vi);
frame.dispVal.QueryInterface(IID_IHTMLWindow2,framewin2);
framedoc:=framewin2.document;
WorkOnFrame(framedoc);
end;
end;
//以上程序,编译出错 Type not allowed in Variant Dispatch call
//请大虾指点,救命呀
 
1.不需要用IHTMLWindow2的Frames属性,doc本身就有get_Frames方法.
2.frame的类型应该是IFrame,
3.frame:=frameCol.Item(vi);改为frame:=frameCol.Item(vi) as IFrame;
 
frame:=frameCol.Item(vi);改为frame:=frameCol.Item(vi) as IFrame;

系统告诉我Iframe没有定义,请大虾写出完整的代码,好吗??
 
呵呵,改成IDispatch,不是改成IFrame
procedure TForm1:WorkOnFrame(doc: IHTMLDocument2);
var
framewin2:IHtmlWindow2;
frameCol:IHtmlFramesCollection2;
i:Integer;
vi:OleVariant;
Frame: IDispatch;

begin
frameCol:=doc.Frames;
for i:=0 to frameCol.Length-1 do
begin
vi:=i;
frame:=frameCol.Item(vi);
frame.QueryInterface(IID_IHTMLWindow2,framewin2);
WorkOnFrame(framewin2.document);
end;
end;
 
LeeChange的代码可以实现。
 
最后一个问题
比如:http://www.abc.com/abc.html中一个框架,镶嵌着一个http://www.123.com/123.html
,这时framewin2.document会发生异常: get_document error: access denied,请大虾如何解决
这个问题??

衷心感谢!!!
 
每个网页都access denied吗?应该不是的吧.
 
it seem that if the document of the page is not located on the same site that
other page located in, the get_document function will throw exception
access denied? anyone can resovle the problem?

Thanks you !
 
多人接受答案了。
 
后退
顶部