// ChildView.cpp : implementation of the CChildView class
//

#include "stdafx.h"
#include "bindmoniker.h"
#include "ChildView.h"
#include "displaynamedlg.h"

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

/////////////////////////////////////////////////////////////////////////////
// CChildView

CChildView::CChildView()
{
}

CChildView::~CChildView()
{
}


BEGIN_MESSAGE_MAP(CChildView,CWnd )
	//{{AFX_MSG_MAP(CChildView)
	ON_WM_PAINT()
	ON_COMMAND(ID_FILE_BINDUSINGCREATEFILEMONIKER, OnFileBindusingcreatefilemoniker)
	ON_COMMAND(ID_FILE_BINDUSINGCOGETCLASSOBJECT, OnFileBindusingcogetclassobject)
	ON_COMMAND(ID_FILE_BINDUSINGMKPARSEDISPLAYNAME, OnFileBindusingmkparsedisplayname)
	ON_COMMAND(ID_FILE_BINDUSINGOWNSTRING, OnFileBindusingownstring)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CChildView message handlers

BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) 
{
	if (!CWnd::PreCreateWindow(cs))
		return FALSE;

	cs.dwExStyle |= WS_EX_CLIENTEDGE;
	cs.style &= ~WS_BORDER;
	cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
		::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL);

	return TRUE;
}

void CChildView::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	
	// Do not call CWnd::OnPaint() for painting messages
}


void CChildView::OnFileBindusingcreatefilemoniker() 
{
	CFileDialog dlg (TRUE);	

	if (dlg.DoModal( ) == IDOK)
	{
				CString path = dlg.GetPathName() ;

/*
Create a file moniker based on the file selected by the user
*/

		USES_CONVERSION ;
		
		IMonikerPtr FileMoniker ;
		CreateFileMoniker (A2W(dlg.GetPathName ()), &FileMoniker) ;


		IStream *pStrm ;

		HGLOBAL hg = GlobalAlloc (GMEM_FIXED, 1024) ;

		CreateStreamOnHGlobal (hg, FALSE, &pStrm) ;
		OleSaveToStream (FileMoniker, pStrm) ;


/*
Create a bind context.
*/
		IBindCtxPtr BC ;
		CreateBindCtx (0, &BC) ;

/*
Tell the file moniker to bind. Ask for IDataObject interface.
*/
		HRESULT hr ;
		IDataObjectPtr DO ;
		hr = FileMoniker->BindToObject(BC, NULL, IID_IDataObject, (void**) &DO) ;

		if (hr != S_OK)
		{
			CString str ;
			str.Format("IMoniker::BindToObject failed, hr == 0x%x", hr) ;
			AfxMessageBox (hr) ;
			return ;
		}
 
/*
Get the data as a metafile, draw on the screen.
*/
	
		FORMATETC fe ;
		STGMEDIUM stg ;

    	fe.cfFormat = CF_ENHMETAFILE ;
    	fe.ptd = NULL ;
		fe.tymed = TYMED_MFPICT ;  
    	fe.dwAspect = DVASPECT_CONTENT ; 
    	fe.lindex = -1 ;
       
		hr = DO->GetData (&fe, &stg) ;

		RECT r ;
		GetClientRect (&r) ;
		GetDC()->PlayMetaFile ((HENHMETAFILE)stg.hEnhMetaFile, &r) ;
		ReleaseStgMedium (&stg) ;

	}
	
}

void CChildView::OnFileBindusingcogetclassobject() 
{

	CFileDialog dlg (TRUE);	

	if (dlg.DoModal( ) == IDOK)
	{
		HRESULT hr ;
		USES_CONVERSION ;

		CString path = dlg.GetPathName() ;
/*
Find the CLSID of the file moniker.
*/
	
		CLSID clsidFileMoniker ;
		CLSIDFromProgID (L"File", &clsidFileMoniker) ;

/*
Get the class object of the File Moniker class. Instead of the usual 
IClassFactory interface, ask for the IParseDisplayName interface 
instead. We will use it to obtain the moniker.
*/

		IParseDisplayNamePtr PDN ;

		hr = CoGetClassObject (clsidFileMoniker, CLSCTX_SERVER, NULL, 
			IID_IParseDisplayName, (void **) &PDN) ;

/*
Pass the file name to the IParseDisplayName interface to
obtain the moniker.
*/
		IMonikerPtr FileMoniker ;
		IBindCtxPtr BC ;
		CreateBindCtx (NULL, &BC) ;

		ULONG CharsEaten ;
		CString DisplayName = "file:" ;
		DisplayName += dlg.GetPathName () ;
		PDN->ParseDisplayName (BC, A2W(DisplayName), &CharsEaten, &FileMoniker) ;


/*
Tell the file moniker to bind. Ask for IDataObject interface.
*/
		IBindCtxPtr NewBC ;
		CreateBindCtx (NULL, &NewBC) ;

		IDataObjectPtr DO ;
		hr = FileMoniker->BindToObject(NewBC, NULL, IID_IDataObject, (void**) &DO) ;

		if (hr != S_OK)
		{
			CString str ;
			str.Format("IMoniker::BindToObject failed, hr == 0x%x", hr) ;
			AfxMessageBox (hr) ;
			return ;
		}
 
/*
Get the data as a metafile, draw on the screen.
*/
	
		FORMATETC fe ;
		STGMEDIUM stg ;

    	fe.cfFormat = CF_ENHMETAFILE ;
    	fe.ptd = NULL ;
		fe.tymed = TYMED_MFPICT ;  
    	fe.dwAspect = DVASPECT_CONTENT ; 
    	fe.lindex = -1 ;
       
		hr = DO->GetData (&fe, &stg) ;

		RECT r ;
		GetClientRect (&r) ;
		GetDC()->PlayMetaFile ((HENHMETAFILE)stg.hEnhMetaFile, &r) ;
		ReleaseStgMedium (&stg) ;
	}

}

void CChildView::OnFileBindusingmkparsedisplayname() 
{
	CFileDialog dlg (TRUE);	

	if (dlg.DoModal( ) == IDOK)
	{
		HRESULT hr ;
		USES_CONVERSION ;

		CString path = dlg.GetPathName() ;

/*
Pass the file name to the IParseDisplatName interface to
obtain the moniker.
*/
		IMonikerPtr FileMoniker ;
		
		IBindCtxPtr BC ;
		CreateBindCtx (NULL, &BC) ;
		ULONG CharsEaten ;

		CString DispName = "file:" ;
		DispName += dlg.GetPathName() ;

		MkParseDisplayName (BC, A2W(DispName) , &CharsEaten, &FileMoniker) ;


/*
Tell the file moniker to bind. Ask for IDataObject interface.
*/

		IDataObjectPtr DO ;
		hr = FileMoniker->BindToObject(BC, NULL, IID_IDataObject, (void**) &DO) ;

		if (hr != S_OK)
		{
			CString str ;
			str.Format("IMoniker::BindToObject failed, hr == 0x%x", hr) ;
			AfxMessageBox (hr) ;
			return ;
		}
 
/*
Get the data as a metafile, draw on the screen.
*/
	
		FORMATETC fe ;
		STGMEDIUM stg ;

    	fe.cfFormat = CF_ENHMETAFILE ;
    	fe.ptd = NULL ;
		fe.tymed = TYMED_MFPICT ;  
    	fe.dwAspect = DVASPECT_CONTENT ; 
    	fe.lindex = -1 ;
       
		hr = DO->GetData (&fe, &stg) ;

		RECT r ;
		GetClientRect (&r) ;
		GetDC()->PlayMetaFile ((HENHMETAFILE)stg.hEnhMetaFile, &r) ;
		ReleaseStgMedium (&stg) ;
	}

	
}

void CChildView::OnFileBindusingownstring() 
{
	USES_CONVERSION ;

	CDisplayNameDlg dlg ;

	if (dlg.DoModal() == IDOK)
	{
		IUnknownPtr pUnk ;

/*
Call CoGetObject, combining MkParseDisplayName with BindMoniker.
*/
		HRESULT hr = CoGetObject (A2W(dlg.m_DisplayName), NULL, IID_IUnknown, (void**) &pUnk) ;

		if (hr == S_OK)
		{
			AfxMessageBox ("Bind Operation Successful.") ;
		}
		else
		{
			CString str ;
			str.Format ("Bind operation unsuccessful, error code == 0x%x", hr) ;
			AfxMessageBox (str) ;
		}
	}
}
