aboutsummaryrefslogtreecommitdiff
path: root/c/win.cpp
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2022-09-02 20:16:04 +0200
committerJohn Ankarström <john@ankarstrom.se>2022-09-02 20:16:18 +0200
commitbc4cef92d8efbf97a9215122abc2d7247c287f12 (patch)
treea5ca307281c4f143b5f172428c9fd2b629d6b426 /c/win.cpp
parent5c1c2ce2bdbf9735ad8a4d162609a8c22a4f0954 (diff)
downloadEpisodeBrowser-bc4cef92d8efbf97a9215122abc2d7247c287f12.tar.gz
Improve Window object.
Diffstat (limited to 'c/win.cpp')
-rw-r--r--c/win.cpp228
1 files changed, 0 insertions, 228 deletions
diff --git a/c/win.cpp b/c/win.cpp
deleted file mode 100644
index 40d68e4..0000000
--- a/c/win.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-#include <utility>
-#include <string>
-#include <string_view>
-#include <windows.h>
-#include <wininet.h>
-
-#include "main.h"
-#include "util.h"
-#include "win.h"
-
-std::wstring WideFromNarrow(const std::string_view src, const int cp)
-{
- int cchNarrow = src.length()+1;
- int cchWide = MultiByteToWideChar(cp, 0, src.data(), cchNarrow, nullptr, 0);
- std::wstring dst(cchWide, 0);
- if (!MultiByteToWideChar(cp, 0, src.data(), cchNarrow, dst.data(), cchWide))
- throw Win32Error();
- return dst;
-}
-
-void WithNextWindow(void (*proc)(HWND))
-{
- /* WithNextWindow uses a CBT hook to call an arbitrary
- * procedure just before the creation of the next window. The
- * hook is removed as soon as HCBT_CREATEWND is received.
- * Thus, proc is guaranteed to be executed only once. Note
- * that static storage must be used, as SetWindowHookEx cannot
- * accept a capturing lambda as the hook procedure. */
-
- static thread_local auto procNext = proc;
- static thread_local HHOOK hHook = Require(SetWindowsHookExW(WH_CBT, [](const int nCode,
- const WPARAM wParam, const LPARAM lParam) -> LRESULT CALLBACK
- {
- if (nCode == HCBT_CREATEWND) {
- Require(UnhookWindowsHookEx(hHook));
- procNext(reinterpret_cast<HWND>(wParam));
- return 0;
- } else
- return CallNextHookEx(0, nCode, wParam, lParam);
- }, nullptr, GetCurrentThreadId()));
-}
-
-/* Display next created window in the center of given window. */
-static void CenterNextWindow(HWND hWnd)
-{
- if (!hWnd)
- return;
-
- /* CenterNextWindow employs a trick similar to that above.
- * Note, however, that repositioning does not work unless it
- * is delayed until the new window is activated. This
- * complicates the code somewhat. */
-
- 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
- {
- if (!hWndNext && nCode == HCBT_CREATEWND) {
- hWndNext = reinterpret_cast<HWND>(wParam);
- return 0;
- } else if (nCode == HCBT_ACTIVATE
- && reinterpret_cast<HWND>(wParam) == hWndNext) {
- Require(UnhookWindowsHookEx(hHook));
-
- long lStyle = GetWindowLongW(hWndNext, GWL_STYLE);
- if (!(lStyle & WS_POPUP)) return 0;
-
- RECT rcMain, rcMsg;
- GetWindowRect(hWndParent, &rcMain);
- GetWindowRect(hWndNext, &rcMsg);
- SetWindowPos(hWndNext, nullptr,
- 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;
- } else
- return CallNextHookEx(0, nCode, wParam, lParam);
- }, nullptr, GetCurrentThreadId()));
-}
-
-int EBMessageBox(const std::wstring_view text, const std::wstring_view caption, const UINT uType)
-{
- extern Window* g_window;
- CenterNextWindow(g_window->hWnd);
- return MessageBox(g_window->hWnd, text.data(), caption.data(), uType);
-}
-
-void ShowException(const wchar_t* const fmt, const wchar_t* const title, const UINT uType) noexcept
-{
- try {
- std::rethrow_exception(std::current_exception());
- } catch (const WideException& e) {
- std::wstring msg(wcslen(fmt)+wcslen(e.What()), 0);
- Swprintf(msg, fmt, e.What());
- EBMessageBox(msg, title, uType);
- } catch (const std::exception& e) {
- std::wstring what = WideFromNarrow(e.what());
- std::wstring msg(wcslen(fmt)+what.length(), 0);
- Swprintf(msg, fmt, what.c_str());
- EBMessageBox(msg, title, uType);
- } catch (...) {
- const wchar_t* what = L"an unknown error occurred";
- std::wstring msg(wcslen(fmt)+wcslen(what), 0);
- Swprintf(msg, fmt, what);
- EBMessageBox(msg, title, uType);
- }
-}
-
-int GetRelativeCursorPos(const HWND hWnd, POINT* const pt) noexcept
-{
- RECT rc;
- if (!GetClientRect(hWnd, &rc)) return 0;
- SetLastError(ERROR_SUCCESS);
- if (!MapWindowPoints(hWnd, nullptr, (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;
-}
-
-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> Library::Maybe(const wchar_t* const lib) noexcept
-{
- HMODULE hModule = LoadLibraryW(lib);
- if (!hModule) return {};
- return Library(hModule);
-}
-
-Library::Library(const HMODULE hModule) noexcept
- : m_hModule(hModule) {}
-
-Library::Library(const wchar_t* const lib)
-{
- m_hModule = LoadLibraryW(lib);
- if (!m_hModule)
- throw Win32Error();
-}
-
-Library::~Library()
-{
- FreeLibrary(m_hModule);
-}