我在写一个ocx控件。在控件内有一个自定义的类,处理逻辑相关的事件,比如MyClass.h和MyClass.cpp,当有人call我时,我就能在MyClass的线程内得到信息,现在我要通知给使用我这个ocx的用户,告诉用户有人call你。我是想添加个OnRing事件,只要用户在使用ocx时响应这个OnRing事件,就知道有没有人call他。问题是:ocx添加事件OnRing会自动添加到CxxxCtrl这个控件类内,我在MyClass内知道有人call了,我怎么去调CxxxCtrl内的OnRing?
解决思路1:
项目是MFC ActiveX, CxxxCtrl类内有处理消息循环的机制,我可以在CMyClass有OnRing事件时向CxxxCtrl发送消息postmessage,在CxxxCtrl的Windowproc内判断调用CxxxCtrl内的OnRing或FireEvent。
解决思路2:
可以写消息事件来设置通知窗口 如果是MFC里面用 OCX 你可以。
CMYCtrl 里面指定一个窗口
class CMYCtrl
{
CWnd *pWnd;
写一个事件
afx_msg void SetWnd(long* pBuffer)
{
pWnd=(CWnd*)pBuffer;
if(pWnd&&pWnd->m_hWnd)
pWnd->SendMessage(WM_CLOSE); // 都可以包括 postmessage
pWnd->SendMessage(WM_COPYDATA,DATA,SIZE);
}
}
//别忘了事件映射
BEGIN_DISPATCH_MAP(CMYCtrl, COleControl)
//自定义事件 1000 为调度时间ID
DISP_FUNCTION_ID(CMYCtrl, "SetWnd", 1000, SetWnd, VT_EMPTY,VTS_PI4)
END_DISPATCH_MAP()
//对了 别忘了 在odl中添加函数原型
[align=left]dispinterface _DScanImage
{
properties:
methods:
//添加自定义调度接口
[id(1000)] void SetWnd(long* pBuffer);//删除指定影像
}[/align]
然后在调用ocx的项目中 自己写一个帮助类
class CHelpWnd : public CWnd
{
//构造函数
//look this
void SetWnd(long *pWnd)
{
static BYTE pbParamInfo[] = VTS_PI4;
InvokeHelper(1000,DISPATCH_METHOD,VT_EMPTY,NULL,pbParamInfo,pWnd);
}
}
别忘了 绑定 窗口
CHelpWnd m_OcxWnd;
DDX_Control(pDX,ID_OCX,m_OcxWnd);
m_OcxWnd.SetWnd((long*)this); // 搞定
还有 这个代码 我可没测试啊 自己试试 有错误 也不会是 大的错误。
如果非要用 FireEvent(1000,EVENT_PARAM(VTS_NONE)); 函数
我也可以给你一份 MFC 中捕获此消息的分析。
据我的了解 侧消息内部也无非是vc当中messag的一种原理。
所以我就尝试用了 CWnd当中的 ON_MESSAGE 消息处理系统来解决。
至于为什么选择CWnd 是因为它既然可以调用OCX函数 那么就一定会有方法来捕获。
所以根据这个原理 我就尝试了很多张方法,终于 在我试用到DECLARE_EVENTSINK_MAP
时间映射的时候发现 终于得到了消息,下面就是我的处理方法。
class CMYCtrl
{
CWnd *pWnd;
写一个事件
void PostEvent()
{
//事件通知
FireEvent(1000,EVENT_PARAM(VTS_NONE));
}
}
class COcxLoadDlg : public CDialog //CDialog 本身就是CWnd派生的 你懂得
{
.......................
.......................
//首先我们要定义事件消息映射表
DECLARE_EVENTSINK_MAP()
//接着 我们就要捕获 FireEvent(1000,EVENT_PARAM(VTS_NONE)); 这个消息
afx_msg void OnGetEndEvent()
{
AfxMessageBox(L"成功接受!");
}
};
//实现事件消息
BEGIN_EVENTSINK_MAP(COcxLoadDlg , CDialog) //注意1000 无论是传入函数捕获,都要ID对应
ON_EVENT(COcxLoadDlg ,IDC_OCX_ID, 1000 , PostEvent, VTS_NONE) //VTS_NONE 无返回值类型
END_EVENTSINK_MAP()
//接下来只要OCX的
CMYCtrl 类的 PostEvent() 就从OCX当总投递出一条event_id为1000的无返回值类型函数(相当于OnGetEndEvent)
//梦寐以求的messagebox 就会提示出来(成功接受)!!!
//下面有一个CMYCtrl 有一个事件映射列表
BEGIN_EVENT_MAP(CMYCtrl , COleControl)
//EVENT_CUSTOM("PostEvent", PostEvent, VTS_NONE)
END_EVENT_MAP()
起初我以为 这个PostEvent 函数必须要映射才会有消息。但是经过我的尝试 即使注释
也会接受到消息。 所以我就猜想 是不是 他是提供OCX(ActiveX)控件属性页里面显示出来PostEvent的
一个时间映射,最后我尝试了 但是右键OCX窗口 添加事件处理 并没有发现PostEvent函数 好失望。
到现在我还是没有能完全理解 这个 到底是嘛意思。
完了 不说了 楼主请试试把,。。。 两种方法都是好用的。
解决思路3:
--------其他类中定义----------
头文件中定义:
//目的:定义容器类CSuperHolterCtrl的对象指针,用于向容器CSuperHolterCtrl发送消息。
COleControl* pOcxControl;
.cpp文件实现://目的:设置并传递容器类CSuperHolterCtrl的对象指针,用于向容器CSuperHolterCtrl发送消息。
void CUICtrView::SetOcxControlContainer(COleControl* pOleControl)
{
pOcxControl = pOleControl;
}
在其他地方使用:
//目的:患者报告生成完成时通知调用者。
pOcxControl->PostMessage(OCX_EVENT_FINISHREPORT, 0, 0);//发送给父窗口
在CSuperHolterCtrl文件中定义:
//目的:患者报告生成完成时通知调用者。
ON_MESSAGE(OCX_EVENT_FINISHREPORT, OnFinishReport)
在CSuperHolterCtrl文件中实现:
CUICtrView *pView = (CUICtrView *)pFrame->GetActiveView();//取得窗口指针
pView->SetOcxControlContainer(this);