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;
}
// 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;
}
相关文章推荐
- webservice系列教学(4)-如何调用webservice(pb,java)
- webservice系列教学(10)-如何调用webservice(vc1)
- webservice系列教学(3)-如何调用webservice
- webservice系列教学(10)-如何调用webservice(vc1)
- webservice系列教学(9)-如何调用webservice(vb6.0,vbscript)
- webservice系列教学(14)-如何调用webservice(vc5)
- webservice系列教学(5)-如何调用webservice(Jscript,vbscript)
- webservice系列教学(11)-如何调用webservice(vc2)
- webservice系列教学(14)-如何调用webservice(vc5)-.NET教程,Web Service开发
- webservice系列教学(11)-如何调用webservice(vc2)
- webservice系列教学(3)-如何调用webservice
- webservice系列教学(4)-如何调用webservice(pb,java)
- webservice系列教学(12)-如何调用webservice(vc3)
- webservice系列教学(5)-如何调用webservice(Jscript,vbscript)
- webservice系列教学(8)-如何调用webservice(vb.net)
- webservice系列教学(13)-如何调用webservice(vc4)
- webservice系列教学(6)-如何调用webservice(C#,)
- webservice系列教学(14)-如何调用webservice(vc5)
- webservice系列教学(9)-如何调用webservice(vb6.0,vbscript)
- webservice系列教学(12)-如何调用webservice(vc3)