Click here to Skip to main content
15,896,153 members
Articles / Desktop Programming / ATL

Discover WIN32. How to use a sync/async retrieve HTTP content in your ASP & VB projects.

Rate me:
Please Sign up or sign in to vote.
4.55/5 (7 votes)
19 May 20023 min read 156.4K   1.8K   32  
This article shows how to create one ATL COM component using the WinInet functions, how to use it in ASP programs and how to test it from the Visual Basic client. It also shows how to use multithreading support in this component.
// RetrievePage1.cpp : Implementation of CRetrievePageApp and DLL registration.

#include "stdafx.h"
#include "RetrievePage.h"
#include "RetrievePage1.h"

//#include <wininet.h>
#include <afxinet.h>


/////////////////////////////////////////////////////////////////////////////
// CMyObjectTemplate

IMPLEMENT_SERIAL(CHTTPpage, CObject, 0)

CHTTPpage::CHTTPpage()
{
}

CHTTPpage::~CHTTPpage()
{
}

void CHTTPpage::FormatMyObject(CString& str)
{
	str.Format(_T("{%i, %s}"), iDone, (LPCTSTR)sBody);
}

void CHTTPpage::Serialize(CArchive& ar)
{
	WORD w;
	if (ar.IsStoring())
	{
		w = (WORD)iDone;
		ar << w;
		ar << sBody;
	}
	else
	{
		ar >> w;
		iDone = w;
		ar >> sBody;
	}
}
// END CMyObjectTemplate
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//

STDMETHODIMP RetrievePage::InterfaceSupportsErrorInfo(REFIID riid)
{
	static const IID* arr[] = 
	{
		&IID_IRetrievePage,
	};

	for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
	{
		if (InlineIsEqualGUID(*arr[i],riid))
			return S_OK;
	}
	return S_FALSE;
}

STDMETHODIMP RetrievePage::Retrieve(BSTR newVal, BSTR *parOut)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())

	// TODO: Add your implementation code here
	CString		sBody;
	CString		sURL;

	sURL	= CString(newVal);
	  
	//no thread
	if ( GetPage(sURL, sBody) )
	{
		CComBSTR bstrTemp;
		
		bstrTemp.Append( sBody ); 
		*parOut = bstrTemp.Detach();
	
	}
	else
	{
		CComBSTR bstrTemp;
		bstrTemp.Append( m_sError ); 
		*parOut = bstrTemp.Detach();
		
	}
	

	return S_OK;
}

UINT MyThreadGetPage(LPVOID pParam)
{
	CString		sKey;
	CString		sBody;

	RetrievePage* pObject = (RetrievePage*)pParam;
//'	if (pObject == NULL )
//		return 0;   // if pObject is not valid

	sKey			= pObject->m_sURL;

	CHTTPpage		*oHTTPpage;
	//tre sa vedem daca nu cumva avem deja object la sKey
	oHTTPpage		= pObject->m_MapStringToHTTPpage[sKey];

	
	if ( pObject->GetPage(sKey, sBody) )
	{
		
		oHTTPpage->iDone				= 1;
		oHTTPpage->sBody				= sBody;
		
		pObject->m_MapStringToHTTPpage[sKey]		= oHTTPpage;
		
		return 1;   // thread completed successfully
	}
	else
	{
		oHTTPpage->iDone				= 0;
		oHTTPpage->sBody				= "";
		
		pObject->m_MapStringToHTTPpage[sKey]		= oHTTPpage;
		return 0;   // thread completed UNsuccessfully
	}
	
	
}

//bool RetrievePage::GetPage(CString URL)
bool RetrievePage::GetPage(CString sURL, CString& sBody)
{
	sURL.TrimLeft();
	sURL.TrimRight();
	
	char *location;
	char pagina[100000];
	
	
	LPTSTR	ppp	= sURL.GetBuffer(sURL.GetLength());
	location	= ppp;
	if (strnicmp(location, "http://",7)==0)
	{
		HINTERNET internet=InternetOpen("Daemon", INTERNET_OPEN_TYPE_PRECONFIG , NULL, NULL, NULL);
		if (internet)
		{
			/*HINTERNET file_handle=InternetOpenUrl(internet,
				location, NULL, 0,
				INTERNET_FLAG_KEEP_CONNECTION & INTERNET_FLAG_DONT_CACHE & INTERNET_FLAG_RELOAD, 0);
			*/
			

			HINTERNET file_handle=InternetOpenUrl(internet,
				location, NULL, 0,
				INTERNET_FLAG_RELOAD, 0);
			

			if (file_handle)
			{
				DWORD bytes_read=0;
				
				//Beep(200, 200);
				InternetReadFile(file_handle, pagina, 100000, &bytes_read);
				
				//in pagina am &bytes_read bytes de pe internet
				//tre sa bag pagina in sBody			
				/*FILE *fp;
				if ((fp=fopen("C:\\HTTPFILE.TXT","wb")) !=NULL)
				{
					fwrite(pagina, bytes_read, 1, fp);
					fclose(fp);
				}*/
				
				sBody	= CString (pagina);
				sBody	= sBody.Left(bytes_read);

				long lll= sBody.GetLength();

				//Sleep(0);
				//AfxMessageBox("GetPage:  "+ sURL + "   "+ sBody);
			}
			else
			{
				m_sError = "Is not possible to connect to internet";
				return FALSE;
			}
		}
		else
		{
			m_sError	= "The sURL location must contain 'http://' string";
			return FALSE;
		}
		
		InternetCloseHandle(internet);
	}	
	
	return true;
}


STDMETHODIMP RetrievePage::RetrieveAsync(BSTR newVal, BSTR *parOut)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
		
		// TODO: Add your implementation code here
	CString			sURL;
	sURL			= CString(newVal);
	
	CComBSTR		bstrTemp;

	CHTTPpage		*oHTTPpage		= NULL;
	
	//tre sa vedem daca nu cumva avem deja object la sKey
	if ( !m_MapStringToHTTPpage.Lookup(sURL, oHTTPpage) )
		oHTTPpage		= new CHTTPpage;					//object nou
	
	if (oHTTPpage != NULL)
	{
		oHTTPpage->iDone				= 0;
		oHTTPpage->sBody				= "";
		
		m_MapStringToHTTPpage[sURL]		= oHTTPpage;
		
		m_sURL							= sURL;
		if ( AfxBeginThread( MyThreadGetPage , this, THREAD_PRIORITY_NORMAL ) )
		{
			bstrTemp.Append( "ok" ); 
			*parOut = bstrTemp.Detach();
		}
		else
		{
			bstrTemp.Append( m_sError ); 
			*parOut = bstrTemp.Detach();
		}
	}
	else
	{
		bstrTemp.Append( "Memory Error" ); 
		*parOut = bstrTemp.Detach();
	}

	return S_OK;
}


STDMETHODIMP RetrievePage::RetrieveAsyncCompleted(BSTR newVal, int *parOut)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())

	// TODO: Add your implementation code here

	CString			sKey	= CString(newVal);

	CHTTPpage		*oHTTPpage = NULL;//	= new CHTTPpage;;

	if (m_MapStringToHTTPpage.Lookup(sKey, oHTTPpage))
	{
		if ( oHTTPpage != NULL )
			*parOut				= oHTTPpage->iDone;
		else
			*parOut				= -1;
	}
	else	//nu mai exista cheia
		*parOut				= -1;

	
	//delete oHTTPpage;

	return S_OK;
}

STDMETHODIMP RetrievePage::RetrieveAsyncPage(BSTR newVal, BSTR *parOut)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())

	// TODO: Add your implementation code here
	CString			sKey			= CString(newVal);
	CString			sToken;
	CComBSTR		bstrTemp("");
 
	CHTTPpage		*oHTTPpage	= NULL;//	= new CHTTPpage;
	
	if (m_MapStringToHTTPpage.Lookup(sKey, oHTTPpage))
	{
		if (oHTTPpage != NULL)
		{
			sToken		= oHTTPpage->sBody;
			bstrTemp.Append( sToken );
			//AfxMessageBox(sToken);
			
			*parOut				= bstrTemp;
		}
		else
		{
			bstrTemp.Append( "" );
			*parOut				= bstrTemp;
		}
	}
	else
	{
		bstrTemp.Append( "" );
		*parOut				= bstrTemp;
	}

	//delete oHTTPpage;

	return S_OK;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Romania Romania
I make programming for over 4 years and extensive experience in C++, ASP, Pascal, MFC, COM+, ATL, TCP/IP, HTTP protocols, XML, XSL, SOAP and SQL.
For the last 2 years i working extensively at the background of financial sites (databases, n tier architecture).

I’m available for contracts and/or outsourcing (<Adrian Bacaianu>adrian_bacaianu@yahoo.com).

Comments and Discussions