一个轻量级的 GUID 包装类






4.22/5 (19投票s)
一个用于操作 GUID 结构的 CGuid 类。
引言
如果您是一位经常使用 COM/DCOM 技术及其基础结构 GUID 的程序员,您就会知道在 API(例如 CLSIDFrom...
)调用中以及将其从/转换为字符串时,会经常使用该结构。还有 MFC 模板 CMap<>
、CList<>
... 因此,几周前,我决定编写一个带有辅助方法的封装类 CGuid
。使用这个类,您可以轻松地将 GUID 结构转换为 CString
或 BSTR
,反之亦然,或者创建新的 GUID。
源代码
// Guid.h: interface for the CGuid class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_GUID_H__BBBFB961_9EC0_4414_8B69_067CDD2FFB85__INCLUDED_) #define AFX_GUID_H__BBBFB961_9EC0_4414_8B69_067CDD2FFB85__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CGuid { public: CGuid(); CGuid(BSTR guid); CGuid(const CString& csGuid); CGuid(LPCTSTR lpszGuid); CGuid(const CGuid& g); CGuid(const GUID& g); virtual ~CGuid(); CGuid& operator=(const GUID& g); CGuid& operator=(const CGuid& g); CGuid& operator=(BSTR g); CGuid& operator=(const CComBSTR& g); CGuid& operator=(const CString& g); CGuid& operator=(LPCTSTR g); bool operator==(const GUID& g); bool operator==(const CGuid& g); bool operator!=(const GUID& g); bool operator!=(const CGuid& g); operator GUID&(); operator GUID*(); operator CComBSTR(); operator CString(); bool operator<(const CGuid& g1) const; bool operator>(const CGuid& g1) const; long HasKey(){ return HashKey(*this); }; BOOL ProgID(CString& csProgID); BOOL ProgID(CComBSTR& bstrProgID); static bool Create(GUID& guid); static bool Create(CComBSTR& guid); static bool Convert(GUID& guid, CComBSTR& bstrGuid); static bool Convert(GUID& guid, CString& csGuid); static bool Convert(BSTR bstrGuid, GUID& guid); static bool Convert(const CComBSTR& bstrGuid, GUID& guid); static bool Convert(const CString& bstrGuid, GUID& guid); static bool Convert(LPCTSTR lpszGuid, GUID& guid); static long HashKey(GUID& guid); protected: GUID m_guid; void copy(const CGuid& g); void copy(const GUID& g); }; #endif // !defined(AFX_GUID_H__BBBFB961_9EC0_4414_8B69_067CDD2FFB85__INCLUDED_) // Guid.cpp: implementation of the CGuid class. // /////////////////////////////////////////////////// #include "stdafx.h" #include "Guid.h" /////////////////////////////////////////////////// // Construction/Destruction /////////////////////////////////////////////////// #pragma comment(lib, "rpcrt4.lib") #define GUID_STRING_LEN 40 CGuid::CGuid() { m_guid = GUID_NULL; } CGuid::CGuid(BSTR guid) { operator=(guid); } CGuid::CGuid(const CString& csGuid) { operator=(csGuid); } CGuid::CGuid(LPCTSTR lpszGuid) { operator=(lpszGuid); } CGuid::~CGuid() { } CGuid::CGuid(const CGuid& g) { m_guid = g.m_guid; } CGuid::CGuid(const GUID& g) { m_guid = g; } bool CGuid::operator==(const GUID& g) { return !::memcmp(&m_guid, &g, sizeof(GUID)); } bool CGuid::operator==(const CGuid& g) { return operator==(g.m_guid); } CGuid::operator GUID&() { return m_guid; } CGuid::operator GUID*() { return &m_guid; } CGuid::operator CComBSTR() { CComBSTR bstrGuid; Convert(m_guid, bstrGuid); return bstrGuid; } CGuid::operator CString() { CString csGuid; Convert(m_guid, csGuid); return csGuid; } bool CGuid::operator!=(const GUID& g) { return ::memcmp(&m_guid, &g, sizeof(GUID)) != 0; } bool CGuid::operator!=(const CGuid& g) { return operator!=(g.m_guid); } CGuid& CGuid::operator=(const GUID& g) { if( ::memcmp(&m_guid, &g, sizeof(GUID)) != 0 ) { copy(g); } return *this; } CGuid& CGuid::operator=(const CComBSTR& g) { ATLASSERT(g.m_str); Convert(g, m_guid); return *this; } CGuid& CGuid::operator=(BSTR g) { ATLASSERT(g); Convert(g, m_guid); return *this; } CGuid& CGuid::operator=(LPCTSTR g) { ATLASSERT(g); Convert(g, m_guid); return *this; } CGuid& CGuid::operator=(const CString& g) { Convert(g, m_guid); return *this; } CGuid& CGuid::operator=(const CGuid& g) { if(this != &g ) { copy(g.m_guid); } return *this; } inline void CGuid::copy(const CGuid& g) { copy(g.m_guid); } inline void CGuid::copy(const GUID& g) { ::memcpy(&m_guid, (void*)&g, sizeof(GUID)); } bool CGuid::operator<(const CGuid& g1) const { RPC_STATUS status; return ::UuidCompare(const_cast<GUID*>(&m_guid), const_cast<GUID*>(&g1.m_guid), &status)==-1; } bool CGuid::operator>(const CGuid& g1) const { return !this->operator<(g1) && ::memcmp(&g1.m_guid, &m_guid, sizeof(GUID)); } bool CGuid::Convert(GUID& guid, CComBSTR& bstrGuid) { OLECHAR szGuid[GUID_STRING_LEN]={0}; int nCount = ::StringFromGUID2(guid, szGuid, GUID_STRING_LEN); bstrGuid = szGuid; return nCount !=0; } bool CGuid::Convert(GUID& guid, CString& csGuid) { OLECHAR szGuid[GUID_STRING_LEN]={0}; int nCount = ::StringFromGUID2(guid, szGuid, GUID_STRING_LEN); csGuid = szGuid; return nCount !=0; } bool CGuid::Convert(const CComBSTR& bstrGuid, GUID& guid) { return Convert(bstrGuid.m_str, guid); } bool CGuid::Convert(BSTR bstrGuid, GUID& guid) { if( bstrGuid == NULL ) { return false; } UINT nLen = ::SysStringLen(bstrGuid); if( nLen < GUID_STRING_LEN - 4 ) { return false; } CString csguid=bstrGuid; if( csguid.GetAt(0) == TCHAR('{') ) { ATLASSERT(csguid.Find(TCHAR('}'))!=-1); return Convert(csguid.Mid(1, csguid.GetLength()-2), guid); } else { return Convert(csguid, guid); } } bool CGuid::Convert(const CString& csGuid, GUID& guid) { if( csGuid.GetLength() < GUID_STRING_LEN - 4 ) { return false; } return Convert((LPCTSTR)csGuid, guid); } bool CGuid::Convert(LPCTSTR lpszGuid, GUID& guid) { ATLASSERT(lpszGuid); return ::UuidFromString((unsigned char*)lpszGuid, &guid) == RPC_S_OK; } bool CGuid::Create(CComBSTR& bstrGuid) { GUID guid; if( Create(guid) ) { return Convert(guid, bstrGuid); } return false; } bool CGuid::Create(GUID& guid) { return ::UuidCreate(&guid) == RPC_S_OK; } long CGuid::HashKey(GUID& guid) { RPC_STATUS status=RPC_S_OK; return ::UuidHash(&guid, &status); } BOOL CGuid::ProgID(CString& csProgID) { CComBSTR bstrTmp; BOOL bRet = ProgID(bstrTmp); csProgID = bstrTmp; return bRet; } BOOL CGuid::ProgID(CComBSTR& bstrProgID) { BOOL bRet=FALSE; if( *this == GUID_NULL ) { return bRet; } LPOLESTR psz = NULL; if( ::ProgIDFromCLSID(m_guid, &psz) == S_OK ) { bstrProgID=psz; ::CoTaskMemFree(psz); psz=NULL; bRet=TRUE; } return bRet; }
如您所见,唯一的依赖项是 Rpcrt4.lib 库。 我已经在 WTL 7.5 中测试了这个类。
尽情享受吧。
历史
- 2005年10月7日 - 添加了额外的构造函数和方法,代码改进。
- 2005年9月21日 - 初始版本。