// ClientDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Client.h"
#include "ClientDlg.h"
#include "synchronizedemo.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#import "..\\Debug\\AsynchDemoDll.dll" no_namespace
/////////////////////////////////////////////////////////////////////////////
// CClientDlg dialog

CClientDlg::CClientDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CClientDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CClientDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CClientDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CClientDlg)
	DDX_Control(pDX, IDC_BUTTON7, m_btnBeginWithCallback);
	DDX_Control(pDX, IDC_EDIT1, m_edtInput);
	DDX_Control(pDX, IDC_BUTTON6, m_btnPoll);
	DDX_Control(pDX, IDC_BUTTON5, m_btnRelease);
	DDX_Control(pDX, IDC_BUTTON4, m_btnFinish);
	DDX_Control(pDX, IDC_BUTTON3, m_btnCancel);
	DDX_Control(pDX, IDC_BUTTON2, m_btnBegin);
	DDX_Control(pDX, IDC_BUTTON1, m_btnCreate);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CClientDlg, CDialog)
	//{{AFX_MSG_MAP(CClientDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON5, OnButton5)
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	ON_BN_CLICKED(IDC_BUTTON4, OnButton4)
	ON_BN_CLICKED(IDC_BUTTON6, OnButton6)
	ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
	ON_BN_CLICKED(IDC_BUTTON7, OnButton7)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClientDlg message handlers

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

	// 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
	
	m_edtInput.SetWindowText ("5") ;

	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 CClientDlg::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 CClientDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

/*
User clicked "Create Object" button. Create the object used in this
sample code demonstration. Ask for the IUnknown interface.
*/

AsyncIChap10DemoPtr  g_pAsyncIChap10Demo ;
IUnknownPtr g_pObject ;

void CClientDlg::OnButton1() 
{

	HRESULT hr = CoCreateInstance (__uuidof(Chap10Demo), NULL, CLSCTX_LOCAL_SERVER,
		IID_IUnknown, (void **) &g_pObject) ;

	if (hr != S_OK)
	{
		CString out ;
		out.Format ("Couldn't create object, hr = 0x%x", hr) ;
		AfxMessageBox (out) ;
		return ;
	}


/*
If it worked, enable user interface.
*/

	m_btnRelease.EnableWindow (TRUE) ;
	m_btnBegin.EnableWindow (TRUE) ;
	m_btnBeginWithCallback.EnableWindow (TRUE) ;
	m_btnCreate.EnableWindow (FALSE) ;
}


/*
User clicked the Begin button. Create a call object, 
get the asynchronous version of the desired interface, then call
the "Begin_" version of the desired method
*/

void CClientDlg::OnButton2() 
{

/*
Query the proxy manager for the ICallFactory interface.
*/

	ICallFactoryPtr pCallFactory ;

	g_pObject->QueryInterface (IID_ICallFactory, (void **) &pCallFactory) ;

/*
Call the method ICallFactory::CreateCall to create the call
object, requesting the asynchronous version of the desired 
interface. 
*/

	pCallFactory->CreateCall (
		__uuidof (AsyncIChap10Demo),		// ID of asynchronous interface
		NULL,								// aggregation, here none
		__uuidof (AsyncIChap10Demo),		// interface wanted on call object
		(IUnknown **) &g_pAsyncIChap10Demo) ; // output pointer



/*
Call the "Begin_" version of the desired method on the
asynchronous interface.
*/
	
	g_pAsyncIChap10Demo->Begin_DoSomething (GetDlgItemInt (IDC_EDIT1)) ;	
	

/*
Enable user interface.
*/
	m_btnFinish.EnableWindow (TRUE) ;
	m_btnCancel.EnableWindow (TRUE) ;
	m_btnPoll.EnableWindow (TRUE) ;

	m_btnBegin.EnableWindow (FALSE) ;
	m_btnBeginWithCallback.EnableWindow (FALSE) ;
}


/*
User clicked the Cancel button.
*/

void CClientDlg::OnButton3() 
{

/*
Query the call object for the ICancelMethodCalls interface.
*/

	ICancelMethodCallsPtr pCancel ;
	g_pAsyncIChap10Demo->QueryInterface (IID_ICancelMethodCalls, (void **)&pCancel) ;

/*
Call the ICancelMethodCalls::Cancel method to send the 
cancellation request to the server. Pray that the server 
watching for it and will obey. 
*/

	pCancel->Cancel (0) ;

}

/*
User clicked the "Finish" button. Attempt to harvest the 
result of the method call by calling the "Finish_" version
of the desired method of the asynchronous interace.
*/

void CClientDlg::OnButton4() 
{
	long l ;

	try
	{
		l = g_pAsyncIChap10Demo->Finish_DoSomething ( ) ;
		SetDlgItemInt (IDC_EDIT2, l) ;
	}
	catch (_com_error e)
	{
		DebugBreak ( ) ;
	}
}


/*
User clicked Release. Disable user interface and release objects.
*/

void CClientDlg::OnButton5() 
{

	g_pObject = 0 ; 
	g_pAsyncIChap10Demo = 0 ;

	m_btnRelease.EnableWindow (FALSE) ;
	m_btnBegin.EnableWindow (FALSE) ;
	m_btnBeginWithCallback.EnableWindow (FALSE) ;
	m_btnPoll.EnableWindow (FALSE) ;
	m_btnFinish.EnableWindow (FALSE) ;
	m_btnCancel.EnableWindow (FALSE) ;

	m_btnCreate.EnableWindow (TRUE) ;
	
}

/*
User clicked the "Poll" button. Check to see whether the server has
completed the call or not. 
*/

void CClientDlg::OnButton6() 
{

	HRESULT hr ;
/*
Query the call object for the ISynchronize interface.
*/
	ISynchronizePtr pSynch ;
	g_pAsyncIChap10Demo->QueryInterface (IID_ISynchronize, (void **)&pSynch) ;

/*
Call ISynchronize::Wait with immediate return.
*/

	hr = pSynch->Wait (/* constant COWAIT_WAITALL not yet in header files  */ 1, 0) ;


/*
If return code is S_OK, it means that the wait has cleared. If it's
RPC_S_CALLPENDING, then the call hasn't completed yet.
*/

	if (hr == S_OK)
	{
		AfxMessageBox ("Call finished") ;
	}
	else if (hr == RPC_S_CALLPENDING)
	{
		AfxMessageBox ("Call still pending") ;
	}
	else
	{
		AfxMessageBox ("Wait error") ;
	}
}

/*
User has clicked the "Begin_DoSomething with Callback" button. Create
the call object as before, but this time, aggregate in our own 
implementation of the ISynchronize interface. COM will call its
Signal method to tell us when the operation has completed.
*/


void CClientDlg::OnButton7() 
{

/*
Query the proxy for the ICallFactory interface.
*/

	ICallFactoryPtr pCallFactory ;
	g_pObject->QueryInterface (IID_ICallFactory, (void **) &pCallFactory) ;

/*
Instantiate an object of our own design that implements the ISynchronize interface.
*/

	IUnknownPtr pSynch = new CComObject <CSynchronizeDemo> ( )  ;

/*
Call the method ICallFactory::CreateCall to create the call
object, requesting the asynchronous version of the desired 
interface. Supply our own implementation of the ISynchronize interface
to be aggregated in. 
*/

	IUnknownPtr * pUnk ;
	HRESULT hr = pCallFactory->CreateCall (
		__uuidof (AsyncIChap10Demo),	// ID of asynchronous interface
		pSynch,				// outer aggregate
		IID_IUnknown,		// interface wanted on call object
		(IUnknown **) &pUnk) ; // output pointer

/*
Query the call object for the asynchronous interface. We couldn't ask for
it directly in the previous call because creating an object with aggregation
requires us to ask for the IUnknown interface.
*/

	hr = pUnk->QueryInterface (__uuidof (AsyncIChap10Demo), (void**) &g_pAsyncIChap10Demo) ;

/*
Call the "Begin_" version of the desired method on the
asynchronous interface.
*/
	
	g_pAsyncIChap10Demo->Begin_DoSomething (GetDlgItemInt (IDC_EDIT1)) ;	
	hr = g_pAsyncIChap10Demo->Begin_DoSomething (GetDlgItemInt (IDC_EDIT1)) ;	

	
/*
Successful, so enable user interface.
*/
	m_btnFinish.EnableWindow (TRUE) ;
	m_btnCancel.EnableWindow (TRUE) ;
	m_btnPoll.EnableWindow (TRUE) ;

	m_btnBegin.EnableWindow (FALSE) ;
	m_btnBeginWithCallback.EnableWindow (FALSE) ;
}
