WEB开发网
开发学院软件开发VC 理解COM编程中的“种类”(Category)概念 阅读

理解COM编程中的“种类”(Category)概念

 2006-07-21 11:42:52 来源:WEB开发网   
核心提示: 用这接口可以枚举实现给定种类的类,为了说明ICatInformation接口使用,理解COM编程中的“种类”(Category)概念(4),我写了一个小程序CatView,用这个程序可以浏览系统中注册的种类

用这接口可以枚举实现给定种类的类。为了说明ICatInformation接口使用,我写了一个小程序CatView,用这个程序可以浏览系统中注册的种类。如图一所示:

图一 CatView 浏览系统中注册的种类

下面是CatView 有关的代码:(全部源代码可以从本文最前面的链接下载)

// CoolCat.h — helper stuff for COMponent categories.
//
#pragma once
#include
//////////////////
// Helper function to get GUID in human-readable format as CString.
//
inline CString CStringFromGuid(GUID& guid)
{
   LPOLESTR pstr=NULL;
   StringFromCLSID(guid, &pstr);
   return CString(pstr);
}
////////////////
// Handy Category Information class. Instantiate and go.
//
class CCatInformation : public CComPtr {
public:
   CCatInformation() {
     CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL,
              CLSCTX_INPROC);
     ASSERT(p);
   }
};
//////////////////
// Handy class to enumerate categories
//
class CCatIterator {
protected:
   CComPtr spEnumCatInfo; // IEnumCATEGORYINFO
   CCatInformation spCatInfo;         // ICatInformation
public:
   CCatIterator(LCID lcid = GetUserDefaultLCID()) {
     HRESULT hr = spCatInfo->EnumCategories(lcid, &spEnumCatInfo);
     ASSERT(SUCCEEDED(hr));
   }
   BOOL Next(CATEGORYINFO& catinfo) {
     ULONG nRet=0;
     return SUCCEEDED(spEnumCatInfo->Next(1, &catinfo, &nRet)) &&
              nRet==1;
   }
};
//////////////////
// Handy class to enumerate classes that implement a category
//
class CCatClassIterator {
protected:
   CComPtr spEnumCLSID; // IEnumCLSID
   CCatInformation spCatInfo;    // ICatInformation
public:
   CCatClassIterator(CATID* arImplCatids, ULONG nImpl,
     CATID* arReqdCatids=NULL, ULONG nReqd=0) {
     HRESULT hr = spCatInfo->EnumClassesOfCategories(
       nImpl,      // num implemented cats in array
       arImplCatids,   // array of cats to look for (implement)
       nReqd,      // num required categories in array
       arReqdCatids,   // array of required categories to look for
       &spEnumCLSID);  // IEnum returned
     ASSERT(SUCCEEDED(hr));
   }
   BOOL Next(CLSID& clsid) {
     ULONG nRet=0;
     return SUCCEEDED(spEnumCLSID->Next(1, &clsid, &nRet)) && nRet==1;
   }
};
View.h
#pragma once
//////////////////
// Right pane is a list of controls that implement a category.
//
class CRightView : public CListView {
public:
   CRightView();
   virtual ~CRightView();
   BOOL ShowCategory(CATID& catid);
protected:
   virtual void OnInitialUpdate(); // called first time after construct
   virtual void OnDraw(CDC* pDC);  // overridden to draw this view
   virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
   DECLARE_DYNCREATE(CRightView)
   DECLARE_MESSAGE_MAP()
};
//////////////////
// Left pane is a list of categories.
//
class CLeftView : public CListView {
public:
   virtual ~CLeftView();
   virtual void OnDraw(CDC* pDC);  // overridden to draw this view
   virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
   void SetRightPane(CRightView* pRightPane) {
     m_pRightPane = pRightPane;
   }
protected:
   CRightView* m_pRightPane;
   CLeftView();
   void PopulateCategoryList();
   virtual void OnInitialUpdate(); // called first time after construct
   afx_msg void OnItemChanged(NMHDR* pNMHDR, LRESULT* pRes);
   afx_msg LRESULT OnWinMgr(WPARAM wp, LPARAM lp);
   DECLARE_MESSAGE_MAP()
   DECLARE_DYNCREATE(CLeftView)
};
LeftView.cpp
//
#include "stdafx.h"
#include "View.h"
#include "WinMgr.h"
#include "CoolCat.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CLeftView, CListView)
BEGIN_MESSAGE_MAP(CLeftView, CListView)
   ON_NOTIFY_REFLECT(LVN_ITEMCHANGED,OnItemChanged)
   ON_REGISTERED_MESSAGE(WM_WINMGR, OnWinMgr)
END_MESSAGE_MAP()
CLeftView::CLeftView() : m_pRightPane(NULL)
{
}
CLeftView::~CLeftView()
{
}
BOOL CLeftView::PreCreateWindow(CREATESTRUCT& cs)
{
   cs.style |= LVS_REPORT | LVS_SORTASCENDING | LVS_NOSORTHEADER;
   return CListView::PreCreateWindow(cs);
}
void CLeftView::OnDraw(CDC* pDC)
{
}
//////////////////
// First-time init: add column headers
//
void CLeftView::OnInitialUpdate()
{
   CListView::OnInitialUpdate();
  
   const COLWIDTH = 250;
   CListCtrl& lc = GetListCtrl();
   lc.InsertColumn(0, _T("Category Name"),LVCFMT_LEFT,COLWIDTH);
   lc.InsertColumn(1, _T("CATID"),LVCFMT_LEFT,COLWIDTH,1);
   PopulateCategoryList();
}
//////////////////
// Populate list of categories.
//
void CLeftView::PopulateCategoryList()
{
   CListCtrl& lc = GetListCtrl();
   lc.DeleteAllItems();
   CATEGORYINFO catinfo;
   CCatIterator it;
   while (it.Next(catinfo)) {
     // add category name to list
     CString sName = catinfo.szDescription;
     if (sName.IsEmpty()) {
       sName = _T("");
     }
     int iItem = lc.InsertItem(0,sName);
     // Add CATID as 1st subitem
     lc.SetItemText(iItem,1,CStringFromGuid(catinfo.catid));
   }
}
//////////////////
// User selected a new category: show controls in right pane.
//
void CLeftView::OnItemChanged(NMHDR* pNMHDR, LRESULT* pRes)
{
   NMLISTVIEW nm = *(NMLISTVIEW*)pNMHDR;
   if (nm.iItem>=0 && (nm.uNewState & LVIS_SELECTED)) {
     CListCtrl& lc = GetListCtrl();
     CString sguid = lc.GetItemText(nm.iItem,1);
     CATID catid;
     USES_CONVERSION;
     if (SUCCEEDED(CLSIDFromString(T2OLE((LPCTSTR)sguid),&catid)))
       m_pRightPane->ShowCategory(catid);
     else
       MessageBeep(0);
   }
   *pRes= 0;
}
//////////////////
// Handle WinMgr request for size info: compute TOFIT size for list view,
// which is sum of widths of columns.
//
LRESULT CLeftView::OnWinMgr(WPARAM wp, LPARAM lp)
{
   ASSERT(lp);
   NMWINMGR& nmw = *(NMWINMGR*)lp;
   if (nmw.code==NMWINMGR::GET_SIZEINFO && (int)wp==GetDlgCtrlID()) {
     CSize sz(0,0);
     CListCtrl& lc = GetListCtrl();
     int nCols = lc.GetHeaderCtrl()->GetItemCount();
     for (int iCol=0; iCol");
     lc.SetItemText(iItem,1,sProgID);
   }
   return TRUE;
}
//

上一页  1 2 3 4 5 6  下一页

Tags:理解 COM 编程

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接