/** * @file XTPGaugeTraits.cpp * * @copyright * (c) 1998-2025 Codejock Software, All Rights Reserved. * * This source file is the property of Codejock Software and must not be * redistributed by any means without the explicit written permission of * Codejock Software. * * The use of this source code is governed by the terms and conditions specified * in the Toolkit Pro license agreement. Codejock Software grants you, as a * single software developer, the limited right to use this software on one * computer only. * * Contact Information: * support@codejock.com * http://www.codejock.com * */ // TODO: Make printf-like labels format #include "stdafx.h" #include "Common/XTPTypeId.h" #include "Common/XTPCasting.h" #include "Common/XTPResourceManager.h" #include "Gauge/XTPGaugeTraits.h" #include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.h" #ifdef _DEBUG # undef THIS_FILE static char THIS_FILE[] = __FILE__; # define new DEBUG_NEW #endif IMPLEMENT_DYNAMIC(CXTPGaugeTraits, CObject); CXTPGaugeTraits::CXTPGaugeTraits(IStream& stream, CString strTraitsArg /*= CString()*/) : m_strTraitsArg(strTraitsArg) , m_hResMod(NULL) { STATSTG st = { 0 }; HRESULT hr = stream.Stat(&st, STATFLAG_NONAME); if (FAILED(hr)) AfxThrowOleException(hr); if (ULONGLONG(INT_MAX) < st.cbSize.QuadPart) AfxThrowOleException(E_OUTOFMEMORY); CArray buffer; buffer.SetSize(static_cast(st.cbSize.QuadPart) + 1); ULONG cbRead = 0; hr = stream.Read(buffer.GetData(), static_cast(st.cbSize.QuadPart), &cbRead); if (FAILED(hr)) AfxThrowOleException(hr); buffer.SetAt(XTPToIntPtr(cbRead), '\0'); m_strTraits = XTP_CA2CT(buffer.GetData()); } CXTPGaugeTraits::~CXTPGaugeTraits() { POSITION pos = EnumCustomTraits(); CString strJsonPath; COleVariant* pValue = NULL; while (GetNextCustomTrait(pos, strJsonPath, pValue)) delete pValue; } BOOL CXTPGaugeTraits::GetNextCustomTrait(POSITION& pos, CString& strJsonPath, COleVariant*& pValue) const { if (NULL == pos) return FALSE; m_customTraits.GetNextAssoc(pos, strJsonPath, reinterpret_cast(pValue)); return TRUE; } void CXTPGaugeTraits::SetCustomTrait(CString strJsonPath, COleVariant vtValue) { COleVariant*& pValue = reinterpret_cast(m_customTraits[strJsonPath]); if (NULL != pValue) delete pValue; pValue = new COleVariant(vtValue); } COleVariant* CXTPGaugeTraits::GetCustomTrait(CString strJsonPath) const { COleVariant* pValue = NULL; return (m_customTraits.Lookup(strJsonPath, reinterpret_cast(pValue)) ? pValue : NULL); } void CXTPGaugeTraits::SetResourcePath(CString strPath) { m_hResMod = NULL; m_strResPath = strPath; m_strResNamespace = _T(""); m_strResPathTraits.Empty(); if (!strPath.IsEmpty()) { strPath.Replace(_T("\\"), _T("\\\\")); m_strResPathTraits.Format(_T("{\"protocol\": \"file\", \"path\": \"%s\"}"), strPath.operator LPCTSTR()); } } inline BOOL CheckGaugeResNamespaceSymbols(LPCTSTR pNamespace) { if (NULL == pNamespace) return TRUE; LPCTSTR pSym = pNamespace; while (_T('\0') != *pSym) { if (!isalnum(*pSym)) return FALSE; if (_T('_') != *pSym && _T('-') != *pSym) return FALSE; ++pSym; } return TRUE; } BOOL CXTPGaugeTraits::SetResourceModule(HMODULE hResMod, LPCTSTR pNamespace /*= NULL*/) { if (!XTP_ASSERT_CHECK("Gauge resource namespace must contain only alpha-numeric a hyphen and a " "underscore symbols" && CheckGaugeResNamespaceSymbols(pNamespace))) return FALSE; m_strResPath = _T(""); m_strResNamespace = (NULL != pNamespace ? pNamespace : _T("")); m_hResMod = hResMod; m_strResPathTraits.Empty(); if (NULL != m_hResMod) m_strResPathTraits.Format(_T("{\"protocol\": \"res\", \"path\": \"#%08X\", \"namespace\": ") _T("\"%s\"}"), m_hResMod, m_strResNamespace.operator LPCTSTR()); return TRUE; } CString CXTPGaugeTraits::GetCompositeTraitsArgument() const { if (m_strResPathTraits.IsEmpty()) return m_strTraitsArg; return _T("[\"__composite__\",") + m_strTraitsArg + _T(",") + m_strResPathTraits + _T("]"); }