#ifndef COMMON_H #define COMMON_H #include #include #include #ifdef UNICODE #define WA "W" #else #define WA "A" #endif int EBMessageBox(const TCHAR* tszText, const TCHAR* tszCaption, unsigned uType); struct Win32Error : public std::exception { Win32Error(DWORD dwErr); ~Win32Error(); virtual const char* what() const noexcept override; virtual const TCHAR* twhat() const noexcept; private: DWORD m_dwErr; char* m_szMsg = NULL; wchar_t* m_wszMsg = NULL; }; struct Library { Library(const TCHAR* tszLibrary); ~Library(); template T* GetProcAddress(const char* szProc); private: HMODULE m_hModule; }; template T* Library::GetProcAddress(const char* const szProc) { return (T*)(void*)::GetProcAddress(m_hModule, szProc); } /* Create and return an object of type C. If construction fails, * return nothing. The returned value must be checked before being * used, as dereferencing is undefined if the value is empty. */ template std::optional maybe_make(U... xs) { try { return T(xs...); } catch (...) { return {}; } } /* Call Windows API function, throwing error on NULL. */ template inline auto require(T... xs) { auto r = F(xs...); if (!r) throw Win32Error(GetLastError()); return r; } /* Call Windows API function, showing a warning on NULL. */ template inline auto prefer(T... xs) { try { return require(xs...); } catch (Win32Error& e) { EBMessageBox(e.twhat(), TEXT("System Error"), MB_ICONWARNING); return (decltype(F(std::declval()...)))NULL; } } /* Return integer scaled for current DPI. */ inline int Dpi(const int i) { extern int g_iDPI; return MulDiv(i, g_iDPI, 96); } inline int Cmp(const int a, const int b) { if (a == b) return 0; if (a > b) return 1; return -1; } #endif