#ifndef COMMON_H #define COMMON_H #include #include #include int EBMessageBox(const wchar_t* wszText, const wchar_t* wszCaption, unsigned uType); int GetRelativeCursorPos(HWND hWnd, POINT* pt); struct wchar_ptr { static wchar_ptr from_narrow(const char* buf, int cp = CP_UTF8); static wchar_ptr copy(const wchar_t* s); wchar_ptr(); wchar_ptr(wchar_t* s); wchar_ptr& operator=(wchar_t* s); wchar_ptr(wchar_ptr& other) = delete; wchar_ptr& operator=(wchar_ptr& other) = delete; wchar_ptr(wchar_ptr&& other) noexcept; wchar_ptr& operator=(wchar_ptr&& other) noexcept; operator wchar_t*() noexcept; wchar_t *release(); ~wchar_ptr(); private: wchar_t* m_p = nullptr; }; struct Win32Error : public std::exception { Win32Error(); Win32Error(DWORD code); ~Win32Error(); const char* what() const noexcept; const wchar_t* WhatW() const noexcept; DWORD code; private: char* m_szMsg = NULL; wchar_t* m_wszMsg = NULL; }; struct Library { static std::optional Maybe(const wchar_t* lib); Library(const wchar_t* lib); ~Library(); template T* GetProcAddress(const char* szProc); private: Library(HMODULE hModule); HMODULE m_hModule; }; template T* Library::GetProcAddress(const char* const szProc) { return (T*)(void*)::GetProcAddress(m_hModule, szProc); } template inline int wszf(wchar_t (&buf)[N], const wchar_t* const fmt, T... xs) { return _snwprintf_s(buf, N, _TRUNCATE, fmt, xs...); } /* Variable template for caching values from GetSystemMetrics. */ template auto Metric = GetSystemMetrics(I); /* Check result of Windows API call, throwing error on NULL. */ template inline T require(const T x) { if (!x) throw Win32Error(); return x; } /* Check result of Windows API call, showing a warning on NULL. */ template inline T prefer(const T x) { if (!x) { EBMessageBox(Win32Error().WhatW(), 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); } inline int Cmp(const int a, const int b) { if (a == b) return 0; if (a > b) return 1; return -1; } /* 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