设为首页 加入收藏

TOP

实战COM编程系列之三(三)
2012-11-04 15:16:16 来源: 作者: 【 】 浏览:549
Tags:实战 COM 编程 系列 之三
  ITask实现类的源文件代码

STDMETHODIMP CTask::GetProcessRateOfTask( float *pRate )
{
if( !pRate )
return E_INVALIDARG;

*pRate = m_Rate;
return S_OK;
}

STDMETHODIMP CTask::TerminateTask()
{
if( !m_hEvent )
return E_FAIL;

return ::SetEvent( m_hEvent ) S_OK : E_FAIL;
}

  业务组件的头文件代码

class ATL_NO_VTABLE CExample1Logic :
public CComObjectRootEx< CComMultiThreadModel >,
public CComCoClass< CExample1Logic, &CLSID_Example1Logic >,
public IExample1Logic,
public ISetTaskManager
{
// ATL定义宏
public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
DECLARE_REGISTRY_RESOURCEID( IDR_EXAMPLE1LOGIC )
BEGIN_COM_MAP( CExample1Logic )
COM_INTERFACE_ENTRY( IExample1Logic )
COM_INTERFACE_ENTRY( ISetTaskManager )
END_COM_MAP()

// 构造、析构
blic:
CExample1Logic() : m_Cookie( static_cast< DWORD >( -1 ) )
{
::InitializeCriticalSection( &m_CS );
}
~CExample1Logic();

// 成员变量
protected:
DWORD m_Cookie; // ITaskManager的GIT的cookie
CRITICAL_SECTION m_CS; // 用于保护m_TaskManagerCookie

// 接口实现
public:
// IExample1Logic
STDMETHOD(Task1)();
STDMETHOD(Task2)();

// ISetTaskManager
STDMETHOD(SetTaskManager)( ITaskManager *pManager );
};

  业务组件的源文件代码

extern IGlobalInterfaceTable *g_pGIT;
CExample1Logic::~CExample1Logic()
{
::DeleteCriticalSection( &m_CS );

ATLASSERT( g_pGIT );
// 注销原来的m_Cookie
if( m_Cookie != static_cast< DWORD >( -1 ) )
ATLVERIFY( SUCCEEDED(
g_pGIT->RevokeInterfaceFromGlobal( m_Cookie ) ) );
}

////////////////////////////IExample1Logic///////////////////////
STDMETHODIMP CExample1Logic::Task1()
{
// Sleep一段时间以模拟长时间的调用
for( DWORD i = 0; i < 30; i++ )
{
Sleep( 300 );
if( ::CoTestCancel() == RPC_E_CALL_CANCELED )
return E_ABORT;
}
return S_OK;
}

STDMETHODIMP CExample1Logic::Task2()
{
// 通过GIT获得正确的ITaskManager的代理
ITaskNotify *pNotify = NULL;
ITaskManager *pManager = NULL;

::EnterCriticalSection( &m_CS );
if( m_Cookie != static_cast< DWORD >( -1 ) )
{
ATLASSERT( g_pGIT );
// 不论GetInterfaceFromGlobal是否成功,都必须完成工作
if( SUCCEEDED( g_pGIT->GetInterfaceFromGlobal(
m_Cookie,
IID_ITaskManager,
reinterpret_cast< void** >( &pManager ) ) ) )
pManager->QueryInterface( IID_ITaskNotify,
reinterpret_cast< void** >( &pNotify ) );
}
::LeaveCriticalSection( &m_CS );

// 开始任务
static DWORD index = 1;
ITask *pTask = NULL;
CComObject< CTask > *pTaskObject = NULL;
if( FAILED( CComObject< CTask >::CreateInstance( &pTaskObject ) ) )
return E_FAIL;
ATLVERIFY( SUCCEEDED( pTaskObject->QueryInterface(
IID_ITask,
reinterpret_cast< void** >( &pTask ) ) ) );
DWORD cookie = static_cast< DWORD >( -1 );
WCHAR temp[10];
wsprintf( temp, L"任务二%d", index++ );

pTaskObject->m_hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
if( pManager && FAILED( pManager->AddTask( temp, pTask, &cookie ) ) )
cookie = static_cast< DWORD >( -1 );
SafeRelease( pManager );

// Sleep各段时间以模拟各步工作的完成
if( ::WaitForSingleObject( pTaskObject->m_hEvent, 4000 ) == WAIT_OBJECT_0 )
goto TERMINATE;
pTaskObject->m_Rate = 0.3f;
if( pNotify )
pNotify->ProcessRateChange( cookie );

if( ::WaitForSingleObject( pTaskObject->m_hEvent, 4000 ) == WAIT_OBJECT_0 )
goto TERMINATE;
pTaskObject->m_Rate = 0.6f;
if( pNotify )
pNotify->ProcessRateChange( cookie );

if( ::WaitForSingleObject( pTaskObject->m_hEvent, 4000 ) == WAIT_OBJECT_0 )
goto TERMINATE;
pTaskObject->m_Rate = 0.9f;
if( pNotify )
pNotify->ProcessRateChange( cookie );

if( pNotify )
{
if( cookie != static_cast< DWORD >( -1 ) )
pNotify->TaskOver( cookie );
pNotify->Release();
}
pTask->Release();

return S_OK;

TERMINATE:
if( pNotify )
{
if( cookie != static_cast< DWORD >( -1 ) )
pNotify->TaskOver( cookie );
pNotify->Release();
}
pTask->Release();

return RPC_E_CALL_CANCELED;
}

/////////////////////////////ISetTaskManager////////////////////////
STDMETHODIMP CExample1Logic::SetTaskManager( ITaskManager *pManager )
{
if( !pManager )
return E_POINTER;
pManager->AddRef();

ATLASSERT( g_pGIT );
// 注销原来的m_Cookie
::EnterCriticalSection( &m_CS );
if( m_Cookie != static_cast< DWORD >( -1 ) )
ATLVERIFY( SUCCEEDED(
g_pGIT->RevokeInterfaceFromGlobal( m_Cookie ) ) );

// 注册新的m_Cookie
if( FAILED( g_pGIT->RegisterInterfaceInGlobal( pManager,
IID_ITaskManager,
&m_Cookie ) ) )
::InterlockedExchange( reinterpret_cast< LONG* >( &m_Cookie ),
static_cast< DWORD >( -1 ) );
::LeaveCriticalSection( &m_CS );

pManager->Release();
return S_OK;
}
首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇VC编程实现OICQ登录号码清除器 下一篇实战COM编程系列之二

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: