您的位置:首页 > 其它

Web服务系列教学-如何调用WebService(5)

2005-11-22 15:49 645 查看
ao < MClientDlg.cpp>
    // MClientDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MClient.h"
#include "MClientDlg.h"
#include "Atlbase.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMClientDlg dialog
CMClientDlg::CMClientDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CMClientDlg::IDD, pParent)
{
    //{{_DATA_INIT(CMClientDlg)
    m_strParameter = _T("");
    m_strURL = _T("");
    //}}AFX_DATA_INIT
    // Note that LoadIcon does require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
AFX_DATA_INIT(CMClientDlg)
    m_strParameter = _T("");
    m_strURL = _T("");
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}AFX_DATA_INIT(CMClientDlg)
    m_strParameter = _T("");
    m_strURL = _T("");
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CMClientDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CMClientDlg)
    DDX_Control(pDX, IDC_TREE, m_TreeCtrl);
    DDX_Control(pDX, IDC_LISTPARAM, m_Parameters);
    DDX_Text(pDX, IDC_PARAMETER, m_strParameter);
    DDX_Text(pDX, IDC_URL, m_strURL);
    //}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMClientDlg, CDialog)
    //{{AFX_MSG_MAP(CMClientDlg)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDBROWSE, OnBrowse)
    ON_BN_CLICKED(IDC_CLOSE, OnClose)
    ON_BN_CLICKED(IDC_EDIT, OnEdit)
    ON_BN_CLICKED(IDC_EXECUTE, OnExecute)
    ON_NOTIFY(LVN_DELETEITEM, IDC_LISTPARAM, OnDeleteitemListparam)
    ON_NOTIFY(TVN_DELETEITEM, IDC_TREE, OnDeleteitemTree)
    ON_NOTIFY(TVN_SELCHANGED, IDC_TREE, OnSelchangedTree)
    ON_BN_CLICKED(IDLOAD, OnLoad)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
// CMClientDlg message handlers

BOOL CMClientDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    if (ModifyDialog() == -1)
        return FALSE;
    // Set the icon for this dialog.  The framework does this automatically
    //  when the application''s main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
   
    // TODO: Add extra initialization here
   
    return TRUE;  // return TRUE  unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.
void CMClientDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting
        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;
        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}
// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMClientDlg::OnQueryDragIcon()
{
    return (HCURSOR) m_hIcon;
}
//  function: CMClientDlg::OnBrowse()
//
//  parameters: No Parameters
//
//  description:  selection of wsdl file
//
//  returns: void
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnBrowse()
{
    // browse dialog will open and get the selected file
    CFileDialog browse(TRUE, _T("wsdl"), NULL, 0, _T("WSDL Files (*.wsdl)|*.wsdl|All files|*.*||"));
    if (browse.DoModal() == IDOK)
    {
        m_strURL = browse.GetPathName();
        if (m_strURL.IsEmpty())
            return;
        UpdateData(FALSE);
        OnLoad();
    }

    return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnClose()
//
//  parameters: No Parameter
//
//  description: called when dialog is being closed, but before close the dialog, tree should be destroyed.
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnClose()
{
     if (!DestroyTree())
         return;
    CMClientDlg::DestroyWindow();
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnEdit()
//
//  parameters: No Parameters
//
//  description: Edits parameters of the operation
//
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnEdit()
{
    // get selected row, insert the user input in 3 column of that row
    // assign -1 to the selection mark  , so next time user has to select a row to insert data
    int                nSelectedRow ;
    LVITEM            LVitem;
    UpdateData();
    if (m_Parameters.GetItemCount() == 0)
        return;
    nSelectedRow = m_Parameters.GetSelectionMark();
    if (nSelectedRow == -1)
        return;
    assignItem (&LVitem, LVIF_TEXT, nSelectedRow, 2, (LPSTR)(LPCTSTR)m_strParameter, ::SysStringLen((LPWSTR)(LPCTSTR)m_strParameter));
    if (m_Parameters.SetItem(&LVitem) == 0)
        MSG("Data could not be inserted !");
cleanup :
    m_strParameter.Empty();
    m_Parameters.SetSelectionMark(-1);
    UpdateData(false);
    UpdateData();
    return;   
}

//  function: CMClientDlg::OnExecute()
//
//  parameters: No Parameters
//
//  description: pressing Execute button calls this function
//  returns: void
//
//////////////////////////////////////////////
void CMClientDlg::OnExecute()
{
    UpdateData();
    UpdateData(false);

    if (CheckforURL() == -1)
        return;
    Execute();
    return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  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;
  
1c476
  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;
}

//  function: CMClientDlg::OnDeleteitemListparam()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for each row of list, it calls the Release
//
//  returns: void
//
////////////////////////////////////////////////////
void CMClientDlg::OnDeleteitemListparam(NMHDR* pNMHDR, LRESULT* pResult)
{
// We have to release lParam that I filled with object of ISoapMapper
    NMLISTVIEW   *tempVar = (NMLISTVIEW*)pNMHDR;;

    if (reinterpret_cast <IUnknown*>(tempVar->lParam))
        (reinterpret_cast <IUnknown*>(tempVar->lParam))->Release();
   
    *pResult = 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnDeleteitemTree()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for each tree elements, it calls the Release method
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnDeleteitemTree(NMHDR* pNMHDR, LRESULT* pResult)
{
    // We have to release lParam that I filled with object
    NMTREEVIEW   *tempVar = (NMTREEVIEW*)pNMHDR;;
    if (reinterpret_cast <IUnknown*>(tempVar->itemOld.lParam))
        (reinterpret_cast <IUnknown*>(tempVar->itemOld.lParam))->Release();
    *pResult = 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnSelchangedTree()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for selection on tree, it updates the list
//
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
    // if the selected is operation, update the list with its parameters
    NMTREEVIEW* pNMTreeView = (NMTREEVIEW*)pNMHDR;

    IUnknown *pUnk = reinterpret_cast<IUnknown *>(pNMTreeView->itemNew.lParam);
    if (! pUnk)
        return;
    IWSDLOperation *pOper = 0;
    m_strParameter.Empty();
    UpdateData(false);
    if(SUCCEEDED(pUnk->QueryInterface(__uuidof(IWSDLOperation), reinterpret_cast<void **>(&pOper))))
    {
        if (UpdateList() != 1)
            MSG("Parameter list can not be created!");
    }
    *pResult = 0;
cleanup:
    if (pOper)
        pOper->Release();
   
    return;
}

//  function: CMClientDlg::OnLoad()
//
//  parameters: No Parameters
//
//  description:  takes the service, ports and operations and fills the tree
//
//  returns: void
//
///////////////////////////////////////////////
void CMClientDlg::OnLoad()
{
    USES_CONVERSION;

    UpdateData(true);
// chech if wsdl file is given, if not, return
    if (CheckforURL() == -1)
        return;
// delete the tree if exist, if a tree exist and cant be deleted, return
    if (!DestroyTree())
        return;
    HRESULT                            hr                        =    S_OK;
    BSTR                            bstrWSDLFileName        =   0;
    BSTR                            bstrServiceName            =    0;
    BSTR                            bstrPortName            =    0;
    BSTR                            bstrOperationName        =    0;
    int                             flag                    =   1;
    int                             flag_SERVICE            =   0;
    int                             flag_PORT               =   0;
    int                             flag_OPERATION          =   0;
    CComPtr<IEnumWSDLService>        pIEnumWSDLServices;
    CComPtr<IEnumWSDLPorts>            pIEnumWSDLPorts;
    CComPtr<IEnumWSDLOperations>    pIEnumWSDLOps;
    CComPtr<IWSDLOperation>            pIOperation;
    CComPtr<IWSDLReader>            pIWSDLReader;
    CComPtr<IWSDLService>            pIWSDLService;
    CComPtr<IWSDLPort>                pIWSDLPort;
    long                            cFetched;
    HTREEITEM                        hSERVICE;
    HTREEITEM                        hPORT;
    HTREEITEM                        hOPERATION;
    // take the name of wsdl file
    bstrWSDLFileName =  m_strURL.AllocSysString();
    if (bstrWSDLFileName == NULL)
        return;
    hr = CoCreateInstance(__uuidof(WSDLReader), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWSDLReader),
                        (void**)&pIWSDLReader);
    CHECK_HRESULT(hr, "Can not create the  object of the CLSID_WSDLReader");
    // loading needs wsdl and wsml files, but I dont know wsml file and I pass ""
    hr = pIWSDLReader->Load(bstrWSDLFileName, L"");   
       CHECK_HRESULT(hr, "Loading WSDL and WSML files failed!");
    // get soap service
    hr = pIWSDLReader->GetSoapServices(&pIEnumWSDLServices);
    CHECK_HRESULT(hr, "Can not get Services");
    if (!pIEnumWSDLServices)
        MSG("Can not get Services");
    while((hr = pIEnumWSDLServices->Next(1, &pIWSDLService, &cFetched)) == S_OK)
    {
        // at least one time this loop should go inside; if it does not, the flag wont be updated
        // so we can not continue and should destroy the tree if any part created
        flag_SERVICE   =   1;
        // get service name
        hr = pIWSDLService->get_name(&bstrServiceName);
        CHECK_HRESULT(hr, "Can not get Service names");
        // add the name of service in to tree
        // first field is NULL, it means insert this as root
        hSERVICE= AddtoTree(NULL,TVI_SORT,W2A(bstrServiceName),TVIF_TEXT,pIWSDLService);
        ::SysFreeString(bstrServiceName);
        if (!hSERVICE)
        {
            flag = 0;
            goto cleanup;
        }
hr = pIWSDLService->GetSoapPorts(&pIEnumWSDLPorts);
        CHECK_HRESULT(hr, "Can not get Ports");
        if (!pIEnumWSDLPorts)
            MSG("Can not get Ports");
        while((hr = pIEnumWSDLPorts->Next(1,&pIWSDLPort, &cFetched)) == S_OK)
        {
            // at least one time this loop should go inside; if it does not, the flag wont be updated
            // so we can not continue and should destroy the tree if any part created
            flag_PORT  =   1;
             // get port name
            hr = pIWSDLPort->get_name(&bstrPortName);
            CHECK_HRESULT(hr, "Can not get Port names");
            // add to tree but as a child of SERVICE
            hPORT= AddtoTree(hSERVICE,TVI_SORT,W2A(bstrPortName),TVIF_TEXT,pIWSDLPort);
            ::SysFreeString(bstrPortName);
            if (!hPORT)
            {
                flag = 0;
                goto cleanup;
            }
            hr = pIWSDLPort->GetSoapOperations(&pIEnumWSDLOps);
            CHECK_HRESULT(hr, "Can not get Operations");
            if (!pIEnumWSDLOps)
                MSG("Can not get Operations");
            while((hr = pIEnumWSDLOps->Next(1,&pIOperation, &cFetched)) == S_OK)
            {
             // at least one time this loop should go inside; if it does not, the flag wont be updated
             // so we can not continue and should destroy the tree if any part created
                flag_OPERATION  =   1;
                hr = pIOperation->get_name(&bstrOperationName);
                CHECK_HRESULT(hr, "Can not get Operation names");
                hOPERATION= AddtoTree(hPORT,TVI_SORT,W2A(bstrOperationName),TVIF_TEXT,pIOperation);
                ::SysFreeString(bstrOperationName);
                if (!hOPERATION)
                {
                    flag = 0;
                    goto cleanup;
                }
                // we do release by assigning to 0
                pIOperation= 0;
            }
            if (flag_OPERATION == 0)
            {
                flag =0;
                MSG("Could not load  OPERATIONS!");
            }
            //// we do release by assigning to 0
            pIWSDLPort = 0;
        }
        if (flag_PORT == 0)
        {
            flag =0;
            MSG("Could not load  PORTS!");
        }
        //// we do release by assigning to 0
        pIWSDLService = 0;
    }
   
    if (flag_SERVICE == 0)
    {
        flag =0;
        MSG("Could not load  SERVICE!");
    }
    UpdateData(false);
cleanup:
    ::SysFreeString(bstrWSDLFileName);
       ::SysFreeString(bstrServiceName);
    ::SysFreeString(bstrPortName);
    ::SysFreeString(bstrOperationName);

    if (flag == 0)
        DestroyTree();
    return;
}

BOOL CMClientDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    if (ModifyDialog() == -1)
        return FALSE;
    // Set the icon for this dialog.  The framework does this automatically
    //  when the application''s main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
   
    // TODO: Add extra initialization here
   
    return TRUE;  // return TRUE  unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.
void CMClientDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting
        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;
        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}
// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMClientDlg::OnQueryDragIcon()
{
    return (HCURSOR) m_hIcon;
}
//  function: CMClientDlg::OnBrowse()
//
//  parameters: No Parameters
//
//  description:  selection of wsdl file
//
//  returns: void
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnBrowse()
{
    // browse dialog will open and get the selected file
    CFileDialog browse(TRUE, _T("wsdl"), NULL, 0, _T("WSDL Files (*.wsdl)|*.wsdl|All files|*.*||"));
    if (browse.DoModal() == IDOK)
    {
        m_strURL = browse.GetPathName();
        if (m_strURL.IsEmpty())
            return;
        UpdateData(FALSE);
        OnLoad();
    }

    return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnClose()
//
//  parameters: No Parameter
//
//  description: called when dialog is being closed, but before close the dialog, tree should be destroyed.
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnClose()
{
     if (!DestroyTree())
         return;
    CMClientDlg::DestroyWindow();
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnEdit()
//
//  parameters: No Parameters
//
//  description: Edits parameters of the operation
//
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnEdit()
{
    // get selected row, insert the user input in 3 column of that row
    // assign -1 to the selection mark  , so next time user has to select a row to insert data
    int                nSelectedRow ;
    LVITEM            LVitem;
    UpdateData();
    if (m_Parameters.GetItemCount() == 0)
        return;
    nSelectedRow = m_Parameters.GetSelectionMark();
    if (nSelectedRow == -1)
        return;
    assignItem (&LVitem, LVIF_TEXT, nSelectedRow, 2, (LPSTR)(LPCTSTR)m_strParameter, ::SysStringLen((LPWSTR)(LPCTSTR)m_strParameter));
    if (m_Parameters.SetItem(&LVitem) == 0)
        MSG("Data could not be inserted !");
cleanup :
    m_strParameter.Empty();
    m_Parameters.SetSelectionMark(-1);
    UpdateData(false);
    UpdateData();
    return;   
}

//  function: CMClientDlg::OnExecute()
//
//  parameters: No Parameters
//
//  description: pressing Execute button calls this function
//  returns: void
//
//////////////////////////////////////////////
void CMClientDlg::OnExecute()
{
    UpdateData();
    UpdateData(false);

    if (CheckforURL() == -1)
        return;
    Execute();
    return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  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;
}

//  function: CMClientDlg::OnDeleteitemListparam()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for each row of list, it calls the Release
//
//  returns: void
//
////////////////////////////////////////////////////
void CMClientDlg::OnDeleteitemListparam(NMHDR* pNMHDR, LRESULT* pResult)
{
// We have to release lParam that I filled with object of ISoapMapper
    NMLISTVIEW   *tempVar = (NMLISTVIEW*)pNMHDR;;

    if (reinterpret_cast <IUnknown*>(tempVar->lParam))
        (reinterpret_cast <IUnknown*>(tempVar->lParam))->Release();
   
    *pResult = 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnDeleteitemTree()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for each tree elements, it calls the Release method
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnDeleteitemTree(NMHDR* pNMHDR, LRESULT* pResult)
{
    // We have to release lParam that I filled with object
    NMTREEVIEW   *tempVar = (NMTREEVIEW*)pNMHDR;;
    if (reinterpret_cast <IUnknown*>(tempVar->itemOld.lParam))
        (reinterpret_cast <IUnknown*>(tempVar->itemOld.lParam))->Release();
    *pResult = 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnSelchangedTree()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for selection on tree, it updates the list
//
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
    // if the selected is operation, update the list with its parameters
    NMTREEVIEW* pNMTreeView = (NMTREEVIEW*)pNMHDR;

    IUnknown *pUnk = reinterpret_cast<IUnknown *>(pNMTreeView->itemNew.lParam);
    if (! pUnk)
        return;
    IWSDLOperation *pOper = 0;
    m_strParameter.Empty();
    UpdateData(false);
    if(SUCCEEDED(pUnk->QueryInterface(__uuidof(IWSDLOperation), reinterpret_cast<void **>(&pOper))))
    {
        if (UpdateList() != 1)
            MSG("Parameter list can not be created!");
    }
    *pResult = 0;
cleanup:
    if (pOper)
        pOper->Release();
   
    return;
}

//  function: CMClientDlg::OnLoad()
//
//  parameters: No Parameters
//
//  description:  takes the service, ports and operations and fills the tree
//
//  returns: void
//
///////////////////////////////////////////////
void CMClientDlg::OnLoad()
{
    USES_CONVERSION;

    UpdateData(true);
// chech if wsdl file is given, if not, return
    if (CheckforURL() == -1)
        return;
// delete the tree if exist, if a tree exist and cant be deleted, return
    if (!DestroyTree())
        return;
    HRESULT                            hr                        =    S_OK;
    BSTR                            bstrWSDLFileName        =   0;
    BSTR                            bstrServiceName            =    0;
    BSTR                            bstrPortName            =    0;
    BSTR                            bstrOperationName        =    0;
    int                             flag                    =   1;
    int                             flag_SERVICE            =   0;
    int                             flag_PORT               =   0;
    int                             flag_OPERATION          =   0;
    CComPtr<IEnumWSDLService>        pIEnumWSDLServices;
    CComPtr<IEnumWSDLPorts>            pIEnumWSDLPorts;
    CComPtr<IEnumWSDLOperations>    pIEnumWSDLOps;
    CComPtr<IWSDLOperation>            pIOperation;
    CComPtr<IWSDLReader>            pIWSDLReader;
    CComPtr<IWSDLService>            pIWSDLService;
    CComPtr<IWSDLPort>                pIWSDLPort;
    long                            cFetched;
    HTREEITEM                        hSERVICE;
    HTREEITEM                        hPORT;
    HTREEITEM                        hOPERATION;
    // take the name of wsdl file
    bstrWSDLFileName =  m_strURL.AllocSysString();
    if (bstrWSDLFileName == NULL)
        return;
    hr = CoCreateInstance(__uuidof(WSDLReader), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWSDLReader),
                        (void**)&pIWSDLReader);
    CHECK_HRESULT(hr, "Can not create the  object of the CLSID_WSDLReader");
    // loading needs wsdl and wsml files, but I dont know wsml file and I pass ""
    hr = pIWSDLReader->Load(bstrWSDLFileName, L"");   
       CHECK_HRESULT(hr, "Loading WSDL and WSML files failed!");
    // get soap service
    hr = pIWSDLReader->GetSoapServices(&pIEnumWSDLServices);
    CHECK_HRESULT(hr, "Can not get Services");
    if (!pIEnumWSDLServices)
        MSG("Can not get Services");
    while((hr = pIEnumWSDLServices->Next(1, &pIWSDLService, &cFetched)) == S_OK)
    {
        // at least one time this loop should go inside; if it does not, the flag wont be updated
        // so we can not continue and should destroy the tree if any part created
        flag_SERVICE   =   1;
        // get service name
        hr = pIWSDLService->get_name(&bstrServiceName);
        CHECK_HRESULT(hr, "Can not get Service names");
        // add the name of service in to tree
        // first field is NULL, it means insert this as root
        hSERVICE= AddtoTree(NULL,TVI_SORT,W2A(bstrServiceName),TVIF_TEXT,pIWSDLService);
        ::SysFreeString(bstrServiceName);
        if (!hSERVICE)
        {
            flag = 0;
            goto cleanup;
        }
hr = pIWSDLService->GetSoapPorts(&pIEnumWSDLPorts);
        CHECK_HRESULT(hr, "Can not get Ports");
        if (!pIEnumWSDLPorts)
            MSG("Can not get Ports");
        while((hr = pIEnumWSDLPorts->Next(1,&pIWSDLPort, &cFetched)) == S_OK)
        {
            // at least one time this loop should go inside; if it does not, the flag wont be updated
            // so we can not continue and should destroy the tree if any part created
            flag_PORT  =   1;
             // get port name
            hr = pIWSDLPort->get_name(&bstrPortName);
            CHECK_HRESULT(hr, "Can not get Port names");
            // add to tree but as a child of SERVICE
            hPORT= AddtoTree(hSERVICE,TVI_SORT,W2A(bstrPortName),TVIF_TEXT,pIWSDLPort);
            ::SysFreeString(bstrPortName);
            if (!hPORT)
            {
                flag = 0;
                goto cleanup;
            }
            hr = pIWSDLPort->GetSoapOperations(&pIEnumWSDLOps);
            CHECK_HRESULT(hr, "Can not get Operations");
            if (!pIEnumWSDLOps)
                MSG("Can not get Operations");
            while((hr = pIEnumWSDLOps->Next(1,&pIOperation, &cFetched)) == S_OK)
            {
             // at least one time this loop should go inside; if it does not, the flag wont be updated
             // so we can not continue and should destroy the tree if any part created
                flag_OPERATION  =   1;
                hr = pIOperation->get_name(&bstrOperationName);
                CHECK_HRESULT(hr, "Can not get Operation names");
                hOPERATION= AddtoTree(hPORT,TVI_SORT,W2A(bstrOperationName),TVIF_TEXT,pIOperation);
                ::SysFreeString(bstrOperationName);
                if (!hOPERATION)
                {
                    flag = 0;
                    goto cleanup;
                }
                // we do release by assigning to 0
                pIOperation= 0;
            }
            if (flag_OPERATION == 0)
            {
                flag =0;
                MSG("Could not load  OPERATIONS!");
            }
            //// we do release by assigning to 0
            pIWSDLPort = 0;
        }
        if (flag_PORT == 0)
        {
            flag =0;
            MSG("Could not load  PORTS!");
        }
        //// we do release by assigning to 0
        pIWSDLService = 0;
    }
   
    if (flag_SERVICE == 0)
    {
        flag =0;
        MSG("Could not load  SERVICE!");
    }
    UpdateData(false);
cleanup:
    ::SysFreeString(bstrWSDLFileName);
       ::SysFreeString(bstrServiceName);
    ::SysFreeString(bstrPortName);
    ::SysFreeString(bstrOperationName);

    if (flag == 0)
        DestroyTree();
    return;
}

BOOL CMClientDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    if (ModifyDialog() == -1)
        return FALSE;
    // Set the icon for this dialog.  The framework does this automatically
    //  when the application''s main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
   
    // TODO: Add extra initialization here
   
    return TRUE;  // return TRUE  unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.
void CMClientDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting
        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;
        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}
// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMClientDlg::OnQueryDragIcon()
{
    return (HCURSOR) m_hIcon;
}
//  function: CMClientDlg::OnBrowse()
//
//  parameters: No Parameters
//
//  description:  selection of wsdl file
//
//  returns: void
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnBrowse()
{
    // browse dialog will open and get the selected file
    CFileDialog browse(TRUE, _T("wsdl"), NULL, 0, _T("WSDL Files (*.wsdl)|*.wsdl|All files|*.*||"));
    if (browse.DoModal() == IDOK)
    {
        m_strURL = browse.GetPathName();
        if (m_strURL.IsEmpty())
            return;
        UpdateData(FALSE);
        OnLoad();
    }

    return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnClose()
//
//  parameters: No Parameter
//
//  description: called when dialog is being closed, but before close the dialog, tree should be destroyed.
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnClose()
{
     if (!DestroyTree())
         return;
    CMClientDlg::DestroyWindow();
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnEdit()
//
//  parameters: No Parameters
//
//  description: Edits parameters of the operation
//
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnEdit()
{
    // get selected row, insert the user input in 3 column of that row
    // assign -1 to the selection mark  , so next time user has to select a row to insert data
    int                nSelectedRow ;
    LVITEM            LVitem;
    UpdateData();
    if (m_Parameters.GetItemCount() == 0)
        return;
    nSelectedRow = m_Parameters.GetSelectionMark();
    if (nSelectedRow == -1)
        return;
    assignItem (&LVitem, LVIF_TEXT, nSelectedRow, 2, (LPSTR)(LPCTSTR)m_strParameter, ::SysStringLen((LPWSTR)(LPCTSTR)m_strParameter));
    if (m_Parameters.SetItem(&LVitem) == 0)
        MSG("Data could not be inserted !");
cleanup :
    m_strParameter.Empty();
    m_Parameters.SetSelectionMark(-1);
    UpdateData(false);
    UpdateData();
    return;   
}

//  function: CMClientDlg::OnExecute()
//
//  parameters: No Parameters
//
//  description: pressing Execute button calls this function
//  returns: void
//
//////////////////////////////////////////////
void CMClientDlg::OnExecute()
{
    UpdateData();
    UpdateData(false);

    if (CheckforURL() == -1)
        return;
    Execute();
    return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  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;
}

//  function: CMClientDlg::OnDeleteitemListparam()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for each row of list, it calls the Release
//
//  returns: void
//
////////////////////////////////////////////////////
void CMClientDlg::OnDeleteitemListparam(NMHDR* pNMHDR, LRESULT* pResult)
{
// We have to release lParam that I filled with object of ISoapMapper
    NMLISTVIEW   *tempVar = (NMLISTVIEW*)pNMHDR;;

    if (reinterpret_cast <IUnknown*>(tempVar->lParam))
        (reinterpret_cast <IUnknown*>(tempVar->lParam))->Release();
   
    *pResult = 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnDeleteitemTree()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for each tree elements, it calls the Release method
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnDeleteitemTree(NMHDR* pNMHDR, LRESULT* pResult)
{
    // We have to release lParam that I filled with object
    NMTREEVIEW   *tempVar = (NMTREEVIEW*)pNMHDR;;
    if (reinterpret_cast <IUnknown*>(tempVar->itemOld.lParam))
        (reinterpret_cast <IUnknown*>(tempVar->itemOld.lParam))->Release();
    *pResult = 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  function: CMClientDlg::OnSelchangedTree()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for selection on tree, it updates the list
//
//  returns: void
//
//////////////////////////////////////////////////////////////////////////////////////////////////
void CMClientDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
    // if the selected is operation, update the list with its parameters
    NMTREEVIEW* pNMTreeView = (NMTREEVIEW*)pNMHDR;

    IUnknown *pUnk = reinterpret_cast<IUnknown *>(pNMTreeView->itemNew.lParam);
    if (! pUnk)
        return;
    IWSDLOperation *pOper = 0;
    m_strParameter.Empty();
    UpdateData(false);
    if(SUCCEEDED(pUnk->QueryInterface(__uuidof(IWSDLOperation), reinterpret_cast<void **>(&pOper))))
    {
        if (UpdateList() != 1)
            MSG("Parameter list can not be created!");
    }
    *pResult = 0;
cleanup:
    if (pOper)
        pOper->Release();
   
    return;
}

//  function: CMClientDlg::OnLoad()
//
//  parameters: No Parameters
//
//  description:  takes the service, ports and operations and fills the tree
//
//  returns: void
//
///////////////////////////////////////////////
void CMClientDlg::OnLoad()
{
    USES_CONVERSION;

    UpdateData(true);
// chech if wsdl file is given, if not, return
    if (CheckforURL() == -1)
        return;
// delete the tree if exist, if a tree exist and cant be deleted, return
    if (!DestroyTree())
        return;
    HRESULT                            hr                        =    S_OK;
    BSTR                            bstrWSDLFileName        =   0;
    BSTR                            bstrServiceName            =    0;
    BSTR                            bstrPortName            =    0;
    BSTR                            bstrOperationName        =    0;
    int                             flag                    =   1;
    int                             flag_SERVICE            =   0;
    int                             flag_PORT               =   0;
    int                             flag_OPERATION          =   0;
    CComPtr<IEnumWSDLService>        pIEnumWSDLServices;
    CComPtr<IEnumWSDLPorts>            pIEnumWSDLPorts;
    CComPtr<IEnumWSDLOperations>    pIEnumWSDLOps;
    CComPtr<IWSDLOperation>            pIOperation;
    CComPtr<IWSDLReader>            pIWSDLReader;
    CComPtr<IWSDLService>            pIWSDLService;
    CComPtr<IWSDLPort>                pIWSDLPort;
    long                            cFetched;
    HTREEITEM                        hSERVICE;
    HTREEITEM                        hPORT;
    HTREEITEM                        hOPERATION;
    // take the name of wsdl file
    bstrWSDLFileName =  m_strURL.AllocSysString();
    if (bstrWSDLFileName == NULL)
        return;
    hr = CoCreateInstance(__uuidof(WSDLReader), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWSDLReader),
                        (void**)&pIWSDLReader);
    CHECK_HRESULT(hr, "Can not create the  object of the CLSID_WSDLReader");
    // loading needs wsdl and wsml files, but I dont know wsml file and I pass ""
    hr = pIWSDLReader->Load(bstrWSDLFileName, L"");   
       CHECK_HRESULT(hr, "Loading WSDL and WSML files failed!");
    // get soap service
    hr = pIWSDLReader->GetSoapServices(&pIEnumWSDLServices);
    CHECK_HRESULT(hr, "Can not get Services");
    if (!pIEnumWSDLServices)
        MSG("Can not get Services");
    while((hr = pIEnumWSDLServices->Next(1, &pIWSDLService, &cFetched)) == S_OK)
    {
        // at least one time this loop should go inside; if it does not, the flag wont be updated
        // so we can not continue and should destroy the tree if any part created
        flag_SERVICE   =   1;
        // get service name
        hr = pIWSDLService->get_name(&bstrServiceName);
        CHECK_HRESULT(hr, "Can not get Service names");
        // add the name of service in to tree
        // first field is NULL, it means insert this as root
        hSERVICE= AddtoTree(NULL,TVI_SORT,W2A(bstrServiceName),TVIF_TEXT,pIWSDLService);
        ::SysFreeString(bstrServiceName);
        if (!hSERVICE)
        {
            flag = 0;
            goto cleanup;
        }
hr = pIWSDLService->GetSoapPorts(&pIEnumWSDLPorts);
        CHECK_HRESULT(hr, "Can not get Ports");
        if (!pIEnumWSDLPorts)
            MSG("Can not get Ports");
        while((hr = pIEnumWSDLPorts->Next(1,&pIWSDLPort, &cFetched)) == S_OK)
        {
            // at least one time this loop should go inside; if it does not, the flag wont be updated
            // so we can not continue and should destroy the tree if any part created
            flag_PORT  =   1;
             // get port name
            hr = pIWSDLPort->get_name(&bstrPortName);
            CHECK_HRESULT(hr, "Can not get Port names");
            // add to tree but as a child of SERVICE
            hPORT= AddtoTree(hSERVICE,TVI_SORT,W2A(bstrPortName),TVIF_TEXT,pIWSDLPort);
            ::SysFreeString(bstrPortName);
            if (!hPORT)
            {
                flag = 0;
                goto cleanup;
            }
            hr = pIWSDLPort->GetSoapOperations(&pIEnumWSDLOps);
            CHECK_HRESULT(hr, "Can not get Operations");
            if (!pIEnumWSDLOps)
                MSG("Can not get Operations");
            while((hr = pIEnumWSDLOps->Next(1,&pIOperation, &cFetched)) == S_OK)
            {
             // at least one time this loop should go inside; if it does not, the flag wont be updated
             // so we can not continue and should destroy the tree if any part created
                flag_OPERATION  =   1;
                hr = pIOperation->get_name(&bstrOperationName);
                CHECK_HRESULT(hr, "Can not get Operation names");
                hOPERATION= AddtoTree(hPORT,TVI_SORT,W2A(bstrOperationName),TVIF_TEXT,pIOperation);
                ::SysFreeString(bstrOperationName);
                if (!hOPERATION)
                {
                    flag = 0;
                    goto cleanup;
                }
                // we do release by assigning to 0
                pIOperation= 0;
            }
            if (flag_OPERATION == 0)
            {
                flag =0;
                MSG("Could not load  OPERATIONS!");
            }
            //// we do release by assigning to 0
            pIWSDLPort = 0;
        }
        if (flag_PORT == 0)
        {
            flag =0;
            MSG("Could not load  PORTS!");
        }
        //// we do release by assigning to 0
        pIWSDLService = 0;
    }
   
    if (flag_SERVICE == 0)
    {
        flag =0;
        MSG("Could not load  SERVICE!");
    }
    UpdateData(false);
cleanup:
    ::SysFreeString(bstrWSDLFileName);
       ::SysFreeString(bstrServiceName);
    ::SysFreeString(bstrPortName);
    ::SysFreeString(bstrOperationName);

    if (flag == 0)
        DestroyTree();
    return;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息