📄 server.cpp
字号:
}
else
{
// Since m_strRemoteMachine is not empty, we will assume it contains
// a valid remote machine name. We will try to instantiate the OPC
// Server object on the machine with that name.
// First we need to initialize a server info structure:
COSERVERINFO tCoServerInfo;
ZeroMemory (&tCoServerInfo, sizeof (tCoServerInfo));
// Allocate memory for the machine name string:
int nSize = m_strRemoteMachine.GetLength () * sizeof (WCHAR);
tCoServerInfo.pwszName = new WCHAR [nSize];
// Check validity of pointer. If it's bad, there's no point in continuing:
if (!tCoServerInfo.pwszName)
{
ASSERT (FALSE);
return (false);
}
// Copy the machine name string into the server info structure:
#ifdef _UNICODE
// For Unicode builds, the contents of m_strRemoteMachine will
// already be in wide character format, as demanded by COM, so
// copy it as is.
lstrcpyn (tCoServerInfo.pwszName, m_strRemoteMachine, nSize);
#else
// For ANSI builds, the contents of m_strRemoteMachine will not
// be in wide character format, as demanded by COM, so we need
// to reformat:
mbstowcs (tCoServerInfo.pwszName, m_strRemoteMachine, nSize);
#endif//_UNICODE
// CoCreateInstanceEx will launch the OPC Server if necessary, and
// call its QueryInterface for us (bumping its reference count):
hr = CoCreateInstanceEx (
clsid, // CLSID
NULL, // No aggregation
CLSCTX_REMOTE_SERVER, // connect to remote servers
&tCoServerInfo, // remote machine name
sizeof (m_arrMultiQI) / sizeof (MULTI_QI), // number of IIDS to query
m_arrMultiQI); // array of IID pointers to query
// COM requires us to free memory allocated for [out] and [in/out]
// arguments (i.e. name string).
delete [] tCoServerInfo.pwszName;
}
// If CoCreateInstanceEx succeeded, we can check the returned
// interface pointers and save them as member variables:
if (SUCCEEDED (hr))
{
TRACE (_T("OTC: Initializing server %s interfaces.\r\n"), GetProgID ());
// Check IOPCServer interface pointer:
if (SUCCEEDED (m_arrMultiQI [MQI_IOPCSERVER].hr))
{
m_pIServer = (IOPCServer *)m_arrMultiQI [MQI_IOPCSERVER].pItf;
if (m_pIServer == NULL)
{
// Warning success but no valid pointer:
ASSERT (FALSE);
}
}
else
{
if (m_arrMultiQI [MQI_IOPCSERVER].pItf != NULL)
{
// Warning failure but pointer not set to null
ASSERT (FALSE);
}
TRACE (_T("OTC: Failed to query IOPCServer (%08X).\r\n"),
m_arrMultiQI [MQI_IOPCSERVER].hr);
}
// Check IOPCCommon interface pointer:
if (SUCCEEDED (m_arrMultiQI [MQI_IOPCCOMMON].hr))
{
m_pICommon = (IOPCCommon *)m_arrMultiQI [MQI_IOPCCOMMON].pItf;
if (m_pICommon == NULL)
{
// Warning success but no valid pointer:
ASSERT (FALSE);
}
}
else
{
if (m_arrMultiQI [MQI_IOPCCOMMON].pItf != NULL)
{
// Warning failure but pointer not set to null:
ASSERT (FALSE);
}
TRACE (_T("OTC: Failed to query IOPCCommon (%08X).\r\n"),
m_arrMultiQI [MQI_IOPCCOMMON].hr);
}
// Check IConnectionPointContainer interface pointer:
if (SUCCEEDED (m_arrMultiQI [MQI_IOPCCONNPT].hr))
{
m_pIConnPtContainer =
(IConnectionPointContainer *)m_arrMultiQI [MQI_IOPCCONNPT].pItf;
if (m_pIConnPtContainer == NULL)
{
// Warning success but no valid pointer:
ASSERT (FALSE);
}
}
else
{
if (m_arrMultiQI [MQI_IOPCCONNPT].pItf != NULL)
{
// Warning failure but pointer not set to null:
ASSERT (FALSE);
}
TRACE (_T("OTC: Failed to query IConnectionPoint (%08X).\r\n"),
m_arrMultiQI [MQI_IOPCCONNPT].hr);
}
// Check IOPCItemProperties interface pointer:
if (SUCCEEDED (m_arrMultiQI [MQI_IOPCITEMPROP].hr))
{
m_pIItemProps =
(IOPCItemProperties *)m_arrMultiQI [MQI_IOPCITEMPROP].pItf;
if (m_pIItemProps == NULL)
{
// Warning success but no valid pointer:
ASSERT (FALSE);
}
}
else
{
if (m_arrMultiQI [MQI_IOPCITEMPROP].pItf != NULL)
{
// Warning failure but pointer not set to null:
ASSERT (FALSE);
}
TRACE (_T("OTC: Failed to query IOPCItemProperties (%08X).\r\n"),
m_arrMultiQI [MQI_IOPCITEMPROP].hr);
}
// Check IOPCBrowseServerAddressSpace interface pointer:
if (SUCCEEDED (m_arrMultiQI [MQI_IOPCBROWSE].hr))
{
m_pIBrowse =
(IOPCBrowseServerAddressSpace *)m_arrMultiQI [MQI_IOPCBROWSE].pItf;
if (m_pIBrowse == NULL)
{
// Warning success but no valid pointer:
ASSERT (FALSE);
}
}
else
{
if (m_arrMultiQI [MQI_IOPCBROWSE].pItf != NULL)
{
// Warning failure but pointer not set to null:
ASSERT (FALSE);
}
TRACE (_T("OTC: Failed to query IOPCBrowseServerAddressSpace (%08X).\r\n"),
m_arrMultiQI [MQI_IOPCBROWSE].hr);
}
// Check IOPCServerPublicGroups interface pointer:
if (SUCCEEDED (m_arrMultiQI [MQI_IOPCPUBLIC].hr))
{
m_pIPublicGroups =
(IOPCServerPublicGroups *)m_arrMultiQI [MQI_IOPCPUBLIC].pItf;
if (m_pIPublicGroups == NULL)
{
// Warning success but no valid pointer:
ASSERT (FALSE);
}
}
else
{
if (m_arrMultiQI [MQI_IOPCPUBLIC].pItf != NULL)
{
// Warning failure but pointer not set to null:
ASSERT (FALSE);
}
TRACE (_T("OTC: Failed to query IOPCServerPublicGroups (%08X).\r\n"),
m_arrMultiQI [MQI_IOPCPUBLIC].hr);
}
// Check IPersistFile interface pointer:
if (SUCCEEDED (m_arrMultiQI [MQI_IOPCPERSIST].hr))
{
m_pIPersistFile =
(IPersistFile *)m_arrMultiQI [MQI_IOPCPERSIST].pItf;
if (m_pIPersistFile == NULL)
{
// Warning success but no valid pointer:
ASSERT (FALSE);
}
}
else
{
if (m_arrMultiQI [MQI_IOPCPERSIST].pItf != NULL)
{
// Warning failure but pointer not set to null:
ASSERT (FALSE);
}
TRACE (_T("OTC: Failed to query IPersistsFile (%08X).\r\n"),
m_arrMultiQI [MQI_IOPCPERSIST].hr);
}
// Check IConnectionPointContainer interface pointer:
if (m_pIConnPtContainer != NULL)
{
// If the server supports the shutdown interface, provide a sink
// to the server.
// Get connection point pointer:
IConnectionPoint *pCP = NULL;
hr = m_pIConnPtContainer->FindConnectionPoint (IID_IOPCShutdown, &pCP);
// If we got the connection point, instantiate our shutdown sink:
if (SUCCEEDED (hr))
{
try
{
// Instantiate the shutdown sink and add us to its reference count:
m_pIShutdownSink = new IKShutdownSink (this);
m_pIShutdownSink->AddRef ();
// Give the connection point a pointer to our shutdown sink:
// (m_dwCookieShutdownSink is a returned token that uniquely
// identifies this connection.)
hr = pCP->Advise (m_pIShutdownSink, &m_dwCookieShutdownSink);
// We are done with the connection point, so release our reference:
pCP->Release ();
}
catch (...)
{
// If we find ourselves here, either "new" failed or pCP is bad.
ASSERT (FALSE);
hr = E_FAIL;
}
}
}
// We will base our success on the validity of the IOPCServer interface
// pointer. If it is invalid, then we won't be able do do anyting:
m_bConnected = (m_pIServer != NULL);
// Log success or failure:
if (m_bConnected)
LogMsg (IDS_SERVER_CONNECT_SUCCESS, GetProgID ());
else
LogMsg (IDS_SERVER_REQUIRED_IID_UNSUPPORTED, GetProgID (), hr);
}
// CoCreateInstanceEx failed:
else
{
// log failure
LogMsg (IDS_SERVER_CONNECT_FAILURE, GetProgID (), hr);
}
}
// Failed to get Class ID:
else
{
// Log failure:
LogMsg (IDS_SERVER_UNABLE_TO_GET_CLSID, GetProgID ());
}
// Return connected state:
return (m_bConnected);
}
// **************************************************************************
// Connect ()
//
// Description:
// Attempts to connect to the OPC Server with specified ProgID and machine name.
//
// Parameters:
// CString &strProgID ProgID of OPC server.
// CString &strRemoteMachine Machine name OPC server is on.
//
// Returns:
// bool - true if success.
// **************************************************************************
bool CKServer::Connect (CString &strProgID, CString &strRemoteMachine)
{
ASSERT (m_bConnected == FALSE);
// Update our prog ID and machine name member variables:
SetProgID (strProgID);
SetRemoteMachine (strRemoteMachine);
// Connect:
return (Connect ());
}
// **************************************************************************
// Disconnect ()
//
// Description:
// Called to disconnect from OPC server.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKServer::Disconnect ()
{
// Log success if we were truly connected:
if (m_bConnected == true)
LogMsg (IDS_SERVER_DISCONNECTED, GetProgID ());
// Reset member variable:
m_bConnected = false;
// Release all of our server interface references:
if (m_pIServer)
{
m_pIServer->Release ();
m_pIServer = NULL;
}
if (m_pICommon)
{
m_pICommon->Release ();
m_pICommon = NULL;
}
if (m_pIConnPtContainer)
{
// Unadvise shutdown notifications:
if (m_dwCookieShutdownSink != 0)
{
HRESULT hr = E_FAIL;
IConnectionPoint *pCP = NULL;
hr = m_pIConnPtContainer->FindConnectionPoint (IID_IOPCShutdown, &pCP);
if (SUCCEEDED (hr))
{
hr = pCP->Unadvise (m_dwCookieShutdownSink);
pCP->Release ();
}
if (FAILED (hr))
{
TRACE (_T("OTC: CKServer::Disconnect () - failed to unadvise shutdown notifications\r\n"));
}
m_dwCookieShutdownSink = 0;
}
if (m_pIShutdownSink != NULL)
{
m_pIShutdownSink->Release ();
m_pIShutdownSink = NULL;
}
m_pIConnPtContainer->Release ();
m_pIConnPtContainer = NULL;
}
if (m_pIItemProps)
{
m_pIItemProps->Release ();
m_pIItemProps = NULL;
}
if (m_pIBrowse)
{
m_pIBrowse->Release ();
m_pIBrowse = NULL;
}
if (m_pIPublicGroups)
{
m_pIPublicGroups->Release ();
m_pIPublicGroups = NULL;
}
if (m_pIPersistFile)
{
m_pIPersistFile->Release ();
m_pIPersistFile = NULL;
}
}
// **************************************************************************
// ShutdownRequest ()
//
// Description:
// 2.0 OPC servers provide a notification if they are shutting down while
// we are still connected. The notification comes through our IKShutdownSink
// and is passed on to the server object through this function.
//
// Parameters:
// LPCTSTR lpszReason String sent from OPC server describing reason
// for shutdown. Could be NULL string.
//
// Returns:
// void
// **************************************************************************
void CKServer::ShutdownRequest (LPCTSTR lpszReason)
{
// Log "server requested shutdown" message:
if (lpszReason)
LogMsg (IDS_SERVER_REQUESTED_SHUTDOWN, GetProgID (), lpszReason);
// Notify the document that an object has been shutdown (i.e., invalidated):
// First get a pointer to the application's main window:
CKMainWnd *pWnd = (CKMainWnd *) AfxGetMainWnd ();
// Post the user defined "UM_SERVER_SHUTDOWN" message to the main window.
// It will pass the message along to the docoument object. It will expect
// a pointer to this server object passed a the lParam.
if (pWnd)
pWnd->PostMessage (UM_SERVER_SHUTDOWN, 0, (LPARAM) this);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -