ActiveX多线程的问题,看了蒋晟老大的文章还是没明白,请各位高手指点,分数不够另开一贴再散!!!!!!!!!!!!!
先描述下功能:就是一个嵌入web页面的ActiveX控件,里面开启一个线程负责对本地的一个目录进行扫描,发现里面有文件后就通知web页面的javascript函数来响应
我的代码;
控件头文件:
#include <MsHTML.h>
class CMyActiveXCtrl : public COleControl
{
virtual void OnSetClientSite();
virtual void OnClose(DWORD dwSaveOption);
public:
CMainDialog m_MainDialog;
IWebBrowser2* pWebBrowser;
IHTMLDocument2* pHTMLDocument;
HANDLE threadHandle;//线程句柄
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
void OnReadSuccesful();
void OnReadFailed();
bool GetJScript(CComPtr<IDispatch>& spDisp);
bool GetJScripts(CComPtr<IHTMLElementCollection>& spColl);
bool CallJScript(const CString strFunc,CComVariant* pVarResult = NULL);
bool CallJScript(const CString strFunc,const CString strArg1,CComVariant* pVarResult = NULL);
bool CallJScript(const CString strFunc,const CString strArg1,const CString strArg2,CComVariant* pVarResult = NULL);
bool CallJScript(const CString strFunc,const CString strArg1,const CString strArg2,const CString strArg3,CComVariant* pVarResult = NULL);
bool CallJScript(const CString strFunc,const CStringArray& paramArray,CComVariant* pVarResult = NULL);
protected:
void FireParameterLoaded(void)
{
FireEvent(eventidParameterLoaded, EVENT_PARAM(VTS_NONE));
}
};
实现文件:
#define CHECK_POINTER(p)\
ATLASSERT(p != NULL);\
if(p == NULL)\
{\
return false;\
}
#define COMRELEASE(p)\
if(p != NULL)\
{\
p->Release();\
p=NULL;\
}
//线程代码
LONG ThreadProc(LPVOID pParam)
{
while (true)
{
CMyActiveXCtrl *pCtrl = (CMyActiveXCtrl*)pParam;
pCtrl->OnReadSuccesful();//就是简单的回调主线程中的方法去call页面的js函数
Sleep(3000); //simulate lengthy processing
}
return TRUE;
}
void CMyActiveXCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
if (!pdc)return;
DoSuperclassPaint(pdc, rcBounds);
m_MainDialog.MoveWindow(rcBounds, TRUE);
CBrush brBackGnd(TranslateColor(AmbientBackColor()));
pdc->FillRect(rcBounds, &brBackGnd);
}
void CMyActiveXCtrl::OnClose(DWORD dwSaveOption)
{
COMRELEASE(pWebBrowser);
COMRELEASE(pHTMLDocument);
COleControl::OnClose(dwSaveOption);
}
void CMyActiveXCtrl::OnSetClientSite()
{
HRESULT hr = S_OK;
IServiceProvider *isp, *isp2 = NULL;
if (!m_pClientSite)
{
COMRELEASE(pWebBrowser);
}
else
{
hr = m_pClientSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&isp));
if (FAILED(hr))
{
hr = S_OK;
goto cleanup;
}
hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast<void **>(&isp2));
if (FAILED(hr))
{
hr = S_OK;
goto cleanup;
}
hr = isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void **>(&pWebBrowser));
if (FAILED(hr))
{
hr = S_OK;
goto cleanup;
}
::CoMarshalInterThreadInterfaceInStream(IID_IWebBrowser2,pWebBrowser,&pStream);
hr = pWebBrowser->get_Document((IDispatch**)&pHTMLDocument);
if(FAILED(hr))
{
hr = S_OK;
goto cleanup;
}
cleanup:
// Free resources.
COMRELEASE(isp);
COMRELEASE(isp2);
}
}
int CMyActiveXCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
m_MainDialog.Create(IDD_MAINDIALOG, this);
//创建线程
DWORD dwID;
threadHandle = CreateThread(NULL,NULL,
(LPTHREAD_START_ROUTINE)ThreadProc,
(LPVOID)this, NULL, &dwID);
return 0;
}
/////////////////////
//回调函数
/////////////////////////
void CMyActiveXCtrl::OnReadSuccesful()
{//读数据成功
FireParameterLoaded();//为了验证确实回调了,故意加个fire事件在这里
CString strOnLoaded("OnLoaded");
this->CallJScript(strOnLoaded);
}
void CMyActiveXCtrl::OnReadFailed()
{//读卡失败
}
bool CMyActiveXCtrl::GetJScript(CComPtr<IDispatch>& spDisp)
{
CHECK_POINTER(pHTMLDocument);
HRESULT hr = pHTMLDocument->get_Script(&spDisp);
ATLASSERT(SUCCEEDED(hr));
return SUCCEEDED(hr);
}
bool CMyActiveXCtrl::GetJScripts(CComPtr<IHTMLElementCollection>& spColl)
{
CHECK_POINTER(pHTMLDocument);
HRESULT hr = pHTMLDocument->get_scripts(&spColl);
ATLASSERT(SUCCEEDED(hr));
return SUCCEEDED(hr);
}
bool CMyActiveXCtrl::CallJScript(const CString strFunc,CComVariant* pVarResult)
{
CStringArray paramArray;
return CallJScript(strFunc,paramArray,pVarResult);
}
bool CMyActiveXCtrl::CallJScript(const CString strFunc,const CString strArg1,CComVariant* pVarResult)
{
CStringArray paramArray;
paramArray.Add(strArg1);
return CallJScript(strFunc,paramArray,pVarResult);
}
bool CMyActiveXCtrl::CallJScript(const CString strFunc,const CString strArg1,const CString strArg2,CComVariant* pVarResult)
{
CStringArray paramArray;
paramArray.Add(strArg1);
paramArray.Add(strArg2);
return CallJScript(strFunc,paramArray,pVarResult);
}
bool CMyActiveXCtrl::CallJScript(const CString strFunc,const CString strArg1,const CString strArg2,const CString strArg3,CComVariant* pVarResult)
{
CStringArray paramArray;
paramArray.Add(strArg1);
paramArray.Add(strArg2);
paramArray.Add(strArg3);
return CallJScript(strFunc,paramArray,pVarResult);
}
bool CMyActiveXCtrl::CallJScript(const CString strFunc, const CStringArray& paramArray,CComVariant* pVarResult)
{
CComPtr<IDispatch> spScript;
if(!GetJScript(spScript))
{
//ShowError("Cannot GetScript");
return false;
}
CComBSTR bstrMember(strFunc);
DISPID dispid = NULL;
HRESULT hr = spScript->GetIDsOfNames(IID_NULL,&bstrMember,1,
LOCALE_SYSTEM_DEFAULT,&dispid);
if(FAILED(hr))
{
//ShowError(GetSystemErrorMessage(hr));
return false;
}
const int arraySize = paramArray.GetSize();
DISPPARAMS dispparams;
memset(&dispparams, 0, sizeof dispparams);
dispparams.cArgs = arraySize;
dispparams.rgvarg = new VARIANT[dispparams.cArgs];
for( int i = 0; i < arraySize; i++)
{
CComBSTR bstr = paramArray.GetAt(arraySize - 1 - i); // back reading
bstr.CopyTo(&dispparams.rgvarg[i].bstrVal);
dispparams.rgvarg[i].vt = VT_BSTR;
}
dispparams.cNamedArgs = 0;
EXCEPINFO excepInfo;
memset(&excepInfo, 0, sizeof excepInfo);
CComVariant vaResult;
UINT nArgErr = (UINT)-1; // initialize to invalid arg
hr = spScript->Invoke(dispid,IID_NULL,0,
DISPATCH_METHOD,&dispparams,&vaResult,&excepInfo,&nArgErr);
delete [] dispparams.rgvarg;
if(FAILED(hr))
{
//ShowError(GetSystemErrorMessage(hr));
return false;
}
if(pVarResult)
{
*pVarResult = vaResult;
}
return true;
}