aboutsummaryrefslogtreecommitdiff
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
parentbb772c84c02aab0a918ed723390c6af79a2e45e8 (diff)
downloadEpisodeBrowser-dccea47e9bc322d654902a1db4fc52cbf6dd0cd7.tar.gz
Improve Win32Error, library handling code.
-rw-r--r--c/common.cpp32
-rw-r--r--c/common.h44
-rw-r--r--c/main.cpp31
3 files changed, 45 insertions, 62 deletions
diff --git a/c/common.cpp b/c/common.cpp
index 155c099..c4624c0 100644
--- a/c/common.cpp
+++ b/c/common.cpp
@@ -4,8 +4,8 @@
/* Win32Error: Exception for Windows API errors. */
-Win32Error::Win32Error() : m_dwErr(GetLastError()) {}
-Win32Error::Win32Error(const DWORD dwErr) : m_dwErr(dwErr) {}
+Win32Error::Win32Error() : dwErr(GetLastError()) {}
+Win32Error::Win32Error(const DWORD dwErr) : dwErr(dwErr) {}
Win32Error::~Win32Error()
{
@@ -15,34 +15,6 @@ Win32Error::~Win32Error()
HeapFree(GetProcessHeap(), 0, m_wszMsg);
}
-template <>
-const char* Win32Error::what() const noexcept
-{
- if (!m_szMsg)
- FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- m_dwErr,
- MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
- (char*)&m_szMsg,
- 0, NULL);
- return m_szMsg;
-}
-
-template <>
-const wchar_t* Win32Error::what() const noexcept
-{
- if (!m_wszMsg)
- FormatMessageW(
- FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- m_dwErr,
- MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
- (wchar_t*)&m_wszMsg,
- 0, NULL);
- return m_wszMsg;
-}
-
/* Library: Wrapper for loading and freeing dynamically linked libraries. */
Library::Library(const TCHAR* const tszLibrary)
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)
{
diff --git a/c/main.cpp b/c/main.cpp
index 057bf32..2037578 100644
--- a/c/main.cpp
+++ b/c/main.cpp
@@ -167,22 +167,21 @@ static LRESULT CALLBACK CBTProc(const int nCode, const WPARAM wParam, const LPAR
g_hWnd = (HWND)wParam;
/* Look up constants. */
- if (auto opLib = maybe_make<Library>(TEXT("User32.dll")))
- if (auto GetDpiForWindow = opLib->GetProcAddress<UINT(HWND)>("GetDpiForWindow"))
- g_iDPI = GetDpiForWindow(g_hWnd);
-
- if (auto opLib = maybe_make<Library>(TEXT("uxtheme.dll")))
- if (opLib->GetProcAddress<void>("SetWindowTheme"))
- g_bThemes = 1;
-
- if (auto opLib = maybe_make<Library>(TEXT("User32.dll"))) {
- if (opLib->GetProcAddress<void>("SystemParametersInfo" WA)) {
- NONCLIENTMETRICS m;
- m.cbSize = sizeof(NONCLIENTMETRICS);
- require(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
- sizeof(NONCLIENTMETRICS), &m, 0));
- g_hfNormal = require(CreateFontIndirect(&m.lfMessageFont));
- }
+ if (auto opLib = maybe_make<Library>(TEXT("User32.dll"));
+ auto GetDpiForWindow = opLib->GetProcAddress<UINT(HWND)>("GetDpiForWindow"))
+ g_iDPI = GetDpiForWindow(g_hWnd);
+
+ if (auto opLib = maybe_make<Library>(TEXT("uxtheme.dll"));
+ opLib->GetProcAddress<void>("SetWindowTheme"))
+ g_bThemes = 1;
+
+ if (auto opLib = maybe_make<Library>(TEXT("User32.dll"));
+ opLib->GetProcAddress<void>("SystemParametersInfo" WA)) {
+ NONCLIENTMETRICS m;
+ m.cbSize = sizeof(NONCLIENTMETRICS);
+ require(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
+ sizeof(NONCLIENTMETRICS), &m, 0));
+ g_hfNormal = require(CreateFontIndirect(&m.lfMessageFont));
} else
g_hfNormal = static_cast<HFONT>(require(GetStockObject(DEFAULT_GUI_FONT)));