diff options
Diffstat (limited to 'c/win.h')
-rw-r--r-- | c/win.h | 105 |
1 files changed, 105 insertions, 0 deletions
@@ -0,0 +1,105 @@ +#ifndef WIN_H +#define WIN_H + +#include <optional> +#include <windows.h> + +int EBMessageBox(const wchar_t* wszText, const wchar_t* wszCaption, unsigned uType); +int GetRelativeCursorPos(HWND hWnd, POINT* pt); + +/* Win32Error: Exception for Windows API errors. */ +struct Win32Error : public std::exception +{ + Win32Error(); + Win32Error(DWORD code); + ~Win32Error(); + const char* what() const noexcept override; + const wchar_t* What() const noexcept; + DWORD code; +private: + char* m_szMsg = NULL; + wchar_t* m_wszMsg = NULL; +}; + +/* Library: Wrapper for loading and freeing dynamically linked libraries. */ +struct Library +{ + static std::optional<Library> Maybe(const wchar_t* lib); + Library(const wchar_t* lib); + ~Library(); + template <class T> T* GetProcAddress(const char* szProc); +private: + Library(HMODULE hModule); + HMODULE m_hModule; +}; + +template <typename T> +T* Library::GetProcAddress(const char* const szProc) +{ + return (T*)(void*)::GetProcAddress(m_hModule, szProc); +} + +/* Variable template for caching values from GetSystemMetrics. */ +template <int I> +auto Metric = GetSystemMetrics(I); + +/* Check result of Windows API call, throwing error on NULL. */ +template <typename T> +inline T require(const T x) +{ + if (!x) throw Win32Error(); + return x; +} + +/* Check result of Windows API call, showing a warning on NULL. */ +template <typename T> +inline T prefer(const T x) +{ + if (!x) { + EBMessageBox(Win32Error().What(), L"System Error", MB_ICONWARNING); + return (T)NULL; + } + return x; +} + +/* Return integer scaled for current DPI. */ +inline int Dpi(const int i) +{ + extern int g_dpi; + return MulDiv(i, g_dpi, 96); +} + +/* Get window rectangle relative to parent. */ +inline BOOL GetRelativeRect(const HWND hWnd, RECT* const rr) +{ + if (!GetClientRect(hWnd, rr)) return 0; + return MapWindowPoints(hWnd, GetParent(hWnd), (POINT*)rr, 2); +} + +inline BOOL SetWindowRect(const HWND hWnd, + const long left, const long top, const long right, const long bottom) +{ + return MoveWindow(hWnd, + left, top, + right-left, bottom-top, + TRUE); +} + +inline BOOL SetWindowRect(const HWND hWnd, const RECT r) +{ + return SetWindowRect(hWnd, r.left, r.top, r.right, r.bottom); +} + +inline BOOL EBIsThemeActive() +{ + extern BOOL (*IsThemeActive)(); + return IsThemeActive? IsThemeActive(): 0; +} + +inline BOOL EBSetWindowTheme(HWND hWnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList) +{ + extern BOOL (*SetWindowTheme)(HWND, LPCWSTR, LPCWSTR); + return SetWindowTheme? SetWindowTheme(hWnd, pszSubAppName, pszSubIdList): 0; +} + +#endif |