C++ Instrument Catalog
MFCController.cpp
Go to the documentation of this file.
1 
6 // Standard includes
7 #include <regex>
8 #include <fstream> // ifstream to read files
9 #include <sstream> // string manipulation
10 
11 // Personal includes
12 #include "MFCController.h"
13 #include "OSDefines.h"
14 
15 #define LOG(__msg__, __level__,__location__) l_SendLogMessage(__msg__, __level__, "", __location__ )
16 
17 #if defined _WIN32
18 #define DIR_SEP '\\'
19 #else
20 #define DIR_SEP '/'
21 #endif
22 
23 
24 //--------------------------------------------------------------------------//
25 // MFC CONTROLLER
26 //--------------------------------------------------------------------------//
27 void CMFCController::l_SendLogMessage(const std::string & rMessage, const CInstrumentCatalog::eLogLevel & rLevel, const std::string & rContext, const std::string & rLocation)
28 {
29  m_ContCat.cLogMessage.RequestControl(CInstrumentCatalog::sLogMessage(rLevel, "MFCManager.Controller"+ rContext, rMessage, rLocation));
30 }
31 
32 void CMFCController::l_SendErrorMessage(const CMFCDevice::sMFCDeviceError & rErrorMessage)
33 {
35  if(CMFCDevice::sMFCDeviceError::kNoError != rErrorMessage.Level)
36  m_ContCat.cError.RequestControl(rErrorMessage);
37 }
38 
39 void CMFCController::l_SendSearchProgress(const U8 & rSearchProgress)
40 {
41  m_ContCat.cSearchProgress.RequestControl(rSearchProgress);
42 }
43 
44 void CMFCController::l_SendSearchResult(const CInstrumentCatalog::sSearchResult & rSearchResult)
45 {
46  m_ContCat.cSearchResult.RequestControl(rSearchResult);
47 }
48 
49 void CMFCController::l_SendMeasResult(const CInstrumentCatalog::sMeasurementResults & rMeasRes)
50 {
51  m_ContCat.cMeasResults.RequestControl(rMeasRes);
52 }
53 
54 bool CMFCController::l_IsAbortRequested()
55 {
56  return CThreadedMailBox::l_IsRequestedToStop();
57 }
58 
59 void CMFCController::l_CheckConnectionOnWarning(const CMFCDevice::sMFCDeviceError & rOriginError, CMFCDevice::sMFCDeviceError & rErrorOut)
60 {
61  rErrorOut = rOriginError;
62  if (CMFCDevice::sMFCDeviceError::eLevel::kWarning == rOriginError.Level && nullptr != m_pMFCDevice)
63  {
64  if(!m_pMFCDevice->IsInstrumentConnected())
65  {
66  rErrorOut.Level = CMFCDevice::sMFCDeviceError::eLevel::kError;
67  rErrorOut.Description = "No instrument connected";
68  rErrorOut.Location = rErrorOut.Location;
69  }
70  }
71 }
72 
73 void CMFCController::l_AbortInstrument()
74 {
76 
77  try
78  {
79  if (nullptr != m_pMFCDevice)
80  {
81  if (!m_pMFCDevice->AbortInstrument())
82  {
83  if (!m_pMFCDevice->AbortInstrument())
84  throw CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kError, "Could not abort instrument", MTL__LOCATION__);
85  }
86  }
87  }
88  catch (CMFCDevice::sMFCDeviceError & rE)
89  {
90  // Signal error
91  l_SendErrorMessage(rE);
92  }
93 }
94 
95 void CMFCController::l_ScanResources()
96 {
98 
99  try
100  {
101  // Check initial conditions
102  MTL_Assert(nullptr != m_pRsrcManager);
103  if (nullptr == m_pRsrcManager)
104  throw CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kFatal, "No given resource manager", MTL__LOCATION__);
105 
106  static CParsedResourceList l_RsrcList, l_NewRsrcList;
107  // Update resource list
108  if (!m_pRsrcManager->FindResources(l_NewRsrcList, "?*"))
109  throw CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kError, "Could not look for resources : " + MTL::Instrument::StatusDescription(m_pRsrcManager->Session(), m_pRsrcManager->Status()), MTL__LOCATION__);
110  if (l_RsrcList != l_NewRsrcList)
111  {
112  l_RsrcList = l_NewRsrcList;
113  m_ContCat.cInstrumentList.RequestControl(l_NewRsrcList);
114  }
115  }
116  catch (CMFCDevice::sMFCDeviceError & rE)
117  {
118  // Signal error
119  l_SendErrorMessage(rE);
120  // Send empty list
122  }
123 }
124 
125 void CMFCController::l_GetRemoteBoxButtonStatus()
126 {
128  try {
129  CMFCDevice::sMFCDeviceError l_RetError;
130  bool l_RemoteBoxPressed(false);
131  // Check initial conditions
132  MTL_Assert(nullptr != m_pMFCDevice);
133  if (nullptr == m_pMFCDevice)
134  throw CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kFatal, "Given instrument pointer is null", MTL__LOCATION__);
135 
136  l_RetError = m_pMFCDevice->RemoteBoxButtonStatus(l_RemoteBoxPressed);
137  if(l_RetError.HasError())
138  {
139  throw l_RetError;
140  }
141  if (l_RemoteBoxPressed)
142  m_ContCat.cRemoteBoxStart.RequestControl(true);
143  }
144  catch (CMFCDevice::sMFCDeviceError & rE)
145  {
147  l_CheckConnectionOnWarning(rE, l_Error);
148  // Signal error
149  l_SendErrorMessage(l_Error);
150  }
151 }
152 
153 bool CMFCController::l_ScanPA()
154 {
156  bool l_PAInfoChanged(false);
157  bool l_PASucceeded(true);
159  try
160  {
161  CMFCDevice::sMFCDeviceError l_RetError;
162 
163  // Check initial conditions
164  MTL_Assert(nullptr != m_pMFCDevice);
165  if (nullptr == m_pMFCDevice)
166  {
167  if (!m_PAInfo.ProbeList.empty())
168  {
169  // Clear whole PA Info including FCA information
172  l_PAInfoChanged = true;
173  }
174  throw CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kFatal, "Given instrument pointer is null", MTL__LOCATION__);
175  }
176 
177  l_RetError = m_pMFCDevice->ScanPA(m_PAInfo, l_InsConf, l_PAInfoChanged);
178  if(l_RetError.HasError())
179  {
180  throw l_RetError;
181  }
182  }
183  catch (CMFCDevice::sMFCDeviceError & rE)
184  {
186  l_CheckConnectionOnWarning(rE, l_Error);
187  // Signal error
188  l_SendErrorMessage(l_Error);
189  l_PASucceeded = false;
190  }
191  if (l_PAInfoChanged) // Send new PA Info if changed
192  {
193  m_ContCat.cPAInfo.RequestControl(m_PAInfo);
194  m_ContCat.cInstrumentConfiguration.rRequestControl(l_InsConf);
195  }
196  return l_PASucceeded;
197 }
198 
199 void CMFCController::l_OperateWithInstrument()
200 {
202  try
203  {
204  CMFCDevice::sMFCDeviceError l_RetError;
205  // Depending on the requested operating mode
206  switch (m_InstrState.OperatingMode)
207  {
208  //------------------------------------------------
209  // Idle operation
211  // Nothing to do
212  throw CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kFatal, "Cannot operate in kIdle mode", MTL__LOCATION__);
213  break;
214 
215  //------------------------------------------------
216  // Search operation
218  {
219  // Check initial conditions
220  // Check that we have an instrument
221  MTL_Assert(nullptr != m_pMFCDevice);
222  if (nullptr == m_pMFCDevice)
223  throw CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kFatal, "Given instrument pointer is null", MTL__LOCATION__);
224  l_RetError = m_pMFCDevice->Search(m_InstrState);
225  if(l_RetError.HasError())
226  {
227  throw l_RetError;
228  }
229  }
230  break;
231 
232  //------------------------------------------------
233  // Measure operation
235  {
236  // Check initial conditions
237  // Check that we have an instrument
238  MTL_Assert(nullptr != m_pMFCDevice);
239  if (nullptr == m_pMFCDevice)
240  throw CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kFatal, "Given instrument pointer is null", MTL__LOCATION__);
241  l_RetError = m_pMFCDevice->Measure(m_InstrState);
242  if(l_RetError.HasError())
243  {
244  throw l_RetError;
245  }
246  }
247  break;
248  }
249  }
250  catch (CMFCDevice::sMFCDeviceError & rE)
251  {
252  // Signal error
253  l_SendErrorMessage(rE);
254  }
255 }
256 
257 void CMFCController::l_RequestSelfAbort()
258 {
259  Terminate();
260 
262  m_ContCat.cState.RequestControl(m_ControllerState);
263 }
264 
265 CMFCController::CMFCController(CMFCManagerCatalog & rCatInstance, const std::string & rDefaultPAConfScriptFilePath, const std::string & rCustomPAConfScriptDir)
266  :
267  m_ContCat(rCatInstance),
268  m_Timer(std::bind(&CMFCController::l_PostTimerEvent, this)),
269  m_ControllerState(CMFCManagerCatalog::eControllerState::kIdle),
270  m_pMFCDevice(nullptr),
271  m_DefaultPAConfScriptFilePath(rDefaultPAConfScriptFilePath),
272  m_CustomPAConfScriptDirectory(rCustomPAConfScriptDir)
273 {
275 }
276 
278 {
280 
281  Terminate();
282 }
283 
284 void CMFCController::l_TimerEventHandler()
285 {
286  try
287  {
288  switch (m_ControllerState)
289  {
291  l_ScanResources();
292  m_Timer.Stop();
293  m_Timer.StartSingleShot(std::chrono::milliseconds(RSRC_POLLING_PERIOD_MS));
294  break;
295 
297  if(l_ScanPA())
298  l_GetRemoteBoxButtonStatus();
299  m_Timer.Stop();
300  m_Timer.StartSingleShot(std::chrono::milliseconds(PA_POLLING_PERIOD_MS));
301  break;
302 
305  l_OperateWithInstrument();
306  Terminate();
307  break;
308 
309  default:
310  // Unhandled case
311  MTL_Assert(false);
312  throw false;
313  break;
314  }
315  }
316  catch (...)
317  {
318  l_SendErrorMessage(CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kFatal, "Unhandled exception type", MTL__LOCATION__));
319  Terminate();
320  }
321 }
322 
323 void CMFCController::l_PostTimerEvent()
324 {
325  CThreadedMailBox::l_SendMsg(sMFCControllerMailBoxMsg(sMFCControllerMailBoxMsg::eMsgType::kTimerEvent));
326 }
327 
328 void CMFCController::l_ThreadTask(eEventType EvtType, sMFCControllerMailBoxMsg * pMsg)
329 {
330  switch (EvtType)
331  {
332  case eEventType::kExit:
333  // Abort instrument
334  l_AbortInstrument();
335  // Set new controller state
337  m_ContCat.cState.RequestControl(m_ControllerState);
338  break;
339  case eEventType::kUserMsg:
340  if (nullptr != pMsg)
341  {
342  switch (pMsg->MsgType)
343  {
344  case sMFCControllerMailBoxMsg::eMsgType::kTimerEvent:
345  l_TimerEventHandler();
346  break;
347  }
348  }
349  break;
350  }
351 }
352 
354 {
355  CThreadedMailBox::ThreadStart();
356 }
357 
359 {
360  CThreadedMailBox::ThreadStop();
361  m_Timer.Stop(); // Must be done after CThreadedMailBox::ThreadStop(). Timer may have been restarted before the thread stop completely.
362 }
363 
365 {
367 
368  // Prepare context for scanning instruments
369  // Start timer to trigger periodic scan
370 
371  Terminate();
372 
373  m_pMFCDevice = nullptr;
374  MTL_Assert(nullptr != pRsrcManager);
375  if (nullptr == pRsrcManager)
376  {
377  l_SendErrorMessage(CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kFatal, "Given resource manager pointer is null", MTL__LOCATION__));
378  return;
379  }
380  m_pRsrcManager = pRsrcManager;
381 
383  m_ContCat.cState.RequestControl(m_ControllerState);
384  Operate();
385  m_Timer.StartSingleShot(std::chrono::milliseconds(0));
386 }
387 
389 {
391 
392  // Prepare context for scanning PA
393  // Start timer to trigger periodic scan
394 
395  Terminate();
396 
397  MTL_Assert(nullptr != pMFCDevice);
398  if (nullptr == pMFCDevice)
399  {
400  l_SendErrorMessage(CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kFatal, "Given instrument pointer is null", MTL__LOCATION__));
401  return;
402  }
403  if (pMFCDevice != m_pMFCDevice)
404  {
405  m_PAInfo.clear(); // Clear PA info
406  }
407  m_pMFCDevice = pMFCDevice;
408 
410  m_ContCat.cState.RequestControl(m_ControllerState);
411  Operate();
412  m_Timer.StartSingleShot(std::chrono::milliseconds(0));
413 }
414 
416 {
418 
419  // Prepare context for changing instrument state
420  // If requested to go Idle, nothing else is done
421  // If requested to operate, trigger operation with a single timer shot
422 
423  Terminate();
424 
425  MTL_Assert(nullptr != pMFCDevice);
426  if (nullptr == pMFCDevice)
427  {
428  l_SendErrorMessage(CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kFatal, "Given instrument pointer is null", MTL__LOCATION__));
429  return;
430  }
431  m_pMFCDevice = pMFCDevice;
432  m_InstrState = InsState;
433 
434  switch (m_InstrState.OperatingMode)
435  {
438  m_ContCat.cState.RequestControl(m_ControllerState);
439  // Nothing to do
440  break;
443  m_ContCat.cState.RequestControl(m_ControllerState);
444  Operate();
445  m_Timer.StartSingleShot(std::chrono::milliseconds(0));
446  break;
449  m_ContCat.cState.RequestControl(m_ControllerState);
450  Operate();
451  m_Timer.StartSingleShot(std::chrono::milliseconds(0));
452  break;
453  }
454 }
455 
457 {
459 
460  try {
461  MTL_Assert(nullptr != m_pMFCDevice);
462  if (nullptr == m_pMFCDevice)
463  throw CMFCDevice::sMFCDeviceError(CMFCDevice::sMFCDeviceError::eLevel::kFatal, "Given instrument pointer is null", MTL__LOCATION__);
464 
465  CMFCDevice::sMFCDeviceError l_RetError;
467  l_RetError = m_pMFCDevice->GetNormalizationDate(l_NewNormDate);
468  if(l_RetError.HasError())
469  {
470  throw l_RetError;
471  }
472  if(l_NewNormDate != m_PAInfo.NormalizationDate)
473  {
474  m_PAInfo.NormalizationDate = l_NewNormDate;
475  m_ContCat.cPAInfo.RequestControl(m_PAInfo);
476  }
477  }
478  catch (CMFCDevice::sMFCDeviceError & rE)
479  {
481  l_CheckConnectionOnWarning(rE, l_Error);
482  // Signal error
483  l_SendErrorMessage(l_Error);
484  }
485 }
MTL::CInstrumentCatalog::tISO8601DateTime
std::string tISO8601DateTime
Definition: InstrumentCatalog.h:28
MTL::CMFCController::Operate
void Operate()
Definition: MFCController.cpp:353
MTL::CMFCManagerCatalog::eControllerState::kSearching
@ kSearching
MTL::Instrument::CVISAResourceManager::FindResources
bool FindResources(CResourceList &rList, std::string Filter="?*")
Definition: VISAInstrument.cpp:121
MTL::CInstrumentCatalog::sProbeArrayInformation::clear
void clear()
Definition: InstrumentCatalog.h:170
MTL::CMFCControllerInterface::cError
CControl< CMFCDevice::sMFCDeviceError > cError
Definition: MFCManagerCatalog.h:113
MTL::CMFCControllerInterface::cRemoteBoxStart
CControl< bool > cRemoteBoxStart
Definition: MFCManagerCatalog.h:115
MTL::CMFCController::SetInstrumentState
void SetInstrumentState(CMFCDevice *pMFCDevice, CInstrumentCatalog::sInstrumentState InsState)
Definition: MFCController.cpp:415
MTL::sMFCControllerMailBoxMsg::MsgType
enum MTL::sMFCControllerMailBoxMsg::eMsgType MsgType
MTL::CInstrumentCatalog::sMeasurementResults
Definition: InstrumentCatalog.h:267
MTL::CInstrumentCatalog::sSearchResult
Definition: InstrumentCatalog.h:250
MTL::Instrument::CVISAResourceManager::Status
ViStatus Status()
Definition: VISAInstrument.cpp:108
MTL::CMFCDevice::sMFCDeviceError::kNoError
@ kNoError
Definition: MFCDevice.h:35
MTL::Instrument::eEventType
eEventType
Definition: VISAInstrumentTypes.h:95
MTL::CMFCController::ScanPA
void ScanPA(CMFCDevice *pMFCDevice)
Definition: MFCController.cpp:388
MTL::CInstrumentCatalog::eLogLevel::kDebug
@ kDebug
MTL::CMFCControllerInterface::cInstrumentConfiguration
CControl< CInstrumentCatalog::sInstrumentConfiguration > cInstrumentConfiguration
Definition: MFCManagerCatalog.h:109
MTL::CInstrumentCatalog::sLogMessage
Definition: InstrumentCatalog.h:319
MTL::CMFCController::Terminate
void Terminate()
Definition: MFCController.cpp:358
MTL::CMFCDevice::ScanPA
virtual sMFCDeviceError ScanPA(CInstrumentCatalog::sProbeArrayInformation &rPAInfo, CInstrumentCatalog::sInstrumentConfiguration &rInstrConfig, bool &rPaInfoChanged)=0
MTL::CMFCDevice::GetNormalizationDate
virtual sMFCDeviceError GetNormalizationDate(CInstrumentCatalog::tISO8601DateTime &rNormDate)=0
MTL_Assert
#define MTL_Assert
Definition: Helpers.h:44
MTL::CMFCManagerCatalog::eControllerState::kScanningInstruments
@ kScanningInstruments
MTL::CInstrumentCatalog::sInstrumentState
Definition: InstrumentCatalog.h:212
MTL::ThreadedMailbox::CTimer::StartSingleShot
bool StartSingleShot(std::chrono::milliseconds Delay_ms)
Definition: ThreadedMailbox.h:177
MTL::CInstrumentCatalog::eLogLevel
eLogLevel
Definition: InstrumentCatalog.h:313
MTL::CInstrumentCatalog::eOperatingMode::kIdle
@ kIdle
MTL::CMFCDevice::sMFCDeviceError
Definition: MFCDevice.h:30
MTL::CMFCDevice::sMFCDeviceError::Level
enum MTL::CMFCDevice::sMFCDeviceError::eLevel Level
MTL::CMFCControllerInterface::cPAInfo
CControl< CInstrumentCatalog::sProbeArrayInformation > cPAInfo
Definition: MFCManagerCatalog.h:108
MTL::Instrument::StatusDescription
std::string StatusDescription(ViSession Session, ViStatus Status)
Return user-readable description of the given status code.
Definition: VISAInstrument.cpp:40
MTL::CMFCDevice
Definition: MFCDevice.h:24
MTL::CMFCDevice::sMFCDeviceError::Description
std::string Description
Definition: MFCDevice.h:37
MTL::CMFCControllerInterface::cSearchProgress
CControl< U8 > cSearchProgress
Definition: MFCManagerCatalog.h:110
MTL::Instrument::CVISAResourceManager::Session
const ViSession & Session()
Definition: VISAInstrument.cpp:112
MTL::InstrumentCatalogInterface::CControl::RequestControl
void RequestControl(const DataType NewValue)
Definition: CatalogInterface.h:28
MTL::CMFCController::ScanInstruments
void ScanInstruments(CVISAResourceManager *pRsrcManager)
Definition: MFCController.cpp:364
MTL::CMFCDevice::sMFCDeviceError::Location
std::string Location
Definition: MFCDevice.h:38
MTL::CInstrumentCatalog::sProbeArrayInformation
Definition: InstrumentCatalog.h:145
MTL::ThreadedMailbox::CTimer::Stop
void Stop()
Definition: ThreadedMailbox.h:203
MTL::CMFCDevice::sMFCDeviceError::HasError
bool HasError()
Definition: MFCDevice.h:45
MTL::CMFCDevice::RemoteBoxButtonStatus
virtual sMFCDeviceError RemoteBoxButtonStatus(bool &rRemoteStartPressed)=0
MTL::CInstrumentCatalog::eOperatingMode::kMeasure
@ kMeasure
MTL::sMFCControllerMailBoxMsg
Definition: MFCController.h:27
MFCController.h
MTL::CMFCController
Definition: MFCController.h:34
MTL::CInstrumentCatalog::sInstrumentState::OperatingMode
eOperatingMode OperatingMode
Definition: InstrumentCatalog.h:213
MTL::CMFCControllerInterface::cLogMessage
CControl< CInstrumentCatalog::sLogMessage > cLogMessage
Definition: MFCManagerCatalog.h:114
MTL::CMFCController::~CMFCController
virtual ~CMFCController()
Definition: MFCController.cpp:277
LOG
#define LOG(__msg__, __level__, __location__)
Definition: MFCController.cpp:15
MTL::CMFCManagerCatalog
Definition: MFCManagerCatalog.h:19
MTL::CMFCManagerCatalog::eControllerState::kIdle
@ kIdle
MTL::CInstrumentCatalog::sProbeArrayInformation::NormalizationDate
tISO8601DateTime NormalizationDate
Definition: InstrumentCatalog.h:149
MTL::CMFCController::UpdateNormalizationDate
void UpdateNormalizationDate()
Definition: MFCController.cpp:456
MTL::CInstrumentCatalog::eOperatingMode::kSearch
@ kSearch
OSDefines.h
Platform Dependent Definitions.
MTL::CMFCControllerInterface::cInstrumentList
CControl< CParsedResourceList > cInstrumentList
Definition: MFCManagerCatalog.h:107
MTL::CMFCManagerCatalog::eControllerState::kMeasuring
@ kMeasuring
MTL::CMFCControllerInterface::cState
CControl< CMFCManagerCatalog::eControllerState > cState
Definition: MFCManagerCatalog.h:106
MTL::CMFCController::CMFCController
CMFCController(CMFCManagerCatalog &rCatInstance, const std::string &rDefaultPAConfScriptFilePath, const std::string &rCustomPAConfScriptDir)
Definition: MFCController.cpp:265
MTL::CMFCDevice::IsInstrumentConnected
virtual bool IsInstrumentConnected()=0
MTL::CMFCDevice::Search
virtual sMFCDeviceError Search(const CInstrumentCatalog::sInstrumentState &rInstrState)=0
MTL::CMFCControllerInterface::cSearchResult
CControl< CInstrumentCatalog::sSearchResult > cSearchResult
Definition: MFCManagerCatalog.h:111
MTL::Instrument::CVISAResourceManager
VISA Resource Manager class.
Definition: VISAInstrument.h:35
MTL::CMFCManagerCatalog::eControllerState::kScanningPA
@ kScanningPA
MTL::CInstrumentCatalog::sInstrumentConfiguration
Definition: InstrumentCatalog.h:116
MTL__LOCATION__
#define MTL__LOCATION__
Definition: Helpers.h:22
MTL::Instrument::CParsedResourceList
Definition: VISAInstrumentTypes.h:253
MTL::CMFCDevice::Measure
virtual sMFCDeviceError Measure(const CInstrumentCatalog::sInstrumentState &rInstrState)=0
MTL::CInstrumentCatalog::sProbeArrayInformation::ProbeList
std::vector< sProbeInformation > ProbeList
Definition: InstrumentCatalog.h:154
MTL::CMFCDevice::AbortInstrument
virtual bool AbortInstrument()=0
MTL::CMFCControllerInterface::cMeasResults
CControl< CInstrumentCatalog::sMeasurementResults > cMeasResults
Definition: MFCManagerCatalog.h:112