【问题标题】:Thowing localized system_error on Win32在 Win32 上显示本地化的 system_error
【发布时间】:2022-08-19 21:19:13
【问题描述】:

这是我自己要回答的问题。我不知道我的解决方案是否完美,但其他人可能对此有一些想法。
如果我使用 system_category() 抛出 system_error,则 system_category() 将错误代码转换为字符串(它返回多态 error_category)不会根据 Windows 下当前线程的语言环境进行本地化。我在 VC++ 支持论坛上提到了这一点,MS 的某个人回应说这是一个限制,将在下一个版本中修复,除了 WInRT 代码。
所以我需要一个解决方案。

    标签: c++ c++11 winapi


    【解决方案1】:

    到目前为止,这是我的解决方案:

    #include <Windows.h>
    #include <iostream>
    #include <system_error>
    
    struct xsystem_category : public std::error_category
    {
        xsystem_category() = default;
        xsystem_category( xsystem_category const & ) = delete;
        virtual ~xsystem_category() override = default;
        void operator =( xsystem_category const & ) = delete;
        virtual char const *name() const noexcept override;
        virtual std::error_condition default_error_condition( int code ) const noexcept override;
        virtual bool equivalent( int code, std::error_condition const &condition ) const noexcept override;
        virtual bool equivalent( std::error_code const &code, int condition ) const noexcept override;
        virtual std::string message( int condition ) const override;
    };
    
    char const *xsystem_category::name() const noexcept
    {
        return "xsystem_category";
    }
    
    std::error_condition xsystem_category::default_error_condition( int code ) const noexcept
    {
        return std::error_condition( code, xsystem_category() );
    }
    
    inline bool xsystem_category::equivalent( int code, std::error_condition const &condition ) const noexcept
    {
        return default_error_condition( code ) == condition;
    }
    
    inline bool xsystem_category::equivalent( std::error_code const &code, int condition ) const noexcept
    {
        return *this == code.category() && code.value() == condition;
    }
    
    std::string xsystem_category::message( int condition ) const
    {
        using namespace std;
        LCID lcid = GetThreadLocale();
        string errStr( 64, '\0' );
        while( !FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, nullptr, condition, lcid, errStr.data(), (DWORD)errStr.size(), nullptr ) )
            if( DWORD dwFmErr = GetLastError(); dwFmErr == ERROR_INSUFFICIENT_BUFFER )
                errStr.resize( 2 * errStr.size(), '\0' );
            else
                throw system_error( (int)dwFmErr, system_category(), "FormatMessage() failed" );
        errStr.resize( strlen( errStr.data() ) );
        return errStr;
    }
    

    也许有人建议在这里进行一些改进。

    【讨论】:

    • 您已经received feedback。你为什么忽略它?这一切看起来像是另一个变相的代码审查请求。
    猜你喜欢
    • 1970-01-01
    • 2011-01-08
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    相关资源
    最近更新 更多