#define WINVER 0x0501
#define _WIN32_WINNT 0x0501	
#define _WIN32_WINDOWS 0x0410
#define _WIN32_IE 0x0600
#define WIN32_LEAN_AND_MEAN

// Необходим для "::CoInitializeEx(NULL,COINIT_MULTITHREADED);" 
#define _WIN32_DCOM

#include <stdio.h>
#include <tchar.h>
#include <atlbase.h>
#include <atlcom.h>

#import "progid:NiApi.SrvrSession" no_namespace


_ATL_FUNC_INFO _infoOnStatusMessage  = {CC_STDCALL, VT_I4, 1, {VT_DISPATCH} };
_ATL_FUNC_INFO _infoOnMessage        = {CC_STDCALL, VT_I4, 1, {VT_DISPATCH} };
_ATL_FUNC_INFO _infoOnLogin          = {CC_STDCALL, VT_I4, 1, {VT_I4} };
_ATL_FUNC_INFO _infoOnConnectionLost = {CC_STDCALL, VT_I4, 0, {} };

IID DIID__ISrvrSessionEvents = __uuidof(_ISrvrSessionEvents);

class CSrvrSessionEvents : public IDispEventSimpleImpl<1, CSrvrSessionEvents, &DIID__ISrvrSessionEvents>
{
public:
	BEGIN_SINK_MAP(CSrvrSessionEvents)
		SINK_ENTRY_INFO(1, DIID__ISrvrSessionEvents, 1, OnLogin, &_infoOnLogin)
		SINK_ENTRY_INFO(1, DIID__ISrvrSessionEvents, 2, OnConnectionLost, &_infoOnConnectionLost)
		SINK_ENTRY_INFO(1, DIID__ISrvrSessionEvents, 3, OnMessage, &_infoOnMessage)
		SINK_ENTRY_INFO(1, DIID__ISrvrSessionEvents, 4, OnStatusMessage, &_infoOnStatusMessage)
	END_SINK_MAP()


	HRESULT  __stdcall OnStatusMessage(IDispatch* pMsg)
	{
		printf("\tOnStatusMessage()\n");
		return S_OK;
	}

	HRESULT  __stdcall OnLogin(long Result)
	{
		printf("\tOnLogin()\n");
		return S_OK;
	}
	
	HRESULT  __stdcall OnConnectionLost(void)
	{
		printf("\tOnConnectionLost()\n");
		return S_OK;
	}
	
	HRESULT  __stdcall OnMessage(IDispatch* pMsg)
	{
		printf("\tOnMessage()\n");
		return S_OK;
	}
};


int _tmain(int argc, _TCHAR* argv[])
{
	::CoInitializeEx(NULL,COINIT_MULTITHREADED);

	// вводим блок для срабатывания dtor`a ISrvrSessionPtr, до вызова ISrvrSessionPtr CoUninitialize
	{ 
		CSrvrSessionEvents		SessionEvents;
		ISrvrSessionPtr			pSession(__uuidof(SrvrSession));

		SessionEvents.DispEventAdvise(pSession,&DIID__ISrvrSessionEvents);

		pSession->HostAddr = _bstr_t("10.200.200.201");
		pSession->HostPort = 2900;
		pSession->Name	   = _bstr_t("sa");
		pSession->Password = _bstr_t("sa");
		// если интересно что происходит, включам журнал протокола
		pSession->Journal  = _bstr_t("journal");
		
		printf("Calling Connect()...\n");
		pSession->Connect();

		// даем время немного поработать....
		::Sleep(5000);

		printf("Calling Disconnect()...\n");
		pSession->Disconnect();
		
		// даем время еще немного поработать, что-бы успеть увидеть OnConnectionLost....
		::Sleep(500);

		printf("Done...\n");

		SessionEvents.DispEventUnadvise(pSession,&DIID__ISrvrSessionEvents);
	}

	::CoUninitialize();
	return 0;
}

