Introduction
This is just another example of using the DHTML support provided by the web browser control that can be used for any operation that needs to be done on web pages over and over again without much logical interaction of the user. This is an attempt to automate the otherwise cumbersome act of logging on to the mail site, then type-in your password (often making mistakes), click on inbox, open each mail and finally logout. I thought it would be a nice idea if some software does this all for me and saves the mails so that you can read them later. What I present here is only a framework, you can now think of some cool tool that does this all.
There are two ways of doing this. First, you can download each page with HTTP. Then find out the links and get mails the same way. The second method is rather exciting. It simulates your mouse-clicks and navigates across pages just like what we would have done, and then save the pages before logging out. I will show the second method here.
The code should be self-explanatory. I have added comments for the important points in the code. Here�s the summary of the entire operation.
- Create an instance of the web browser control
- Navigate to http://mail.yahoo.com
- When the log-in page is loaded, find out the input fields-username and password
- Paste your User-Id and Password into the fields
- Click on Login button
- The next page shows you the inbox information with links to the �Inbox�
- Click on �Inbox� to see the list of mails
- Once the mail-list is loaded click on the first unread mail
- When the mail window opens up find where the content of the mail is written in the underlying HTML code. For HTML formats the mail content was found to appear between <XBODY> and </XBODY> tags. Text messages appear within a different pair of tags.
- Get the message and save it.
- Go back and get the next unread message
- When all unread mails are downloaded, don�t even think for a second, Sign-out!!!
- That�s it!
Using the code
In the code, I have used many interfaces pertinent to the HTML elements. As you can see the usage is much the same. I haven�t done any optimization or error/exception handling, leaving it to the benefactors of the code. Please refer to the comments placed along side the lines of code. Although I built this on VS 7, it should work on VC 6 as well.
All you need to do is to change the method OnBnClickedButton1() to the corresponding button handler in VC 6.
void CYahooDlg::OnBnClickedButton1()
{
BSTR bsStatus;
bReady=0;
CString mPass("*****");
CString mUser("*****");
BSTR bsPW = mPass.AllocSysString();
BSTR bsUser=mUser.AllocSysString();
CString mStr;
HRESULT hr1 ;
hr1 = CoInitialize(NULL);
if(!SUCCEEDED(hr1))
return ;
hr1 = CoCreateInstance (CLSID_InternetExplorer,
NULL, CLSCTX_LOCAL_SERVER,
IID_IWebBrowser2, (LPVOID *)&pBrowser);
if(hr1==S_OK)
{
VARIANT_BOOL pBool=true;
pBrowser->put_Visible( pBool ) ;
COleVariant vaURL("http://mail.yahoo.com") ;
COleVariant null;
pBrowser->Navigate2(vaURL,null,null,null,null) ;
while(!bReady)
{
pBrowser->get_StatusText(&bsStatus);
mStr=bsStatus;
if(mStr=="Done")bReady=1;
}
IDispatch* pDisp;
hr1=pBrowser->get_Document(&pDisp);
if (pDisp != NULL )
{
IHTMLDocument2* pHTMLDocument2;
HRESULT hr;
hr = pDisp->QueryInterface( IID_IHTMLDocument2,
(void**)&pHTMLDocument2 );
if (hr == S_OK)
{
IHTMLElementCollection* pColl = NULL;
hr = pHTMLDocument2->get_all( &pColl );
if (hr == S_OK && pColl != NULL)
{
LONG celem;
hr = pColl->get_length( &celem );
if ( hr == S_OK )
{
for ( int i=0; i< celem; i++ )
{
VARIANT varIndex;
varIndex.vt = VT_UINT;
varIndex.lVal = i;
VARIANT var2;
VariantInit( &var2 );
IDispatch* pDisp;
hr = pColl->item( varIndex,
var2, &pDisp );
if ( hr == S_OK )
{
IHTMLElement* pElem;
hr = pDisp->QueryInterface(
IID_IHTMLElement,
(void **)&pElem);
if ( hr == S_OK )
{
BSTR bstr;
hr = pElem->get_tagName(&bstr);
CString strTag;
strTag = bstr;
IHTMLInputTextElement* pUser;
hr = pDisp->QueryInterface(
IID_IHTMLInputTextElement,
(void **)&pUser );
if ( hr == S_OK )
{
pUser->get_name(&bstr);
mStr=bstr;
if(mStr=="login")
pUser->put_value(bsUser);
else if(mStr=="passwd")
pUser->put_value(bsPW);
pUser->Release();
}
else{
IHTMLInputButtonElement* pButton;
hr = pDisp->QueryInterface(
IID_IHTMLInputButtonElement,
(void **)&pButton);
if ( hr == S_OK )
{
IHTMLFormElement* pForm;
hr=pButton->get_form(&pForm);
if ( hr == S_OK )
{
pForm->submit();
i=celem;
pForm->Release();
}
pButton->Release();
}
}
pElem->Release();
}
pDisp->Release();
}
}
}
pColl->Release();
}
pHTMLDocument2->Release();
}
pDisp->Release();
}
}
CString statustext="OK";
pBrowser->put_StatusText(statustext.AllocSysString());
bReady=0;
while(!bReady)
{
pBrowser->get_StatusText(&bsStatus);
mStr=bsStatus;
if(mStr=="Done")bReady=1;
}
GetInbox();
}
int CYahooDlg::GetInbox(void)
{
BSTR bsStatus;
CString mStr,mLocation;
bReady=0;
HRESULT hr1;
IDispatch* pDisp;
hr1=pBrowser->get_Document(&pDisp);
if (pDisp != NULL )
{
IHTMLDocument2* pHTMLDocument2;
HRESULT hr;
hr = pDisp->QueryInterface( IID_IHTMLDocument2,
(void**)&pHTMLDocument2 );
if (hr == S_OK)
{
IHTMLElementCollection* pColl = NULL;
hr = pHTMLDocument2->get_all( &pColl );
if (hr == S_OK && pColl != NULL)
{
LONG celem;
hr = pColl->get_length( &celem );
if ( hr == S_OK )
{
for ( int i=0; i< celem; i++ )
{
VARIANT varIndex;
varIndex.vt = VT_UINT;
varIndex.lVal = i;
VARIANT var2;
VariantInit( &var2 );
IDispatch* pDisp;
hr = pColl->item( varIndex, var2, &pDisp );
if ( hr == S_OK )
{
IHTMLElement* pElem;
hr = pDisp->QueryInterface(
IID_IHTMLElement,
(void **)&pElem);
if ( hr == S_OK)
{
IHTMLAnchorElement* pLink;
hr = pDisp->QueryInterface(
IID_IHTMLAnchorElement,
(void **)&pLink);
if ( hr == S_OK)
{
BSTR bstr;
hr = pLink->get_href(&bstr);
if(hr == S_OK){
CString strTag;
strTag = bstr;
if(strTag.Find("Inbox")>=0 &&
strTag.Find("ym/ShowFolder")>0)
{
pElem->click();
i=celem;
}
}
pLink->Release();
}
pElem->Release();
}
pDisp->Release();
}
}
pColl->Release();
}
}
pHTMLDocument2->Release();
}
pDisp->Release();
}
CString statustext="OK";
pBrowser->put_StatusText(statustext.AllocSysString());
bReady=0;
while(!bReady)
{
pBrowser->get_StatusText(&bsStatus);
mStr=bsStatus;
if(mStr=="Done")bReady=1;
}
OnBnClickedGetmail();
return 0;
}
void CYahooDlg::OnBnClickedGetmail()
{
BSTR bsStatus=0;
CString mStr,mLocation;
CString statustext="OK";
bReady=0;
BOOL bMailAhead=0;
HRESULT hr1;
IDispatch* pDisp;
hr1=pBrowser->get_Document(&pDisp);
if (pDisp != NULL )
{
IHTMLDocument2* pHTMLDocument2;
HRESULT hr;
hr = pDisp->QueryInterface( IID_IHTMLDocument2,
(void**)&pHTMLDocument2 );
if (hr == S_OK)
{
IHTMLElementCollection* pColl = NULL;
hr = pHTMLDocument2->get_all( &pColl );
if (hr == S_OK && pColl != NULL)
{
LONG celem;
hr = pColl->get_length( &celem );
if ( hr == S_OK )
{
for ( int i=0; i< celem; i++ )
{
VARIANT varIndex;
varIndex.vt = VT_UINT;
varIndex.lVal = i;
VARIANT var2;
VariantInit( &var2 );
IDispatch* pDisp;
hr = pColl->item( varIndex, var2, &pDisp );
if ( hr == S_OK )
{
IHTMLElement* pElem;
hr = pDisp->QueryInterface(
IID_IHTMLElement,
(void **)&pElem);
if ( hr == S_OK)
{
BSTR bstr;
CString classname;
pElem->get_className(&bstr);
classname = bstr;
if(classname=="msgnew") {bMailAhead=1;}
else if(classname=="msgold")
{bMailAhead=0;}
IHTMLAnchorElement* pLink;
hr = pDisp->QueryInterface(
IID_IHTMLAnchorElement,
(void **)&pLink);
if ( hr == S_OK)
{
BSTR bstr;
hr = pLink->get_href(&bstr);
if(hr == S_OK){
CString strTag;
strTag = bstr;
if(strTag.Find("ShowLetter")>=0
&& strTag.Find("Inbox")>0
&& bMailAhead)
{
pElem->click();
pBrowser->put_StatusText
(statustext.AllocSysString());
bReady=0;
while(!bReady)
{
pBrowser->
get_StatusText(&bsStatus);
mStr=bsStatus;
if(mStr=="Done")bReady=1;
}
OnBnClickedSavemail();
bMailAhead=0;
OnBnClickedBack();
pBrowser->put_StatusText
(statustext.AllocSysString());
bReady=0;
while(!bReady)
{
pBrowser->
get_StatusText(&bsStatus);
mStr=bsStatus;
if(mStr=="Done")bReady=1;
}
}
}
pLink->Release();
}
pElem->Release();
}
pDisp->Release();
}
}
pColl->Release();
}
}
pHTMLDocument2->Release();
}
pDisp->Release();
}
OnBnClickedSignout();
return ;
}
void CYahooDlg::OnBnClickedSavemail()
{
BOOL bAdd=0,bHeader=0;
CString mStr,mLocation;
bReady=0;
HRESULT hr1;
IDispatch* pDisp;
hr1=pBrowser->get_Document(&pDisp);
if (pDisp != NULL )
{
IHTMLDocument2* pHTMLDocument2;
HRESULT hr;
hr = pDisp->QueryInterface( IID_IHTMLDocument2,
(void**)&pHTMLDocument2 );
if (hr == S_OK)
{
IHTMLElementCollection* pColl = NULL;
hr = pHTMLDocument2->get_all( &pColl );
if (hr == S_OK && pColl != NULL)
{
LONG celem;
hr = pColl->get_length( &celem );
if ( hr == S_OK )
{
for ( int i=0; i< celem; i++ )
{
VARIANT varIndex;
varIndex.vt = VT_UINT;
varIndex.lVal = i;
VARIANT var2;
VariantInit( &var2 );
IDispatch* pDisp;
hr = pColl->item( varIndex, var2, &pDisp );
if ( hr == S_OK )
{
IHTMLElement* pElem;
hr = pDisp->QueryInterface(
IID_IHTMLElement,
(void **)&pElem);
if ( hr == S_OK)
{
BSTR tagName;
CString tag,tempStr;
COleVariant attrb;
if(!bHeader){
pElem->get_tagName(&tagName);
tag=tagName;
if(tag=="TR" ||tag=="tr")
{
tag="className";
tagName=tag.AllocSysString();
pElem->getAttribute(tagName,0,attrb);
tag=attrb;
if(tag=="bge"){
pElem->get_innerText(&tagName);
tag=tagName;
if(tag.Find("To:")>-1){
pElem->get_outerText(&tagName);
tempStr=tagName;
m_Body+="<YMailTo>"+
tempStr+"</YMailTo><BR>";
}
if(tag.Find("From:")>-1){
pElem->get_outerText(&tagName);
tempStr=tagName;
m_Body+="<YMailFrom>"+
tempStr+"</YMailFrom><BR>";
}
if(tag.Find("Date:")>-1){
pElem->get_outerText(&tagName);
tempStr=tagName;
m_Body+="<YMailDate>"+
tempStr+"</YMailDate><BR>";
}
if(tag.Find("Subject:")>-1){
pElem->get_outerText(&tagName);
tempStr=tagName;
m_Body+="<YMailSub>"+tempStr+
"</YMailSub><BR><BR>";
bHeader=1;
}
}
}
}
pElem->get_tagName(&tagName);
tag=tagName;
if((tag.Find("xbody")>-1) ||
(tag.Find("XBODY")>-1) )bAdd=1;
if(bAdd)
{
pElem->get_outerHTML(&tagName);
m_Body+=tagName;
if((m_Body.Find("/xbody")>-1)
||(m_Body.Find("/XBODY")>-1) )
{
bAdd=0;
i=celem;
}
}
pElem->Release();
}
pDisp->Release();
}
}
pColl->Release();
}
}
pHTMLDocument2->Release();
}
pDisp->Release();
}
WriteMailFile();
return ;
}
void CYahooDlg::WriteMailFile()
{
SYSTEMTIME sysTime;
GetSystemTime(&sysTime);
COleDateTime Today(sysTime);
CString filename,mStr;
CFile datafile;
filename.Format("m%d%d%d%d%d.htm",
Today.GetDayOfYear(),Today.GetYear(),
Today.GetHour(),Today.GetMinute(),Today.GetSecond());
if(datafile.Open(filename,CFile::modeCreate
| CFile::modeWrite)){
datafile.Write(m_Body,m_Body.GetLength());
datafile.Close();
}
m_DLStatus="Download Complete";
UpdateData(0);
}
CYahooDlg::~CYahooDlg(void)
{
}
void CYahooDlg::OnBnClickedSignout()
{
BSTR bsStatus=0;
CString mStr,mLocation;
bReady=0;
HRESULT hr1;
IDispatch* pDisp;
hr1=pBrowser->get_Document(&pDisp);
if (pDisp != NULL )
{
IHTMLDocument2* pHTMLDocument2;
HRESULT hr;
hr = pDisp->QueryInterface( IID_IHTMLDocument2,
(void**)&pHTMLDocument2 );
if (hr == S_OK)
{
IHTMLElementCollection* pColl = NULL;
hr = pHTMLDocument2->get_all( &pColl );
if (hr == S_OK && pColl != NULL)
{
LONG celem;
hr = pColl->get_length( &celem );
if ( hr == S_OK )
{
for ( int i=0; i< celem; i++ )
{
VARIANT varIndex;
varIndex.vt = VT_UINT;
varIndex.lVal = i;
VARIANT var2;
VariantInit( &var2 );
IDispatch* pDisp;
hr = pColl->item( varIndex, var2, &pDisp );
if ( hr == S_OK )
{
IHTMLElement* pElem;
hr = pDisp->QueryInterface(
IID_IHTMLElement,
(void **)&pElem);
if ( hr == S_OK)
{
IHTMLAnchorElement* pLink;
hr = pDisp->QueryInterface(
IID_IHTMLAnchorElement,
(void **)&pLink);
if ( hr == S_OK)
{
BSTR bstr;
hr = pLink->get_href(&bstr);
if(hr == S_OK){
CString strTag;
strTag = bstr;
if(strTag.Find("Logout")>=0 ||
strTag.Find("Sign Out")>=0){
pElem->click();
i=celem;
}
}
pLink->Release();
}
pElem->Release();
}
pDisp->Release();
}
}
pColl->Release();
}
}
pHTMLDocument2->Release();
}
pDisp->Release();
}
return ;
pBrowser->Release();
CoUninitialize();
}
void CYahooDlg::OnBnClickedBack()
{
pBrowser->GoBack();
}