通过学习,OCX添加方法、OCX回调JavaScript函数很简单,没什么说的。关键在于业务逻辑需要有一段执行时间,大约在3s左右,则出现一个很不友好的现象,当页面点击按钮后执行,按钮则会卡在那等待执行完毕,页面出现一种假死状态,在JS中添加异步调用OCX中的方法无果,所以咬着牙要把业务逻辑的执行放到多线程下,通过子线程回调JS方法。
回调事件必须由OCX初始化时所产生的线程发起子线程发起没试过怎么做,思路就是子线程执行完毕后发起postMessage,定义一个消息处理方法,接收消息发起回调。
根据这个思路,得到的解决方案如下
- 定一个消息头
#define WM_OJBK WM_USER+666
- 声明一个消息处理函数
afx_msg LRESULT OnFinishPublic(WPARAM wParam, LPARAM lParam);
- 定义消息处理函数宏
BEGIN_MESSAGE_MAP(COcxHelloCtrl, COleControl)
ON_MESSAGE(WM_OJBK,&COcxHelloCtrl::OnFinishPublic)
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()
- 实现函数
LRESULT COcxHelloCtrl::OnFinishPublic(WPARAM wParam, LPARAM lParam)
{
//此函数是你的回调函数
onFinish(L"123");
return 0;
}
完事后跑起来,没啥效果。。。Google半天没有回应
这里需要理解一下MFC的消息机制,MFC的消息机制是在窗口的基础上,没有窗口就没有消息机制。
还有解决方案是添加一个隐藏的Dialog,在ActiveX的OnCreate方法中使用
mDialog.Create(IDD_XXX,this);
创建一个隐藏的窗体,俺各种尝试,均无果。这种方式可能适合MFC Dialog的程序使用,但是该OCX是运行在IE浏览器上的,我觉得是不能在IE浏览器上创建Dialog。
功夫不负有心人,终于找到能解决OCX无Dialog即无消息机制的方案。
重写OnSetClientSite函数,在OnSetClientSite函数的实现中创建一个Dialog
具体代码:
void COcxHelloCtrl::OnSetClientSite()
{
if(m_pClientSite){
VERIFY(CreateControlWindow(::GetDesktopWindow(),CRect(0,0,0,0),CRect(0,0,0,0)));
}
COleControl::OnSetClientSite();
}
运行即可,所有的消息机制都可以成功发送与接收了!
如果还有什么不懂怎么添加的可以留言回复。
这里附上我Demo项目的源码+测试程序+注册与注销脚本,初学者据此加仔细琢磨必能攻克之。
https://download.youkuaiyun.com/download/w1213096890/10812481
谢谢。