// CaoSQLSample.cpp : コンソール アプリケーション用のエントリ ポイントの定義
//

#include "stdafx.h"

CComModule _Module;

#include "EventSink.h"
#include "..\..\Include\CaoSQL_i.c"

void Run();

int main(int argc, char* argv[])
{
	CoInitialize(0);
	_Module.Init(NULL, ::GetModuleHandle(NULL));

	Run();

	_Module.Term();
	CoUninitialize();

	return 0;
}

void Run()
{
	USES_CONVERSION;

	HRESULT hr = S_OK;
	CComPtr<ICaoSQLEngine> pIEng;
	CComPtr<ICaoSQLController> pICtrl;
	CComPtr<ICaoSQLItem> pIItem;

	// CaoEngineの生成
	hr = CoCreateInstance(CLSID_CaoSQLEngine, NULL, CLSCTX_LOCAL_SERVER, IID_ICaoSQLEngine, (void **)&pIEng);
	if (FAILED(hr)) {
		std::cout << "Error : CoCreateInstance - CaoSQLEngine" << std::endl;
		std::cout << "Press enter key." << std::endl;
		getwchar();
		return;
	}

	// コントローラの取得
	hr = pIEng->Controller(CComVariant(0), &pICtrl);
	if (FAILED(hr)) {
		std::cout << "Error : Controller(" << hr << ")"<< std::endl;
		std::cout << "Press enter key." << std::endl;
		getwchar();
		return;
	}

	// アイテムの取得
	hr = pICtrl->Item(CComVariant(0), &pIItem);
	if (FAILED(hr)) {
		std::cout << "Error : Item(" << hr << ")"<< std::endl;
		std::cout << "Press enter key." << std::endl;
		getwchar();
		return;
	}

	//シンクオブジェクトの生成
	CComObject<CEventSink>* pCEventSink;
	CComPtr<IUnknown> pIEventSink;
	hr = CComObject<CEventSink>::CreateInstance(&pCEventSink);
	if (FAILED(hr)) {
		return;
	}
	pCEventSink->QueryInterface(IID_IUnknown,(void**)&pIEventSink);

	//シンクオブジェクトの通知
	hr = pCEventSink->DispEventAdvise(pICtrl, &DIID__ICaoSQLControllerEvents);
	if(FAILED(hr)) {
		return;
	}

	while (true) {
		// 値の取得
		CComVariant vntVal;
		hr = pIItem->get_Value(&vntVal);
		if (FAILED(hr)) {
			std::cout << "Error : get_Value(" << hr << ")"<< std::endl;
			std::cout << "Press enter key." << std::endl;
			getwchar();
			return;
		}

		wchar_t wcsBuf[256];
		hr = vntVal.ChangeType(VT_BSTR);	// 文字列で表示できるもののみ画面に表示
		if (SUCCEEDED(hr)) {
			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));
#endif
		}

		// 値の設定
		std::cout << "Input data : ";
#if _MSC_VER <  1400
		_getws(wcsBuf);
#else
		_getws_s(wcsBuf, sizeof(wcsBuf));
#endif

		if (wcsBuf[0] == L'\0') {	// 未入力で終了
			break;
		}

		hr = pIItem->put_Value(CComVariant(wcsBuf));
		if (FAILED(hr)) {
			std::cout << "Error : put_Value(" << hr << ")"<< std::endl;
			std::cout << "Press enter key." << std::endl;
			getwchar();
			return;
		}
		std::cout << "Press enter key." << std::endl;
		getwchar();

		// DoEvents
		MSG msg;
		if(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
			::TranslateMessage(&msg);
			::DispatchMessage(&msg);
		}
	}
	pCEventSink->DispEventUnadvise(pICtrl, &DIID__ICaoSQLControllerEvents);

	return;
}
