123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634 |
- using System.Collections.Generic;
- using OTSDataType;
- using System;
- using System.Drawing;
- using static OTSDataType.otsdataconst;
- using OTSModelSharp.ImageProcess;
- using OTSModelSharp.ServiceInterface;
- using System.Threading;
- namespace OTSModelSharp
- {
- // enum and struct used for send message to App
- public enum ENUM_MSG_TYPE
- {
- MTHREADSTATUS = 1001,
- MSAMPLESTATUS = 1002,
- MSAMPLERESULT = 1003
- };
- public enum MSAMPLE_RET
- {
- BSE_DATA = 0,
- FIELD_DATA = 1,
- START_MSR_FIELD = 2
- };
- public struct SMSR_COMPLETE_DATA
- {
- public OTS_MSR_THREAD_STATUS MsrStatus;
- public string csMsrStartTime;
- public int iMsrCompleteSampleCount;
- public int iMsrCompleteFieldCount;
- public int iParticleCount;
- public TimeSpan MsrUsedTime;
- public string csMsrEndTime;
- };
- public struct STMThreadStatus
- {
- public OTS_MSR_THREAD_STATUS iMsrStatu; //OTS_MSR_THREAD_STATUS
- public string csMsrStartTime; //MSR_START_TIME
- public string csMsrEndTime; //MSR_END_TIME
- public SMSR_COMPLETE_DATA SMsrCompleteData;
- };
- public struct STMSampleStatus
- {
- public OTS_MSR_SAMPLE_STATUS iMsrSampleStatu; //OTS_MSR_SAMPLE_STATUS
- public string cSampleName;
- public string csSampleMsrStartTime;
- public List<PointF> BCompleteFieldList;
- };
- public struct STMSampleResultData
- {
- public MSAMPLE_RET iRetDataType; //ENUM_MEASURE_SAMPLE_RESULT
- public struct RBSEDATA
- {
- public System.Drawing.Point pos;
- public int iBSEDataHeight;
- public int iBSEDataWidth;
- public byte[] lpBSEData;
- };
- public struct SAMPLEFIELDDATA
- {
- public System.Drawing.Point FieldPos;
- public int iMeasureFieldCount;
- public int iCompleteFieldCount;
- public int iSParticleCount; // Field particle count
- public TimeSpan TUsedTime;
- };
- public struct StartToMsrField
- {
- public System.Drawing.Point FieldPos;
- };
- public RBSEDATA BSEData;
- public SAMPLEFIELDDATA SFieldData;
- public StartToMsrField SMsrField;
- };
- public struct ST_MSTMsg
- {
-
- public ENUM_MSG_TYPE iMsgType;
- public STMThreadStatus STMThreadStu;
- public STMSampleStatus STMSampleStu;
- public STMSampleResultData STMSampleRetData;
- };
-
- public class CMeasure
- {
-
- private const string UNTITLED_FILE_NAME = "Untitled";
- public delegate void ProgressEventHandler(ST_MSTMsg msg);
- public event ProgressEventHandler ProgressEvent;
- COTSMsrPrjResultData m_pProjData;
- List< COTSSample> m_listMeasurableSamples=new List<COTSSample>();
- string m_strWorkingFolder;
- CMsrThreadStatus m_ThreadStatus;
-
-
- SemController m_SemController;// there is no correspondense clr,so use this instead temporarilly
- protected static NLog.Logger loger = NLog.LogManager.GetCurrentClassLogger();
- public SortedDictionary<string, CSmplMeasure> mapSmplMsr = new SortedDictionary<string, CSmplMeasure>();//use this map to hold all the smplMeasure object
- public List<COTSSample> GetListMeasurableSamples()
- {
- return m_listMeasurableSamples;
- }
- public void SetListMeasurableSamples(List<COTSSample> value)
- {
- m_listMeasurableSamples = value;
- }
- public CMeasure()
- {
- m_strWorkingFolder = "";
- m_ThreadStatus = new CMsrThreadStatus();
- m_SemController = SemController.GetSEMController();
-
- }
-
- public COTSMsrPrjResultData GetProjResultData()
- {
- return m_pProjData;
- }
- public ISemController GetSEMController()
- {
- // get SEM, scanner and x-ray controller via hardware manager
- return m_SemController;
- }
-
- public CMsrThreadStatus GetMsrThreadStatus() { return m_ThreadStatus; }
- public void Init(COTSMsrPrjResultData a_pProjMgrFile)
- {
- m_pProjData = a_pProjMgrFile;
-
- SetListMeasurableSamples(a_pProjMgrFile.GetSampleList());
- return ;
- }
- void ThreadOver()
- {
-
- DateTime timeEnd = m_ThreadStatus.GetEndTime();
- ST_MSTMsg MsrMsg = new ST_MSTMsg();
- MsrMsg.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
-
- MsrMsg.STMThreadStu.iMsrStatu = m_ThreadStatus.GetStatus();
-
- MsrMsg.STMThreadStu.csMsrEndTime = timeEnd.ToString("yyyy-MM-dd HH:mm:ss");
- ProgressEvent(MsrMsg);
-
-
- }
- void ThreadOverWithoutDisConnect()
- {
- DateTime timeEnd = m_ThreadStatus.GetEndTime();
- ST_MSTMsg MsrMsg = new ST_MSTMsg();
- MsrMsg.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
- MsrMsg.STMThreadStu.iMsrStatu = m_ThreadStatus.GetStatus();
-
- MsrMsg.STMThreadStu.csMsrEndTime = timeEnd.ToString("yyyy-MM-dd HH:mm:ss");
- ProgressEvent(MsrMsg);
-
- }
- void SetWorkingFolderStrAndSaveCurrentSettings()
- {
- // get project file pathname
- string strSettingFilePathName = m_pProjData.GetPathName();
- strSettingFilePathName.Trim();
- if (strSettingFilePathName == "")
- {
- loger .Error("SetWorkingFolderStr: project file pathname is an empty string");
- return ;
- }
- else if (strSettingFilePathName==UNTITLED_FILE_NAME)
- {
- loger .Error ("SetWorkingFolderStr: project file pathname is an invalid string");
- return ;
- }
- // working folder string
- m_strWorkingFolder = FileHelper.GetFolderName(strSettingFilePathName);
- m_pProjData.Save();
- return ;
- }
- public void SendMessageToMeasureApp(ST_MSTMsg msg)
- {
- ProgressEvent(msg);
- }
- public bool IsMeasureStopped()
- {
- return m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.STOPPED;
- }
- public bool IsMeasureRunning() { return m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.INPROCESS; }
- public bool IsMeasureFailed() { return m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.FAILED; }
- public bool IsMeasureCompleted() { return m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.COMPLETED; }
- public void DoMeasure()
- {
- // start measurement, creat thread measure status class, let the main thread know that measurement started
- m_ThreadStatus.SetStartTime(System.DateTime.Now);
- DateTime timeStart = m_ThreadStatus.GetStartTime();
-
- ST_MSTMsg MsgMsrStart=new ST_MSTMsg();
- MsgMsrStart.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
- MsgMsrStart.STMThreadStu.iMsrStatu = OTS_MSR_THREAD_STATUS.INPROCESS;
- MsgMsrStart.STMThreadStu.csMsrStartTime = timeStart.ToShortDateString();
- ProgressEvent (MsgMsrStart);
- loger.Info("Measurement started!");
- // connect hardware
- loger.Info("Connect SEM!");
- if (!m_SemController.Connect())
- {
- loger .Error("DoMeasure: failed to connect hardware.");
- m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.FAILED);
-
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- ThreadOver();
- return;
- }
- // set working directory which is the same directory of the setting file
- SetWorkingFolderStrAndSaveCurrentSettings();
-
-
- List <string > listMeasuredSamples = m_ThreadStatus.GetCompletedSamples();
- // got through measure list
- foreach (var pSample in GetListMeasurableSamples())
- {// check and break if stop button is clicked
- if (m_ThreadStatus.GetStatus()== OTS_MSR_THREAD_STATUS.STOPPED )
- {
- // stop button clicked
- loger .Info("DoMeasure: stop button is clicked.");
- // record end time
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- ThreadOver();
- return;
- }
- if (m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.PAUSED)
- {
- // stop button clicked
- loger.Info("DoMeasure: stop button is clicked.");
- // record end time
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- while (m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.PAUSED)
- {
- Thread.Sleep(300);
- }
- //return;
- }
- if (!pSample.GetSwitch())
- {
- continue;
- }
- var sta = pSample.GetMsrStatus().GetStatus();
- if (sta == OTS_MSR_SAMPLE_STATUS.SUCCESSED || sta == OTS_MSR_SAMPLE_STATUS.STOPPED)
- {
- continue;
-
- }
-
- CSmplMeasure pSmplMeasure;
- if (!mapSmplMsr.ContainsKey(pSample.GetName()))
- {// create a sample measure object for the sample
- switch (m_pProjData.m_nPackId)
- {
- case OTS_SysType_ID.IncA:
- pSmplMeasure = new CSmplMeasureInclution(m_strWorkingFolder, pSample);
- break;
- case OTS_SysType_ID.CleannessA:
- pSmplMeasure = new CSmplMeasureCleanliness(m_strWorkingFolder, pSample);
- break;
- default:
- pSmplMeasure = new CSmplMeasureInclution(m_strWorkingFolder, pSample);
- break;
- }
-
-
-
- // set measure thread
- pSmplMeasure.SetMsrThread(this);
- mapSmplMsr[pSample.GetName()] = pSmplMeasure;
- }
- else
- {
- pSmplMeasure = mapSmplMsr[pSample.GetName()];
- pSample.GetMsrStatus().SetStatus(OTS_MSR_SAMPLE_STATUS.INPROCESS);
- m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.INPROCESS);
- }
-
- pSmplMeasure.DoMeasureForOneSample();
-
- // check if measurement is successful
- if (pSample.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.PAUSED)
- {// record end time
- m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.PAUSED);
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- // update thread measure status class, let the main thread know that this sample measurement stopped
- ST_MSTMsg MsgSmpStop = new ST_MSTMsg();
- MsgSmpStop.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
- MsgSmpStop.STMThreadStu.iMsrStatu = OTS_MSR_THREAD_STATUS.PAUSED;
- MsgSmpStop.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.PAUSED;
- MsgSmpStop.STMThreadStu.csMsrEndTime = DateTime.Now.ToShortDateString();
- MsgSmpStop.STMThreadStu.iMsrStatu = OTS_MSR_THREAD_STATUS.PAUSED;
- ProgressEvent(MsgSmpStop);
- ThreadOver();
- return;
- }else if (pSample.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.STOPPED)
- {// record end time
- m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.STOPPED);
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- // update thread measure status class, let the main thread know that this sample measurement stopped
- ST_MSTMsg MsgSmpStop = new ST_MSTMsg();
- MsgSmpStop.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
- MsgSmpStop.STMThreadStu.iMsrStatu= OTS_MSR_THREAD_STATUS.STOPPED;
- MsgSmpStop.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.STOPPED;
- MsgSmpStop.STMThreadStu.csMsrEndTime = DateTime .Now .ToShortDateString();
- MsgSmpStop.STMThreadStu.iMsrStatu= OTS_MSR_THREAD_STATUS.STOPPED;
- ProgressEvent(MsgSmpStop);
- ThreadOver();
- break;
- }
- else if (pSample.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.FAILED)
- {
- // measurement failed
- m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.FAILED);
- // record end time
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- // update thread measure status class, let the main thread know that this sample measurement failed
- ST_MSTMsg MsgSmpFailed=new ST_MSTMsg();
-
- MsgSmpFailed.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
- MsgSmpFailed.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.FAILED;
-
- ProgressEvent(MsgSmpFailed);
- ThreadOver();
- return;
- }
-
- // update thread measure status class, let the main thread know that this sample measurement successes
- ST_MSTMsg MsgSmpSuccess = new ST_MSTMsg();
- MsgSmpSuccess.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
- MsgSmpSuccess.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.SUCCESSED;
- ProgressEvent(MsgSmpSuccess);
- // continue to the next sample
- listMeasuredSamples.Add(pSample.GetName());
- }
- // measurement completed
- m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.COMPLETED);
- // record end time
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- ThreadOver();
- }
- //public bool DoReMeasure(List<Particle> particles, int imgscanspeed_index, int xrayscanmode_index, int scantime_count)
- //{
- // // got through measure list
- // foreach (var pSample in m_listMeasurableSamples)
- // {
- // // check and break if stop button is clicked
- // if (m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.STOPPED)
- // {
- // // stop button clicked
- // loger.Info("DoMeasure: stop button is clicked.");
- // // record end time
- // m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- // ThreadOver();
- // return false;
- // }
- // CSmplMeasure pSmplMeasure;
- // // create a sample measure object for the sample
- // switch (m_pProjData.m_nPackId)
- // {
- // case OTS_SysType_ID.IncA:
- // pSmplMeasure = new CSmplMeasureInclution(m_strWorkingFolder, pSample);
- // break;
- // case OTS_SysType_ID.CleannessA:
- // pSmplMeasure = new CSmplMeasureCleanliness(m_strWorkingFolder, pSample);
- // break;
- // default:
- // pSmplMeasure = new CSmplMeasureInclution(m_strWorkingFolder, pSample);
- // break;
- // }
- // // set measure thread
- // pSmplMeasure.SetMsrThread(this);
- // pSmplMeasure.DoMeasureForOneSample();
- // }
- // // measurement completed
- // m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.COMPLETED);
- // // record end time
- // m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- // ThreadOver();
- // return true;
- //}
- // hole preview
- public void DoHolePreview()
- {
- // start measurement, creat thread measure status class, let the main thread know that measurement started
- // set measure status to in-process
- //record time
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.START);
- DateTime timeStart = m_ThreadStatus.GetStartTime();
-
- ST_MSTMsg MsgMsrStart = new ST_MSTMsg();
-
- MsgMsrStart.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
- MsgMsrStart.STMThreadStu.iMsrStatu =OTS_MSR_THREAD_STATUS.INPROCESS;
-
- SendMessageToMeasureApp(MsgMsrStart);
- // connect hardware
- if (!m_SemController.Connect())
- {
- // failed to connect hardware
-
- SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS.FAILED);
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- ThreadOverWithoutDisConnect();
- }
- var a_pMeasureArea = m_pProjData.GetWorkingSample().GetMsrDomain();
- COTSSample pSampleHole = CreateHoleSample(a_pMeasureArea);
- var sample = m_pProjData.GetWorkingSample();
- // create a sample measure object for the sample
- CSmplMeasure pSmplMeasure = new CSmplMeasure(m_strWorkingFolder, sample);
-
- // set measure thread
- pSmplMeasure.SetMsrThread(this);
- // update thread measure status class, let the main thread know that this sample measurement starts
- // set working folder string
- pSmplMeasure.SetSample(sample);
- pSmplMeasure.SetHolePreviewSample(pSampleHole);
- pSmplMeasure.SetWorkingFolder(m_strWorkingFolder);
- // do measure
- pSmplMeasure.DoHolePreview();
- // check if measurement is successful
- if (pSampleHole.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.STOPPED)
- {
- // record end time
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- // measurement stopped
- SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS.STOPPED);
- // update thread measure status class, let the main thread know that this sample measurement stopped
- ST_MSTMsg MsgSmpStop = new ST_MSTMsg();
-
- MsgSmpStop.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
- MsgSmpStop.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.STOPPED;
-
- SendMessageToMeasureApp(MsgSmpStop);
- ThreadOverWithoutDisConnect();
- return;
- }
- else if (pSampleHole.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.FAILED)
- {
- // measurement failed
- SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS.FAILED);
- // record end time
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- // update thread measure status class, let the main thread know that this sample measurement failed
- ST_MSTMsg MsgSmpFailed = new ST_MSTMsg();
-
- MsgSmpFailed.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
- MsgSmpFailed.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.FAILED;
-
- SendMessageToMeasureApp(MsgSmpFailed);
- ThreadOverWithoutDisConnect();
- return;
- }
- // record end time
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- // update thread measure status class, let the main thread know that this sample measurement successes
- ST_MSTMsg MsgSmpSuccess = new ST_MSTMsg();
-
- MsgSmpSuccess.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
- MsgSmpSuccess.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.SUCCESSED;
-
- SendMessageToMeasureApp(MsgSmpSuccess);
- // measurement completed
- SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS.COMPLETED);
- // record end time
- m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
- ThreadOverWithoutDisConnect();
- }
- public COTSSample CreateHoleSample(CDomain a_pMsrArea)
- {
-
- COTSSample pHoleSample = new COTSSample();
- pHoleSample.SetMsrDomain(a_pMsrArea);
-
- // get min magnification
- CSEMStageData pSEMStageData = m_pProjData.GetSEMStageData();
- double dMinMag = pSEMStageData.GetMinMag();
- // get scan field size 100
- int nScanFieldSize100 = pSEMStageData.GetScanFieldSize100();
- // get working distance
- double dWorkingDistance = 0.0;
- if (!GetSEMWorkingDistanceFromHW(ref dWorkingDistance))
- {
- return null;
- }
- CSEMDataMsr poSEMDataMsr = new CSEMDataMsr();
- poSEMDataMsr.SetScanFieldSize100(nScanFieldSize100);
- poSEMDataMsr.SetWorkingDistance(dWorkingDistance);
- poSEMDataMsr.SetMagnification(dMinMag);
- pHoleSample.SetSEMDataMsr(poSEMDataMsr);
- // Set image scan param
- COTSImgScanPrm poImageScanParam = new COTSImgScanPrm();
- poImageScanParam.SetStopMode(((int)OTS_MEASURE_STOP_MODE.CoverMode).ToString());
- poImageScanParam.SetStartImageMode(OTS_GET_IMAGE_MODE.FROM_CENTER);
- poImageScanParam.SetScanImageSpeed(OTS_IMAGE_SCANSPEED_OPTIONS.low);
- //poImageScanParam.SetImagePixelSize(OTS_FIVE_TIES_OPTIONS.TIE1);
- CSampleParam poMsrParams = pHoleSample.GetMsrParams();
- poImageScanParam.SetImageResulotion(GetListMeasurableSamples()[0].GetMsrParams().GetImageScanParam().GetImageResulotion());//由于各样品分辨率应该一致,故此处没有读取选取的特定样品孔样品
- poMsrParams.SetImageScanParam(poImageScanParam);
- pHoleSample.SetMsrParams(poMsrParams);
- return pHoleSample;
- }
- public bool GetSEMWorkingDistanceFromHW(ref double a_dWorkingDistance)
- {
- m_SemController.GetWorkingDistance(ref a_dWorkingDistance);
- return true;
- }
-
- // measure status
- public void SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS a_nMsrLoopStatus)
- {
-
- m_ThreadStatus.SetStatus( a_nMsrLoopStatus);
-
- }
-
- }
- }
|