webservice系列教学(13)-如何调用webservice(vc4)

80酷酷网    80kuku.com

  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;
}

分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: