From dccea47e9bc322d654902a1db4fc52cbf6dd0cd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Tue, 26 Jul 2022 18:51:15 +0200 Subject: Improve Win32Error, library handling code. --- c/common.cpp | 32 ++------------------------------ c/common.h | 44 ++++++++++++++++++++++++++++---------------- c/main.cpp | 31 +++++++++++++++---------------- 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 std::basic_string BstrFromSz(const char* sz, int iCp = CP_UTF8); int EBMessageBox(const TCHAR* tszText, const TCHAR* tszCaption, unsigned uType); +/* Conditionally choose between two values. */ +template +constexpr std::enable_if_t choose(X x, Y) { return x; } +template +constexpr std::enable_if_t choose(X, Y y) { return y; } + +/* Conditionally choose between ANSI and wide string literal. */ +#define AWTEXT(t, s) choose>(L"" s, s) + +/* Conditionally choose between ANSI and wide Windows API function. */ +#define AWFUN(t, f) choose>(f##W, f##A) + struct Win32Error : public std::exception { Win32Error(); Win32Error(DWORD dwErr); ~Win32Error(); template const T* what() const noexcept; - + DWORD dwErr; private: - DWORD m_dwErr; char* m_szMsg = NULL; wchar_t* m_wszMsg = NULL; }; +template +const T* Win32Error::what() const noexcept +{ + TCHAR* tszMsg = choose>(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 -constexpr std::enable_if_t choose(X x, Y) { return x; } -template -constexpr std::enable_if_t choose(X, Y y) { return y; } - -/* Conditionally choose between ANSI and wide string literal. */ -#define AWTEXT(t, s) choose>(L"" s, s) - -/* Conditionally choose between ANSI and wide Windows API function. */ -#define AWFUN(t, f) choose>(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(TEXT("User32.dll"))) - if (auto GetDpiForWindow = opLib->GetProcAddress("GetDpiForWindow")) - g_iDPI = GetDpiForWindow(g_hWnd); - - if (auto opLib = maybe_make(TEXT("uxtheme.dll"))) - if (opLib->GetProcAddress("SetWindowTheme")) - g_bThemes = 1; - - if (auto opLib = maybe_make(TEXT("User32.dll"))) { - if (opLib->GetProcAddress("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(TEXT("User32.dll")); + auto GetDpiForWindow = opLib->GetProcAddress("GetDpiForWindow")) + g_iDPI = GetDpiForWindow(g_hWnd); + + if (auto opLib = maybe_make(TEXT("uxtheme.dll")); + opLib->GetProcAddress("SetWindowTheme")) + g_bThemes = 1; + + if (auto opLib = maybe_make(TEXT("User32.dll")); + opLib->GetProcAddress("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(require(GetStockObject(DEFAULT_GUI_FONT))); -- cgit v1.2.3