Click to See Complete Forum and Search --> : Homemade HTML-mangling browser


TRhodes
August 21st, 2002, 12:08 PM
I have created a simple VC++ Active-X web browser based on some codeguru code posted elsewhere. It uses the Microsoft Web Browser Active-X control. The available methods for this control provide a straightforward means of retrieving and displaying HTML as expected.

I would however like to dynamically modify each HTML page fetched prior to displaying it. I would like to force all text to be uniform in color, force background colors, etc. Simple stuff that I do not believe IE can do currently.

Does anyone know the best way to accomplish this?
Perhaps IE itself could be augmented to do this for me?

Thanks,

TR

gangelo
August 25th, 2002, 05:02 PM
If you are using VC++ you might want to create an SDI or MDI app whos View derive from the CHtmlView MFC class. From there you can use DOM in order to accomplish what you want to do. I do not know if the CHtmlView class provides a way to alter the html page PRIOR to it loading, however, there are callbacks that let you know when the page has been loaded (onload etc.) at which time you can manipulate the page.

Take a look at the GetHtmlDocument() member of the CHtmlView class which provides a COM pointer so you can use the IID_IHTMLDocument or IID_IHTMLDocument2 interface. These allow access to the many methods that allow you to gain access to any element on the page. Below is some code that updates a form text value. Of course, you are not limited to manipulating form data, it is just an example and it is all I can provide you at this time:

p.s. even if you do not want to use MFC, you can still use your own classes to access the COM object in your own code, but MFC makes it a ton easier. gl.

// Update
bool CEZBay2View::PutHtmlTextData(LPCTSTR pHtmlFormName, LPCTSTR pHtmlTextName, LPCTSTR pHtmlTextData)
{
bool bResult = false;

HRESULT hr = S_FALSE;

LPDISPATCH pIDispatch = GetHtmlDocument(); // get the interface to the html document

CComPtr<IHTMLDocument2> spHtmlDocument2;

hr = pIDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&spHtmlDocument2);

if(FAILED(hr) || ! spHtmlDocument2)
return false;

CComPtr<IHTMLElementCollection> spHtmlElementCollection;

hr = spHtmlDocument2->get_forms(&spHtmlElementCollection); // get all the forms in the page...

if(FAILED(hr) || ! spHtmlElementCollection)
return false;

COleVariant varFormName(pHtmlFormName);
COleVariant varFormIndex((long)0);

hr = spHtmlElementCollection->item(varFormName, varFormIndex, &pIDispatch); // get the specific form

if(FAILED(hr) || ! pIDispatch)
return false;

CComPtr<IHTMLElement> spHtmlForm;

hr = pIDispatch->QueryInterface(IID_IHTMLElement, (void**)&spHtmlForm);

if(FAILED(hr) || ! spHtmlForm)
return false;

hr = spHtmlForm->get_all(&pIDispatch); // get all the objects in this form

if(FAILED(hr) || ! pIDispatch)
return false;

CComPtr<IHTMLElementCollection> spHtmlObjectCollection;

hr = pIDispatch->QueryInterface(IID_IHTMLElementCollection, (void**)&spHtmlObjectCollection);

if(FAILED(hr) || ! spHtmlObjectCollection)
return false;

long nObjectCount = 0;
if(spHtmlObjectCollection->get_length(&nObjectCount) != S_OK) // get the length of the collection
return false;

COleVariant varObjectName(pHtmlTextName);

for(int n = 0; n < nObjectCount; n++)
{
COleVariant varObjectIndex((long)n);

hr = spHtmlObjectCollection->item(varObjectName, varObjectIndex, &pIDispatch);

if(SUCCEEDED(hr) && pIDispatch)
{
CComPtr<IHTMLInputTextElement> spHtmlFormElement;

hr = pIDispatch->QueryInterface(IID_IHTMLInputTextElement, (void**)&spHtmlFormElement);

if(SUCCEEDED(hr) && spHtmlFormElement)
{
_bstr_t bstrHtmlTextData(pHtmlTextData);

hr = spHtmlFormElement->put_value(bstrHtmlTextData.copy());

if(SUCCEEDED(hr))
{
bResult = true;

break; // found it finally!
}
}
}
}

return bResult;
}

TRhodes
August 26th, 2002, 12:05 PM
Thanks for the reply and sharing your knowledge.
I usually create dialog-based MFC applications, but will try out an SDI-based app to take advantage of CHtmlView. It's probably possible to embed dialogs in an SDI app though, and should get me off the hook.

I will try your approach and post my findings. Perhaps there is a way to refrain from displaying anything to the user prior to a full HTML page load. If so, I would do the following on a user page load request: Shut off display, start the new page loading, nab the callback for "page loaded", perform the quick manipulation, and finally display the page.

Does anyone know if there is a way to do the above in IE?