新建ATL Project,工程名命名為MyAtlCom;
出現工程 向導,一路“Next”;
Add class,點擊添加 ATL Simple Object , 類名CStatistic, 接口IStatistic,“Next”到底;
打開類視圖,可以看到ATLCOM下新增了CStatistic類和IStatistic接口;
在ISample上右鍵,Add->Add Method (或Add Property...)來豐富接口了,然后在CStatistic內實現相應的的方法(屬性)即可。
增加一個Add方法:
STDMETHOD(Add)(LONG nNum1, LONG nNUm2, LONG* nRet); STDMETHODIMP CStatistic::Add(LONG nNum1, LONG nNUm2, LONG* nRet) { // TODO: Add your implementation code here *nRet = nNum1 + nNUm2; return S_OK; }
編譯運行,生成MyAtlCom.dll,並注冊到Windows中去。
下面,測試上述生成的COM組件MyAtlCom.dll
新建一個Win32控制台應用程序,取名MyAtlComTest
#include "stdafx.h" #include<iostream> using namespace std; #include "../MyAtlCom/MyAtlCom_i.h" #include "../MyAtlCom/MyAtlCom_i.c" int _tmain(int argc, _TCHAR* argv[]) { IStatistic * pIStatisticATL = NULL; HRESULT hr = CoInitialize(NULL); //初始化COM //使用SUCCEEDED宏並檢查我們是否能得到一個接口指針 if(SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_Statistic, NULL, CLSCTX_INPROC_SERVER, IID_IStatistic, (void **)&pIStatisticATL); //如果成功,則調用Add方法,否則顯示相應的出錯信息 if(SUCCEEDED(hr)) { LONG nReturnValue; pIStatisticATL->Add(8, 9, &nReturnValue); cout << "The Add result for 8 + 9 is " << nReturnValue << endl; pIStatisticATL->Release(); } else { cout << "CoCreateInstance Failed." << endl; } } CoUninitialize(); //釋放COM return 0; }
結果:
或使用IDispath接口
#include "stdafx.h" #include <atlbase.h> #include <atlcom.h> #include <iostream> using namespace std; #include "../MyAtlCom/MyAtlCom_i.h" #include "../MyAtlCom/MyAtlCom_i.c" int _tmain(int argc, _TCHAR* argv[]) { CoInitializeEx(NULL, COINIT_MULTITHREADED); CComPtr<IStatistic> spCar; spCar.CoCreateInstance(CLSID_Statistic); // use IDispatch DISPID PropertyID[1] = {0}; BSTR PropName[1]; PropName[0] = SysAllocString(L"Add"); HRESULT hr = spCar->GetIDsOfNames(IID_NULL, PropName, 1, LOCALE_SYSTEM_DEFAULT, PropertyID); SysFreeString(PropName[0]); CComVariant avarParams[3]; avarParams[2].vt = VT_I4; avarParams[2] = 8; avarParams[1].vt = VT_I4; avarParams[1] = 9; LONG vTotal = 0; avarParams[0].vt = VT_I4 | VT_BYREF; avarParams[0] = &vTotal; DISPPARAMS params = { avarParams, NULL, // Dispatch identifiers of named arguments. 3, // Number of arguments. 0 }; // Number of named arguments. CComVariant Result; hr = spCar->Invoke(PropertyID[0], IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &Result, NULL, NULL); cout << "The Add function result is " << (int)(*params.rgvarg->plVal) << endl; spCar.Release(); CoUninitialize();
cin.get();
return 0;
}
結果:
使用COleDispatchDriver封裝類
#include "stdafx.h" #include <atlbase.h> #include <atlcom.h> #include <iostream> using namespace std; #include "../MyAtlCom/MyAtlCom_i.h" #include "../MyAtlCom/MyAtlCom_i.c" int _tmain(int argc, _TCHAR* argv[]) { CoInitialize(NULL); COleDispatchDriver disp; COleException *e = new COleException; try { // Create instance of MyAtlCom Control by using CLSID. if (disp.CreateDispatch(CLSID_Statistic, e)) { static BYTE params[] = VTS_I4 VTS_I4 VTS_I4; LONG nNum1 = 4; LONG nNum2 = 5; LONG nAdd = 0; disp.InvokeHelper(0x01, DISPATCH_METHOD, VT_EMPTY, NULL, params, nNum1, nNum2, &nAdd); if (nAdd == nNum1 + nNum2) AfxMessageBox(_T("InvokerHelper successed!")); else { CString cStr; cStr.Format(_T("InvokerHelper Failed! Error %d"), GetLastError()); AfxMessageBox(cStr); } } else throw e; } //Catch control-specific exceptions. catch (COleDispatchException * e) { CString cStr; if (!e->m_strSource.IsEmpty()) cStr = e->m_strSource + " - "; if (!e->m_strDescription.IsEmpty()) cStr += e->m_strDescription; else cStr += "unknown error"; AfxMessageBox(cStr, MB_OK, (e->m_strHelpFile.IsEmpty())? 0:e->m_dwHelpContext); e->Delete(); } e->Delete(); CoUninitialize(); cin.get(); return 0; }
本文源碼下載:僅供學習參考
百度雲:http://pan.baidu.com/s/1pL13D03 密碼:88ix