diff options
author | John Ankarström <john@ankarstrom.se> | 2022-07-26 18:51:15 +0200 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2022-07-26 18:51:15 +0200 |
commit | dccea47e9bc322d654902a1db4fc52cbf6dd0cd7 (patch) | |
tree | debae66516428387003c2eb1cf0142e1f4b33e2e /c/common.h | |
parent | bb772c84c02aab0a918ed723390c6af79a2e45e8 (diff) | |
download | EpisodeBrowser-dccea47e9bc322d654902a1db4fc52cbf6dd0cd7.tar.gz |
Improve Win32Error, library handling code.
Diffstat (limited to 'c/common.h')
-rw-r--r-- | c/common.h | 44 |
1 files changed, 28 insertions, 16 deletions
@@ -14,19 +14,45 @@ template <typename T> std::basic_string<T> BstrFromSz(const char* sz, int iCp = CP_UTF8); int EBMessageBox(const TCHAR* tszText, const TCHAR* tszCaption, unsigned uType); +/* Conditionally choose between two values. */ +template <bool B, typename X, typename Y> +constexpr std::enable_if_t<B == true, X> choose(X x, Y) { return x; } +template <bool B, typename X, typename Y> +constexpr std::enable_if_t<B == false, Y> choose(X, Y y) { return y; } + +/* Conditionally choose between ANSI and wide string literal. */ +#define AWTEXT(t, s) choose<std::is_same_v<t, wchar_t>>(L"" s, s) + +/* Conditionally choose between ANSI and wide Windows API function. */ +#define AWFUN(t, f) choose<std::is_same_v<t, wchar_t>>(f##W, f##A) + struct Win32Error : public std::exception { Win32Error(); Win32Error(DWORD dwErr); ~Win32Error(); template <typename T = char> const T* what() const noexcept; - + DWORD dwErr; private: - DWORD m_dwErr; char* m_szMsg = NULL; wchar_t* m_wszMsg = NULL; }; +template <typename T> +const T* Win32Error::what() const noexcept +{ + TCHAR* tszMsg = choose<std::is_same_v<T, wchar_t>>(m_wszMsg, m_szMsg); + if (!tszMsg) + AWFUN(T, FormatMessage)( + FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dwErr, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + (TCHAR*)&tszMsg, + 0, NULL); + return tszMsg; +} + struct Library { Library(const TCHAR* tszLibrary); @@ -79,20 +105,6 @@ inline T prefer(const T x) return x; } -/* Conditionally choose between two values. This template is necessary - * because the ternary conditional operator can choose only between - * values of the same type. */ -template <bool B, typename X, typename Y> -constexpr std::enable_if_t<B == true, X> choose(X x, Y) { return x; } -template <bool B, typename X, typename Y> -constexpr std::enable_if_t<B == false, Y> choose(X, Y y) { return y; } - -/* Conditionally choose between ANSI and wide string literal. */ -#define AWTEXT(t, s) choose<std::is_same_v<t, wchar_t>>(L"" s, s) - -/* Conditionally choose between ANSI and wide Windows API function. */ -#define AWFUN(t, f) choose<std::is_same_v<t, wchar_t>>(f##W, f##A) - /* Return integer scaled for current DPI. */ inline int Dpi(const int i) { |