• ATL 连接点例子(atlduck)


    一.客户端获取连接点IConnectionPoint

    LRESULT CMyDlg::OnCreateDoDuck(WORD wNotifyCode, WORD wID, HWND hwndCtl, BOOL& bHandled)
    {
    
        HRESULT hr;
        IUnknown* pUnk = NULL;
        IConnectionPointContainer* pConnPtContainer = NULL;
        hr = CoCreateInstance(CLSID_DuckDoer, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pUnk);
        if (!SUCCEEDED(hr))
        {
            ::MessageBox(m_hWnd, _T("Could not create DuckDoer object.  Make sure the server is registered."),
                _T("Object Instantiation Error."), MB_OK | MB_ICONINFORMATION);
    
            return 0L;
        }
    
        ATLENSURE(pUnk != NULL);
    
        hr = pUnk->QueryInterface(IID_IConnectionPointContainer, (void**)&pConnPtContainer);
        ATLENSURE(SUCCEEDED(hr) && pConnPtContainer != NULL);
        hr = pConnPtContainer->FindConnectionPoint(IID_IDuckInt, &m_pIDuckConnectionPoint);
        ATLENSURE(SUCCEEDED(hr) && m_pIDuckConnectionPoint != NULL);
        ATLENSURE(m_pDuckInt != NULL);
        pUnk->Release();
        pConnPtContainer->Release();
    
        return 0L;
    }
    

    二.服务器和客户端都是一个exe,所以此时服务器会开启一个窗体

    class CAtlDuckModule : public CAtlExeModuleT< CAtlDuckModule >
    {
    public:
        DECLARE_REGISTRY_APPID_RESOURCEID(IDR_Atlduck, "{120B7294-65BF-11D0-9DDC-00A0C9034892}")
        DECLARE_LIBID(LIBID_ATLDUCKLib)
        
        HRESULT PreMessageLoop(int nShowCmd)
        {
            _ASSERT(CDuckDoer::m_pDlg == NULL);
            CDuckDoer::m_pDlg = new CDuckDoerDlg();
            CDuckDoer::m_pDlg->Create(NULL);
            CDuckDoer::m_pDlg->ShowWindow(SW_SHOWNORMAL);
            _ASSERT(CDuckDoer::m_pDlg != NULL);
            
            HRESULT hr = CAtlExeModuleT<CAtlDuckModule>::PreMessageLoop(nShowCmd);
            if (FAILED(hr))
                return hr;
        
    
            
            return S_OK;
        }
    };
    

    三.客户端发送服务端一个接收器(调用Advise)

    LRESULT CMyDlg::OnAdvise(WORD , WORD wID, HWND , BOOL& )
    {
        HRESULT hr;
        ATLENSURE(m_pIDuckConnectionPoint != NULL);
        hr = m_pIDuckConnectionPoint->Advise((IUnknown*)m_pDuckInt, &m_dwCookie);
          return 0;
    }
    

    四.服务器端将此接收器存放起来

    STDMETHODIMP CDuckDoer::Advise(IUnknown* pUnk, DWORD* pdwCookie)
    {
        if (!m_bLocked)  // lock the server on the first advise received
        {
            ((IDuckDoer*)this)->AddRef();
            m_bLocked = TRUE;
        }
    
        HRESULT hr = CProxyIDuckInt<CDuckDoer>::Advise(pUnk, pdwCookie);
        if (SUCCEEDED(hr))
        {
          …    
    } return hr; }

    细节在CProxyIDuckInt<CDuckDoer>::Advise内部

    五.服务器端通知客户端

    LRESULT CDuckDoerDlg::OnQuack(WORD , WORD , HWND , BOOL& )
    {
        USES_CONVERSION;
        TCHAR szWhosCalling[100];
        _tcscpy_s(szWhosCalling, 100, _T("Server Quacking for Sink No. XX."));
        CComBSTR szOut(szWhosCalling);
        m_pObject->Fire_Quack(szOut);
        return 1;
    }
    

    Fire_Quack代码可以自动生成,客户端必须有一个类实现了IDuckInt接口(就是通过调用Advise传入的接口)

  • 相关阅读:
    解决SpringMVC中jsp页面无法加载js,css,jpg中的信息
    浅谈SpringMVC
    Java垃圾回收与算法
    Linux常见命令
    Warm_up(HCTF_2018)
    house_of_storm 详解
    malloc 函数分析 glibc2.23
    Fastbin attack 总结
    Unlink学习总结
    xman_2019_format(非栈上格式化字符串仅一次利用的爆破)
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/2108390.html
Copyright © 2020-2023  润新知