📄 item.cpp
字号:
// Append the formatted element data:
strValue += szNum;
// Terminate each row (except the last):
if (++dwCol == dwCols)
{
if (i < dwSize - cbElements)
strValue += _T(" ] [ ");
dwCol = 0;
}
}
// End delimiter:
strValue += _T(" ]");
}
// Else bad array data:
else
{
strValue = _T("???");
LogMsg (IDS_BADITEMARRAYDATA, GetItemID ());
}
}
break;
default:
strValue = cStringContainer.m_lpszUnknown;
break;
}
}
// Else if data item is not an array:
else
{
// Format output string according to data type:
switch (m_vtValue.vt)
{
case VT_BOOL:
wsprintf (szNum, _T("%d"), m_vtValue.boolVal ? 1 : 0);
break;
case VT_UI1:
wsprintf (szNum, _T("%u"), m_vtValue.bVal);
break;
case VT_I1:
wsprintf (szNum, _T("%d"), m_vtValue.cVal);
break;
case VT_UI2:
wsprintf (szNum, _T("%u"), m_vtValue.uiVal);
break;
case VT_I2:
wsprintf (szNum, _T("%d"), m_vtValue.iVal);
break;
case VT_UI4:
wsprintf (szNum, _T("%u"), m_vtValue.ulVal);
break;
case VT_I4:
wsprintf (szNum, _T("%d"), m_vtValue.lVal);
break;
case VT_R4:
_stprintf (szNum, _T("%G"), m_vtValue.fltVal);
break;
case VT_R8:
_stprintf (szNum, _T("%G"), m_vtValue.dblVal);
break;
case VT_BSTR:
strValue = m_vtValue.bstrVal;
return;
default:
strValue = cStringContainer.m_lpszUnknown;
return;
}
strValue = szNum;
}
}
// Else if item is inactive and/or invalid set value accordingly:
else
{
strValue = cStringContainer.m_lpszUnknown;
}
}
// **************************************************************************
// GetQuality ()
//
// Description:
// Returns a string representation of the current quality.
//
// Parameters:
// none
//
// Returns:
// LPCTSTR - Pointer to quality string.
// **************************************************************************
LPCTSTR CKItem::GetQuality ()
{
// Create a CSafeLock to make this object thread safe. Our critical
// section gets locked here, and will automatically be unlocked when the
// CSafeLock goes out of scope.
CSafeLock cs (&m_csDataLock);
// If item is active an valid, we can rely on server's data:
if (IsValid ())
{
// Quality bits arranged QQSSSLL (each letter a bit).
// Parse quality bits (omit limit bits) and output appropriate string:
switch (m_wQuality & 0xFC)
{
case OPC_QUALITY_BAD_NON_SPECIFIC:
return (cStringContainer.m_lpszQualityBad);
case OPC_QUALITY_BAD_CONFIG_ERR0R:
return (cStringContainer.m_lpszQualityBadConfigError);
case OPC_QUALITY_BAD_NOT_CONNECTED:
return (cStringContainer.m_lpszQualityBadNotConnected);
case OPC_QUALITY_BAD_DEVICE_FAILURE:
return (cStringContainer.m_lpszQualityBadDeviceFailure);
case OPC_QUALITY_BAD_SENSOR_FAILURE:
return (cStringContainer.m_lpszQualityBadSensorFailure);
case OPC_QUALITY_BAD_LAST_KNOWN_VALUE:
return (cStringContainer.m_lpszQualityBadLastKnownValue);
case OPC_QUALITY_BAD_COMM_FAILURE:
return (cStringContainer.m_lpszQualityBadCommFailure);
case OPC_QUALITY_BAD_OUT_OF_SERVICE:
return (cStringContainer.m_lpszQualityBadOutOfService);
case OPC_QUALITY_UNCERTAIN_NON_SPECIFIC:
return (cStringContainer.m_lpszQualityUncertain);
case OPC_QUALITY_UNCERTAIN_LAST_USABLE_VALUE:
return (cStringContainer.m_lpszQualityUncertainLastUsableValue);
case OPC_QUALITY_UNCERTAIN_SENSOR_NOT_ACCURATE:
return (cStringContainer.m_lpszQualityUncertainSensorNotAccurate);
case OPC_QUALITY_UNCERTAIN_EU_UNITS_EXCEEDED:
return (cStringContainer.m_lpszQualityUncertainEUExceeded);
case OPC_QUALITY_UNCERTAIN_SUB_NORMAL:
return (cStringContainer.m_lpszQualityUncertainSubnormal);
case OPC_QUALITY_GOOD_NON_SPECIFIC:
return (cStringContainer.m_lpszQualityGood);
case OPC_QUALITY_GOOD_LOCAL_OVERRIDE:
return (cStringContainer.m_lpszQualityGoodLocalOverride);
default:
return (cStringContainer.m_lpszQualityNoValue);
}
}
// If we make it here, then item is invalid. Return appropriate string:
return (cStringContainer.m_lpszQualityNoValue);
}
// **************************************************************************
// GetTimeStamp ()
//
// Description:
// Returns a string representation of the current timestamp.
//
// Parameters:
// CString &strTimeStamp Output string.
//
// Returns:
// void
// **************************************************************************
void CKItem::GetTimeStamp (CString &strTimeStamp)
{
// Create a CSafeLock to make this object thread safe. Our critical
// section gets locked here, and will automatically be unlocked when the
// CSafeLock goes out of scope.
CSafeLock cs (&m_csDataLock);
// Output timestamp if we are infact timestamped:
if (m_bTimeStamped)
{
FILETIME ftLocal;
// Convert raw timestamp from file time to local file time.
// Proceed with next step in conversion only if successful.
if (FileTimeToLocalFileTime (&m_ftTimeStamp, &ftLocal))
{
SYSTEMTIME systime;
TCHAR szTime [64];
// Convert file time to system time:
if (FileTimeToSystemTime (&ftLocal, &systime))
{
// Format system time string:
wsprintf (szTime, _T("%02d:%02d:%02d:%03d"),
systime.wHour, systime.wMinute, systime.wSecond, systime.wMilliseconds);
// Assign formatted system time string to output string:
strTimeStamp = szTime;
}
// Conversion failed:
else
{
ASSERT (FALSE);
}
}
// Conversion failed:
else
{
ASSERT (FALSE);
}
}
// Else we are not timestamped so set timestamp to non-applicable:
else
strTimeStamp = cStringContainer.m_lpszNonApplicable;
}
// **************************************************************************
// GetUpdateCount ()
//
// Description:
// Returns the number of updates the item has recieved.
//
// Parameters:
// none
//
// Returns:
// DWORD - Current update count.
// **************************************************************************
DWORD CKItem::GetUpdateCount ()
{
// Create a CSafeLock to make this object thread safe. Our critical
// section gets locked here, and will automatically be unlocked when the
// CSafeLock goes out of scope.
CSafeLock cs (&m_csDataLock);
// Return current update count:
return (m_cdwUpdates);
}
/////////////////////////////////////////////////////////////////////////////
// CKItem serialization
/////////////////////////////////////////////////////////////////////////////
// **************************************************************************
// Serialize ()
//
// Description:
// Save or load item settings.
//
// Parameters:
// CArchive &ar The archive to save or load item settings.
//
// Returns:
// void
// **************************************************************************
void CKItem::Serialize (CArchive &ar)
{
// Saving object information:
if (ar.IsStoring ())
{
// Save verion first so we will know how to read information later.
// If format of data needs to change at some point, say we need
// to add another property, then bump up the version number.
ar << CURRENT_VERSION; // current version
// Save item access path:
ar << m_strAccessPath;
// Save full qualified item ID:
ar << m_strItemID;
// Save item active state:
ar << m_bActive;
// Save item data type:
ar << m_vtDataType;
// Save item access rights:
ar << m_dwAccessRights;
// Save flag bit field (we can add flags, for up to a total of 32 in
// this case, without having to change version):
ar.Write (&m_bfFlags, sizeof (m_bfFlags));
}
// Else loading object information:
else
{
// Read version of saved information:
DWORD dwSchema;
ar >> dwSchema;
// Read data according to version:
switch (dwSchema)
{
case VERSION_1:
ar >> m_strAccessPath; // access path
ar >> m_strItemID; // fully qualified item ID
ar >> m_bActive; // active state
ar >> m_vtDataType; // data type
ar >> m_dwAccessRights; // access rights
ar.Read (&m_bfFlags, sizeof (m_bfFlags)); // flags
break;
default:
// Unexpected version. Self-delete and throw achive exception:
delete this;
AfxThrowArchiveException (CArchiveException::badSchema);
break;
}
}
}
// **************************************************************************
// Copy ()
//
// Description:
// Copy an instance of this class. (Save properties to a shared memory file.)
//
// Parameters:
// CFixedSharedFile &sf Shared memory file to copy properties to.
//
// Returns:
// void
// **************************************************************************
void CKItem::Copy (CFixedSharedFile &sf)
{
int nLen;
// To save a string to a shared memory file, we need to first save the
// string length. (CArchive objects, as in Serialize(), has this logic
// built in.)
// Save access path string:
nLen = m_strAccessPath.GetLength ();
sf.Write (&nLen, sizeof (nLen));
sf.Write (m_strAccessPath, nLen * sizeof (TCHAR));
// Save item ID string:
nLen = m_strItemID.GetLength ();
sf.Write (&nLen, sizeof (nLen));
sf.Write (m_strItemID, nLen * sizeof (TCHAR));
// Save active state:
sf.Write (&m_bActive, sizeof (m_bActive));
// Save data type:
sf.Write (&m_vtDataType, sizeof (m_vtDataType));
// Save access rights:
sf.Write (&m_dwAccessRights, sizeof (m_dwAccessRights));
// Save flag bit field:
sf.Write (&m_bfFlags, sizeof (m_bfFlags));
}
// **************************************************************************
// Paste ()
//
// Description:
// Paste an instance of this class. (Load properties from a shared memory file.)
//
// Parameters:
// CFixedSharedFile &sf Shared memory file to paste properties from.
//
// Returns:
// void
// **************************************************************************
void CKItem::Paste (CFixedSharedFile &sf)
{
int nLen;
// To save a string to a shared memory file, we need to first save the
// string length. (CArchive objects, as in Serialize(), has this logic
// built in.) So to read the string back, we read its length first:
// Read access path string:
sf.Read (&nLen, sizeof (nLen));
sf.Read (m_strAccessPath.GetBufferSetLength (nLen), nLen * sizeof (TCHAR));
// Read item ID string:
sf.Read (&nLen, sizeof (nLen));
sf.Read (m_strItemID.GetBufferSetLength (nLen), nLen * sizeof (TCHAR));
// Read active state:
sf.Read (&m_bActive, sizeof (m_bActive));
// Read data type:
sf.Read (&m_vtDataType, sizeof (m_vtDataType));
// Read access rights:
sf.Read (&m_dwAccessRights, sizeof (m_dwAccessRights));
// Read flag bit field:
sf.Read (&m_bfFlags, sizeof (m_bfFlags));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -