抓狂!JS响应COM事件的问题

ringphone 2013-10-23 05:24:55
做个COM,需要事件通知页面,参考下面这篇帖子实现了:
http://bbs.csdn.net/topics/370096340

COM是多线程的,但是奇怪的是只有JS调用了我COM的某个方法,在那个方法里产生事件JS才会收到,百思不得其解,以为是多线程的问题,后来专门编写了测试代码,COM初始化时创建一个弹出窗口,所有线程的事件全部SendMessage到这个窗口,再由这个窗口产生事件通知JS,同时这个窗口加个菜单,通过菜单命令产生事件,这样所有事件都是由这个窗口去通知JS了,结果是,所有线程通过SendMessage通知窗口,再由窗口产生的事件JS都无法收到,只有通过这个窗口菜单产生的事件JS才会收到,有人知道是什么原因或怎么解决吗?

那篇帖子里有两种方法实现JS响应COM事件,我试了这两种方法都成功了,我用了后一种方法测试,这个方法其实不算是JS响应事件,是COM执行JS函数了:

STDMETHODIMP CXXX::SetWindow(VARIANT vtWindow)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
if(vtWindow.vt != VT_DISPATCH)
{
return S_FALSE;
}
CoInitialize(NULL);
vtWindow.pdispVal->QueryInterface(IID_IHTMLWindow2, (void**)&iw);
return S_OK;
}


上面代码中的iw是全局变量,IHTMLWindow2指针

窗口调用JS的test函数:


case WM_USER://自定义窗口消息
{
OutputDebugString("执行JS函数");
VARIANT vt;
if(iw)
iw->execScript(CComBSTR(L"test()"), CComBSTR(L"javascript"), &vt);
break;
}


JS的test函数就是一个alert("COM调用");
页面初始化时JS调用ComObj.SetWindow(window);进行iw的初始化。

COM的线程有事件通知就是SendMessage(ghWnd,WM_USER,0,0);
响应窗口菜单命令同样是SendMessage,结果就是线程发送的消息,页面一点反应都没有,通过菜单操作,页面会弹出消息框。两者的唯一区别是菜单操作和执行JS代码是在同一个线程,而没响应的是其他线程发送的MESSAGE,DebugView能看到“执行JS函数”的信息,说明消息是收到了的,彻底抓狂!
...全文
435 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
程序猿Jacky 2014-12-22
  • 打赏
  • 举报
回复
虽然com进程只有一个,但里边会实例化多个对象。
程序猿Jacky 2014-12-22
  • 打赏
  • 举报
回复
你是进程外com吧?很可能是因为你两个进程实例化的是两个Com对象,故两个进程分别操作的两个对象,所有事件传不过来。
oyljerry 2013-11-04
  • 打赏
  • 举报
回复
COM直接调用JS函数的方式比较靠谱。
潇潇雨云 2013-11-04
  • 打赏
  • 举报
回复
学习学习学习
版主大哥 2013-10-23
  • 打赏
  • 举报
回复

//class **** : public CDHtmlDialog 

BOOL ****::OnCallDisp( WPARAM wParam ,LPARAM lParam )
{
	BOOL Temp = TRUE;
	VARIANT varRet ;
	memset(&varRet,0,sizeof(VARIANT));
	varRet.intVal = TRUE ;

	HRESULT hr;
	IHTMLDocument2 *spDoc = NULL; 
	hr = GetDHtmlDocument(&spDoc); 
	if(hr != S_OK) 
	{
		Temp = FALSE;
		varRet.boolVal = FALSE; 
	}

	IDispatch *pDisp = NULL; 
	hr = spDoc->get_Script(&pDisp); 
	if(hr != S_OK) 
	{
		Temp = FALSE;
		varRet.boolVal = FALSE; 
	}

	DISPID dispid; 
	CString str("CallJs_Component");
	BSTR bstrValue = str.AllocSysString(); 
	OLECHAR *pszFunct = bstrValue; 
	hr = pDisp->GetIDsOfNames(IID_NULL, &pszFunct, 1, LOCALE_SYSTEM_DEFAULT, &dispid); 

	if(hr != S_OK) 
	{
		Temp = FALSE;
		varRet.boolVal = FALSE; 
	}

	DISPPARAMS* npDispParams = new DISPPARAMS;
	memset( npDispParams, 0 , sizeof(DISPPARAMS));
	npDispParams->cArgs = 2 ;
	npDispParams->rgvarg = new VARIANT[2];

	npDispParams->rgvarg[1].vt = VT_INT;
	npDispParams->rgvarg[1].intVal = (int)wParam;

	npDispParams->rgvarg[0].vt = VT_BSTR;
	CString sendstr((char*)lParam);
	npDispParams->rgvarg[0].bstrVal = sendstr.AllocSysString();

	
	//异常处理,防止disp出现异常
	try
	{
		hr = pDisp->Invoke(dispid,IID_NULL,0,
			DISPATCH_METHOD,npDispParams,&varRet,NULL,NULL);
	}
	catch(...)
	{
		Temp = FALSE;
	}

	if(hr != S_OK) 
	{
		Temp = FALSE;
		varRet.boolVal = FALSE; 
	} 

	return Temp;
}
版主大哥 2013-10-23
  • 打赏
  • 举报
回复
记得以前弄过这个东西,什么vc <--->html <---> flash js 汗.....不过貌似忘记了,得回去看以前的代码
许文君 2013-10-23
  • 打赏
  • 举报
回复
询问下哥们你当年的界面库 的地址
许文君 2013-10-23
  • 打赏
  • 举报
回复
那就post消息,我们在微软的黑盒下确实蛋疼

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧