| webservice系列教学(13)-如何调用webservice(vc4) |
| 日期:2006-9-9 10:20:53 人气: [大 中 小] |
////////////////////////////////////////////////////////////////////////////////////////////////// // 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; } |
| 出处:CnCode转载收集 作者:不详 |