我动态的创建了一个ActiveX控件,是当按下一个按键后才Create的。 这个控件可以发出事件,我想在dialog里面响应这些事件。但努力了一个还是失败了。我是这样做的。在dialog里面放进一个ActiveX控件。然后所有做的事是跟我的想动态添加的一样。再在dialog里面把那个ActiveX控件删除了。然后在create里面的ID就用我删除了的那个ID。   dialog里面还有一个相同的ActiceX控件的。不过用的ID是不同的。麻烦知道我怎样错的人帮我找一下问题的所在。我想这是很简单的。我新学。谢谢了!

解决方案 »

  1.   

    1)实现EventSink类;  
    class   CYourEventSink   :   public   IDispatch  
    {  
         ...  
    }  
       
     2)挂接你的Sink类:  
     CYourCtrl ctl; // 控件
    IConnectionPoint   *pCPEvents = NULL;  
    CYourEventSink   Sink;                    
    DWORD   dwEventsCookie;  
    HRESULT   hr = S_OK;  
    hr = ctl.Create(.....);
    IConnectionPointContainer   *pCPCtr   =   NULL;  
    hr   =   ctl.QueryInterface(  IID_IConnectionPointContainer,  (void   **)&pCPCtr);  
    hr   =   ctl.FindConnectionPoint(__uuidof(IYourCtlEvent), &pCPEvents);  
    hr   =   pCPEvents->Advise(&Sink,   &dwEventsCookie);if   (pCPCtr!=NULL)   pCPCtr->Release();  
       
    3)使用完后释放  
    hr   =   pCPEvents->UnAdvise(dwEventsCookie);     
      

  2.   

    BEGIN_EVENTSINK_MAP(CClockTestDlg, CDialog)
        //{{AFX_EVENTSINK_MAP(CClockTestDlg)
    ON_EVENT(CClockTestDlg, IDC_CLOCKCTRL, -600 /* Click */, OnClickClockctrl, VTS_NONE)
    ON_EVENT(CClockTestDlg, IDC_CLOCKCTRL, 1 /* NewMinute */, OnNewMinuteClockctrl, VTS_NONE)
    ON_EVENT(CClockTestDlg, IDC_CLOCKCTRL_NEW, -600 /* Click */, OnClickClockctrlNew, VTS_NONE)
    //}}AFX_EVENTSINK_MAP
    END_EVENTSINK_MAP()
    //事件的绑定是在上面所示的代吗里面的吧?但我创建是在click button后才有的,可以在click button的响应函数里面加吗?
    // 谢谢
    //
      

  3.   

    楼主上面的代码是对的 具体不多说了,楼主去看一下http://blog.csdn.net/Tinary3v0/archive/2008/11/17/3321610.aspx中 6.添加MAPX控件的事件响应中有关部分 可以把MapX看做是你自己的控件。
    主要是看事件链接过程。如果楼主动态生成的控件只有一个的话 那问题就好解决了 指定了ID后 事件和响应函数之间通过这个ID就可以搞定了。如果动态生成的控件是多个 只要是定好ID 依次添加就可以了
    要是随机生成控件ID的话就比较麻烦了 需要使用楼上几位高手所说的连接点等 我就不太懂了。
      

  4.   

    这个映射只是事件到回调函数的映射,还不是绑定,绑定需要调用IConnectionPoint:;Advise
      

  5.   


    请问可不可以给一个代码的例子?我查了一下MSDN,没有例子我不太会。 谢谢
      

  6.   


    你这个我也不能做出来啊。你说的啊。在OnCreate里面就创建了的。但是我的是在按下一个button后才创建的。我的做法与你的那个贴相差不多,但是运行时出出错。
      

  7.   

    上面的例子是正确的,应该你实现哪里出了问题,再查一下吧。我以前也象你这样做过。过程 就是http://blog.csdn.net/Tinary3v0/archive/2008/11/17/3321610.aspx这里提到的。
      

  8.   

    自己派生一个CCmdTarget类,使用连接点获取消息与CCmdTarget派生类连接起来就可以了.
      

  9.   


    我不否认6楼所说的方法可行。但是要的不是我的要求啊。6楼的我刚才试过了,可以。但是我想试的是在我按下一个button后才创建一个新的clock ActiceX控件,这个新的也能响应我所设的消息。 有没有人提供进一步和方法? 谢谢
      

  10.   


    ///////////////////////////////////////
    void CClockTestDlg::OnButtonHello() 
    {
    // TODO: Add your control notification handler code here
    m_clock.Hello();

    if(!dynamic_clock.m_hWnd)
    {
      dynamic_clock.Create("Dynamic Clock",WS_CHILD|WS_VISIBLE,CRect(0,0,100,150),this,IDC_CLOCKCTRL_NEW);
      dynamic_clock.SetForeColor(RGB(255,23,45));
    }
    }
    ////////////////////////////////////////////////
    int CClockTestDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
    if (CDialog::OnCreate(lpCreateStruct) == -1)
    return -1;

    // TODO: Add your specialized creation code here

    if(!dynamic_clock.m_hWnd)
    {
      dynamic_clock.Create("Dynamic Clock",WS_CHILD|WS_VISIBLE,CRect(0,0,100,150),this,IDC_CLOCKCTRL_NEW);
      dynamic_clock.SetForeColor(RGB(255,23,45));
    }
    return 0;
    }//我再试过了,其他的一样,只是上面的两段代码不一样,如果是上面第一段的代码就会出错,是编译时没有问题,运行不了,出错。
    //如果是第二段的代码就可以正常运行。
    //有谁知道是怎么回事吗?谢谢!
      

  11.   

    按照你方法试了一下,需要把下面函数里的dynamic_clock对应的那一行注释掉,这是因为dlg create之后会自动调用这个函数,你上面所说的后者可以而前者不可以是因为运行到DDX_Control(pDX, IDC_CLOCKCTRL_NEW, dynamic_clock);时后者已经创建控件完毕,而前者尚未创建控件导致出错
    void CXXXDlg::DoDataExchange(CDataExchange* pDX)
    {
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CTest_dlgDlg)
    DDX_Control(pDX, IDC_CLOCKCTRL_NEW, dynamic_clock);//这一行要注释掉
    //}}AFX_DATA_MAP
    }