Introduction
If you are programmer who strongly use COM/DCOM technology and its base structure GUID, you know how (and I now :-) often you are using this structure in API (CLSIDFrom...
) calls and converting it from/to string, and what about MFC templates CMap<>
, CList<>
... So, for these reasons, some weeks ago I decided to write a wrapper class CGuid
with some helper methods. With this class, you can easily convert GUID structures to CString
or BSTR
s and vice versa or create new GUIDs.
Source Code
#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
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
#include "stdafx.h"
#include "Guid.h"
#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;
}
As you can see, the only dependence is on the Rpcrt4.lib library. I have tested this class in WTL 7.5.
So enjoy.
History
- 07 Oct 2005 - additional constructors and methods added, code improvements.
- 21 Sep 2005 - initial version.