//////////////////////////////////////////////////////////////////////////////////////////////////
// function: cmclientdlg::execute()
//
// parameters: no parameters
//
// description: pass the parameters and invoke the operation, get the result and update the
// parameters and the result value
// returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void cmclientdlg::execute()
{
uses_conversion;
disablebuttons();
htreeitem hitem;
htreeitem hport;
htreeitem hservice;
dispparams parms;
variant result;
variant vtempvariable;
ccomptr<isoapclient> pclient = null;
hresult hr = s_ok;
bstr bstrport = 0;
bstr bstrservice = 0;
bstr bstrwsdlfilename = 0;
bstr bstrwsmlfilename = 0;
lvitem item;
lvitem item1;
int nnumparameters;
int ncounter;
int ncount;
dispid dispidfn;
wchar *pstrfunctionname;
char name[1024] ;
excepinfo excepinfo;
vartype vt = vt_empty;
hitem = m_treectrl.getselecteditem();
dispidfn = 0;
excepinfo.wcode = 1001;
excepinfo.wreserved = 0;
excepinfo.bstrsource = 0;
excepinfo.bstrdescription = 0;
excepinfo.bstrhelpfile = 0;
excepinfo.dwhelpcontext = 0;
excepinfo.pvreserved = 0;
excepinfo.pfndeferredfillin = 0;
excepinfo.scode = 0;
variant variantbstrtemp;
variant *parg = 0;
variant *pref = 0;
smisinputenum isinput;
nnumparameters = ncountparameter();
if (nnumparameters != -1)
{
parg = new variant[nnumparameters];
pref = new variant[nnumparameters];
}
else
msg("could not get parameters from parameter list!");
if ((!parg) || (!pref))
msg("there is no enough memory!");
if (m_treectrl.itemhaschildren(hitem))
msg("please select an operation!");
hr = cocreateinstance(__uuidof(soapclient), null, clsctx_inproc_server, __uuidof(isoapclient),
(void **)&pclient);
check_hresult(hr, "can not create the object of the clsid_soapclient");
if (!pclient)
msg("can not create the object of the clsid_soapclient!");
// we need to have wsdl file and port and service name for mssoapinit
hport = m_treectrl.getparentitem(hitem);
if (!hport)
msg("can not get port!");
bstrport = m_treectrl.getitemtext(hport).allocsysstring();
if (bstrport == null)
msg("can not get port name!");
hservice = m_treectrl.getparentitem(hport);
if (!hservice)
msg("can not get service !");
bstrservice = m_treectrl.getitemtext(hservice).allocsysstring();
if (bstrservice == null)
msg("can not get service name!");
bstrwsdlfilename = m_strurl.allocsysstring();
if (bstrwsdlfilename == null)
msg("can not get wsdl file name!");
hr = pclient->mssoapinit(bstrwsdlfilename,bstrservice,bstrport,bstrwsmlfilename);
check_hresult(hr, "soap initiation failed");
// get the selected functions name
pstrfunctionname = m_treectrl.getitemtext(hitem).allocsysstring();
if (pstrfunctionname == null)
msg("could not get function name!");
parms.cargs = nnumparameters ;
parms.cnamedargs = 0;
parms.rgdispidnamedargs = 0;
//there is a pass by ref, and i will use pref as parameter list
parms.rgvarg = pref;
::variantinit(&result);
::variantinit(&vtempvariable);
ncount = 0;
// the loop should be 'number of parameters' times
for (ncounter=0; ncounter < m_parameters.getitemcount() ; ncounter ++)
{
// i need to get the value of parameter and its type
assignitem(&item, lvif_param,ncounter,0,0,0);
assignitem(&item1, lvif_text,ncounter,2,name,sizeof(name));
if (m_parameters.getitem(&item) == 0)
msg("could not get item!");
if (m_parameters.getitem(&item1) == 0)
msg("could not get item!");
// we will not fill the arguments with result
reinterpret_cast<isoapmapper *>(item.lparam)->get_isinput(&isinput);
if (isinput != smoutput)
{
::variantinit(&parg[ncount]);
// i have to fill this array in reverse order bacause the server expects it in reverse order
::variantinit(&pref[nnumparameters - ncount -1]);
// i keep the parameter as bstr
vtempvariable.vt = vt_bstr;
vtempvariable.bstrval = ::sysallocstring(a2w(item1.psztext));
// the conversion for type and value of parameter is done
// the value with correct type and value is taken into parg
long ltype;
hr = (reinterpret_cast<isoapmapper*>(item.lparam))->get_varianttype(<ype);
check_hresult(hr, "could not get variant type");
hr = ::variantchangetype(&parg[ncount],&vtempvariable,variant_nouseroverride, (unsigned short) ltype);
check_hresult(hr, "can not convert variant type! either no function selected or parameter is wrong or empty");
::variantclear(&vtempvariable);
// assign the correct parameter to pref and indicate it is byref
pref[nnumparameters - ncount -1 ].vt = parg[ncount].vt | vt_byref;
assignpref(&pref[nnumparameters - ncount -1],&parg[ncount]);
ncount ++;
}
}
// get the id of operation
hr = pclient->getidsofnames(iid_null, &pstrfunctionname, 1, locale_system_default, &dispidfn);
check_hresult(hr, "taking ids failed!");
// calling the operation
::variantclear(&result);
hr = pclient->invoke(dispidfn, iid_null, locale_system_default, dispatch_method, &parms,
&result, &excepinfo, 0);
check_hresult(hr, "function call failed!");
::variantinit(&variantbstrtemp);
// update the results
for(ncounter = 0; ncounter < m_parameters.getitemcount() ; ncounter++)
{
if (ncounter < nnumparameters)
{
hr = ::variantchangetype(&variantbstrtemp,&parg[ncounter],variant_nouseroverride,vt_bstr);
}
else
{
hr = ::variantchangetype(&variantbstrtemp,&result,variant_nouseroverride,vt_bstr);
}
check_hresult(hr, "variant could not be converted");
cstring text(variantbstrtemp.bstrval);
assignitem(&item, lvif_text,ncounter,2, (lptstr)(lpctstr)text,::sysstringlen(variantbstrtemp.bstrval));
if (m_parameters.setitem(&item) == 0)
msg("could not set item to list");
}
updatedata(false);
cleanup:
for(ncounter = 0; ncounter < nnumparameters ; ncounter++)
{
::variantclear(&parg[ncounter]);
::variantclear(&pref[ncounter]);
}
::variantclear(&result);
::variantclear(&variantbstrtemp);
::variantclear(&vtempvariable);
::sysfreestring(bstrport);
::sysfreestring(bstrservice);
::sysfreestring(bstrwsdlfilename);
if (parg)
delete [] parg;
if (pref)
delete [] pref;
enablebuttons();
return;
}