📄 tracker.cpp
字号:
// Tracker.cpp : Implementation of CTracker
#include "stdafx.h"
#include "ATLServer.h"
// needed for the high resolution timer services
#include <mmsystem.h>
#include "Tracker.h"
/////////////////////////////////////////////////////////////////////////////
// CTracker
STDMETHODIMP CTracker::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* arr[] =
{
&IID_ITracker,
};
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
if (InlineIsEqualGUID(*arr[i],riid))
return S_OK;
}
return S_FALSE;
}
// constructor
CTracker::CTracker()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// To keep the application running as LONG as an
// OLE automation object is active
::AfxOleLockApp();
// setup our timer resolution
m_lTimeBegin = timeBeginPeriod(1);
m_lHiResTime = m_lLastHiResTime = timeGetTime();
// get the current date and time
CTime oTimeStamp = CTime::GetCurrentTime();
CString cstrFileName;
// create a file name based on the date
cstrFileName.Format(_T("%s.tracklog"), (LPCTSTR) oTimeStamp.Format("%Y%m%d"));
// open a file
m_fileLog = fopen(cstrFileName, _T("a"));
// if we have a file handle
if(m_fileLog)
{
// output some starting information
fprintf(m_fileLog, _T("************************\n"));
fprintf(m_fileLog, _T("Start %s\n"),
(LPCTSTR) oTimeStamp.Format("%B %#d, %Y, %I:%M %p"));
fprintf(m_fileLog, _T("\n"));
}
m_lIndent = 0;
}
// destructor
CTracker::~CTracker()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// if we have a file handle
if(m_fileLog)
{
// output some closing information
CTime oTimeStamp = CTime::GetCurrentTime();
fprintf(m_fileLog, _T("\n"));
fprintf(m_fileLog, _T("End %s\n"), oTimeStamp.Format("%B %#d, %Y, %I:%M %p"));
fprintf(m_fileLog, _T("************************\n"));
// close the file
fclose(m_fileLog);
}
// if we have valid timer services
if(m_lTimeBegin == TIMERR_NOERROR)
// reset the timer to its original state
timeEndPeriod(1);
// no longer necessary to keep the application in memory
::AfxOleUnlockApp();
}
STDMETHODIMP CTracker::OutputLines(VARIANT * varOutputArray, VARIANT varIndent,
VARIANT_BOOL * RetVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
HRESULT hResult = S_OK;
*RetVal = VARIANT_TRUE;
// if we have a file a if the variant contains a string array
if(m_fileLog && varOutputArray->vt == (VT_ARRAY | VT_BSTR))
{
// lock the array so we can use it
if(::SafeArrayLock(varOutputArray->parray) == S_OK)
{
LONG lLBound;
// get the lower bound of the array
if(::SafeArrayGetLBound(varOutputArray->parray, 1, &lLBound) == S_OK)
{
LONG lUBound;
// get the number of elements in the array
if(::SafeArrayGetUBound(varOutputArray->parray, 1, &lUBound) == S_OK)
{
CString cstrIndent;
CTime oTimeStamp;
BSTR bstrTemp;
// if we have an indent parameter
if(varIndent.vt != VT_I4)
{
// get a variant that we can use for conversion purposes
VARIANT varConvertedValue;
// initialize the variant
::VariantInit(&varConvertedValue);
// see if we can convert the data type to something
// useful - VariantChangeTypeEx() could also be used
if(S_OK == ::VariantChangeType(&varConvertedValue,
(VARIANT *) &varIndent, 0, VT_I4))
// assign the value to our member variable
m_lIndent = varConvertedValue.lVal;
}
else
// assign the value to our member variable
m_lIndent = varIndent.lVal;
// if we have to indent the text
for(long lIndentCount = 0; lIndentCount < m_lIndent;
lIndentCount++)
// add a tab to the string
cstrIndent += _T("\t");
// for each of the elements in the array
for(long lArrayCount = lLBound; lArrayCount <
(lUBound + lLBound); lArrayCount++)
{
// update the time
oTimeStamp = CTime::GetCurrentTime();
m_lHiResTime = timeGetTime();
// get the data from the array
if(::SafeArrayGetElement(varOutputArray->parray,
&lArrayCount, &bstrTemp) == S_OK)
{
// output the data
fprintf(m_fileLog, _T("%s(%10ld)-%s%ls\n"),
(LPCTSTR) oTimeStamp.Format("%H:%M:%S"),
m_lHiResTime - m_lLastHiResTime,
(LPCTSTR) cstrIndent, bstrTemp);
// store the last timer value
m_lLastHiResTime = m_lHiResTime;
// free the bstr
::SysFreeString(bstrTemp);
}
}
}
else
{
*RetVal = VARIANT_FALSE;
// create the error message
hResult = AtlReportError(CLSID_Tracker,
"Unable to retrieve the upper bound dimension of the array.",
IID_ITracker,
MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF,
MFCSERVER_E_NO_UBOUND));
}
}
else
{
*RetVal = VARIANT_FALSE;
// create the error message
hResult = AtlReportError(CLSID_Tracker,
"Unable to retrieve the lower bound dimension of the array.",
IID_ITracker,
MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, MFCSERVER_E_NO_LBOUND));
}
// unlock the array we don't need it anymore
::SafeArrayUnlock(varOutputArray->parray);
}
else
{
*RetVal = VARIANT_FALSE;
// create the error message
hResult = AtlReportError(CLSID_Tracker,
"Unable to lock the array memory.",
IID_ITracker,
MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, MFCSERVER_E_NO_ARRAYLOCK));
}
}
else
{
*RetVal = VARIANT_FALSE;
// if there wasn't a file
if(!m_fileLog)
// create the error message
hResult = AtlReportError(CLSID_Tracker,
"Invalid File Handle. File could not be opened for output.",
IID_ITracker,
MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, MFCSERVER_E_NO_FILE));
else
// create the error message
hResult = AtlReportError(CLSID_Tracker,
"The first parameter must be a string array passed by reference.",
IID_ITracker,
MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, MFCSERVER_E_BAD_ARRAY_PARAMETER));
}
// return the result
return hResult;
}
STDMETHODIMP CTracker::get_Indent(long * pVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
HRESULT hResult = S_OK;
// return the member variable
*pVal = m_lIndent;
// return the result
return hResult;
}
STDMETHODIMP CTracker::put_Indent(long newVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
HRESULT hResult = S_OK;
// if the new value is a least 0
if(newVal >= 0)
// assign the value to our member variable
m_lIndent = newVal;
else
{
// create the error message
hResult = AtlReportError(CLSID_Tracker,
"Invalid value. Value must be 0 or greater.",
IID_ITracker,
MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, MFCSERVER_E_INVALID_VALUE));
}
// return the result
return hResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -