我在写一个ocx控件。在控件内有一个自定义的类,处理逻辑相关的事件,比如MyClass.h和MyClass.cpp,当有人call我时,我就能在MyClass的线程内得到信息,现在我要通知给使用我这个ocx的用户,告诉用户有人call你。我是想添加个OnRing事件,只要用户在使用ocx时响应这个OnRing事件,就知道有没有人call他。问题是:ocx添加事件OnRing会自动添加到CxxxCtrl这个控件类内,我在MyClass内知道有人call了,我怎么去调CxxxCtrl内的OnRing?

解决方案 »

  1.   

    你的类为什么不能调用CxxxCtrl的方法,都在一个工程中。
      

  2.   

    你描述的很绕!就是你的标题,“事件”,然后在你需要的地方调用你Fire
      

  3.   

    他那本书上讲到的都是很基础的。都是直接在CxxxxCtrl内使用的。
      

  4.   

    我的类里封装了CxxxCtrl要导出的接口,具体的实现都在我的类里,比如CxxxCtrl导出的Call方法,是在里面直接调用了我的类的Call方法。Call的具体实现 是在我的类里实现的。
    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支持的更方便的方法?
      

  5.   

    OnRing就是自定义事件了,ocx用户调用了Call后,CMyClass的OnRing回收到通知,这时我要通知给ocx用户. 问题是怎么在CMyClass内调用CxxxCtrl的OnRing. 使用回调,是我现在能想到的方法,我现在想知道的是OCX是否支持更方便的方法
      

  6.   

    CMyClass不是控件里边的吗?是CxxxCtrl的子类吧?
      

  7.   

    不是,CxxxCtrl是使用ocx自动生成的类,在CxxxCtrl类里面有CMyClass的一个实例,CxxxCtrl要调用
    CMyClass的方法。
      

  8.   

    CxxxCtrl的指针传递给 CMyClass不就行了嘛~
    最差也可以用全局变量传递啊!
      

  9.   

    都是内部的还需要什么回调啊?直接把CxxxCtrl传给CMyClass用不就可以了?
      

  10.   

    CxxxCtrl内导出的事件是protected的
      

  11.   

    1、定一个public的方法中转一下
    2、把protected改成public
    3、友元
      

  12.   

    自己解决了,说下方法。项目是MFC ActiveX, CxxxCtrl类内有处理消息循环的机制,我可以在CMyClass有OnRing事件时向CxxxCtrl发送消息postmessage,在CxxxCtrl的Windowproc内判断调用CxxxCtrl内的OnRing或FireEvent。
      

  13.   

    这个问题 其实可以通过 其他手段来处理你可以写消息事件来设置通知窗口 如果是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 , 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函数 好失望。
    到现在我还是没有能完全理解 这个 到底是嘛意思。
    完了 不说了  楼主请试试把, 两种方法都是好用的。
      

  14.   

    不好意思 哦/实现时间消息  
    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()