web//////////////////////////////////////////////////////////////////////////////////////////////////
// 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;
}
webservice系列教学(13)-如何调用webservice(vc4)
80酷酷网 80kuku.com