⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pja_format.cpp

📁 图像显示软件源码
💻 CPP
字号:
// pja_format.cpp - implementation file for the CFormat class
//
// Copyright (c) 2006 PJ Arends
//
// This file is provided "AS-IS". Use and/or abuse it in any way you feel fit.
//

#include "pja_format.h"
#include <crtdbg.h>            // for _ASSERT

using namespace pja;

// ReservedMarkers is used by the AddMarker and RemoveMarker functions
const TCHAR ReservedMarkers[] = _T("%nt123456789");

CFormat::CFormat(unsigned int Precision /* = 6 */) :
precision(Precision)
{
    markermap[_T('%')] = _T("%");
    markermap[_T('n')] = _T("\r\n");
    markermap[_T('t')] = _T("\t");
}

unsigned int CFormat::SetPrecision(unsigned int p)
{
    unsigned int ret = precision;
    precision = p;
    return ret;
}

std::tstring CFormat::AddMarker(TCHAR Marker, std::tstring ReplaceWith)
{
    _ASSERT(_tcschr(ReservedMarkers, Marker) == 0);
    _ASSERT (!ReplaceWith.empty());

    if (_tcschr(ReservedMarkers, Marker) == 0 && !ReplaceWith.empty())
    {
        return markermap[Marker] = ReplaceWith;
    }
    return _T("");
}

std::tstring CFormat::RemoveMarker(TCHAR Marker)
{
    _ASSERT(_tcschr(ReservedMarkers, Marker) == 0);

    if (_tcschr(ReservedMarkers, Marker) == 0 && markermap.find(Marker) != markermap.end())
    {
        std::tstring ret = markermap[Marker];
        markermap.erase(Marker);
        return ret;
    }

    return _T("");
}

#ifdef _WINDOWS_
// The file windows.h declares the HMODULE type and the GetModuleHandle, LoadString and
// OutputDebugString APIs so it has to be included in your project in order to use this
// overridden version of MakeMessage

std::tstring CFormat::MakeMessage(HMODULE hModule,
                                  unsigned long FormatStringID,
                                  unsigned int ParameterCount /* = 0 */,
                                  ...)
{
    _ASSERT(FormatStringID != 0);

    std::tstring ret = _T("");
    va_list valist;
    va_start(valist, ParameterCount);

    if (hModule == NULL)
    {
        hModule = ::GetModuleHandle(NULL);
        _ASSERT(hModule != NULL);
    }

    // following code based on CString::LoadString
    int size = 0;
    int len = 256;
    TCHAR *buffer = NULL;

    try
    {
        while (len && len > size - 2)
        {
            size += 256;
            len = 0;
            delete[] buffer;
            buffer = new TCHAR[size];
            if (hModule && FormatStringID && buffer)
            {
                len = ::LoadString(hModule, FormatStringID, buffer, size);
            }
        }
    }
    catch (std::bad_alloc &)
    {
        len = 0;
    }

    if (len)
    {
        ret = _make(buffer, ParameterCount, valist);
    }
    else
    {
#ifdef _DEBUG
        std::tostringstream error;
        error << _T("Unable to load string resource: ") << FormatStringID;
        error << _T(", GetLastError() returns: ") << GetLastError() << std::endl;
        OutputDebugString(error.str().c_str());
        _ASSERT(0);
#endif // _DEBUG

        // maybe substitute this text for a more meaningful error text,
        // or possibly leave the ret value empty
        ret = _T("<< ? ? ? >>");
    }

    delete[] buffer;
    return ret;
}

#endif // _WINDOWS_

std::tstring CFormat::MakeMessage(const TCHAR * FormatString,
                                  unsigned int ParameterCount /* = 0 */,
                                  ...)
{
    va_list valist;
    va_start(valist, ParameterCount);

    return _make(FormatString, ParameterCount, valist);
}

std::tstring CFormat::MakeMessage(std::tstring FormatString,
                                  unsigned int ParameterCount /* = 0 */,
                                  ...)
{
    va_list valist;
    va_start(valist, ParameterCount);

    return _make(FormatString, ParameterCount, valist);
}

std::tstring CFormat::_make(std::tstring FormatString,
                            unsigned int ParameterCount,
                            va_list valist)
{
    _ASSERT(ParameterCount < 10);

    // only handle a maximum of nine variables ( %1 to %9 )
    if (ParameterCount > 9)
    {
        ParameterCount = 9;
    }

    // here we grab the variables from the variable argument list and
    // store them in the marker map for quick and easy access later.
    // They should all be std::tstring
    unsigned int LoopCounter = 0;
    for (; LoopCounter < ParameterCount; ++LoopCounter)
    {
        std::tstring Variable = va_arg(valist, std::tstring);
        markermap[_T('1') + static_cast<TCHAR>(LoopCounter)] = Variable;
    }

    // remove any variables that may be left over from a previous call to _make.
    for (; LoopCounter < 10; ++LoopCounter)
    {
        markermap.erase(_T('1') + static_cast<TCHAR>(LoopCounter));
    }

    va_end(valist);

    // Scan the format string for insertion markers, and replace any found
    // with the corresponding text stored in the marker map.
    //
    // I am using the tostringstream insertion operator to build the final string,
    // not the tstring::replace function because I am hoping to be able to have the
    // marker map be able to map insertion markers to any type that has an ostream
    // insertion operator defined rather than simply a static text. But at the
    // moment I am unsure how to declare the map to take multiple data types.
    size_t LastPosition = 0;
    size_t Position = LastPosition;
    std::tostringstream FinalString;

    while (Position != std::tstring::npos)
    {
        Position = FormatString.find(_T('%'), Position);
        if (Position != std::tstring::npos)
        {
            FinalString << FormatString.substr(LastPosition, Position - LastPosition);
            TCHAR marker = FormatString[Position + 1];

            // if the format string ends with a single '%', marker will be the terminating NULL
            if (marker != NULL)
            {
                if (markermap.find(marker) != markermap.end())
                {
                    FinalString << markermap[marker];
                }
                ++Position;
            }

            ++Position;
            LastPosition = Position;
        }
    }

    if (LastPosition != 0)
    {
        FinalString << FormatString.substr(LastPosition);
        FormatString = FinalString.str();
    }

    return FormatString;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -