/////////////////////////////////////////////////////////////// // client.cpp - client for component Dispatch1 // // // // Platform: Micron Dual Pentium 200, WinNT 4.0, SP3 // // Application: Demonstration for CSE791 - Distrib. Objs // // Authors: Eddon & Eddon, Inside Distributed COM, // // Microsoft Press, 1998 // // Modified: Jim Fawcett, Syracuse Univ, CST 2-187 // // (315) 443-3948, fawcett@ecs.syr.edu // /////////////////////////////////////////////////////////////// #include #include #include #include "dispatch1.h" using namespace std; int main() { cout << "\n Testing automation component's custom interface " << "\n =================================================\n" << endl; // Initialize COM Library CoInitialize(NULL) ; string prefix = " Client: \t\t"; cout << prefix + "Call to CoCreateInstance to get interface ISum." << endl; ISum* pISum = NULL ; HRESULT hr = ::CoCreateInstance( CLSID_Sum, NULL, CLSCTX_INPROC_SERVER, IID_ISum, (void**)&pISum ); if (SUCCEEDED(hr)) { cout << prefix + "Succeeded getting ISum." << endl; int z; hr = pISum->Sum(3,4,&z) ; if(SUCCEEDED(hr)) cout << prefix + "received " << z << " as sum of 3 and 4" << endl; else cout << prefix + "Client: call to Sum failed" << endl; } else { cout << prefix + "Could not get interface ISum." << endl; } cout << prefix + "Release ISum interface." << "\n\n"; pISum->Release() ; // cout << "\n Testing automation component's IDispatch interface " << "\n ====================================================\n" << endl; // get CLSID from ProgID CLSID clsid; ::CLSIDFromProgID(L"Dispatch1.Sum",&clsid); // get pointer to IDispatch cout << prefix + "Call to CoCreateInstance to get interface IDispatch." << endl; IDispatch *pDispatch; hr = ::CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void**)&pDispatch ); if (SUCCEEDED(hr)) { cout << prefix + "Succeeded getting IDispatch." << endl; // get dispatch ID from method name DISPID dispid; WCHAR *szName = L"Sum"; hr = pDispatch->GetIDsOfNames( IID_NULL, // reserved &szName, // name array 1, // number of names ::GetUserDefaultLCID(), // get default locale &dispid // store dispatch ID here ); if(FAILED(hr)) { cout << prefix + "Failed to map interface name to dispatch ID" << "\n\n"; pDispatch->Release(); ::CoUninitialize(); return 1; } else cout << prefix + "Succeeded mapping method name to dispatch ID" << endl; // // pack method arguments in DISPPARAMS struct VARIANTARG args[2]; int values[2] = { 2, 3 }; DISPPARAMS params = { args, NULL, 2, 0 }; int i; for(i=0; i<2; i++) { ::VariantInit(&args[i]); args[i].vt = VT_I4; V_I4(&args[i]) = values[i]; // V_I4 defined in oleauto.h as: // V_I4(x) is V_UNION(x,lval) is ((x)->n1.n2.n3.lval) // comparing this to Variant structure we see that it // simply accesses the lval data type member } // call IDispatch::invoke(...) to invoke Sum method VARIANT result; ::VariantInit(&result); pDispatch->Invoke( dispid, // id of method to invoke, e.g., Sum IID_NULL, // reserved ::GetUserDefaultLCID(), // default locale DISPATCH_METHOD, // this is a method, not a property ¶ms, // method parameters &result, // place to return result NULL, // no error info requested NULL // " ); if(FAILED(hr)) { cout << prefix + "call to invoke method failed" << "\n\n"; pDispatch->Release(); ::CoUninitialize(); return 1; } else cout << prefix + "Call to invoke method succeeded" << endl; // unpack result long lResult = V_I4(&result); cout << prefix + "received " << lResult << " as sum of " << values[0] << " and " << values[1] << endl; // return any storage allocated to args and result ::VariantClear(&args[0]); ::VariantClear(&args[1]); ::VariantClear(&result); } // else { cout << prefix + "Could not get interface IDispatch." << endl; } cout << prefix + "Release IDispatch interface." << endl; pDispatch->Release(); // Uninitialize COM Library CoUninitialize() ; cout << "\n\n"; return 0 ; }