From 2f7b69d6d4cf18ca9ca04d9a44aaa6871ce51160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Wed, 7 Sep 2022 00:40:26 +0200 Subject: Improve error handling. --- c/win32.cpp | 107 ++++++++++-------------------------------------------------- 1 file changed, 18 insertions(+), 89 deletions(-) (limited to 'c/win32.cpp') diff --git a/c/win32.cpp b/c/win32.cpp index fa5116d..73316e8 100644 --- a/c/win32.cpp +++ b/c/win32.cpp @@ -32,17 +32,21 @@ void WithNextWindow(void (*proc)(HWND)) static thread_local void (*procNext)(HWND); static thread_local HHOOK hHook; - procNext = proc; - hHook = Require(SetWindowsHookExW(WH_CBT, [](const int nCode, + static const auto procCBT = [](const int nCode, const WPARAM wParam, const LPARAM lParam) -> LRESULT CALLBACK { if (nCode == HCBT_CREATEWND) { - Require(UnhookWindowsHookEx(hHook)); + if (!UnhookWindowsHookEx(hHook)) + throw Err(WINDOWS, L"Window hook could not be removed: %s"); procNext(reinterpret_cast(wParam)); return 0; } else return CallNextHookEx(0, nCode, wParam, lParam); - }, nullptr, GetCurrentThreadId())); + }; + + procNext = proc; + if (!(hHook = SetWindowsHookExW(WH_CBT, procCBT, nullptr, GetCurrentThreadId()))) + throw Err(WINDOWS, L"Window hook could not be set: %s"); } /* Display next created window in the center of given window. */ @@ -59,18 +63,16 @@ static void CenterNextWindow(HWND hWnd) static thread_local HWND hWndParent; static thread_local HWND hWndNext; static thread_local HHOOK hHook; - - hWndParent = hWnd; - hWndNext = nullptr; - hHook = Require(SetWindowsHookExW(WH_CBT, [](const int nCode, - const WPARAM wParam, const LPARAM lParam) noexcept -> LRESULT CALLBACK + static const auto procCBT = [](const int nCode, + const WPARAM wParam, const LPARAM lParam) -> LRESULT CALLBACK { if (!hWndNext && nCode == HCBT_CREATEWND) { hWndNext = reinterpret_cast(wParam); return 0; } else if (nCode == HCBT_ACTIVATE && reinterpret_cast(wParam) == hWndNext) { - Require(UnhookWindowsHookEx(hHook)); + if (!UnhookWindowsHookEx(hHook)) + throw Err(WINDOWS, L"Window hook could not be removed: %s"); long lStyle = GetWindowLongW(hWndNext, GWL_STYLE); if (!(lStyle & WS_POPUP)) return 0; @@ -87,7 +89,12 @@ static void CenterNextWindow(HWND hWnd) return 0; } else return CallNextHookEx(0, nCode, wParam, lParam); - }, nullptr, GetCurrentThreadId())); + }; + + hWndParent = hWnd; + hWndNext = nullptr; + if (!(hHook = SetWindowsHookExW(WH_CBT, procCBT, nullptr, GetCurrentThreadId()))) + throw Err(WINDOWS, L"Window hook could not be set: %s"); } int EBMessageBox(const std::wstring_view text, const std::wstring_view caption, const UINT uType) @@ -112,84 +119,6 @@ int GetRelativeCursorPos(const HWND hWnd, POINT* const pt) noexcept return 1; } -Win32Error::Win32Error(const DWORD code, const HMODULE hModule) noexcept - : code(code), hModule(hModule) {} - -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_FROM_HMODULE - |FORMAT_MESSAGE_IGNORE_INSERTS, - hModule, - code, - MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (char*)&m_szMsg, - 0, nullptr); - return m_szMsg? m_szMsg: "An unknown error occurred"; -} - -const wchar_t* Win32Error::What() const noexcept -{ - if (!m_wszMsg) - FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER - |FORMAT_MESSAGE_FROM_SYSTEM - |FORMAT_MESSAGE_FROM_HMODULE - |FORMAT_MESSAGE_IGNORE_INSERTS, - hModule, - code, - MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (wchar_t*)&m_wszMsg, - 0, nullptr); - return m_wszMsg? m_wszMsg: L"An unknown error occurred"; -} - -InternetError::InternetError(DWORD codeSystem) -{ - if (codeSystem != ERROR_INTERNET_EXTENDED_ERROR) - throw Win32Error(codeSystem, GetModuleHandle(L"wininet.dll")); - - DWORD len, cch; - InternetGetLastResponseInfo(&code, nullptr, &len); - - cch = len+1; - m_szMsg = new char[cch]; - if (!InternetGetLastResponseInfoA(&code, m_szMsg, &cch)) - throw Win32Error(); - - cch = len+1; - m_wszMsg = new wchar_t[cch]; - if (!InternetGetLastResponseInfoW(&code, m_wszMsg, &len)) - throw Win32Error(); -} - -InternetError::~InternetError() -{ - delete m_szMsg; - delete m_wszMsg; -} - -const char* InternetError::what() const noexcept -{ - return m_szMsg; -} - -const wchar_t* InternetError::What() const noexcept -{ - return m_wszMsg; -} - std::optional Library::Maybe(const wchar_t* const lib) noexcept { HMODULE hModule = LoadLibraryW(lib); -- cgit v1.2.3