首页 > 开发 > 综合 > 正文

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

2024-07-21 02:21:47
字体:
来源:转载
供稿:网友
//////////////////////////////////////////////////////////////////////////////////////////////////
//  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;
}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表