
#include "stdafx.h"

CComModule _Module;

#include "EventSink.h"
#include "CAO_i.c"

void Run();

void main()
{
	CoInitialize(0);
	_Module.Init(NULL, ::GetModuleHandle(NULL));

	Run();

	_Module.Term();
	CoUninitialize();
}

void Run()
{
	USES_CONVERSION;
	HRESULT hr = S_OK;
	CComPtr<ICaoEngine> pIEng;
	CComPtr<ICaoWorkspaces> pIWss;
	CComPtr<ICaoWorkspace> pIWs;
	CComPtr<ICaoController> pICtrl;
	CComPtr<ICaoVariable> pIVar;

	// CaoEngineの生成
	hr = CoCreateInstance(CLSID_CaoEngine, NULL, CLSCTX_LOCAL_SERVER, IID_ICaoEngine, (void**)&pIEng);
	if (FAILED(hr)) {
		return;
	}

	// Workespaceコレクションの取得
	hr = pIEng->get_Workspaces(&pIWss);
	if (FAILED(hr)) {
		return;
	}

	// Workspaceの取得
	hr = pIWss->Item(CComVariant(0L), &pIWs);
	if (FAILED(hr)) {
		return;
	}

	// Controllerの生成
	hr = pIWs->AddController(CComBSTR(L"RC1"), CComBSTR(L"CaoProv.Dummy"), CComBSTR(L""), CComBSTR(L"@EventDisable=false"), &pICtrl);
	if (FAILED(hr)) {
		return;
	}

	// Variableの生成
	hr = pICtrl->AddVariable(CComBSTR(L"S11"), CComBSTR(L""), &pIVar);
	if (FAILED(hr)) {
		return;
	}

	//シンクオブジェクトの生成
	CComObject<CEventSink>* pICEventSink;
	CComPtr<IUnknown> pIEventSink;
	hr = CComObject<CEventSink>::CreateInstance(&pICEventSink);
	if (FAILED(hr)) {
		return;
	}
	pICEventSink->QueryInterface(IID_IUnknown,(void**)&pIEventSink);

	//シンクオブジェクトの通知
	hr = pICEventSink->DispEventAdvise(pICtrl, &DIID__ICaoControllerEvents);
	if(FAILED(hr)) {
		return;
	}

	while (true) {
		// 値の設定
		wchar_t wcsBuf[256];
		std::cout << "Input data : ";
#if _MSC_VER <  1400
		_getws(wcsBuf);
#else
		_getws_s(wcsBuf, sizeof(wcsBuf)/sizeof(wchar_t));
#endif

		if (wcsBuf[0] == L'\0') {
			break;
		}

		hr = pIVar->put_Value(CComVariant(wcsBuf));
		if (FAILED(hr)) {
			std::cout << "Error : put_Value(" << hr << ")"<< std::endl;
			std::cout << "Press enter key." << std::endl;
#if _MSC_VER <  1400
			_getws(wcsBuf);
#else
			_getws_s(wcsBuf, sizeof(wcsBuf)/sizeof(wchar_t));
#endif

			return;
		}

		// 値の取得
		CComVariant vntVal;
		hr = pIVar->get_Value(&vntVal);
		if (FAILED(hr)) {
			std::cout << "Error : get_Value(" << hr << ")"<< std::endl;
			std::cout << "Press enter key." << std::endl;
#if _MSC_VER <  1400
			_getws(wcsBuf);
#else
			_getws_s(wcsBuf, sizeof(wcsBuf)/sizeof(wchar_t));
#endif

			return;
		}

		std::cout << "Output data : " << W2A(vntVal.bstrVal) << std::endl;
		std::cout << "Press enter key." << std::endl;
#if _MSC_VER <  1400
		_getws(wcsBuf);
#else
		_getws_s(wcsBuf, sizeof(wcsBuf)/sizeof(wchar_t));
#endif


		// DoEvents
		MSG msg;
		if(::PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
			::TranslateMessage(&msg);
			::DispatchMessage(&msg);
		}
	}
	pICEventSink->DispEventUnadvise(pICtrl, &DIID__ICaoControllerEvents);

	return;
}