aboutsummaryrefslogtreecommitdiff
path: root/c/common.h
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2022-07-26 18:51:15 +0200
committerJohn Ankarström <john@ankarstrom.se>2022-07-26 18:51:15 +0200
commitdccea47e9bc322d654902a1db4fc52cbf6dd0cd7 (patch)
treedebae66516428387003c2eb1cf0142e1f4b33e2e /c/common.h
parentbb772c84c02aab0a918ed723390c6af79a2e45e8 (diff)
downloadEpisodeBrowser-dccea47e9bc322d654902a1db4fc52cbf6dd0cd7.tar.gz
Improve Win32Error, library handling code.
Diffstat (limited to 'c/common.h')
-rw-r--r--c/common.h44
1 files changed, 28 insertions, 16 deletions
diff --git a/c/common.h b/c/common.h
index 709a258..3f27ba4 100644
--- a/c/common.h
+++ b/c/common.h
@@ -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)
{