⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tracker.cpp

📁 用VC开发ACTIVEX 一书 实例2 ATLServer
💻 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 + -