Question ===================================================== =
I read the usage of twebbrowser on your website, but I have been troubled by the problem of how to obtain the HTML source code of the nested frame of a frame. I only know how to obtain the source code of a single frame, but there is no way to nest multiple frames. Please take a look!
23:41:28
A: ===================================================== =
To obtain the source code, you must first obtain the frame. There are two methods to access frame:
1. Obtain the set of frames through the webbrowser Document Interface and access them one by one.
Hresult ihtmldocument2: get_frames (ihtmlframescollection2 ** P );
The item method of the ihtmlframescollection2 interface can access the corresponding frame with the frame index number (starting from 0) or frame name, pvarresult returns an idispatch interface (or an array of idispatch interfaces, multi-layer nesting ).
Hresult item (
Variant * pvarindex,
Variant * pvarresult
);
For example, we suppose pwin is a valid ihtmlwindow interface pointer pointing to the main window.
......
Variant framerequested;
Variant frameout;
Ihtmlframescollection2 * pframescol;
Ihtmlwindow2 * prightframewindow;
Ihtmldocument2 * prightdoc;
Framerequested. Vt = vt_bstr; // If vt_i4 is used, access the database with the index number.
Framerequested. bstrval = l "rightframe"; // access by name
// Framerequested. Vt = vt_i4;
// Framerequested. bstrval = (BSTR) 0;
HR = pwin-> get_frames (& pframescol );
HR = pframescol-> item (& framerequested, & frameout );
HR = frameout. pdispval-> QueryInterface (iid_ihtmlwindow2, (void **) & prightframewindow );
HR = prightframewindow-> get_document (& prightdoc );
......
2. Use iolecontainer to enumerate embedded objects to access webbrowser objects.
Void cmyhtmlview: refreshframes ()
{
// Obtain the document's idispatch pointer
Lpdispatch lpdisp = NULL;
Lpdisp = gethtmldocument ();
If (lpdisp)
{
Iolecontainer * pcontainer;
Hresult hR = lpdisp-> QueryInterface (iid_iolecontainer, (void **) & pcontainer );
Lpdisp-> release ();
If (failed (HR ))
Return hr;
Ienumunknown * penumerator;
// Obtain the enumerator
HR = pcontainer-> enumobjects (olecontf_embeddings, & penumerator );
Pcontainer-> release ();
If (failed (HR ))
Return hr;
Iunknown * punk;
Ulong ufetched;
// Enumerate and refresh all frames
For (uint I = 0; s_ OK = penumerator-> next (1, & punk, & ufetched); I ++)
{
Iwebbrowser2 * pbrowser;
HR = punk-> QueryInterface (iid_iwebbrowser2, (void **) & pbrowser );
Punk-> release ();
If (succeeded (HR ))
{
Pbrosh-> refresh ();
Pbroase-> release ();
}
}
Penumerator-> release ();
}
3. Multi-layer nested frame accessed
Note that each frame can contain its own frame. The above method is implemented for a webbrowser window and does not involve a deep frame. To implement multi-layer nested frame access, you only need to add a recursive operation. For example, for prightframewindow in 1 and pbrowindow in 2, slightly modify the function and call it recursively after obtaining two pointers.
4. Access source code
The following method comes from chtmlview and is a more formal method (the original format of the webpage can be maintained ).
Bool chtmlview: getsource (cstring & refstring)
{
Bool bretval = false;
Ccomptr <idispatch> spdisp = gethtmldocument ();
If (spdisp! = NULL)
{
Hglobal hmemory;
Hmemory = globalalloc (gmem_moveable, 0 );
If (hmemory! = NULL)
{
Ccomqiptr <ipersiststreaminit> sppersiststream = spdisp;
If (sppersiststream! = NULL)
{
Ccomptr <istream> spstream;
If (succeeded (createstreamonhglobal (hmemory, true, & spstream )))
{
Sppersiststream-> Save (spstream, false );
Maid (hmemory );
If (pstr! = NULL)
{
// Stream is always ANSI, but cstring
// Assignment operator will convert implicitly.
Bretval = true;
Try
{
Refstring = pstr;
}
Catch_all (E)
{
Bretval = false;
Delete_exception (E );
}
End_catch_all
If (bretval = false)
Globalfree (hmemory );
Else
Globalunlock (hmemory );
}
}
}
}
}
Return bretval;
}
Reference address:FAQ: two methods to access Multi-layer nested Frame