//////////////////////////////////////////\//////////////////////////////// // Yes i know i'm writing code in the headers // You know why....because i can. SO STFU ////////////////////////////////////////////////////////////////////////// #include #include #include #include #include ////////////////////////////////////////////////////////////////////////// // // Saves time converting bstr crap // ////////////////////////////////////////////////////////////////////////// class cStringTools { public: cStringTools(); ~cStringTools(); static void BStrToSTDString ( std::string &sOutputString, BSTR inputString ) { char szTempString[2048]; wcstombs( szTempString, inputString, sizeof( szTempString ) ); sOutputString = szTempString; } static void BStrToCString ( char *szOutput, DWORD size, BSTR inputString ) { if( inputString == NULL ) { strcpy( szOutput, "cStringTools::BStrToCString( inputString == NULL )" ); return; } wcstombs( szOutput, inputString, size ); } static char * BStrToCString ( BSTR inputString ) { static char szTempBuffer[4096]; BStrToCString( szTempBuffer, sizeof( szTempBuffer ), inputString ); return( szTempBuffer ); } protected: private: }; ////////////////////////////////////////////////////////////////////////// // Need to write a BSTR class to auto alloc and crap ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // // Dispatcher help saves time writing a GetInterface for each class // I'm pretty sure there will be plenty more functions to implement into // this later on too. // ////////////////////////////////////////////////////////////////////////// template class cDispatchHelper { public: cDispatchHelper() { } ~cDispatchHelper() { } ////////////////////////////////////////////////////////////////////////// // Get the interface for an element. ////////////////////////////////////////////////////////////////////////// // ReturnType : The elements return type. // pElements : Pointer to an elements collection. // itemNumberIndex : The index in the element collection. // refIID : The query type which is IID_returntype. ////////////////////////////////////////////////////////////////////////// static ReturnType * GetInterface( IHTMLElementCollection * pElements, long itemNumberIndex, REFIID refIID ) { VARIANT varName; VARIANT varIndex; IDispatch * pDispatch = NULL; ReturnType * pInterface = NULL; varName.vt = VT_I4; varName.lVal = itemNumberIndex; varIndex.vt = VT_I4; varIndex.lVal = 1; if( SUCCEEDED( pElements->item( varName, varIndex, &pDispatch ) ) ) { if( SUCCEEDED( pDispatch->QueryInterface( refIID, (LPVOID *)&pInterface ) ) ) { pDispatch->Release(); return( pInterface ); } pDispatch->Release(); } return( NULL ); } protected: private: }; ////////////////////////////////////////////////////////////////////////// // // cElementCollectionHelper saves implementing ElementCollection // functions into each class. It also stores the document pointer. // ////////////////////////////////////////////////////////////////////////// class cElementCollectionHelper { public: cElementCollectionHelper( IHTMLDocument2 *pDocument ) { m_pDocument = pDocument; } ~cElementCollectionHelper() { } ////////////////////////////////////////////////////////////////////////// // // Get the number of elements in an element collection // ////////////////////////////////////////////////////////////////////////// long GetNumberOfElements ( IHTMLElementCollection *pElements ) { long lNumberofElements = 0; HRESULT hr = pElements->get_length( &lNumberofElements ); if( SUCCEEDED( hr ) ) { return( lNumberofElements ); } return( 0 ); } ////////////////////////////////////////////////////////////////////////// // // Should be implemented by all subclasses // ////////////////////////////////////////////////////////////////////////// protected: IHTMLDocument2 * m_pDocument; // The current document std::ofstream m_debugStream; // If you fancy doing some debug then... private: virtual bool GetAllElements ( IHTMLElementCollection **ppElements ) = 0; virtual bool GetElementIterator ( IHTMLElementCollection **ppElements, long * plNumberofElements ) = 0; }; /* - Really need a class like cAnchorFinder, cElementFinder etc etc.. CANT BE ARSED THOUGH */ ////////////////////////////////////////////////////////////////////////// // // cElementManager will return all elements in the HTML document. // ////////////////////////////////////////////////////////////////////////// class cElementManager : public cElementCollectionHelper { public: ////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////// cElementManager( IHTMLDocument2 *pDocument ) : cElementCollectionHelper( pDocument ) { } ~cElementManager() { } public: ////////////////////////////////////////////////////////////////////////// // Provides ability to get HTML element to all subclasses. // HTML element is applicable to all types i think ? ////////////////////////////////////////////////////////////////////////// IHTMLElement * GetHTMLElement ( IHTMLElementCollection * pElements, long itemNumberIndex ) { return cDispatchHelper::GetInterface( pElements, itemNumberIndex, IID_IHTMLElement ); } private: bool GetAllElements ( IHTMLElementCollection **ppElements ) { HRESULT hr = m_pDocument->get_all( ppElements ); if( SUCCEEDED( hr ) ) { return( true ); } return( false ); } bool GetElementIterator ( IHTMLElementCollection **ppElements, long * plNumberofElements ) { IHTMLElementCollection * pElements = NULL; if( GetAllElements( &pElements ) ) { *ppElements = pElements; *plNumberofElements = GetNumberOfElements( pElements ); return( true ); } return( false ); } IHTMLElement * GetElement ( IHTMLElementCollection * pElements, long itemNumberIndex ) { return GetHTMLElement( pElements, itemNumberIndex ); } }; class cAnchorManager : public cElementManager { public: cAnchorManager( IHTMLDocument2 *pDocument ) : cElementManager( pDocument ) { m_debugStream.open( "cAnchorManager.txt", std::ofstream::out ); } ~cAnchorManager() { m_debugStream.close(); } private: bool GetAllElements ( IHTMLElementCollection **ppElements ) { // Get all the anchors HRESULT hr = m_pDocument->get_anchors( ppElements ); if( SUCCEEDED( hr ) ) { return( true ); } return( false ); } bool GetElementIterator ( IHTMLElementCollection **ppElements, long * plNumberofElements ) { IHTMLElementCollection * pElements = NULL; if( GetAllElements( &pElements ) ) { *ppElements = pElements; *plNumberofElements = GetNumberOfElements( pElements ); return( true ); } return( false ); } IHTMLAnchorElement * GetElement ( IHTMLElementCollection * pElements, long itemNumberIndex ) { return cDispatchHelper::GetInterface( pElements, itemNumberIndex, IID_IHTMLAnchorElement ); } public: IHTMLElement * FindLinkFromText ( char *pszText ) { IHTMLElementCollection * pElements = NULL; long lNumberofElements; IHTMLAnchorElement * pAnchor = NULL; IHTMLElement * pElement = NULL; BSTR bstrInnerText; char * pText = NULL; if( GetElementIterator( &pElements, &lNumberofElements ) ) { for( long lItemIndex = 0; lItemIndex < lNumberofElements; lItemIndex++ ) { pElement = GetHTMLElement( pElements, lItemIndex ); if( pElement != NULL ) { pElement->get_innerText( &bstrInnerText ); pText = cStringTools::BStrToCString( bstrInnerText ); if( bstrInnerText != NULL ) { m_debugStream << pText << std::endl; } pElement->get_tagName( &bstrInnerText ); pText = cStringTools::BStrToCString( bstrInnerText ); if( bstrInnerText != NULL ) { m_debugStream << pText << std::endl; if( strstr( pText, pszText ) ) { return( pElement ); } } } } } return( NULL ); } IHTMLElement * FindLinkFromHref ( char *pszHref ) { } }; ////////////////////////////////////////////////////////////////////////// // // // ////////////////////////////////////////////////////////////////////////// class cLinkManager : public cElementManager { public: cLinkManager( IHTMLDocument2 *pDocument ) : cElementManager( pDocument ) { m_debugStream.open( "cLinkManager.txt", std::ofstream::out ); } ~cLinkManager() { m_debugStream.close(); } private: ////////////////////////////////////////////////////////////////////////// // // This is retarded. It's get links which makes you think...LinkElement. // In fact if its an tagged link you need to use anchor :@ // get_anchor won't retrieve links though. // so you do get_links. // QueryInterface(IID_IHTMLAnchor); IID_IHTMLLink is tags :S // ////////////////////////////////////////////////////////////////////////// bool GetAllElements ( IHTMLElementCollection **ppElements ) { // Get all the anchors HRESULT hr = m_pDocument->get_links( ppElements ); if( SUCCEEDED( hr ) ) { return( true ); } return( false ); } bool GetElementIterator ( IHTMLElementCollection **ppElements, long * plNumberofElements ) { IHTMLElementCollection * pElements = NULL; if( GetAllElements( &pElements ) ) { *ppElements = pElements; *plNumberofElements = GetNumberOfElements( pElements ); return( true ); } return( false ); } IHTMLAnchorElement * GetElement ( IHTMLElementCollection * pElements, long itemNumberIndex ) { return cDispatchHelper::GetInterface( pElements, itemNumberIndex, IID_IHTMLAnchorElement ); } public: IHTMLElement * FindLinkFromText ( char *pszText ) { IHTMLElementCollection * pElements = NULL; long lNumberofElements; IHTMLAnchorElement * pLink = NULL; IHTMLElement * pElement = NULL; BSTR bstrInnerText; char *pText = NULL; if( GetElementIterator( &pElements, &lNumberofElements ) ) { for( long lItemIndex = 0; lItemIndex < lNumberofElements; lItemIndex++ ) { pElement = GetHTMLElement( pElements, lItemIndex ); pLink = GetElement( pElements, lItemIndex ); if( pElement != NULL ) { pElement->get_innerText( &bstrInnerText ); pText = cStringTools::BStrToCString( bstrInnerText ); // messy should add log funcs tbh cant be arsed. if( bstrInnerText != NULL ) { m_debugStream << pszText << std::endl; } if( strstr( pText, pszText ) ) { BSTR bstrTarget = SysAllocString( L"target"); BSTR bstrSelf = SysAllocString( L"_self" ); VARIANT vValue; if( pLink ) { pLink->put_target( bstrSelf ); } else { VARIANT_BOOL bSucess = false; vValue.vt = VT_BSTR; vValue.bstrVal = bstrSelf; pElement->removeAttribute( bstrTarget, 0, &bSucess ); //pElement->setAttribute( bstrTarget, vValue, 1 ); } SysFreeString( bstrSelf ); SysFreeString( bstrTarget ); return( pElement ); } } } } return( NULL ); } IHTMLLinkElement2 * FindLinkFromHref ( char *pszHref ) { } }; class cFormManager : public cElementManager { public: ////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////// cFormManager( IHTMLDocument2 *pDocument ) : cElementManager( pDocument ) { } ~cFormManager() { } ////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////// private: bool GetAllElements ( IHTMLElementCollection **ppElements ) { // Get all the anchors HRESULT hr = m_pDocument->get_forms( ppElements ); if( SUCCEEDED( hr ) ) { return( true ); } return( false ); } bool GetElementIterator ( IHTMLElementCollection **ppElements, long * plNumberofElements ) { IHTMLElementCollection * pElements = NULL; if( GetAllElements( &pElements ) ) { *ppElements = pElements; *plNumberofElements = GetNumberOfElements( pElements ); return( true ); } return( false ); } IHTMLFormElement * GetElement ( IHTMLElementCollection * pElements, long itemNumberIndex ) { return cDispatchHelper::GetInterface( pElements, itemNumberIndex, IID_IHTMLFormElement ); } public: IHTMLFormElement * FindFormFromAction ( char *pszAction ) { IHTMLElementCollection * pElements = NULL; long lNumberofElements; IHTMLFormElement * pForm = NULL; IHTMLElement * pElement = NULL; BSTR bstrText; char * pText = NULL; if( GetElementIterator( &pElements, &lNumberofElements ) ) { for( long lItemIndex = 0; lItemIndex < lNumberofElements; lItemIndex++ ) { pForm = GetElement( pElements, lItemIndex ); if( pForm != NULL ) { pForm->get_action( &bstrText ); pText = cStringTools::BStrToCString( bstrText ); if( strstr( pText, pszAction ) ) { return( pForm ); } } } } return( NULL ); } }; class cTextInputManager : public cElementManager { public: cTextInputManager( IHTMLDocument2 * pDocument ) : cElementManager( pDocument ) { } ~cTextInputManager() { } private: bool GetAllElements ( IHTMLElementCollection **ppElements ) { // Get all the anchors HRESULT hr = m_pDocument->get_all( ppElements ); if( SUCCEEDED( hr ) ) { return( true ); } return( false ); } bool GetElementIterator ( IHTMLElementCollection **ppElements, long * plNumberofElements ) { IHTMLElementCollection * pElements = NULL; if( GetAllElements( &pElements ) ) { *ppElements = pElements; *plNumberofElements = GetNumberOfElements( pElements ); return( true ); } return( false ); } IHTMLInputTextElement * GetElement ( IHTMLElementCollection * pElements, long itemNumberIndex ) { return cDispatchHelper::GetInterface( pElements, itemNumberIndex, IID_IHTMLInputTextElement ); } public: IHTMLInputTextElement * FindTextBox ( char *pszName ) { IHTMLElementCollection * pElements = NULL; long lNumberofElements; IHTMLInputTextElement * pTextbox = NULL; IHTMLElement * pElement = NULL; BSTR bstrText; char * pText = NULL; if( GetElementIterator( &pElements, &lNumberofElements ) ) { for( long lItemIndex = 0; lItemIndex < lNumberofElements; lItemIndex++ ) { pTextbox = GetElement( pElements, lItemIndex ); if( pTextbox != NULL ) { pTextbox->get_name( &bstrText ); pText = cStringTools::BStrToCString( bstrText ); if( strstr( pText, pszName ) ) { return( pTextbox ); } } } } return( NULL ); } }; ////////////////////////////////////////////////////////////////////////// // // // ////////////////////////////////////////////////////////////////////////// class cIEBrowser { public: cIEBrowser(); ~cIEBrowser(); void CreateBrowserProcess (); void ShutdownBrowserProcess (); void HideBrowser (); void ShowBrowser (); bool IsBrowserVisible (); HRESULT NavigateToWebsite ( BSTR pbstrWebsite ); bool IsBrowserBusy (); bool IsBrowserReady (); void WaitForBrowserReady (); ////////////////////////////////////////////////////////////////////////// IHTMLDocument2 * GetDocument (); long GetAllElements ( IHTMLDocument2 *pDocument, IHTMLElementCollection **ppElements ); IHTMLElement * GetElement ( IHTMLElementCollection * pElements, long itemNumberIndex ); IHTMLElement * FindHyperLinkFromHref ( char * pszHref ); IHTMLElement * FindHyperLinkFromText ( char * pszText ); void FindAndClickElement ( char * szText ); protected: private: void BStrToSTDString ( std::string &sOutputString, BSTR inputString ); IWebBrowser2 *m_pWebBrowser; };