|
|
Comments and Discussions
|
|
 |

|
I got this problem same with you. I debug the DLL and found that DllRegisterServer entry point was really exist, but that function didn't work right. It failed when the function call "RegCreateKeyEx" API with the return code 0x5(ERROR_ACCESS_DENNIED).
I solved the problem with the following method:
Run "regedit", and assign "Full control" privilage to current user to the registry key "HKEY_CLASSES_ROOT\CLSID" and "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\".
|
|
|
|

|
Make sure to add the dll.def file to
project properties > configuration properties > linker > input > module definition file
if you created your own project
|
|
|
|

|
hmm, seems like the BHO cannot access the post data. Author, can you get the post data ?
|
|
|
|

|
Hi,
I got the same thing like you did, while explicitly testing post data retrieval.
I'm not very good at COMs, I could say I'm a rookie on that, but I looked closely at the code and MSDN documentation and there is a mistake in the code.
First, that function VariantChangeType acts as a pointer
dereferenciation on the VARIANTS of type VT_BYREF.
Secondly, if you look closely in MSDN at BeforeNavigate2 event, you will see that "PostData is a pointer to a VARIANT structure of type VT_BYREF|VT_VARIANT that contains the data to send...". Which means you get as input a VARIANT that points to another VARIANT which finally points to the post data VARIANT. In C++ is equivalent of type VARIANT**. In remarks below they clear out the things by saying that the content of PostData is a SAFEARRAY and that VARIANT should have type VT_ARRAY|VT_UI1. To solve the problem you'll have to dereference that pointer twice not once as in the BHO example code.
I'm getting the post data ARRAY like this way:
SAFEARRAY *pPostData = PostDataArg -> pvarVal -> pvarVal ->parray;
The buffer containing the actual content of the POST DATA
is pPostData->pvData.
Hope this will work for you,
Good luck!
Radu.
|
|
|
|

|
Thanks for the hint, I had the same problem.
However, substituting the line
VariantChangeType(&v[3],&pDispParams->rgvarg[2],0,VT_UI1|VT_ARRAY); // PostData
with
VariantChangeType(&v[3], pDispParams->rgvarg[2].pvarVal,0,VT_UI1|VT_ARRAY); // PostData
helped, as rss1987 pointed out.
Greetings,
theStack
|
|
|
|

|
Hi,
It is a great article with very clear code. Excellent!
The only issue is the source code was created by VS 2008. But the header says it is VC6, VC7 and VC7.1 compatible. Actually lower version VS can not open the source code. My trick is to manually modify the proj and solution file to let lower version VS to open it.
Thanks!
-hw
|
|
|
|

|
I would like to create a menu for the IE add-on like (http://msdn.microsoft.com/en-us/library/bb735853(VS.85).aspx[^]. Would you please teach me how to implement IOleCommandTarget? Can I change it to multi inheritance like the following?
class CObjectWithSite : public CUnknown<IObjectWithSite>, public CUnknown<IOleCommandTarget>
Thank you for yr great article!
|
|
|
|

|
Hi All,
i am working on project which requires logging user action on internet explorer.
I am able to get browsing event using BHO, but not able to log menu bar, toolbar events.
your valuable comments required.
Please help me!!
thanks.
|
|
|
|

|
If my environment has the .NET installed then i can register the DLL and it works fine.
But it fails on XP system saying that : "LoadLibrary (filename) : Failed this application has failed to start because the application is incorrect reinstalling the application may fixed this problem." scanning the web it seams that there is conflict compiling it in VC2008 with native code.
Do you have a VC 6.0 version that can be compiled. I have tried to convert from VC2008 to VC6.0 but has too many annoying errors that cannot be traced. I will be nice if you have project that can be compiled in VC 6.0 then i can get round the registering problem. I need application that doing a silent registering and if the .NET framework not installed we need to installed it (i guest this is the problem) but i cannot installed such in customer PC.
Please help here
Thanks
Arie
|
|
|
|

|
I think your problem is being caused by the VC2008 runtime library not being available on the system. You can fix this problem using two methods:
Install the VC2008 Runtime Redistributable on the target system.
OR
Right-click the project in VC2008, and go to Properties.
Select Debug configuration.
Go to Configuration Properties -> C/C++ -> Code Generation and change the Runtime Library option to Multi-threaded Debug.
Now select Release configuration.
Go to Configuration Properties -> C/C++ -> Code Generation and change the Runtime Library option to Multi-threaded.
This will cause the VC2008 Runtime Library to be statically linked to the DLL. It will make the DLL larger in size, but will allow it to run on systems that don't have the VC2008 Runtime installed.
|
|
|
|

|
Hi
I do Installed the VC2008 Runtime Redistributable on the target system and it didn't work. I got the same error.
It looks like i need it complied in VC 6.0 which will solved the problem.
Thanks
Arie
|
|
|
|

|
Hi, It is a great article and i would like to know how can i get the document object so i can perform some changes to it. I don't want to mass with ATL and i need it urgent if you can help on it.
I need sample that will work on your code.
I do use event completed and it work great because of your hep and hope you will help me in my above request and sample
Thanks in advance
Arie
|
|
|
|

|
You can use pSite->get_Document() in CObjectWithSite, then use the QueryInterface() method of the resulting interface pointer with the appropriate IID (IID_IHtmlDocument, IID_IHtmlDocument2, or IID_IHtmlDocument3). The documentation for get_Document() is here: http://msdn.microsoft.com/en-us/library/aa752116(VS.85).aspx[^].
|
|
|
|

|
I understood now but when adding code like :
IHTMLDocument *ppDisp ;
pSite->get_Document((IDispatch**) &ppDisp);
hr=ppDisp->QueryInterface(IID_IHtmlDocument2,(void**)&pDocument);
I get
error C2065: 'IID_IHtmlDocument2' : undeclared identifier d:\develop\iedemos\demo-2\bhoincpp\bhoincpp\objectwithsite.cpp 56 BHOinCPP
where this 'IID_IHtmlDocument2 define ????
Thanks
Arie
|
|
|
|

|
Sorry it my fault i have used your definition where it should be in capital letter IID_IHTMLDocument2 and not IID_IHtmlDocument2
Sorry and thanks
|
|
|
|

|
I have the pDoc interface created on
how can i used this variables in the EventSink class when event of type "if (dispIdMember == DISPID_DOCUMENTCOMPLETE) is called.
in the
STDMETHODIMP CEventSink::Invoke(...)
{
.......
if (dispIdMember == DISPID_DOCUMENTCOMPLETE)
{ // Handle the BeforeNavigate2 event
VariantChangeType(&v[0],&pDispParams->rgvarg[0],0,VT_BSTR); // url
how do i cann access the pDocumnet interface here in the EventSink class.
}
The pDocumnet object is created and declared in CObjectWithSite
STDMETHODIMP CObjectWithSite::SetSite(IUnknown *pUnkSite)
{
HRESULT hr;
if(pUnkSite) pUnkSite->AddRef(); // if a new site object is given, AddRef() it to make sure the object doesn't get deleted while we are working with it
DisconnectEventSink(); // disconnect any previous connection with IE
if(pUnkSite==NULL) return S_OK; // if only unsetting the site, return S_OK
hr=pUnkSite->QueryInterface(IID_IWebBrowser2,(void**)&pSite); // query the site object for the IWebBrowser2 interface, from which we can access IE
pUnkSite->Release(); // we are done working with pUnkSite, so call Release() since we called AddRef() before
if(FAILED(hr)) return hr; // if we couldn't find the IWebBrowser2 interface, return the error
ConnectEventSink(); // connect the new connection with IE
IHTMLDocument *ppDisp ;
pSite>get_Document((IDispatch**) &ppDisp);
hr=ppDisp>QueryInterface(IID_IHTMLDocument2,(void**)&pDocument);
if (hr != S_OK)
{
//S_OK The operation was successful.
//S_FALSE Windows Internet Explorer 7. The object was not safe for scripting.
//E_FAIL The operation failed.
//E_INVALIDARG One or more parameters are invalid.
//E_NOINTERFACE
}
return S_OK;
}
How can i proceed from here
Thanks
Arie
|
|
|
|

|
Declare an interface pointer of the type you need (IHTMLDocument, IHTMLDocument2, or IHTMLDocument3) as a member of CObjectWithSite, called pDocument. Also declare an interface pointer of the same type in CEventSink but as a public static member, also with the name pDocument.
Put the code to get the interface pointer to the document object before the call to ConnectEventSink() in CObjectWithSite::SetSite(). This code should store the interface pointer into the pDocument member variable of CObjectWithSite. You can then modify ConnectEventSink() to assign the interface pointer in the pDocument member variable of CObjectWithSite to the pDocument static member variable of CEventSink, in the EventSink global instance. Be sure to also modify DisconnectEventSink() to Release() the interface pointer.
The document object is then accessible through the pDocument static member variable of CEventSink in the CEventSink::Invoke() method.
|
|
|
|

|
I have truble to follow this explanation. Could you please post the code such that I can understand how to access the actual content of a site? I have the same problm as the other person, I can not access to document object :(
|
|
|
|

|
I have solved it like that :
I would like to say i wrote is fast and not so elegant but it works :
1. Move the object IWebBrowser2 *pSite; from ObjectWithSite.h to EventSink.h as public
The every place in ObjectWithSite cile refere to EventSink.pSite see the code module ObjectWithSite
actually what the code does is getting the documnet completed event and reading the file for input fields tag and read the filed name and value from the specify ini file then automatically enter the pweb page i.e. page with password and usr name can be entered automatically if the values of filed name and field value (can be encrypted by you) are defined in the ini file hope it help and get you started
STDMETHODIMP CObjectWithSite::SetSite(IUnknown *pUnkSite)
{
HRESULT hr;
if (pUnkSite)
{
pUnkSite->AddRef(); // if a new site object is given, AddRef() it to make sure the object doesn't get deleted while we are working with it
}
DisconnectEventSink(); // disconnect any previous connection with IE
if (pUnkSite == NULL)
{
//////MessageBox(NULL,_T("SetSite : pUnkSite == NULL"),_T("CObjectWithSite"),MB_OK|MB_ICONINFORMATION);
return S_OK; // if only unsetting the site, return S_OK
}
hr = pUnkSite->QueryInterface(IID_IWebBrowser2,(void**)&EventSink.pSite); // query the site object for the IWebBrowser2 interface, from which we can access IE
pUnkSite->Release(); // we are done working with pUnkSite, so call Release() since we called AddRef() before
if (FAILED(hr))
{
//////MessageBox(NULL,_T("SetSite : pUnkSite->QueryInterface error"),_T("CObjectWithSite"),MB_OK|MB_ICONINFORMATION);
return hr; // if we couldn't find the IWebBrowser2 interface, return the error
}
ConnectEventSink(); // connect the new connection with IE
return S_OK;
}
// This is called by IE to get an interface from the currently set site object
STDMETHODIMP CObjectWithSite::GetSite(REFIID riid,void **ppvSite)
{
// Validate the ppvSite pointer
if (IsBadWritePtr(ppvSite, sizeof(void*)))
{
//////MessageBox(NULL,_T("GetSite : IsBadWritePtr error"),_T("CObjectWithSite"),MB_OK|MB_ICONINFORMATION);
return E_POINTER;
}
// Set *ppvSite to NULL
(*ppvSite) = NULL;
// If we don't have a current site set we must return E_FAIL
if (EventSink.pSite == NULL)
{
//////MessageBox(NULL,_T("GetSite : EventSink.pSite = NULL"),_T("CObjectWithSite"),MB_OK|MB_ICONINFORMATION);
return E_FAIL;
}
// Otherwise we let the site's QueryInterface method take care of it
return EventSink.pSite->QueryInterface(riid,ppvSite);
}
// This is called by us to get a connection to IE and start handling IE events
void CObjectWithSite::ConnectEventSink()
{
HRESULT hr;
IConnectionPointContainer* pCPC;
if (EventSink.pSite == NULL)
{
//////MessageBox(NULL,_T("ConnectEventSink : EventSink.pSite == NULL"),_T("CObjectWithSite"),MB_OK|MB_ICONINFORMATION);
return; // If we don't have a site, don't do anything
}
// Get an IConnectionPointContainer interface pointer from the site
hr = EventSink.pSite->QueryInterface(IID_IConnectionPointContainer,(void**)&pCPC);
if (FAILED(hr))
{
//////MessageBox(NULL,_T("ConnectEventSink : EventSink.pSite->QueryInterface error"),_T("CObjectWithSite"),MB_OK|MB_ICONINFORMATION);
return; // If we couldn't get it, abort
}
// Now we use the IConnectionPointContainer interface to get an IConnectionPoint interface pointer that will handle DWebBrowserEvents2 "dispatch interface" events.
// That means we have to plug our implementation of DWebBrowserEvents2 into the returned IConnectionPoint interface using its Advise() method, as below
hr = pCPC->FindConnectionPoint(DIID_DWebBrowserEvents2,&pCP);
if (FAILED(hr))
{ // If it failed, release the pCPC interface pointer and abort
//////MessageBox(NULL,_T("ConnectEventSink : pCPC->FindConnectionPoint error"),_T("CObjectWithSite"),MB_OK|MB_ICONINFORMATION);
pCPC->Release();
return;
}
// Finally we can plug our event handler object EventSink into the connection point and start receiving IE events
// The advise cookie is just a return value we use when we want to "unplug" our event handler object from the connection point
pCP->Advise((IUnknown*)&EventSink,&adviseCookie);
}
// This is called by us to remove our connection to IE, if it exists, and stop handling IE events
void CObjectWithSite::DisconnectEventSink()
{
if (pCP)
{ // if we have a valid connection point, unplug the event handler from it, then Release() it
pCP->Unadvise(adviseCookie);
adviseCookie=0;
pCP->Release();
pCP=NULL;
}
if (EventSink.pSite)
{ // if we have a valid site, Release() it
EventSink.pSite->Release();
EventSink.pSite=NULL;
}
}
I will attached more file EventSink and other to add to the project it also has sample of reading the document parameters and more
/*
Copyright (C) 2009 Moutaz Haq <cefarix@gmail.com>
This file is released under the Code Project Open License <http://www.codeproject.com/info/cpol10.aspx>
This file contains our implementation of the DWebBrowserEvents2 dispatch interface.
*/
//#include "Winbase.h"
#include "common.h"
#include "EventSink.h"
#include "comdef.h"
#include "CBstrImpl.h"
// The single global object of CEventSink
CEventSink EventSink;
STDMETHODIMP CEventSink::QueryInterface(REFIID riid,void **ppvObject)
{
// Check if ppvObject is a valid pointer
if (IsBadWritePtr(ppvObject,sizeof(void*)))
{
//////MessageBox(NULL,_T("QueryInterface not valid pointer"),_T("CEventSink"),MB_OK|MB_ICONINFORMATION);
return E_POINTER;
}
// Set *ppvObject to NULL
(*ppvObject) = NULL;
// See if the requested IID matches one that we support
// If it doesn't return E_NOINTERFACE
if (!IsEqualIID(riid,IID_IUnknown) && !IsEqualIID(riid,IID_IDispatch) && !IsEqualIID(riid,DIID_DWebBrowserEvents2))
{
//////MessageBox(NULL,_T("QueryInterface requested IID not matches"),_T("CEventSink"),MB_OK|MB_ICONINFORMATION);
return E_NOINTERFACE;
}
// If it's a matching IID, set *ppvObject to point to the global EventSink object
(*ppvObject) = (void*)&EventSink;
return S_OK;
}
STDMETHODIMP_(ULONG) CEventSink::AddRef()
{
return 1; // We always have just one static object
}
STDMETHODIMP_(ULONG) CEventSink::Release()
{
return 1; // Ditto
}
// We don't need to implement the next three methods because we are just a pure event sink
// We only care about Invoke() which is what IE calls to notify us of events
STDMETHODIMP CEventSink::GetTypeInfoCount(UINT *pctinfo)
{
UNREFERENCED_PARAMETER(pctinfo);
return E_NOTIMPL;
}
STDMETHODIMP CEventSink::GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo)
{
UNREFERENCED_PARAMETER(iTInfo);
UNREFERENCED_PARAMETER(lcid);
UNREFERENCED_PARAMETER(ppTInfo);
return E_NOTIMPL;
}
STDMETHODIMP CEventSink::GetIDsOfNames(REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId)
{
UNREFERENCED_PARAMETER(riid);
UNREFERENCED_PARAMETER(rgszNames);
UNREFERENCED_PARAMETER(cNames);
UNREFERENCED_PARAMETER(lcid);
UNREFERENCED_PARAMETER(rgDispId);
return E_NOTIMPL;
}
// This is called by IE to notify us of events
// Full documentation about all the events supported by DWebBrowserEvents2 can be found at
// http://msdn.microsoft.com/en-us/library/aa768283(VS.85).aspx
STDMETHODIMP CEventSink::Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr)
{
UNREFERENCED_PARAMETER(lcid);
UNREFERENCED_PARAMETER(wFlags);
UNREFERENCED_PARAMETER(pVarResult);
UNREFERENCED_PARAMETER(pExcepInfo);
UNREFERENCED_PARAMETER(puArgErr);
VARIANT v[5]; // Used to hold converted event parameters before passing them onto the event handling method
int n;
bool b;
PVOID pv;
LONG lbound,ubound,sz;
//MessageBox(NULL,_T("Invoke has been called"),_T("CEventSink"),MB_OK|MB_ICONINFORMATION);
// if (!IsEqualIID(riid,DIID_DWebBrowserEvents2))
// {
// }
if(!IsEqualIID(riid,IID_NULL)) return DISP_E_UNKNOWNINTERFACE; // riid should always be IID_NULL
// Initialize the variants
for (n = 0; n < 5; n++)
{
VariantInit(&v[n]);
}
do
{
if (dispIdMember == DISPID_DOCUMENTCOMPLETE)
{ // Handle the AfterDocumentComplete event
VariantChangeType(&v[0],&pDispParams->rgvarg[0], 0, VT_BSTR); // url
b = Event_AfterDocumentComplete2((LPOLESTR)v[0].bstrVal);
if (b)
{
*(pDispParams->rgvarg[0].pboolVal) = VARIANT_TRUE;
}
else
{
*(pDispParams->rgvarg[0].pboolVal) = VARIANT_FALSE;
}
break ;
}
}while (0) ;
// Free the variants
for(n = 0; n < 5; n++)
{
VariantClear(&v[n]);
}
return S_OK;
}
// Return true to prevent the url from being opened
bool CEventSink::Event_BeforeNavigate2(LPOLESTR url,LONG Flags,LPOLESTR TargetFrameName,PUCHAR PostData,LONG PostDataSize,LPOLESTR Headers,bool Cancel)
{
// Do whatever you like here
// This is just an example
//TCHAR msg[1024];
//wsprintf(msg,_T("url=%ls\nFlags=0x%08X\nTargetFrameName=%ls\nPostData=%hs\nPostDataSize=%d\nHeaders=%ls\nCancel=%s"),url,Flags,TargetFrameName,(char*)PostData,PostDataSize,Headers,((Cancel)?(_T("true")):(_T("false"))));
////////MessageBox(NULL,msg,_T("CodeProject BHO Example - BeforeNavigate2 event fired!"),MB_OK|MB_ICONINFORMATION);
return Cancel;
}
// Return true to prevent the url from being opened
bool CEventSink::Event_AfterDocumentComplete2(LPOLESTR url)
{
static int iNumRetry = 0 ;
// Do whatever you like here
// This is just an example
CBstr sUrl(url) ;
TCHAR strIniFilename[255] ;
TCHAR strUserID[60] ;
TCHAR strPassword[60] ;
TCHAR strUserFieldID[60] ;
TCHAR strPasswordField[60] ;
TCHAR strURL[255] ;
TCHAR strKey[255] ;
int intLength ;
if (GetConfigFilename(&strIniFilename[0]) == false)
{
////////MessageBox(NULL,_T("filename not found"),_T("filename"),MB_OK|MB_ICONINFORMATION);
return false ;
}
intLength = GetPrivateProfileString(_T("Parameters"), _T("URL"), _T("0"), strURL, 255, strIniFilename) ;
if (sUrl.CompareNoCase(strURL) == 0)
{
intLength = GetPrivateProfileString(_T("Param"), _T("Key"), _T("0"), strKey, 255, strIniFilename) ;
int iNumFields = 2 ;
iNumFields = GetPrivateProfileInt(_T("Param"), _T("NumFields"), 0, strIniFilename) ;
if (iNumFields == 0)
{
return false ;
}
//iDecryptKey = CInt(Decrypt(4, strKey))
TCHAR strEntry[10] ;
bool bNeedSubmit = true ;
for (int i = 0; ((i < iNumFields) && (bNeedSubmit == true)); i++)
{
wsprintf(strEntry, _T("F%c"), CHAR(i + 49)) ;
////////MessageBox(NULL,strEntry,_T("Entry Fi"),MB_OK|MB_ICONINFORMATION);
intLength = GetPrivateProfileString(_T("Parameters"), strEntry, _T("0"), strUserID , 60, strIniFilename) ;
wsprintf(strEntry, _T("FN%c"), CHAR(i + 49)) ;
////////MessageBox(NULL,strEntry,_T("Entry FNi"),MB_OK|MB_ICONINFORMATION);
intLength = GetPrivateProfileString(_T("Parameters"), strEntry, _T("0"), strUserFieldID, 60, strIniFilename) ;
bNeedSubmit = FindUserNameReplaceValue(strUserFieldID, strUserID) ;
}
if (bNeedSubmit == true)
{
FindSubmitAndActivate(_T("submit")) ;
}
return true ;
}
return true;
}
bool CEventSink::FindSubmitAndActivate(TCHAR *ptName)
{
if (pSite == NULL)
{
return false;
}
HRESULT hr;
IDispatch* pHtmlDocDispatch = NULL;
IHTMLDocument2 * pHtmlDoc = NULL;
bool bSearch = true;
// Retrieve the document object.
hr = pSite->get_Document(&pHtmlDocDispatch);
if (SUCCEEDED(hr) && (pHtmlDocDispatch != NULL))
{
hr = pHtmlDocDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&pHtmlDoc);
if (SUCCEEDED(hr) && (pHtmlDoc != NULL))
{
IHTMLElementCollection* pColl = NULL;
hr = pHtmlDoc->get_all (&pColl);
if (SUCCEEDED(hr) && (pColl != NULL))
{
// Obtained the Anchor Collection...
long nLength = 0;
pColl->get_length (&nLength);
for (int i = 0; i < nLength && bSearch; i++)
{
VARIANT vIdx ;
vIdx.vt = VT_I4 ;
vIdx.lVal = (long)i ;
IDispatch* pElemDispatch = NULL;
IHTMLElement* pElem = NULL;
hr = pColl->item (vIdx, vIdx, &pElemDispatch);
if (SUCCEEDED(hr) && (pElemDispatch != NULL))
{
hr = pElemDispatch->QueryInterface(IID_IHTMLElement, (void**)&pElem);
if (SUCCEEDED(hr) && (pElem != NULL))
{
BSTR bstrTagName;
CBstr sTempTagName ;
if (!FAILED(pElem->get_tagName(&bstrTagName)))
{
sTempTagName = bstrTagName ;
SysFreeString (bstrTagName);
}
if (sTempTagName.CompareNoCase(_T ("input")) == 0)
{
IHTMLInputElement * pInputElem = NULL;
hr = pElemDispatch->QueryInterface(IID_IHTMLInputElement, (void**)&pInputElem);
if (SUCCEEDED(hr) && (pInputElem != NULL))
{
BSTR bstrType ;
CBstr sTempType ;
CBstr sTempName ;
CBstr sTempValue;
if (!FAILED(pInputElem->get_type(&bstrType)))
{
sTempType = bstrType;
SysFreeString (bstrType);
if (sTempType.CompareNoCase(ptName) == 0)
{
//MessageBox (NULL, _T("Before Submit pressed"), _T(""), MB_OK | MB_ICONINFORMATION);
pElem->click();
// can be clicked via Documnet as in the next 3 line below
//IHTMLFormElement *pLogOnForm ;
//pInputElem->get_form(&pLogOnForm);
//pLogOnForm->submit() ;
//MessageBox (NULL, _T("After Submit pressed"), _T(""), MB_OK | MB_ICONINFORMATION);
bSearch = false ;
}
}
pInputElem->Release();
}
}
pElem->Release();
}
pElemDispatch->Release();
}
}
pColl->Release();
}
pHtmlDoc->Release();
}
pHtmlDocDispatch->Release();
}
return (bSearch == false);
}
bool CEventSink::FindUserNameReplaceValue(TCHAR *ptName, TCHAR* ptNewValue)
{
if (pSite == NULL)
{
return false;
}
HRESULT hr;
IDispatch* pHtmlDocDispatch = NULL;
IHTMLDocument2 * pHtmlDoc = NULL;
bool bSearch = true;
// Retrieve the document object.
hr = pSite->get_Document(&pHtmlDocDispatch);
if (SUCCEEDED(hr) && (pHtmlDocDispatch != NULL))
{
hr = pHtmlDocDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&pHtmlDoc);
if (SUCCEEDED(hr) && (pHtmlDoc != NULL))
{
IHTMLElementCollection* pColl = NULL;
hr = pHtmlDoc->get_all (&pColl);
if (SUCCEEDED(hr) && (pColl != NULL))
{
// Obtained the Anchor Collection...
long nLength = 0;
pColl->get_length (&nLength);
for (int i = 0; i < nLength && bSearch; i++)
{
VARIANT vIdx ;
vIdx.vt = VT_I4 ;
vIdx.lVal = (long)i ;
IDispatch* pElemDispatch = NULL;
IHTMLElement* pElem = NULL;
hr = pColl->item (vIdx, vIdx, &pElemDispatch);
if (SUCCEEDED(hr) && (pElemDispatch != NULL))
{
hr = pElemDispatch->QueryInterface(IID_IHTMLElement, (void**)&pElem);
if (SUCCEEDED(hr) && (pElem != NULL))
{
BSTR bstrTagName;
CBstr sTempTagName ;
if (!FAILED(pElem->get_tagName(&bstrTagName)))
{
sTempTagName = bstrTagName ;
SysFreeString (bstrTagName);
}
if (sTempTagName.CompareNoCase(_T ("input")) == 0)
{
IHTMLInputElement * pInputElem = NULL;
hr = pElemDispatch->QueryInterface(IID_IHTMLInputElement, (void**)&pInputElem);
if (SUCCEEDED(hr) && (pInputElem != NULL))
{
BSTR bstrType ;
BSTR bstrName ;
CBstr sTempType ;
CBstr sTempName ;
CBstr sTempValue;
if (!FAILED(pInputElem->get_type(&bstrType)))
{
sTempType = bstrType;
SysFreeString (bstrType);
}
if (!FAILED(pInputElem->get_name(&bstrName)))
{
sTempName = bstrName;
SysFreeString (bstrName);
if (sTempName.CompareNoCase(ptName) == 0)
{
CBstr bstrNewValue = ::SysAllocString(ptNewValue);
pInputElem->put_value(bstrNewValue);
SysFreeString(bstrNewValue);
bSearch = false ;
}
}
pInputElem->Release();
}
}
pElem->Release();
}
pElemDispatch->Release();
}
}
pColl->Release();
}
pHtmlDoc->Release();
}
pHtmlDocDispatch->Release();
}
return (bSearch == false);
}
bool CEventSink::FindInput()
{
static int iNumRetry = 0 ;
if (pSite == NULL)
{
return false;
}
HRESULT hr;
IDispatch* pHtmlDocDispatch = NULL;
IHTMLDocument2 * pHtmlDoc = NULL;
bool bSearch = true;
BSTR bstrInput = ::SysAllocString(L"input");
// Retrieve the document object.
hr = pSite->get_Document(&pHtmlDocDispatch);
if (SUCCEEDED(hr) && (pHtmlDocDispatch != NULL))
{
hr = pHtmlDocDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&pHtmlDoc);
if (SUCCEEDED(hr) && (pHtmlDoc != NULL))
{
IHTMLElementCollection* pColl = NULL;
hr = pHtmlDoc->get_all (&pColl);
if (SUCCEEDED(hr) && (pColl != NULL))
{
// Obtained the Anchor Collection...
long nLength = 0;
pColl->get_length (&nLength);
for (int i = 0; i < nLength && bSearch; i++)
{
VARIANT vIdx ;
vIdx.vt = VT_I4 ;
vIdx.lVal = (long)i ;
IDispatch* pElemDispatch = NULL;
IHTMLElement* pElem = NULL;
hr = pColl->item (vIdx, vIdx, &pElemDispatch);
if (SUCCEEDED(hr) && (pElemDispatch != NULL))
{
hr = pElemDispatch->QueryInterface(IID_IHTMLElement, (void**)&pElem);
if (SUCCEEDED(hr) && (pElem != NULL))
{
BSTR bstrTagName;
CBstr sTempTagName ;
if (!FAILED(pElem->get_tagName(&bstrTagName)))
{
sTempTagName = bstrTagName ;
SysFreeString (bstrTagName);
}
if (sTempTagName.CompareNoCase(_T ("input")) == 0)
{
#if 0
wsprintf(msg1,_T("Input fiels found %ls"), (TCHAR*)sTempTagName ) ;;
MessageBox (NULL, msg1, _T(""), MB_OK | MB_ICONINFORMATION);
#endif
IHTMLInputElement * pInputElem = NULL;
hr = pElemDispatch->QueryInterface(IID_IHTMLInputElement, (void**)&pInputElem);
if (SUCCEEDED(hr) && (pInputElem != NULL))
{
BSTR bstrType ;
BSTR bstrName ;
BSTR bstrValue ;
CBstr sTempType ;
CBstr sTempName ;
CBstr sTempValue;
if (!FAILED(pInputElem->get_type(&bstrType)))
{
sTempType = bstrType;
SysFreeString (bstrType);
}
if (!FAILED(pInputElem->get_name(&bstrName)))
{
sTempName = bstrName;
SysFreeString (bstrName);
}
if (!FAILED(pInputElem->get_value(&bstrValue)))
{
sTempValue = bstrValue;
SysFreeString (bstrValue);
}
if (iNumRetry == 0)
{
if (sTempName.CompareNoCase(_T ("ZIHMIST")) == 0)
{
CBstr bstrNewValue = ::SysAllocString(L"AAAA");
pInputElem->put_value(bstrNewValue);
SysFreeString(bstrNewValue);
}
if (sTempName.CompareNoCase(_T ("KOD")) == 0)
{
CBstr bstrNewValue = ::SysAllocString(L"Levy");;
pInputElem->put_value(bstrNewValue);
SysFreeString(bstrNewValue);
}
if (sTempType.CompareNoCase(_T ("submit")) == 0)
{
//MessageBox (NULL, _T("Before Submit pressed"), _T(""), MB_OK | MB_ICONINFORMATION);
pElem->click();
// can be clicked via Documnet as in the next 3 line below
//IHTMLFormElement *pLogOnForm ;
//pInputElem->get_form(&pLogOnForm);
//pLogOnForm->submit() ;
//MessageBox (NULL, _T("After Submit pressed"), _T(""), MB_OK | MB_ICONINFORMATION);
}
}
pInputElem->Release();
}
}
pElem->Release();
}
pElemDispatch->Release();
}
}
iNumRetry++ ;
pColl->Release();
}
pHtmlDoc->Release();
}
pHtmlDocDispatch->Release();
}
::SysFreeString(bstrInput);
return (bSearch == false);
}
bool CEventSink::GetConfigFilename(TCHAR* psConfigWebFullName)
{
bool bFileOK = false ;
int iLen ;
TCHAR sComputerName[255] ;
TCHAR sConfigFileFullName[255] ;
DWORD nSize ;
GetComputerName(&sComputerName[0], &nSize) ;
//MessageBox (NULL, sComputerName, _T("computer name before swapping "), MB_OK | MB_ICONINFORMATION);
if (nSize > 0)
{
wsprintf(psConfigWebFullName, _T("C:\\%s.ini"), sComputerName) ;
bFileOK = true ;
}
return bFileOK ;
}
more file add those files to the project
// file : CBstr.h
////////////////////////////////////////////////////////
//
// CBStr : BSTR wrapper class with manipulation routines
//
// Gary Olliffe : Parallax Solutions Ltd
//
// e-mail : Gary_Olliffe@hotmail.com
//
// date : 14/07/1998
//
// updated : 19/10/98
// Fixed SetAt() to work with ANSI and Unicode
// Tested under UNICODE release and Debug.
// Added LoadString() method.
//
////////////////////////////////////////////////////////
//
// The public interface to this class was
// "inspired by"/"poached from" the NoMFC::CString example
// www.worldofatl.com. As a result it fairly closely mimics the
// MFC CString interface - the methods not implemented have been left
// in the class definition but are commented out.
// Additional constructorsto mimic _bstr_t have been added, these include a
// _variant_t constructor and a BSTR constructor with copy/attach flag
//
// If you have a string that will require manipulation then use this
// otherwise stick to the basic _bstr_t class.
//
// The reason I have written this _bstr_t based class rather than use the
// basic_string implementation is that the MS STL requires a support dll
// to be shipped to support the allocators, and not everyone want to use STL
//
// This is by no means intended as an optimised implementation of this class,
// most or the routines use the standard "c" string manipulation routines
//
// Users looking at the implementation should also note that the _bstr_t base class
// has two internal representations (one ASNI, one uNICODE) methods on this
// class that modify the string (eg. MakeUpper, SetAt, etc...) modify both internal
// strings to maintain consistency.
//
// Users should also note that where appropriate the class makes use of the TCHAR
// typedef, giving UNICODE compatibility.
//
/////////////////////////////////////////////////////////////
#ifndef _CBSTR_H_D130E080_1B3E_11d2_955A_00805FC3DFB4
#define _CBSTR_H_D130E080_1B3E_11d2_955A_00805FC3DFB4
class CBstr : public _bstr_t
{
// These methods groupings and names have been taken from
// NoMFC::CString from www.worldofatl.com
public:
// Constructors
CBstr();
CBstr( const CBstr& strInput);
CBstr( const _bstr_t& strInput);
CBstr( const TCHAR* strInput);
// _bstr_t mimic constructors
CBstr( const _variant_t& varinput );
CBstr( BSTR strinput, bool bcopy );
// CBstr(TCHAR ch, int nRepeat = 1);
//string population
bool LoadString(HINSTANCE hInstance, UINT uID);
// The string as an array
// int GetLength() const;
bool IsEmpty() const;
void Empty();
TCHAR GetAt(int nIndex) const;
void SetAt(int nIndex, TCHAR ch);
// Comparison
int Compare(const TCHAR* psz) ;//const;
int Compare(const CBstr& str) const;
int CompareNoCase(const TCHAR* psz) const;
int CompareNoCase(const CBstr& str) const;
int Collate(const TCHAR* psz) const;
int Collate(const CBstr& str) const;
// Extraction
// CBstr Mid(int nFirst) const;
CBstr Mid(int nFirst, int nCount) const;
CBstr Left(int nCount) const;
CBstr Right(int nCount) const;
CBstr SpanIncluding(const TCHAR* pszCharSet) const;
CBstr SpanExcluding(const TCHAR* pszCharSet) const;
// Other Conversions
void MakeUpper();
void MakeLower();
void MakeReverse();
void TrimLeft();
void TrimRight();
void Format(const TCHAR* pszFormat, ... );
// Searching
int Find(const TCHAR& ch) const;
int Find(const TCHAR* psz) const;
int ReverseFind(const TCHAR& ch) const;
int FindOneOf(const TCHAR* pszCharSet) const;
// Operators
TCHAR operator[](int nIndex) const;
operator const TCHAR*() const;
};
#endif // _CBSTR_H_D130E080_1B3E_11d2_955A_00805FC3DFB4
// file CBstrImpl.h
////////////////////////////////////////////////////////
//
// CBStr : BSTR wrapper class with manipulation routines
//
// Gary Olliffe : Parallax Solutions Ltd
//
// e-mail : Gary.Olliffe@parallax.co.uk
//
// updated : 19/10/98
// Fixed SetAt() to work with ANSI and Unicode
// Tested under UNICODE release and Debug.
// Added LoadString() method.
#ifndef _CBSTR_IMPLEMENTATION_H_00944610_1B3F_11d2_955A_00805FC3DFB4
#define _CBSTR_IMPLEMENTATION_H_00944610_1B3F_11d2_955A_00805FC3DFB4
#include <stdio.h>
#include <comdef.h>
#include <tchar.h>
#include "CBStr.h"
///////////////////////////////////////////////////////////////////////////
// The string as an array
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Constructors
///////////////////////////////////////////////////////////////////////////
inline CBstr::CBstr()
: _bstr_t() {}
inline CBstr::CBstr(const CBstr& strInput)
: _bstr_t(strInput) {}
inline CBstr::CBstr(const _bstr_t& strInput)
: _bstr_t(strInput) {}
inline CBstr::CBstr(const TCHAR* strInput)
: _bstr_t(strInput) {}
inline CBstr::CBstr(const variant_t& varinput)
: _bstr_t(varinput) {}
inline CBstr::CBstr(const BSTR strInput, bool bcopy)
: _bstr_t(strInput, bcopy) {}
////////////////////////////////////////////////////////////////////////////
// Methods
////////////////////////////////////////////////////////////////////////////
// New Loadstring method
inline bool CBstr::LoadString(HINSTANCE hInstance, UINT uID)
{
bool bRetval = false;
TCHAR lpBuffer[256];
if (0 != ::LoadString(hInstance, uID, lpBuffer, 256))
{
bRetval = true;
// assign value to this class
*this = lpBuffer;
}
return bRetval;
}
inline bool CBstr::IsEmpty() const
{
return _bstr_t::length() == 0;
};
inline void CBstr::Empty()
{
_bstr_t::operator=( _T("") );
return;
};
inline TCHAR CBstr::GetAt(int nIndex) const
{
unsigned int len = _bstr_t::length();
if (len > 0 && len > static_cast<unsigned int>(nIndex))
{
const TCHAR* tmp = _bstr_t::operator const TCHAR*() ;
return tmp[nIndex];
}
return L'\0';
};
inline void CBstr::SetAt(int nIndex, TCHAR ch)
{
unsigned int len = _bstr_t::length();
if (len > 0 && len > static_cast<unsigned int>(nIndex))
{
// We need to modify both internal representations in the
// base class
char* tmp = _bstr_t::operator char*() ;
wchar_t* tmpw = _bstr_t::operator wchar_t*() ;
#if defined(UNICODE) && defined(_UNICODE)
// This is a UNICODE build
wchar_t wch = ch;
char mbch;
WideCharToMultiByte(CP_ACP, 0, &ch, 1,
&mbch, 1, NULL,NULL);
#else
// This is an ANSI build
wchar_t wch;
char mbch = ch;
MultiByteToWideChar(CP_ACP, 0, &ch, 1,
&wch, 1 );
#endif
tmp[nIndex] = mbch;
tmpw[nIndex] = wch;
}
return;
};
///////////////////////////////////////////////////////////////////////////
// Comparison
///////////////////////////////////////////////////////////////////////////
inline int CBstr::Compare(LPCTSTR psz) //const
{
const TCHAR* tmp = _bstr_t::operator TCHAR*();
return _tcscmp(tmp, psz);
};
inline int CBstr::Compare(const CBstr& str) const
{
const TCHAR* tmpthis = _bstr_t::operator const TCHAR*();
const TCHAR* tmpOther = static_cast<const TCHAR*>(str);
return _tcscmp(tmpthis, tmpOther);
};
inline int CBstr::CompareNoCase(const TCHAR* psz) const
{
const TCHAR* tmp = _bstr_t::operator const TCHAR*();
return _tcsicmp(tmp, psz);
};
inline int CBstr::CompareNoCase(const CBstr& str) const
{
const TCHAR* tmpthis = _bstr_t::operator const TCHAR*();
const TCHAR* tmpOther = static_cast<const TCHAR*>(str);
return _tcsicmp(tmpthis, tmpOther);
};
inline int CBstr::Collate(const TCHAR* psz) const
{
const TCHAR* tmpthis = _bstr_t::operator const TCHAR*();
return _tcscoll(tmpthis, psz);
};
inline int CBstr::Collate(const CBstr& str) const
{
const TCHAR* tmpthis = _bstr_t::operator const TCHAR*();
const TCHAR* tmpOther = static_cast<const TCHAR*>(str);
return _tcscoll(tmpthis, tmpOther);
};
///////////////////////////////////////////////////////////////////////////
// Extraction
///////////////////////////////////////////////////////////////////////////
/* inline CBstr<T> CBstr::Mid(int nFirst) const
{
const TCHAR* tmp = _bstr_t::operator TCHAR*();
return _tcsnstr(nFirst);
};
*/
inline CBstr CBstr::Mid(int nFirst, int nCount) const
{
TCHAR* tmp = _bstr_t::operator TCHAR*();
int len = _bstr_t::length() + 1;
TCHAR *result = new TCHAR[ len ];
memset( result, '\0', len * sizeof(TCHAR) );
_tcsncpy( result, &tmp[nFirst], nCount );
CBstr cbRes = result;
delete result;
return cbRes;
};
inline CBstr CBstr::Left(int nCount) const
{
return CBstr::Mid(0, nCount);
};
inline CBstr CBstr::Right(int nCount) const
{
return CBstr::Mid(length() - nCount, nCount);
};
inline CBstr CBstr::SpanIncluding(const TCHAR* pszCharSet) const
{
const TCHAR* tmp = _bstr_t::operator const TCHAR*();
int strlen = _tcsspn( tmp, pszCharSet );
return CBstr::Mid(0, strlen);
};
inline CBstr CBstr::SpanExcluding(const TCHAR* pszCharSet) const
{
const TCHAR* tmp = _bstr_t::operator const TCHAR*();
int pos = _tcscspn( tmp, pszCharSet );
return CBstr::Mid(0, pos);
};
///////////////////////////////////////////////////////////////////////////
// Other Conversions
///////////////////////////////////////////////////////////////////////////
inline void CBstr::MakeUpper()
{
// We need to modify both internal representations in the
// base class
char* tmp = _bstr_t::operator char*() ;
wchar_t* tmpw = _bstr_t::operator wchar_t*() ;
strupr(tmp);
_wcsupr(tmpw);
return;
};
inline void CBstr::MakeLower()
{
// We need to modify both internal representations in the
// base class
char* tmp = _bstr_t::operator char*() ;
wchar_t* tmpw = _bstr_t::operator wchar_t*() ;
strlwr(tmp);
_wcslwr(tmpw);
return;
};
inline void CBstr::MakeReverse()
{
// We need to modify both internal representations in the
// base class
char* tmp = _bstr_t::operator char*() ;
wchar_t* tmpw = _bstr_t::operator wchar_t*() ;
strrev(tmp);
_wcsrev(tmpw);
return;
};
inline void CBstr::TrimLeft()
{
const TCHAR* tmp = _bstr_t::operator const TCHAR*();
TCHAR* trimstr = _tcsspnp( tmp, _T(" \t") );
*this = trimstr;
return;
};
inline void CBstr::TrimRight()
{
const TCHAR* tmp = _bstr_t::operator const TCHAR*();
TCHAR* trimstr = _tcsspnp( tmp, _T(" \t") );
int pos = _bstr_t::length() - 1;
while (trimstr[pos] == ' ')
{
trimstr[pos--] = '\0';
}
*this = trimstr;
return;
};
inline void CBstr::Format(const TCHAR* pszFormat, ... )
{
// Doesn't have all the features of CString::Format()
va_list vl;
va_start(vl, pszFormat);
TCHAR* pszTemp = NULL;
int nBufferSize = 0;
int nRetVal = -1;
do
{
// Increment the buffer 100 characters at a time
// I'm not sure whether this is robust!
nBufferSize += 100;
delete [] pszTemp;
pszTemp = new TCHAR [nBufferSize];
nRetVal = _vstprintf(pszTemp, pszFormat, vl);
} while (nRetVal < 0);
*this = pszTemp;
delete [] pszTemp;
va_end(vl);
return;
};
///////////////////////////////////////////////////////////////////////////
// Searching
///////////////////////////////////////////////////////////////////////////
inline int CBstr::Find(const TCHAR& ch) const
{
// npos == -1 in this implementation, but it might not always be, so this is
// a bit dodgy.
const TCHAR* tmp = _bstr_t::operator const TCHAR*() ;
//TCHAR* pdest = _tcschr( tmp, ch );
// return pdest - tmp;
return 0 ;
};
inline int CBstr::Find(const TCHAR* psz) const
{
const TCHAR* tmp = _bstr_t::operator const TCHAR*() ;
// TCHAR* pdest = _tcsstr( tmp, psz );
// return pdest - tmp;
return 0 ;
};
inline int CBstr::ReverseFind(const TCHAR& ch) const
{
const TCHAR* tmp = _bstr_t::operator const TCHAR*() ;
// TCHAR* pdest = _tcsrchr( tmp, ch );
// return pdest - tmp;
return 0 ;
};
inline int CBstr::FindOneOf(const TCHAR* psz) const
{
const TCHAR* tmp = _bstr_t::operator const TCHAR*() ;
int pos = _tcscspn( tmp, psz );
if (pos == static_cast<long>(_bstr_t::length()))
{
pos = -1;
}
return pos;
};
///////////////////////////////////////////////////////////////////////////
// Operators
///////////////////////////////////////////////////////////////////////////
inline CBstr::operator const TCHAR*() const
{ return _bstr_t::operator const TCHAR*(); };
inline TCHAR CBstr::operator[](int nIndex) const
{ return GetAt(nIndex); };
///////////////////////////////////////////////////////////////////////////
// Comparison Operators
///////////////////////////////////////////////////////////////////////////
inline bool operator==(const CBstr& s1, const CBstr& s2)
{ return s1.Compare(s2) == 0; }
inline bool operator==(const CBstr& s1, const TCHAR* s2)
{ return s1.Compare(s2) == 0; }
inline bool operator==(const TCHAR* s1, const CBstr& s2)
{ return s2.Compare(s1) == 0; }
inline bool operator!=(const CBstr& s1, const CBstr& s2)
{ return s1.Compare(s2) != 0; }
inline bool operator!=(const CBstr& s1, const TCHAR* s2)
{ return s1.Compare(s2) != 0; }
inline bool operator!=(const TCHAR* s1, const CBstr& s2)
{ return s2.Compare(s1) != 0; }
inline bool operator<(const CBstr& s1, const CBstr& s2)
{ return s1.Compare(s2) < 0; }
inline bool operator<(const CBstr& s1, const TCHAR* s2)
{ return s1.Compare(s2) < 0; }
inline bool operator<(const TCHAR* s1, const CBstr& s2)
{ return s2.Compare(s1) > 0; }
inline bool operator>(const CBstr& s1, const CBstr& s2)
{ return s1.Compare(s2) > 0; }
inline bool operator>(const CBstr& s1, const TCHAR* s2)
{ return s1.Compare(s2) > 0; }
inline bool operator>(const TCHAR* s1, const CBstr& s2)
{ return s2.Compare(s1) < 0; }
inline bool operator<=(const CBstr& s1, const CBstr& s2)
{ return s1.Compare(s2) <= 0; }
inline bool operator<=(const CBstr& s1, const TCHAR* s2)
{ return s1.Compare(s2) <= 0; }
inline bool operator<=(const TCHAR* s1, const CBstr& s2)
{ return s2.Compare(s1) >= 0; }
inline bool operator>=(const CBstr& s1, const CBstr& s2)
{ return s1.Compare(s2) >= 0; }
inline bool operator>=(const CBstr& s1, const TCHAR* s2)
{ return s1.Compare(s2) >= 0; }
inline bool operator>=(const TCHAR* s1, const CBstr& s2)
{ return s2.Compare(s1) <= 0; }
#endif //_CBSTR_IMPLEMENTATION_H_00944610_1B3F_11d2_955A_00805FC3DFB4
Hope it helps you can send mail to arieelahlevy@gmail.com for more help
|
|
|
|

|
This is how I did it...
EventSink.h:
...
#include <MsHTML.h>
class CEventSink : public DWebBrowserEvents2 {
public:
...
void Init(IWebBrowser2* pSite); protected:
...
IWebBrowser2 *pSite; };
EventSink.cpp:
void CEventSink::Init(IWebBrowser2* pSite) {
this->pSite = pSite;
}
ObjectWithSite.cpp:
STDMETHODIMP CObjectWithSite::SetSite(IUnknown *pUnkSite)
{
...
if(FAILED(hr)) return hr;
EventSink.Init(pSite); // initialize EventSink with the pSite reference
ConnectEventSink();
...
}
void CEventSink::Event_OnDocumentComplete()
{
IHTMLDocument2 *pDocument;
pSite->get_Document((IDispatch**)&pDocument); // get a reference to the IHTMLDocument2 and do something with it
BSTR str;
pDocument->get_readyState(&str);
...
}
Thanks, cefarix, for the great tutorial!
Peter
|
|
|
|

|
Hi,
First of all, thanks for the great article.
Have you noticed that in Microsoft they started to use [out] parameters in events? This contradicts the COM Events concept of having only [in] arguments. Pity, it is not documented in MSDN.
This maybe does not relate to the subject of your article. At the moment I am developing a COM interface to use by a third party software. The COM interface is a dialog window, which contains a button, which in turn should call a dialog from the calling program, which should return some data back to the COM object. [out] parameter should do the job (and it does, I tested). The problem is I can't use it, because it is an undocumented feature of COM technology.
But, looking at the MSDN article for DWebBrowserEvents2::NewWindow3 Event[^] I can see that they started using [out] parameters and even include them to MSDN?
Any thoughts?
|
|
|
|

|
Really appreciate the article.
|
|
|
|

|
baloneyman wrote: Really appreciate the article.Thumbs Up
me too.
|
|
|
|

|
It is easy to read and clear. I wish I can read more like the applications for IE.
I have a question for you. Can I use BHO with ASP.net? Can I exchange data between ASP.net and BHO?
Thanks,
|
|
|
|

|
I don't have experience with ASP.net so I can't answer your question specifically. But if you want to interact with the DOM on the page, you should use the get_Document method of the site object to get an IUnknown interface pointer to the document object. You can then use the QueryInterface method of the document object to get an interface pointer to the IHTMLDocument2 interface or to the IHTMLDocument3 interface which will let you interact with the DOM and also scripts on the page.
You can find the documentation for IWebBrowser2::get_Document here[^], for IHTMLDocument2 here[^], and for IHTMLDocument3 here[^].
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
How to write an Internet Explorer plug-in (Browser Helper Object - BHO) using just C++ and the Windows API; no ATL or MFC involved!
| Type | Article |
| Licence | CPOL |
| First Posted | 6 Jun 2009 |
| Views | 72,037 |
| Downloads | 4,685 |
| Bookmarked | 110 times |
|
|