// ==========================================================================
// Author:  Yee Hsu
// Date:    6/2/2008
// File:    ComExample.h
//
// Desc:    Example using COM interface via C++ COM
// ==========================================================================

// ComExamplecom_test.cpp : Defines the entry point for the console application.
//

#define _WIN32_DCOM
#include "stdafx.h"

// include com headers
#include <objbase.h>
#include <comdef.h>
#include <Wbemidl.h>
#include <comutil.h>

// import library and type library
#pragma comment(lib, "wbemuuid.lib")
#import "..\\..\\ComExampleCOM\\_ComExampleCOM.tlb"

// global function decl
#define PrintReturnCode(s1, s2)   {printf("%s Result: %s\n", (s2), _com_util::ConvertBSTRToString(s1));}
typedef HRESULT ( STDAPICALLTYPE *pDllGetClassObject )(   REFCLSID rclsid, REFIID riid,  LPVOID * ppv );

// ===============================================================
//           SAMPLE USING ComExample IN COM
// ===============================================================

int _tmain(int argc, _TCHAR* argv[])
{
    try
    {
        using namespace ComExampleCOM;    // namespace and interfaces via IDL

        IClassFactory*      pICF;
        pDllGetClassObject  m_pDllGCO;

        HMODULE hLib = NULL;
        IComComExample* pIUV;

        _bstr_t sDLL = _T("ComExampleCOM.dll");

        // init COM, use [COINIT_MULTITHREADED] if multi-threaded
        _tprintf( _T("Initializing COM\n") );
        CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

        // load COM DLL
        _tprintf( _T("Loading ComExample COM DLL\n") );
        if( (hLib = LoadLibrary(sDLL)) == NULL )
        {
            _ftprintf( stderr, _T("Loading DLL Unsuccessful.\n") );
            goto end;
        }

        // load class factory
        _tprintf( _T("Loading COM Class Factory\n") );
        if( ( m_pDllGCO = ( pDllGetClassObject ) GetProcAddress( hLib, "DllGetClassObject" ) ) == NULL )
        {
            _ftprintf( stderr, _T("Failed to resolve function addresses: DllGetClassObject.\n") );
            goto end;
        }

        // loadings successful, instantiate objects
        if ( SUCCEEDED( m_pDllGCO(__uuidof(CComComExample), __uuidof(IClassFactory),(void**)&pICF) ) )
        {
            _tprintf( _T("Instantiating COM Object\n") );
            if ( SUCCEEDED( pICF->CreateInstance(NULL, __uuidof(IComComExample), (void**)&pIUV) ) )
            {
                try
                {
                    _tprintf( _T("Instantiating ComExample Object\n") );
                    if ( SUCCEEDED(pIUV->Init("") ) )
                    {
                        _tprintf( _T("Parsing XML File: ") );
                        if ( SUCCEEDED(pIUV->ParseXmlFile("filename.xml") ) )
                        {
                            // ==========================================================================================
                            _bstr_t sXmlInputBlock = _T("");

                            sXmlInputBlock += _T("<XmlRoot>");
                            sXmlInputBlock += _T("</XmlRoot>");
                            // ==========================================================================================

                            _tprintf( _T("Success!\n\n") );
                            BSTR rcRes;

                            rcRes = pIUV->InvokeMethod(1, 0, 1, sXmlInputBlock);
                            PrintReturnCode(rcRes, "FuncName");

                        }
                        _tprintf( _T("Term\n\n") );
                        pIUV->Term();
                    }
                }
                catch (_com_error &)
                {
                    _ftprintf( stderr, _T("COM Error.\n") );   
                }
                pIUV->Release();
            }
            else
            {
                _ftprintf( stderr, _T("Error: CreateInstance for IComComExample failed.\n") );   
            }
            pICF->Release();
        }
        else
        {
            _ftprintf( stderr, _T("Error: Creating IClassFactory for IComComExample failed.\n") );
        }   

end:
        if( hLib )
            FreeLibrary(hLib);

        CoUninitialize();
    }
    catch (...)
    {
        _ftprintf( stderr, _T("Error: Unexpected error in ComExampleCOM.\n") );
    }
    return 0;
}

/*
int PrintReturnCode(const BSTR rcRes, const char* sTitle)
{
    printf("%s Result: ", sTitle);

    char* szRes = _com_util::ConvertBSTRToString(rcRes);
    printf("%s\n", szRes);

    return 1;
}

*/