» 网友学堂 » NET教程 » webservice系列教学(13)-如何调用webservice(vc4)
webservice系列教学(13)-如何调用webservice(vc4)
作者:问天 发表时间:2007-2-20 11:29 阅读:324次 在百度搜索相关内容

//////////////////////////////////////////////////////////////////////////////////////////////////
// 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 **)&;amp;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(&;amp;result);
::VariantInit(&;amp;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(&;amp;Item, LVIF_PARAM,nCounter,0,0,0);
assignItem(&;amp;Item1, LVIF_TEXT,nCounter,2,name,sizeof(name));

if (m_Parameters.GetItem(&;amp;Item) == 0)
MSG("Could not get item!");
if (m_Parameters.GetItem(&;amp;Item1) == 0)
MSG("Could not get item!");

// we will not fill the arguments with result
reinterpret_cast<ISoapMapper *>(Item.lParam)->get_isInput(&;amp;IsInput);
[color=#FFFFFF'][/color]

if (IsInput != smOutput)
{
::VariantInit(&;amp;pArg[nCount]);
// I have to fill this array in reverse order bacause the server expects it in reverse order
::VariantInit(&;amp;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(&;amp;pArg[nCount],&;amp;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(&;amp;vTempVariable);
// assign the correct parameter to pRef and indicate it is BYREF
pRef[nNumParameters - nCount -1 ].vt = pArg[nCount].vt │ VT_BYREF;
AssignpRef(&;amp;pRef[nNumParameters - nCount -1],&;amp;pArg[nCount]);
nCount ;
}
}

// get the ID of operation
hr = pClient->GetIDsOfNames(IID_NULL, &;amp;pstrFunctionName, 1, LOCALE_SYSTEM_DEFAULT, &;amp;dispidFn);
CHECK_HRESULT(hr, "Taking IDs Failed!");

// calling the operation
::VariantClear(&;amp;result);

hr = pClient->Invoke(dispidFn, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &;amp;parms,
&;amp;result, &;amp;excepinfo, 0);
CHECK_HRESULT(hr, "Function call Failed!");

::VariantInit(&;amp;variantbstrtemp);

// update the results

for(nCounter = 0; nCounter < m_Parameters.GetItemCount() ; nCounter )
{
if (nCounter < nNumParameters)
{
hr = ::VariantChangeType(&;amp;variantbstrtemp,&;amp;pArg[nCounter],VARIANT_NOUSEROVERRIDE,VT_BSTR);
}
else
{
hr = ::VariantChangeType(&;amp;variantbstrtemp,&;amp;result,VARIANT_NOUSEROVERRIDE,VT_BSTR);
}

CHECK_HRESULT(hr, "Variant could not be converted");

CString Text(variantbstrtemp.bstrVal);
assignItem(&;amp;Item, LVIF_TEXT,nCounter,2, (LPTSTR)(LPCTSTR)Text,::SysStringLen(variantbstrtemp.bstrVal));

if (m_Parameters.SetItem(&;amp;Item) == 0)
MSG("Could not set Item to list");
}

UpdateData(false);

cleanup:
for(nCounter = 0; nCounter < nNumParameters ; nCounter )
{
::VariantClear(&;amp;pArg[nCounter]);
::VariantClear(&;amp;pRef[nCounter]);
}

::VariantClear(&;amp;result);
::VariantClear(&;amp;variantbstrtemp);
::VariantClear(&;amp;vTempVariable);
::SysFreeString(bstrPort);
::SysFreeString(bstrService);
::SysFreeString(bstrWSDLFileName);

if (pArg)
delete [] pArg;
if (pRef)
delete [] pRef;

EnableButtons();
return;
}




#Advertisement