我在写一个ocx控件。在控件内有一个自定义的类,处理逻辑相关的事件,比如MyClass.h和MyClass.cpp,当有人call我时,我就能在MyClass的线程内得到信息,现在我要通知给使用我这个ocx的用户,告诉用户有人call你。我是想添加个OnRing事件,只要用户在使用ocx时响应这个OnRing事件,就知道有没有人call他。问题是:ocx添加事件OnRing会自动添加到CxxxCtrl这个控件类内,我在MyClass内知道有人call了,我怎么去调CxxxCtrl内的OnRing?
CxxxCtrl里面有我的类的一个实例。
MyClass
{
void Call(LPCTSTR strDestURL, USHORT nVideoNum);
OnRing();
}//CxxxCtrl
CxxxCtrl
{ CMyClass m_myClass;
LONG Call(LPCTSTR strDestURL, USHORT nVideoNum);
void OnRing(void)
{
FireEvent(eventidOnRing, EVENT_PARAM(VTS_NONE));
}
}LONG CxxxCtrl::Call(LPCTSTR strDestURL, USHORT nVideoNum)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()); // TODO: 在此添加调度处理程序代码
m_myClass.Call(strDestURL, nVideoNum); return 0;
}
现在OnRing了,我要通知ocx的用户,我就要调用CxxxCtrl的OnRing,直接调用是不行的,通过回调用是一种方法,我现在想问的是有没有ocx支持的更方便的方法?
CMyClass的方法。
最差也可以用全局变量传递啊!
2、把protected改成public
3、友元
{
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 , PostScanImageEnd, 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函数 好失望。
到现在我还是没有能完全理解 这个 到底是嘛意思。
完了 不说了 楼主请试试把, 两种方法都是好用的。
BEGIN_EVENTSINK_MAP(COcxLoadDlg , CDialog) //注意1000 无论是传入函数捕获,都要ID对应
ON_EVENT(COcxLoadDlg ,IDC_OCX_ID, 1000 , PostScanImageEnd, VTS_NONE) //VTS_NONE 无返回值类型
END_EVENTSINK_MAP()这句是这样的 /实现时间消息
BEGIN_EVENTSINK_MAP(COcxLoadDlg , CDialog) //注意1000 无论是传入函数捕获,都要ID对应
ON_EVENT(COcxLoadDlg ,IDC_OCX_ID, 1000 , PostEvent, VTS_NONE) //VTS_NONE 无返回值类型
END_EVENTSINK_MAP()