diff options
-rw-r--r-- | c/data.cpp | 69 | ||||
-rw-r--r-- | c/main.cpp | 2 | ||||
-rw-r--r-- | c/win.cpp | 86 | ||||
-rw-r--r-- | c/win.h | 26 |
4 files changed, 122 insertions, 61 deletions
@@ -6,46 +6,45 @@ #include <libxml/xpath.h> #include "data.h" +#include "win.h" struct InternetFile { - InternetFile(const wchar_t* url); - ~InternetFile(); - DWORD Read(void* buf, DWORD cb); - HINTERNET hi; - HINTERNET hiUrl; -}; + InternetFile(const wchar_t* url) + { + hi = InternetOpen(L"Episode Browser", + INTERNET_OPEN_TYPE_DIRECT, nullptr, nullptr, + /*INTERNET_FLAG_ASYNC*/0); + if (!hi) + throw Win32Error{}; + + hiUrl = InternetOpenUrl(hi, url, + nullptr, 0, INTERNET_FLAG_NO_UI, 0); + if (!hiUrl) { + DWORD e = GetLastError(); + InternetCloseHandle(hi); + throw InternetError(e); + } + } -InternetFile::InternetFile(const wchar_t* url) -{ - hi = InternetOpen(L"Episode Browser", - INTERNET_OPEN_TYPE_DIRECT, nullptr, nullptr, - /*INTERNET_FLAG_ASYNC*/0); - if (!hi) - throw Win32Error{}; - - hiUrl = InternetOpenUrl(hi, url, - nullptr, 0, INTERNET_FLAG_NO_UI, 0); - if (!hiUrl) { + ~InternetFile() + { + InternetCloseHandle(hiUrl); InternetCloseHandle(hi); - throw Win32Error{}; } -} -InternetFile::~InternetFile() -{ - InternetCloseHandle(hiUrl); - InternetCloseHandle(hi); -} + DWORD Read(void* buf, DWORD cb) + { + DWORD cbRead; + if (InternetReadFile(hiUrl, buf, cb, &cbRead)) + return cbRead; + else + throw InternetError{}; + } -DWORD InternetFile::Read(void* buf, DWORD cb) -{ - DWORD cbRead; - if (InternetReadFile(hiUrl, buf, cb, &cbRead)) - return cbRead; - else - throw Win32Error{}; -} + HINTERNET hi; + HINTERNET hiUrl; +}; template <auto F, typename T> struct XmlPtr @@ -98,8 +97,8 @@ void FetchData() { LIBXML_TEST_VERSION; - InternetFile inf{L"https://www.detectiveconanworld.com/wiki/Anime"}; - //InternetFile inf{L"file://C:/Users/John/Desktop/dcw.html"}; + InternetFile inf(L"https://www.detectiveconanworld.com/wiki/Anime"); + //InternetFile inf(L"file://C:/Users/John/Desktop/dcw.html"); char buf[1024]; HtmlParserCtxtPtr ctxt = htmlCreatePushParserCtxt(nullptr, nullptr, @@ -167,6 +166,6 @@ void WaitFetchData(bool* bDone) noexcept *bDone = true; } catch (...) { *bDone = true; - ShowException(L"Remote data could not be fetched due to %s: %s", L"Error", MB_ICONWARNING); + ShowException(L"Remote data could not be fetched due to an error: %s", L"Error", MB_ICONWARNING); } } @@ -81,7 +81,7 @@ static void UpdateTheme(); void OnTerminate() noexcept { - ShowException(L"Episode Browser was terminated due to %s: %s", L"Fatal Error", MB_ICONERROR); + ShowException(L"Episode Browser was terminated due to an error: %s", L"Fatal Error", MB_ICONERROR); _Exit(1); } @@ -2,6 +2,7 @@ #include <string> #include <SWI-Prolog.h> #include <windows.h> +#include <wininet.h> #include "pl.h" #include "util.h" @@ -84,24 +85,29 @@ int EBMessageBox(const std::wstring_view text, const std::wstring_view caption, void ShowException(const wchar_t* const fmt, const wchar_t* const title, const UINT uType) noexcept { - const wchar_t* what = L"an exception"; - WcharPtr why; - try { std::rethrow_exception(std::current_exception()); } catch (const term_t& t) { - what = L"a Prolog exception"; - try { why = PlString(t); } catch (...) {} - } catch (const Win32Error& e) { - what = L"a Windows error"; - try { why = WcharPtr::Copy(e.What()); } catch (...) {} + WcharPtr what = PlString(t); + std::wstring msg(wcslen(fmt)+wcslen(what), 0); + Swprintf(msg, fmt, static_cast<wchar_t*>(what)); + EBMessageBox(msg, title, uType); + } 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) { - try { why = WcharPtr::FromNarrow(e.what()); } catch (...) {} - } catch (...) {} + auto what = WcharPtr::FromNarrow(e.what()); + std::wstring msg(wcslen(fmt)+wcslen(what), 0); + Swprintf(msg, fmt, static_cast<wchar_t*>(what)); + 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); + } - std::wstring msg(wcslen(fmt)+wcslen(what)+wcslen(why), 0); - Swprintf(msg, fmt, what, static_cast<wchar_t*>(why)); - EBMessageBox(msg, title, uType); } int GetRelativeCursorPos(const HWND hWnd, POINT* const pt) noexcept @@ -118,9 +124,6 @@ int GetRelativeCursorPos(const HWND hWnd, POINT* const pt) noexcept return 1; } -Win32Error::Win32Error() noexcept - : code(GetLastError()) {} - Win32Error::Win32Error(const DWORD code) noexcept : code(code) {} @@ -136,25 +139,66 @@ const char* Win32Error::what() const noexcept { if (!m_szMsg) FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, + FORMAT_MESSAGE_ALLOCATE_BUFFER + |FORMAT_MESSAGE_FROM_SYSTEM + |FORMAT_MESSAGE_FROM_HMODULE + |FORMAT_MESSAGE_IGNORE_INSERTS, + GetModuleHandle(L"wininet.dll"), code, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (char*)&m_szMsg, 0, nullptr); - return m_szMsg; + return m_szMsg? m_szMsg: "An unknown error occurred"; } const wchar_t* Win32Error::What() const noexcept { if (!m_wszMsg) FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, + FORMAT_MESSAGE_ALLOCATE_BUFFER + |FORMAT_MESSAGE_FROM_SYSTEM + |FORMAT_MESSAGE_FROM_HMODULE + |FORMAT_MESSAGE_IGNORE_INSERTS, + GetModuleHandle(L"wininet.dll"), 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}; + + 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 (!InternetGetLastResponseInfo(&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; } @@ -16,14 +16,32 @@ int GetRelativeCursorPos(HWND hWnd, POINT* pt) noexcept; /* Cached values from GetSystemMetrics. */ template <int I> auto Metric = GetSystemMetrics(I); +struct WideException : public std::exception +{ + virtual const char* what() const noexcept = 0; + virtual const wchar_t* What() const noexcept = 0; +}; + /* Exception for Windows API errors. */ -struct Win32Error : public std::exception +struct Win32Error : public WideException { - Win32Error() noexcept; - Win32Error(DWORD code) noexcept; + Win32Error(DWORD code = GetLastError()) noexcept; ~Win32Error() noexcept; const char* what() const noexcept override; - const wchar_t* What() const noexcept; + const wchar_t* What() const noexcept override; + DWORD code; +private: + char* m_szMsg = nullptr; + wchar_t* m_wszMsg = nullptr; +}; + +/* Exception for extended Wininet errors. */ +struct InternetError : public WideException +{ + InternetError(DWORD codeSystem = GetLastError()); + ~InternetError() noexcept; + const char* what() const noexcept override; + const wchar_t* What() const noexcept override; DWORD code; private: char* m_szMsg = nullptr; |