none
請問VC++ 2015 如何註用 COM DLL 的 CALLBACK EVENT RRS feed

  • 問題

  • 我在

    stdafx.h 中加入了

    #import  "SCOM.DLL"

    之後,

    可以在主程式中,使用

    HRESULT hr = CoInitialize(0);

    啟動 COM

    再用

    SCOMLib::ISCOM1Ptr ISCOMObj;

    ISCOMObj.CreateInstance(__uuidof(SCOMLib::SCOM1));

    建立 COM 物件,之後就可以用

    ISCOMObj->func1(...) 來呼叫 SCOMLib 中 SCOM1 的 function 了

    現在 SCOMLib 中 SCOM2 有一個  Event  :  OnData( );

    在 tlh 中是顯示如下:

    struct __declspec(uuid("xxx"))
    _ISCOM2Events : IDispatch
    {
        //
        // Wrapper methods for error-handling
        //

        // Methods:
        HRESULT OnData (
            long nCode,
            long nSocketCode );

    }

    也寫好了我的 Event function :

    HRESULT OnData(long nCode, long nSocketCode) {

       int i = 1;

    }

    請問我如何註冊這個 OnData()

    能讓 SCOM2 發生 EVENT 時會 呼叫我的

    OnData() function


    kuolung

    2016年8月19日 下午 11:12

解答

所有回覆

  • 您可以參考這篇文件的做法:

    Handling VB ActiveX Events in Visual C++ client

    • 已標示為解答 kuolung 2016年8月23日 上午 02:39
    2016年8月20日 下午 12:33
  • 謝謝您,這一篇確實有我需要的文件和參考,

    但是我用 VS 2015 的 VC++ 參考它的作法時,有一些問題

    1. 我有找到在 C:\Program Files (x86)\Windows Kits\8.1\bin\x64\oleview.exe

       去參考我的 .dll 檔 產生 -> IDL 加入 Project 中,去 compile 加入的 idl

      出現以下錯誤

      嚴重性    程式碼    說明    專案    檔案    行    隱藏項目狀態
    錯誤    MIDL2025    syntax error : expecting a type specification near "SKFOREIGN"    VBComClient    C:\COM\x64\VBCOM.IDL    248    
    錯誤    MIDL2026    cannot recover from earlier syntax errors; aborting compilation    VBComClient    C:\COM\x64\VBCOM.IDL    248

    可是我去查看 IDL 檔中,有 SKFOREIGN 的定義,只是放在後面

    請問這要如何解決

    補充一下,

    IDL 的內容有

    Created by MIDL version 7.00.0555 at Tue May 24 11:54:15 2016

    請問這個版配 vc++ 2015 對嗎


    kuolung


    • 已編輯 kuolung 2016年8月22日 下午 11:50
    2016年8月22日 下午 11:45
  • 參考了那篇文章後,已經知道其中的做法

    先建一個 class 來收 evnet

    class CenterEvent : public CCmdTarget {

    }

    在 CenterEvent 中的加入

    INTERFACE_PART 的宣告

        INTERFACE_PART(CenterEvent, __uuidof(VBCOM::_ICenterEvents), Dispatch)

    之後在主程式中加入

    hr = CoCreateInstance(__uuidof(VBCOMb::_ICenterEvents), NULL, CLSCTX_INPROC_SERVER,
                IID_IDispatch, (void**)&m_pCenterSrc);

    LPUNKNOWN m_pUnk = m_pCenter->GetIDispatch(FALSE);

    AfxConnectionAdvise(m_pCenterSrc, __uuidof(VBCOM::_ICenterEvents), m_pUnk, FALSE, &m_CenterCookie);

    好像這樣就可以收到 EVENT 了

    只是因為中間的 CoCreateInstance ( -> 要用 IID

    AfxConnectionAdvise( -> 要用 CLSIS

    這兩值還不知道如何查,所以還測不出來

    主要的差別,是因為改用 VC++ 2015 可以直接 import "VBCOM.dll" 產生

    .tli .tlh  .tbl 這些檔案,就可以直接用了,

    但也就不知道 這些 IID , CLSID , UUID 的存放位置了


    kuolung


    • 已編輯 kuolung 2016年8月23日 上午 02:42
    2016年8月23日 上午 02:39
  • 再補充一下,

    https://support.microsoft.com/en-us/kb/181845

    有比較詳細的說明,

    但是有一點比較覺得不方便的,

    這些範例都是很久以前的 FOR .NET OR VB 6.0 的

    不知道有沒有人有比較新的範例如 VS 2013/2015 新的做

    因為說明文件中有說,新版的 VS 會有 SINK INTERFACE 的 wizard 來做這些事情,

    Microsoft Foundation Classes (MFC) has wizard support to add sink interfaces for ActiveX controls.

    但是找不到 for vs 2013/2015 的新範例 ,和做法


    kuolung

    2016年8月23日 上午 03:07