分享
 
 
 

COM样例(四)——客户端代码

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

COM样例(四)

——客户端代码

本文为此系列文章的最后一篇,罗列客户端的源代码。客户端使用MFC实现,其中的框架类CMainFrame实现了IModuleSite、IErrorReport和ICompanyInfo,而另一个窗口包装类CTaskManager实现ITaskManager,并由CMainFrame聚合它以表现出CMainFrame实现了ITaskManager。由于代码较长,本篇只罗列CMainFrame::OnCreate和CMainFrame的定义,其中实现了获取部门组件的实例(通过COM的组件类别功能进行记录,而非通过注册表),并进行管理。

如果欲查看本样例的所有代码,可于文末下载。而本样例的可执行文件也请于文末下载。由于本样例只是我很早以前编的一个程序精简修改而成,代码中可能有不少幼稚的地方,我现在也没兴致再仔细修改,只是大致修整了一下,还请见谅。

CMainFrame的定义

#include "NewStatusBar.h"

class CMainFrame : public CFrameWnd

{

// MFC定义宏

DECLARE_DYNCREATE( CMainFrame )

DECLARE_MESSAGE_MAP()

DECLARE_INTERFACE_MAP()

// 辅助结构

private:

struct TEMPSTRUCT

{

HWND m_hWnd;

HMENU m_hMenu;

IModule *m_pModule;

CLSID m_CLSID;

TEMPSTRUCT() : m_hWnd( NULL ), m_hMenu( NULL ), m_pModule( NULL )

{

// 什么都不做

}

~TEMPSTRUCT()

{

SafeRelease( m_pModule );

}

};

// 构造、析构

public:

CMainFrame();

~CMainFrame();

// 操作

public:

void UpdateErrorState() // 更新状态条上的错误标志以表示指示最新错误的发生

{

ASSERT_VALID( this );

if( m_wndStatusBar.GetSafeHwnd() )

m_wndStatusBar.Invalidate();

}

// 辅助函数

protected:

// 根据菜单项ID确定是否是基本框架的菜单命令

BOOL BeMenuOfBase( DWORD nID ) const;

// 成员变量

protected:

CNewStatusBar m_wndStatusBar;

CToolBar m_wndToolBar;

DWORD m_Selected;

long m_OldViewID;

IUnknown *m_pTaskManager;

CTypedPtrList< CPtrList, TEMPSTRUCT* > m_ModuleList;

// 重载

protected:

void GetMessageString( UINT nID, CString &rMessage ) const;

BOOL OnCommand( WPARAM wParam, LPARAM lParam );

// 窗口消息

protected:

afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );

afx_msg void OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized );

afx_msg void OnSetFocus( CWnd *pOldWnd );

afx_msg void OnInitMenuPopup( CMenu *pPopupMenu, UINT nIndex, BOOL bSysMenu );

afx_msg void OnInitMenu( CMenu *pMenu );

afx_msg BOOL OnEraseBkgnd( CDC *pDC );

afx_msg void OnClose();

// 菜单消息

protected:

void OnModule( UINT nID );

void OnUpdateModule( CCmdUI *pCmdUI );

// 自定消息

protected:

afx_msg LRESULT OnAllTaskTerminated( WPARAM, LPARAM );

// 接口映射

public:

// IModuleSite

BEGIN_INTERFACE_PART( ModuleSite, IModuleSite )

INIT_INTERFACE_PART( CMainFrame, ModuleSite )

STDMETHOD(ChangeModule)( REFCLSID clsid,

WCHAR *pModuleName,

ULONG command,

ULONG param );

STDMETHOD(GetFrameWindow)( HWND *pHwnd );

END_INTERFACE_PART_STATIC( ModuleSite )

// IErrorReport

BEGIN_INTERFACE_PART( ErrorReport, IErrorReport )

INIT_INTERFACE_PART( CMainFrame, ErrorReport )

STDMETHOD(ReportSoftError)( WCHAR *fileName,

ULONG row,

WCHAR *errorString );

STDMETHOD(ReportHardError)( WCHAR *fileName,

ULONG row,

WCHAR *errorString );

END_INTERFACE_PART_STATIC( ErrorReport )

// ICompanyInfo

BEGIN_INTERFACE_PART( CompanyInfo, ICompanyInfo )

INIT_INTERFACE_PART( CMainFrame, CompanyInfo )

STDMETHOD(GetDataServerInfo)( WCHAR **pLoaction,

WCHAR **pServer,

WCHAR **pPassword );

END_INTERFACE_PART_STATIC( CompanyInfo )

};

CMainFrame::OnCreate代码

int CMainFrame::OnCreate( LPCREATESTRUCT lpCreateStruct )

{

if( CFrameWnd::OnCreate( lpCreateStruct ) == -1 )

return -1;

// 创建基本工具条及状态条

EnableDocking( CBRS_ALIGN_ANY );

if( !m_wndToolBar.CreateEx( this,

TBSTYLE_FLAT,

WS_CHILD | WS_VISIBLE | CBRS_TOP |

CBRS_GRIPPER | CBRS_TOOLTIPS |

CBRS_FLYBY | CBRS_SIZE_DYNAMIC,

CRect( 0, 0, 0, 0 ) ) )

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_MAINFRM_CREATETOOLBAR );

else

{

m_wndToolBar.EnableDocking( CBRS_ALIGN_ANY );

DockControlBar( &m_wndToolBar );

}

if( !m_wndStatusBar.Create( this ) ||

!m_wndStatusBar.SetIndicators( indicators,

sizeof( indicators ) / sizeof( UINT ) ) )

{

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_MAINFRM_CREATESTATUSBAR );

return -1;

}

else

{

CCmdTarget *pTarget = m_wndStatusBar.Initial();

if( !pTarget )

{

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_MAINFRM_CREATESTATUSBAR );

return -1;

}

ASSERT_VALID( pTarget );

// 设置任务管理器的指针以使得CMainFrame聚合CTaskManager

pTarget->m_pOuterUnknown = GetControllingUnknown();

m_pTaskManager = reinterpret_cast< IUnknown* >( &pTarget->m_xInnerUnknown );

ASSERT( m_pTaskManager );

}

// 创建组件类别管理器并获得模块CLSID枚举器

IEnumCLSID *pEnum = NULL;

ICatInformation *pCat = NULL;

CATID tempCATID[1] = { CATID_Example };

if( FAILED( CoCreateInstance( CLSID_StdComponentCategoriesMgr,

NULL,

CLSCTX_INPROC_SERVER,

IID_ICatInformation,

reinterpret_cast< void** >( &pCat ) ) ) ||

FAILED( pCat->EnumClassesOfCategories( 1, tempCATID, 0, NULL, &pEnum ) ) )

{

MessageBox( L"致命错误!系统即将退出。", g_SysCaption );

WriteHardErrorLog( __LINE__,

__WFILE__,

IDS_KILLINGERROR );

SafeRelease( pCat );

SafeRelease( pEnum );

return -1;

}

pCat->Release();

// 枚举每个模块信息

g_theApp.BeginWaitCursor();

CLSID clsid;

CStringW temp;

TEMPSTRUCT *pStruct = NULL;

IModuleUI *pUI = NULL;

IMenuUpdate *pMenuUp = NULL;

long index = -1;

IModuleSite *pSite = static_cast< IModuleSite* >(

GetInterface( &IID_IModuleSite ) );

pSite->AddRef();

while( pEnum->Next( 1, &clsid, NULL ) == S_OK )

{

++index;

pStruct = new TEMPSTRUCT;

if( !pStruct )

{

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_OUTOFMEMORY );

continue;

}

// 创建模块对象

if( FAILED( CoCreateInstance( clsid,

NULL,

CLSCTX_INPROC_SERVER,

IID_IModule,

reinterpret_cast< void** >(

&pStruct->m_pModule ) ) ) )

{

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_MAINFRM_CREATEMODULE );

delete pStruct;

continue;

}

pStruct->m_CLSID = clsid;

// 初始化模块

if( FAILED( pStruct->m_pModule->InitialModule( pSite,

IDC_MODULE_VIEW +

index –

1 ) ) )

{

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_MAINFRM_CREATEMODULE );

delete pStruct;

continue;

}

// 获取模块窗口

if( FAILED( pStruct->m_pModule->QueryInterface(

IID_IModuleUI,

reinterpret_cast< void** >( &pUI ) ) ) )

{

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_MAINFRM_GETMODULEWND );

delete pStruct;

continue;

}

if( FAILED( pUI->GetMainWindow( &pStruct->m_hWnd ) ) || !pStruct->m_hWnd )

{

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_MAINFRM_GETMODULEWND );

pUI->Release();

delete pStruct;

continue;

}

pUI->Release();

{

// 修改窗口风格,确保模块窗口具有WS_EX_CLIENTEDGE风格

if( !::SetWindowLong( pStruct->m_hWnd,

GWL_EXSTYLE,

::GetWindowLong( pStruct->m_hWnd,

GWL_EXSTYLE ) |

WS_EX_CLIENTEDGE ) )

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_SETWINDOWSTYLE );

}

// 隐藏模块窗口

::ShowWindow( pStruct->m_hWnd, SW_HIDE );

// 获取模块的菜单句柄,并插入到MainFrame

if( SUCCEEDED( pStruct->m_pModule->QueryInterface(

IID_IMenuUpdate,

reinterpret_cast< void** >( &pMenuUp ) ) ) )

{

// 模块提供了菜单,获取菜单句柄

if( FAILED( pMenuUp->GetMenu( &pStruct->m_hMenu ) ) )

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_MAINFRM_CREATEMODULEMENU );

pMenuUp->Release();

}

m_ModuleList.AddTail( pStruct );

}

pSite->Release();

pEnum->Release();

// 一个模块都不激活

m_Selected = static_cast< ULONG >( -1 );

ULONG count = m_ModuleList.GetCount();

if( count )

{

// 获取模块的图标,并将其插入到模块工具条和菜单中

m_wndToolBar.SetSizes( CSize( 23, 22 ), CSize( 16, 15 ) );

if( !m_wndToolBar.SetButtons( NULL, count ) )

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_CREATETOOLBARBUTTON );

else

{

// 将图标画到位图中

CBitmap bitmap;

CDC *pScreen = CDC::FromHandle( ::GetDC( NULL ) );

CDC sdc;

if( !bitmap.CreateCompatibleBitmap( pScreen,

ICONWIDTH * count,

ICONHEIGHT ) ||

!sdc.CreateCompatibleDC( pScreen ) )

{

WriteSoftErrorLog( __LINE__,

__WFILE__,

L"创建缓冲位图失败!" );

return 0;

}

sdc.SelectObject( &bitmap );

sdc.FillSolidRect( 0,

0,

ICONWIDTH * count,

ICONHEIGHT,

RGB( 0xC0, 0xC0, 0xC0 ) );

HICON hIcon = NULL;

ULONG i = 0;

POSITION pos = m_ModuleList.GetHeadPosition();

CMenu *pMenu = GetMenu()->GetSubMenu(0)->GetSubMenu(0);

ASSERT_VALID( pMenu );

// 清空原来的占位符

while( pMenu->DeleteMenu( 0, MF_BYPOSITION ) );

while( pos )

{

pStruct = m_ModuleList.GetNext( pos );

ASSERT( pStruct );

// 将图标画到位图上

if( SUCCEEDED( pStruct->m_pModule->GetIcon( &hIcon ) ) )

::DrawIconEx( sdc.GetSafeHdc(),

i * ICONWIDTH,

0,

hIcon,

ICONWIDTH,

ICONHEIGHT,

0,

NULL,

DI_NORMAL );

else

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_MAINFRM_GETMODULEICON );

// 添加菜单

{

// 获取模块的名字

WCHAR *io = NULL;

if( FAILED( pStruct->m_pModule->GetName( &io ) ) )

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_MAINFRM_GETMODULENAME );

else

{

if( !pMenu->AppendMenu( MF_STRING, ID_MODULE + i, io ) )

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_MAINFRM_CREATEMODULEMENU );

::CoTaskMemFree( io );

}

}

// 设置工具条上的按钮

m_wndToolBar.SetButtonInfo( i, ID_MODULE + i, TBBS_BUTTON, i );

i++;

}

// 将位图设置到工具条中

if( !m_wndToolBar.SetBitmap(

static_cast< HBITMAP >( bitmap.Detach() ) ) )

WriteSoftErrorLog( __LINE__,

__WFILE__,

IDS_SETTOOLBARBITMAP );

}

}

g_theApp.EndWaitCursor();

return 0;

}

(我不知道在csdn上怎样上传文件,故借用了朋友的个人主页空间,但那个服务器不知什么原因,不能通过IE直接下载,必须使用下载软件下载,如:FlashGet。)

COM样例编译完成文件 COM样例源码

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有