Click here to Skip to main content
15,885,537 members
Articles / Desktop Programming / WTL
Article

A light wrapper class for GUID

Rate me:
Please Sign up or sign in to vote.
4.22/5 (20 votes)
6 Oct 2005CPOL 64.8K   641   39   10
A CGuid class for manipulating the GUID structure.

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 BSTRs and vice versa or create new GUIDs.

Source Code

// 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;
}

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO bring-it-together s.r.o.
Slovakia Slovakia
Jozef Božek is currently a software engineer at bring-it-together s.r.o. in area of large scale infomation systems and mobile applications development.
He has been developing in C++ nearly full time since 2000, in Java since 2004 and in Objective-C since 2009. He is programming using Java EE SDK, iOS SDK, COM/DCOM, MFC, ATL, STL and so on Smile | :)

Comments and Discussions

 
SuggestionGreat, but can't be used as-is Pin
Dilukhin1-Dec-13 21:57
Dilukhin1-Dec-13 21:57 
GeneralRe: Great, but can't be used as-is Pin
Dilukhin29-Dec-13 23:21
Dilukhin29-Dec-13 23:21 
GeneralRe: Great, but can't be used as-is Pin
memo-57-Mar-14 0:47
memo-57-Mar-14 0:47 
GeneralMy vote of 5 Pin
John Patrick Francis8-Jul-11 9:51
John Patrick Francis8-Jul-11 9:51 
GeneralVery Useful Class [modified] Pin
rahul.kulshreshtha11-Dec-10 18:48
rahul.kulshreshtha11-Dec-10 18:48 
GeneralGood wrapper class Pin
Todd Chen16-Sep-09 17:54
Todd Chen16-Sep-09 17:54 
Generalconst operators Pin
tmcgarr17-Oct-07 15:42
tmcgarr17-Oct-07 15:42 
GeneralNice Work Pin
dr3´28-Mar-07 23:09
dr3´28-Mar-07 23:09 
GeneralNice Work Pin
dr3´28-Mar-07 23:09
dr3´28-Mar-07 23:09 
GeneralSmall remark Pin
zero2zero200127-Aug-06 22:55
zero2zero200127-Aug-06 22:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.