📄 cppsimpleserver.cpp
字号:
// CPPSimpleServer.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "SLIKServerEvents.h"
#include <string>
using namespace std;
//
// This is required by <atlcom.h> - it's not used otherwise
//
CComModule _Module;
BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()
/////////////////////////////////////////////////////////////////////////////
//
// G L O B A L V A R I A B L E S
//
/////////////////////////////////////////////////////////////////////////////
//
// Required to be global so we can access in Simulate routine!
//
ISLIKServerPtr g_spSlikSvr;
/////////////////////////////////////////////////////////////////////////////
//
// H E L P E R R O U T I N E S
//
/////////////////////////////////////////////////////////////////////////////
LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
{
while (p1 != NULL && *p1 != NULL)
{
LPCTSTR p = p2;
while (p != NULL && *p != NULL)
{
if (*p1 == *p)
return CharNext(p1);
p = CharNext(p);
}
p1 = CharNext(p1);
}
return NULL;
}
HRESULT CreateSLIKServer( ISLIKServerPtr &spSlikSvr )
{
HRESULT hr = S_OK;
//
// SLIK-DA is a licensed ActiveX control. Therefore, we
// MUST use the IClassFactory2 interface to create an instance
// of the control.
//
CComPtr<IClassFactory2> spCF;
try
{
_com_util::CheckError( CoGetClassObject(
__uuidof(SLIKServer),
CLSCTX_INPROC_SERVER,
NULL,
IID_IClassFactory2,
(void **) &spCF
) );
//
// NOTE: The run-time license key used here works for
// DEMO VERSIONS OF SLIK-DA ONLY!
//
spCF->CreateInstanceLic(
NULL,
NULL,
__uuidof(ISLIKServer),
L"{95A710F2-7D58-419A-92FE-D7E5E0FEC804}",
(void **) &spSlikSvr
);
}
catch( _com_error e )
{
hr = e.Error();
}
return hr;
}
HRESULT SetupNamespace(
ISLIKServerPtr &spSlikSvr
)
{
HRESULT hr = S_OK;
try
{
_variant_t vOptionalVal;
vOptionalVal.vt = VT_ERROR;
_variant_t vInitVal;
for( long i = 1; i <= 5; i++ )
{
vInitVal = i;
WCHAR wsz[5];
_ltow( i, wsz, 10 );
//
// Add a few read-only tags - these source tags will change in value
// via simulation
//
wstring wstrName = L"src.tag0";
wstrName += wsz;
spSlikSvr->SLIKTags->Add(
wstrName.c_str(),
sdaReadAccess,
vInitVal,
sdaGood,
0, // Value to pass for SLIK-DA to auto-generate the timestamp
vtMissing // Access paths not used - pass vtMissing
);
//
// Add a few read-write tags - these target tags will NOT change
// via simulation
//
wstrName = L"trg.tag0";
wstrName += wsz;
spSlikSvr->SLIKTags->Add(
wstrName.c_str(),
sdaReadAccess | sdaWriteAccess,
vInitVal,
sdaGood,
0,
vtMissing
);
}
}
catch( _com_error e )
{
hr = e.Error();
}
return hr;
}
VOID CALLBACK Simulate(
HWND hwnd, // handle to window
UINT uMsg, // WM_TIMER message
UINT_PTR idEvent, // timer identifier
DWORD dwTime // current system time
)
{
//
// Simulate data changes for all read-only tags.
//
// NOTE: SLIKTags collection uses 1-based indices
for( long i = 1; i <= g_spSlikSvr->SLIKTags->Count; i++ )
{
CComPtr<ISLIKTag> spTag;
spTag = g_spSlikSvr->SLIKTags->Item( i );
if( spTag->AccessPermissions == sdaReadAccess )
{
long lVal = spTag->GetValue();
lVal = (lVal + 1) % 1000;
// NOTE: passing a 0 for Timestamp means SLIK-DA will
// autogenerate one.
spTag->SetVQT( lVal, sdaGood, 0 );
}
}
}
/////////////////////////////////////////////////////////////////////////////
//
// M O D U L E E N T R Y P O I N T
//
/////////////////////////////////////////////////////////////////////////////
extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
{
HRESULT hr = CoInitialize( NULL );
_ASSERTE( SUCCEEDED( hr ) );
//
// The following is required to facilitate use of ATL's event handling
// support. The global CComMoudle object instance is not used otherwise.
//
_Module.Init( ObjectMap, hInstance );
try
{
_com_util::CheckError( CreateSLIKServer( g_spSlikSvr ) );
//
// Set up the SLIKServer properties - MUST be done before
// calling RegisterServer() / UnregisterServer().
//
g_spSlikSvr->ProgID = L"NDI.CPPSimpleServer.1";
g_spSlikSvr->AppID = L"{E33BB673-514F-4812-84AC-DEE625C97070}";
g_spSlikSvr->CLSID = g_spSlikSvr->AppID;
g_spSlikSvr->AppName = L"C++ Simple Server";
g_spSlikSvr->Description = L"C++ Simple Server using SLIK-DA 2.0";
g_spSlikSvr->VendorName = L"Northern Dynamic Inc.";
g_spSlikSvr->MaxUpdateRate = 500;
//
// Check command line for registration switches - an OPC server
// EXE must support self-registration.
//
BOOL bRun = TRUE;
TCHAR szTokens[] = _T("-/");
LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
while (lpszToken != NULL)
{
if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
{
g_spSlikSvr->UnregisterServer();
bRun = FALSE;
break;
}
if (lstrcmpi(lpszToken, _T("RegServer"))==0)
{
g_spSlikSvr->RegisterServer();
bRun = FALSE;
break;
}
lpszToken = FindOneOf(lpszToken, szTokens);
}
if( bRun )
{
//
// Hook up handler for SLIKServer events
//
CSLIKServerEvents *pEv = new CSLIKServerEvents;
_com_util::CheckError( pEv->DispEventAdvise( g_spSlikSvr ) );
//
// Create the server tag namespace
//
SetupNamespace( g_spSlikSvr );
//
// Start the OPC server services
//
g_spSlikSvr->StartServer();
//
// Set up a timer to simulate data chnages
//
UINT uiTimer = SetTimer( NULL, 0, 500, Simulate );
//
// Must dispatch Windows Messages to receive event notifications
// from SLIK-DA.
//
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
KillTimer( NULL, uiTimer );
}
}
catch( _com_error e )
{
}
catch(...)
{
}
// Be sure to Release the ISLIKServer interface pointer before the
// CoUninitialize() call. Otherwise, the CComPtr<> destructor will execute
// after the underlying SLIKServer object has been destroyed by the
// CoUninitialize() call, causing an access violation.
g_spSlikSvr.Release();
CoUninitialize();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -