Hungry Mind , Blog about everything in IT - C#, Java, C++, .NET, Windows, WinAPI, ...

Inventing wheel for 1000001 time

А как же еще назвать пост, если эти классы написаны уже 1,000,000 раз?

Exception.h

#pragma once
#include <string>
#include <map>
#include <boost/any.hpp>

namespace win32 {

    class Exception
    {
    protected:
        typedef std::wstring properties_key_t;
        typedef std::map<properties_key_t, boost::any> properties_t;

    protected:
        static const properties_key_t propertyMessageKey;

    protected:
        Exception();
        Exception(const std::wstring &message);
    public:
        virtual ~Exception() = 0 {};

    public:
        __declspec(property(get=get_Message))
        std::wstring Message;
        virtual std::wstring get_Message() const;

    protected:
        properties_t _properties;

    };

}

Exception.cpp




#include "Exception.h"

namespace win32 {

    const Exception::properties_key_t Exception::propertyMessageKey(L"msg");

    Exception::Exception() {
    }

    Exception::Exception(const std::wstring &message) {
        _properties.insert(std::make_pair(propertyMessageKey, boost::any(message)));
    }

    /*virtual*/ std::wstring Exception::get_Message() const {
        properties_t::const_iterator i = _properties.find(propertyMessageKey);
        if (i != _properties.end())
            return(boost::any_cast<std::wstring>(i->second));
        return(std::wstring());
    }

}



Win32Exception.h



#pragma once
#include "Exception.h"
#include <Windows.h>
#include <string>

namespace win32 {

    class Win32Exception : public virtual Exception
    {

    protected:
        static const properties_key_t propertyErrorCodeKey;

    public:
        Win32Exception(DWORD errorCode = GetLastError());
        virtual ~Win32Exception();

    public:
        __declspec(property(get=get_ErrorCode))
        DWORD ErrorCode;
        DWORD get_ErrorCode() const;

    public:
        static std::wstring FormatMessage(DWORD errorCode);

    };

}


Win32Exception.cpp



#include "Win32Exception.h"
#include <sstream>
#include <cassert>

namespace win32 {

    const Exception::properties_key_t Win32Exception::propertyErrorCodeKey(L"dwErrorCode");

    Win32Exception::Win32Exception(DWORD errorCode/* = GetLastError()*/) : Exception(FormatMessage(errorCode)) {
        _properties.insert(std::make_pair(propertyErrorCodeKey, boost::any(errorCode)));
    }

    /*virtual*/ Win32Exception::~Win32Exception() {
    }

    DWORD Win32Exception::get_ErrorCode() const {
        properties_t::const_iterator i = _properties.find(propertyErrorCodeKey);
        assert(i != _properties.end());
        return(boost::any_cast<DWORD>(i->second));
    }

    std::wstring Win32Exception::FormatMessage(DWORD errorCode) {
        std::wstring returnValue;

        LPWSTR pwszMsg(NULL);
        DWORD nChars = ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                                                    NULL,
                                                    errorCode,
                                                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                                                    reinterpret_cast<LPWSTR>(&pwszMsg),
                                                    0,
                                                    NULL
                                                );

        if (nChars == 0) {
            std::wstringstream ss;
            ss << L"Error " << std::showbase << std::hex << errorCode;
            returnValue = ss.str();
        }
        if (pwszMsg) {
            int i = wcslen(pwszMsg);
            while (--i > 0)
                if (pwszMsg[i] == L'\r' || pwszMsg[i] == L'\n')
                    pwszMsg[i] = L'\0';
            returnValue = pwszMsg;
            ::LocalFree(pwszMsg);
        }

        return(returnValue);
    }

}



COMException.h



#pragma once
#include "Exception.h"
#include <Windows.h>

namespace win32 {

    class COMException : public virtual Exception
    {

    private:
        enum {
            WCODE_HRESULT_FIRST = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x200),
            WCODE_HRESULT_LAST = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF + 1, 0) - 1
        };

    protected:
        static const properties_key_t propertyHrKey;
        static const properties_key_t propertyDescriptionKey;
        static const properties_key_t propertyInterfaceKey;
        static const properties_key_t propertyHelpContextKey;
        static const properties_key_t propertyHelpFileKey;
        static const properties_key_t propertySourceKey;

    public:
        COMException(HRESULT hr);
        virtual ~COMException();

    public:
        __declspec(property(get=get_HResult))
        HRESULT HResult;
        HRESULT get_HResult() const;

        __declspec(property(get=get_Description))
        std::wstring Description;
        std::wstring get_Description() const;

        __declspec(property(get=get_Interface))
        GUID Interface;
        GUID get_Interface() const;

        __declspec(property(get=get_HelpContext))
        DWORD HelpContext;
        DWORD get_HelpContext() const;

        __declspec(property(get=get_HelpFile))
        std::wstring HelpFile;
        std::wstring get_HelpFile() const;

        __declspec(property(get=get_Source))
        std::wstring Source;
        std::wstring get_Source() const;

    public:
        static std::wstring FormatMessage(HRESULT hr);
        static HRESULT WCodeToHRESULT(WORD wCode);
        static WORD HRESULTToWCode(HRESULT hr);

    };

}


COMException.cpp



#include "COMException.h"
#include <sstream>
#include <cassert>

namespace win32 {

    const Exception::properties_key_t COMException::propertyHrKey(L"hr");
    const Exception::properties_key_t COMException::propertyDescriptionKey(L"IErrorInfo_Description");
    const Exception::properties_key_t COMException::propertyInterfaceKey(L"IErrorInfo_GUID");
    const Exception::properties_key_t COMException::propertyHelpContextKey(L"IErrorInfo_HelpContext");
    const Exception::properties_key_t COMException::propertyHelpFileKey(L"IErrorInfo_HelpFile");
    const Exception::properties_key_t COMException::propertySourceKey(L"IErrorInfo_Source");

    COMException::COMException(HRESULT hr) : Exception(FormatMessage(hr)) {
        _properties.insert(std::make_pair(propertyHrKey, boost::any(hr)));
        IErrorInfo *pErrorInfo(NULL);
        if (::GetErrorInfo(0, &pErrorInfo) == S_OK) {
            BSTR bstr;
            if (SUCCEEDED(pErrorInfo->GetDescription(&bstr))) {
                _properties.insert(std::make_pair(propertyDescriptionKey, boost::any(std::wstring(bstr))));
                SysFreeString(bstr);
            }
            GUID guid;
            if (SUCCEEDED(pErrorInfo->GetGUID(&guid))) {
                _properties.insert(std::make_pair(propertyInterfaceKey, boost::any(guid)));
            }
            DWORD dw;
            if (SUCCEEDED(pErrorInfo->GetHelpContext(&dw))) {
                _properties.insert(std::make_pair(propertyHelpContextKey, boost::any(dw)));
            }
            if (SUCCEEDED(pErrorInfo->GetHelpFile(&bstr))) {
                _properties.insert(std::make_pair(propertyHelpFileKey, boost::any(std::wstring(bstr))));
                SysFreeString(bstr);
            }
            if (SUCCEEDED(pErrorInfo->GetSource(&bstr))) {
                _properties.insert(std::make_pair(propertySourceKey, boost::any(std::wstring(bstr))));
                SysFreeString(bstr);
            }

            pErrorInfo->Release();
        }
    }

    /*virtual*/ COMException::~COMException() {
    }

    HRESULT COMException::get_HResult() const {
        properties_t::const_iterator i = _properties.find(propertyHrKey);
        assert(i != _properties.end());
        return(boost::any_cast<HRESULT>(i->second));
    }

    std::wstring COMException::get_Description() const {
        properties_t::const_iterator i = _properties.find(propertyDescriptionKey);
        if (i != _properties.end())
            return(boost::any_cast<std::wstring>(i->second));
        else
            return(std::wstring());
    }

    GUID COMException::get_Interface() const {
        properties_t::const_iterator i = _properties.find(propertyInterfaceKey);
        if (i != _properties.end())
            return(boost::any_cast<GUID>(i->second));
        else
            return(GUID_NULL);
    }

    DWORD COMException::get_HelpContext() const {
        properties_t::const_iterator i = _properties.find(propertyHelpContextKey);
        if (i != _properties.end())
            return(boost::any_cast<DWORD>(i->second));
        else
            return(0);
    }

    std::wstring COMException::get_HelpFile() const {
        properties_t::const_iterator i = _properties.find(propertyHelpFileKey);
        if (i != _properties.end())
            return(boost::any_cast<std::wstring>(i->second));
        else
            return(std::wstring());
    }

    std::wstring COMException::get_Source() const {
        properties_t::const_iterator i = _properties.find(propertySourceKey);
        if (i != _properties.end())
            return(boost::any_cast<std::wstring>(i->second));
        else
            return(std::wstring());
    }

    std::wstring COMException::FormatMessage(HRESULT hr) {
        std::wstring returnValue;

        LPWSTR pwszMsg(NULL);
        DWORD nChars = ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            static_cast<DWORD>(hr),
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            reinterpret_cast<LPWSTR>(&pwszMsg),
            0,
            NULL
            );

        if (nChars == 0) {
            std::wstringstream ss;
            WORD wCode = HRESULTToWCode(hr);
            if (wCode != 0)
                ss << L"IDispatch error #" << wCode;
            else
                ss << L"Unknown error " << std::showbase << std::hex << hr;
            returnValue = ss.str();
        }
        if (pwszMsg) {
            int i = wcslen(pwszMsg);
            while (--i > 0)
                if (pwszMsg[i] == L'\r' || pwszMsg[i] == L'\n')
                    pwszMsg[i] = L'\0';
            returnValue = pwszMsg;
            ::LocalFree(pwszMsg);
        }

        return(returnValue);
    }

    HRESULT COMException::WCodeToHRESULT(WORD wCode) {
        return (wCode >= 0xFE00 ? WCODE_HRESULT_LAST : WCODE_HRESULT_FIRST + wCode);
    }

    WORD COMException::HRESULTToWCode(HRESULT hr) {
        return((hr >= WCODE_HRESULT_FIRST && hr <= WCODE_HRESULT_LAST) ? static_cast<WORD>(hr - WCODE_HRESULT_FIRST) : 0);
    }

}

0 коммент.:

Отправить комментарий

Copyright 2007-2011 Chabster