科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件实战COM编程系列之三

实战COM编程系列之三

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

由于客户和和组件实现的接口IModule、IModuleSite等都包有界面的传递,出于利用MFC的界面包装功能而都使用MFC来实现。

作者:lop5712 来源:论坛 2007年10月20日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
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;
}

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章