📄 tracker.cpp
字号:
// Tracker.cpp : implementation file
//
#include "stdafx.h"
#include "MFCServer.h"
// shared object support
#include "sharedobject.h"
// error info support
#include "ErrorInfoMacros.h"
// ODL generated interface file
#include "trackerinterface.h"
#include "Tracker.h"
// needed for the high resolution timer services
#include <mmsystem.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTracker
IMPLEMENT_DYNCREATE(CTracker, CCmdTarget)
CTracker::CTracker()
{
EnableAutomation();
// make sure that the application won't unload until the reference count is 0
::AfxOleLockApp();
// clear the member
/* m_dwRegister = NULL;
// QI for the IUnknown - remember no AddRef
LPUNKNOWN pIUnknown = this->GetInterface(&IID_IUnknown);
// if we have an IUnknown
if(pIUnknown)
{
// register the clsid as an active object so other applications will get the same object
if(::RegisterActiveObject(pIUnknown, CLSID_TRACKER, ACTIVEOBJECT_STRONG, &m_dwRegister) != S_OK)
// make sure that the reference is clear
m_dwRegister = NULL;
}
*/
// 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;
}
CTracker::~CTracker()
{
// 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);
// make sure that the application can un-loaded
::AfxOleUnlockApp();
}
void CTracker::OnFinalRelease()
{
// When the last reference for an automation object is released
// OnFinalRelease is called. The base class will automatically
// deletes the object. Add additional cleanup required for your
// object before calling the base class.
CCmdTarget::OnFinalRelease();
}
BEGIN_MESSAGE_MAP(CTracker, CCmdTarget)
//{{AFX_MSG_MAP(CTracker)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP(CTracker, CCmdTarget)
//{{AFX_DISPATCH_MAP(CTracker)
DISP_PROPERTY_EX(CTracker, "Indent", GetIndent, SetIndent, VT_I4)
DISP_FUNCTION(CTracker, "OutputLines", OutputLines, VT_BOOL, VTS_PVARIANT VTS_VARIANT)
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
// Note: we add support for IID_ITracker to support typesafe binding
// from VBA. This IID must match the GUID that is attached to the
// dispinterface in the .ODL file.
// {11C82946-4EDD-11D0-BED8-00400538977D}
static const IID IID_ITracker =
{ 0x11c82946, 0x4edd, 0x11d0, { 0xbe, 0xd8, 0x0, 0x40, 0x5, 0x38, 0x97, 0x7d } };
#include <initguid.h>
DEFINE_GUID(CLSID_TRACKER,0x11C82947L,0x4EDD,0x11D0,0xBE,0xD8,0x00,0x40,0x05,0x38,0x97,0x7D);
BEGIN_INTERFACE_MAP(CTracker, CCmdTarget)
INTERFACE_PART(CTracker, IID_IDispatch, SubDispatch)
INTERFACE_PART(CTracker, IID_ITracker, SubDispatch)
DUAL_ERRORINFO_PART(CTracker)
END_INTERFACE_MAP()
IMPLEMENT_OLECREATE_SHARED(CTracker, _T("MFCServer.Tracker"), 0x11C82947, 0x4edd, 0x11d0, 0xbe, 0xd8, 0x0, 0x40, 0x5, 0x38, 0x97, 0x7d)
// Implement ISupportErrorInfo to indicate we support the
// OLE Automation error handler.
IMPLEMENT_DUAL_ERRORINFO(CTracker, IID_ITracker)
// this code is based on the ACDUAL MFC\OLE sample application provided with Visual C++
HRESULT CTracker::CreateErrorInfo(CException * pAnyException, REFIID riidSource)
{
ASSERT_VALID(pAnyException);
// create an error info object
ICreateErrorInfo * pcerrinfo;
HRESULT hr = ::CreateErrorInfo(&pcerrinfo);
// if we succeeded
if(SUCCEEDED(hr))
{
// dispatch exception?
if(pAnyException->IsKindOf(RUNTIME_CLASS(COleDispatchException)))
{
// specific IDispatch style exception
COleDispatchException * e = (COleDispatchException *) pAnyException;
// set the return value to the error
hr = e->m_scError;
// Set up ErrInfo object
pcerrinfo->SetGUID(riidSource);
pcerrinfo->SetDescription(e->m_strDescription.AllocSysString());
pcerrinfo->SetHelpContext(e->m_dwHelpContext);
pcerrinfo->SetHelpFile(e->m_strHelpFile.AllocSysString());
pcerrinfo->SetSource(e->m_strSource.AllocSysString());
}
else if (pAnyException->IsKindOf(RUNTIME_CLASS(CMemoryException)))
{
// failed memory allocation
hr = E_OUTOFMEMORY;
// Set up ErrInfo object
pcerrinfo->SetGUID(riidSource);
CString cstrFileName(AfxGetAppName());
pcerrinfo->SetSource(cstrFileName.AllocSysString());
}
else
{
// other unknown/uncommon error
hr = E_UNEXPECTED;
// Set up ErrInfo object
pcerrinfo->SetGUID(riidSource);
CString cstrFileName(AfxGetAppName());
pcerrinfo->SetSource(cstrFileName.AllocSysString());
}
// QI for the IErrorInfo interface
IErrorInfo * perrinfo;
if(SUCCEEDED(pcerrinfo->QueryInterface(IID_IErrorInfo, (LPVOID *) &perrinfo)))
{
// set the error info object
::SetErrorInfo(0, perrinfo);
// release the reference
perrinfo->Release();
}
// release the reference
pcerrinfo->Release();
}
// delete the exception
pAnyException->Delete();
// return the error value
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// CTracker Standard IDispatch Dual Interface Handlers
ULONG FAR EXPORT CTracker::XSubDispatch::AddRef()
{
METHOD_PROLOGUE(CTracker, SubDispatch)
return pThis->ExternalAddRef();
}
ULONG FAR EXPORT CTracker::XSubDispatch::Release()
{
METHOD_PROLOGUE(CTracker, SubDispatch)
// call the function and check the refcount
long lRefCount = pThis->ExternalRelease();
// if we are registered as running and there is the only refcount left
// if(pThis->m_dwRegister && lRefCount == 1)
if(pThis->factory.m_dwRegister && lRefCount == 1)
{
// bump our refcount up so we don't destroy ourselves until we are done
pThis->ExternalAddRef();
// get the registration ID
// DWORD tdwRegister = pThis->m_dwRegister;
DWORD tdwRegister = pThis->factory.m_dwRegister;
// clear the member variable to prevent us from hitting this method again
// pThis->m_dwRegister = 0;
pThis->factory.m_dwRegister = 0;
// remove the interface from the running object table
::RevokeActiveObject(tdwRegister, NULL);
// the revoke should have decremented our refcount by one
// this call to Release should destroy our server
return pThis->ExternalRelease();
}
// exit
return lRefCount;
}
HRESULT FAR EXPORT CTracker::XSubDispatch::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
{
METHOD_PROLOGUE(CTracker, SubDispatch)
return (HRESULT) pThis->ExternalQueryInterface(&riid, ppvObj);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -