diff options
author | John Ankarström <john@ankarstrom.se> | 2022-08-03 21:57:27 +0200 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2022-08-03 21:57:27 +0200 |
commit | 04daecdd21e86e7556a9462380096530228cd6ca (patch) | |
tree | ed2a8134532607687c165c4a13d6f6c020c42d18 /c/win.cpp | |
parent | 32bb4696396e48521614d00e5b8f6e6586822f31 (diff) | |
download | EpisodeBrowser-04daecdd21e86e7556a9462380096530228cd6ca.tar.gz |
Split common.h to util.h, wcharptr.h and win.h.
Diffstat (limited to 'c/win.cpp')
-rw-r--r-- | c/win.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/c/win.cpp b/c/win.cpp new file mode 100644 index 0000000..435e739 --- /dev/null +++ b/c/win.cpp @@ -0,0 +1,108 @@ +#include <utility> +#include <windows.h> + +#include "win.h" + +Win32Error::Win32Error() : code(GetLastError()) {} +Win32Error::Win32Error(const DWORD code) : code(code) {} + +Win32Error::~Win32Error() +{ + if (m_szMsg) + HeapFree(GetProcessHeap(), 0, m_szMsg); + if (m_wszMsg) + HeapFree(GetProcessHeap(), 0, m_wszMsg); +} + +const char* Win32Error::what() const noexcept +{ + if (!m_szMsg) + FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + code, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + (char*)&m_szMsg, + 0, NULL); + return m_szMsg; +} + +const wchar_t* Win32Error::What() const noexcept +{ + if (!m_wszMsg) + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + code, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + (wchar_t*)&m_wszMsg, + 0, NULL); + return m_wszMsg; +} + +std::optional<Library> Library::Maybe(const wchar_t* const lib) +{ + HMODULE hModule = LoadLibrary(lib); + if (!hModule) return {}; + return Library(hModule); +} + +Library::Library(const HMODULE hModule) : m_hModule(hModule) {} + +Library::Library(const wchar_t* const lib) +{ + m_hModule = LoadLibrary(lib); + if (!m_hModule) + throw Win32Error(); +} + +Library::~Library() +{ + FreeLibrary(m_hModule); +} + +int EBMessageBox(const wchar_t* const wszText, const wchar_t* const wszCaption, const unsigned uType) +{ + extern HWND g_hWnd; + + auto proc = [](const int nCode, const WPARAM wParam, const LPARAM lParam) noexcept + -> LRESULT CALLBACK + { + if (!g_hWnd || nCode < 0 || nCode != HCBT_ACTIVATE) + return CallNextHookEx(0, nCode, wParam, lParam); + + HWND hWnd = (HWND)wParam; + long lStyle = GetWindowLong(hWnd, GWL_STYLE); + if (!(lStyle & WS_POPUP)) return 0; + + RECT rcMain, rcMsg; + GetWindowRect(g_hWnd, &rcMain); + GetWindowRect(hWnd, &rcMsg); + SetWindowPos(hWnd, NULL, + rcMain.left+(rcMain.right-rcMain.left)/2-(rcMsg.right-rcMsg.left)/2, + rcMain.top+(rcMain.bottom-rcMain.top)/2-(rcMsg.bottom-rcMsg.top)/2, + -1, -1, + SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE); + + return 0; + }; + + HHOOK hHook = require(SetWindowsHookEx(WH_CBT, proc, (HINSTANCE)NULL, GetCurrentThreadId())); + int r = MessageBox(g_hWnd, wszText, wszCaption, uType); + require(UnhookWindowsHookEx(hHook)); + return r; +} + +int GetRelativeCursorPos(HWND hWnd, POINT* pt) +{ + RECT rc; + if (!GetClientRect(hWnd, &rc)) return 0; + SetLastError(ERROR_SUCCESS); + if (!MapWindowPoints(hWnd, NULL, (POINT*)&rc, 2)) return 0; + + POINT ptMouse; + if (!GetCursorPos(&ptMouse)) return 0; + pt->x = ptMouse.x-rc.left; + pt->y = ptMouse.y-rc.top; + return 1; +} |