diff options
-rw-r--r-- | README | 8 | ||||
-rw-r--r-- | c/data.cpp | 9 | ||||
-rw-r--r-- | c/data.h | 1 | ||||
-rw-r--r-- | c/datalistview.cpp | 2 | ||||
-rw-r--r-- | c/datalistview.h | 2 | ||||
-rw-r--r-- | c/listview.cpp | 2 | ||||
-rw-r--r-- | c/listview.h | 6 | ||||
-rw-r--r-- | c/main.cpp | 11 | ||||
-rw-r--r-- | c/test.cpp | 3 | ||||
-rw-r--r-- | c/util.h | 2 | ||||
-rw-r--r-- | c/win32.cpp | 21 | ||||
-rw-r--r-- | c/win32.h | 3 | ||||
-rw-r--r-- | c/window.h | 2 |
13 files changed, 50 insertions, 22 deletions
@@ -60,7 +60,7 @@ To build Episode Browser, the following programs are required: Furthermore, the following dependencies are required: - - libxml2 (included with MSYS GCC) + - libxml2 (included with MSYS GCC, downloaded separately for MSVC) You may need to manually provide library and header file directories in c/CMakeLists.txt. @@ -69,7 +69,9 @@ Episode Browse may be built by issuing `make' from the root directory. The build process is controlled by a few environment variables: - SYSTEM = vs2019 (default) or mingw - - CONFIG = Debug (default) or Release + - VS_CONFIG = Debug (default) or Release + - VS_TOOLSET = v142 (default), v141_xp (for Windows XP support) + - VS_PLATFORM = x64 (default) or Win32 (32-bit x86) Hacking ~~~~~~~ @@ -98,3 +100,5 @@ without NUL, `len' is used. While specific Hungarian prefixes are unnecessary for most variables, "natural" word order should be avoided. In other words, lenString is preferred over stringLen, because it mirrors vString. + +Hungarian notation should not be used for type names. @@ -125,7 +125,7 @@ void WaitFor(Window& window, void (*f)(unsigned char*)) sig |= DONE; } catch (...) { sig |= DONE; - ShowException(L"Remote data could not be fetched due to an error: %s", + ShowException(L"Remote data could not be fetched due to an error while %s: %s", L"Error", MB_ICONWARNING); } }; @@ -155,6 +155,8 @@ void WaitFor(Window& window, void (*f)(unsigned char*)) void FetchData(unsigned char* sig) { + Act(L"fetching and parsing general episode data"); + /* The remote data is retrieved using WinINet from the * Detective Conan World wiki. Using libxml2's "push parser", * the HTML is parsed piece by piece as it is retrieved. The @@ -181,6 +183,8 @@ void FetchData(unsigned char* sig) if (!nodes || !nodes->nodeNr) throw std::runtime_error("could not find remote episode information"); + Act(L"inserting remote data"); + for (int i = 0; i < nodes->nodeNr; i++) { if (*sig & ABORT) return; @@ -222,6 +226,8 @@ void FetchData(unsigned char* sig) void FetchScreenwriters(unsigned char* sig) { + Act(L"fetching and parsing screenwriter data"); + /* Screenwriters are expensive to fetch, so we try to avoid * fetching screenwriters for episodes that already have a * screenwriter. Additionally, in the same session, we don't @@ -262,7 +268,6 @@ void FetchScreenwriters(unsigned char* sig) Wcscpy(Buf(url)+Len(prefix), d.wiki); /* Retrieve screenwriter from HTML. */ - UniqueOk<htmlParserCtxtPtr, xmlFreeParserCtxt> ctx = RemoteParserCtxt(url, nullptr); xpathCtx = xmlXPathNewContext(ctx.v->myDoc); if (xpathCtx.Bad(0)) @@ -74,6 +74,7 @@ struct CfgA wchar_t root[260] = {0}; wchar_t glob[64] = {0}; wchar_t url[192] = {0}; + wchar_t prefixUrl[48] = {0}; }; /* Variable template for obtaining the version of a given struct. */ diff --git a/c/datalistview.cpp b/c/datalistview.cpp index 92fc05c..4ed3d41 100644 --- a/c/datalistview.cpp +++ b/c/datalistview.cpp @@ -30,7 +30,7 @@ DataListView::DataListView(Window& parent) m_height = parent.cfg.heightDlv; } -int DataListView::Height() +int DataListView::Height() noexcept { return m_height? m_height: ListView::Height(); } diff --git a/c/datalistview.h b/c/datalistview.h index 21d6f05..2593b49 100644 --- a/c/datalistview.h +++ b/c/datalistview.h @@ -12,7 +12,7 @@ struct DataListView : public ListView DataListView(Window& parent); /* Return manual height, if set, or calculate height * appropriate for number of items. */ - int Height() override; + int Height() noexcept override; void ResizeColumns(int w) override; /* Set manual height. */ void SetHeight(int h); diff --git a/c/listview.cpp b/c/listview.cpp index 03a65ae..b638f7b 100644 --- a/c/listview.cpp +++ b/c/listview.cpp @@ -29,7 +29,7 @@ ListView::ListView(Window& parent, const HMENU hMenu, const DWORD dwStyle) : par SendMessageW(hWnd, WM_SETFONT, reinterpret_cast<WPARAM>(g_hfNormal), MAKELPARAM(FALSE, 0)); } -int ListView::Height() +int ListView::Height() noexcept { const int cItem = ListView_GetItemCount(hWnd); return Dpi(4)+cItem*Dpi(19); diff --git a/c/listview.h b/c/listview.h index 30164f7..ba3a115 100644 --- a/c/listview.h +++ b/c/listview.h @@ -13,9 +13,9 @@ struct ListView ListView(Window& parent, HMENU hMenu, DWORD dwStyle); /* Retrieve next matching list view item. */ - bool FindNextItem(LVITEM* lvi, LPARAM lParam); + bool FindNextItem(LVITEM* lvi, LPARAM lParam) noexcept; /* Naively calculate height appropriate for number of items. */ - virtual int Height(); + virtual int Height() noexcept; /* Update column widths on window size change (unimplemented * by default). */ virtual void ResizeColumns(int w); @@ -26,7 +26,7 @@ protected: WNDPROC m_proc0; }; -inline bool ListView::FindNextItem(LVITEM* const lvi, const LPARAM lParam) +inline bool ListView::FindNextItem(LVITEM* const lvi, const LPARAM lParam) noexcept { if ((lvi->iItem = ListView_GetNextItem(hWnd, lvi->iItem, lParam)) == -1) return false; @@ -124,11 +124,13 @@ static void InitializeMainWindow_(const HWND hWnd) * initializes global variables that are used by WndProc. */ /* Look up DPI. */ + Act(L"looking up DPI"); if (auto lib = Library::Maybe(L"User32.dll"); auto GetDpiForWindow = lib? lib->GetProcAddress<UINT(HWND)>("GetDpiForWindow"): nullptr) g_dpi = GetDpiForWindow(hWnd); /* Load normal font. */ + Act(L"loading fonts"); if (auto lib = Library::Maybe(L"User32.dll"); lib && lib->GetProcAddress<void>("SystemParametersInfoW")) { NONCLIENTMETRICSW m = {sizeof(NONCLIENTMETRICSW)}; @@ -156,6 +158,7 @@ static void InitializeMainWindow_(const HWND hWnd) SetWindowTheme = (decltype(SetWindowTheme))(void*)GetProcAddress(hModule, "SetWindowTheme"); } + Act(L"setting up main window"); g_window = new Window(hWnd); } @@ -164,17 +167,18 @@ void InitializeMainWindow(const HWND hWnd) noexcept try { InitializeMainWindow_(hWnd); } catch (...) { - ShowException(L"Initialization failed due to an error: %s"); + ShowException(L"Initialization failed due to an error while %s: %s"); exit(1); } } LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, const LPARAM lParam) { + Act(nullptr); try { return g_window->WndProc(hWnd, uMsg, wParam, lParam); } catch (...) { - ShowException(L"The action was cancelled due to an error: %s"); + ShowException(L"The action was cancelled due to an error while %s: %s"); } return DefWindowProc(hWnd, uMsg, wParam, lParam); } @@ -200,6 +204,7 @@ LRESULT CALLBACK Window::WndProc(const HWND hWnd, const UINT uMsg, const WPARAM { switch (uMsg) { case WM_CREATE: + Act(L"creating main window"); UpdateTheme(); SetWindowPos(hWnd, nullptr, -1, -1, Dpi(510), Dpi(412), SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE); SetFocus(elv.hWnd); @@ -426,7 +431,7 @@ void Window::HandleMainMenu(const HWND hWnd, const WORD command) } } -void Window::Status(const wchar_t* msg, unsigned short i) +void Window::Status(const wchar_t* msg, unsigned short i) noexcept { SendMessage(hWndStatus, SB_SETTEXT, MAKEWPARAM(i, 0), reinterpret_cast<LPARAM>(msg)); } @@ -107,6 +107,7 @@ TESTS // SCPY(root); // SCPY(glob); // SCPY(url); +// SCPY(prefixUrl); // #undef CPY // #undef SCPY @@ -120,7 +121,7 @@ int RunTests(Window& window) const Test tests[] = { StrcpyWithSmallerDestination(), //IO(), - //MigrateCfg(), + // MigrateCfg(), }; printf("Results (%llu tests):\n", sizeof(tests)/sizeof(*tests)); @@ -15,7 +15,7 @@ std::set_terminate([]() noexcept \ { \ ShowException( \ - L"Episode Browser was terminated due to an error: %s", \ + L"Episode Browser was terminated due to an error while %s: %s", \ L"Fatal Error", MB_ICONERROR); \ _Exit(1); \ }) diff --git a/c/win32.cpp b/c/win32.cpp index ce1fc9d..2686f2e 100644 --- a/c/win32.cpp +++ b/c/win32.cpp @@ -8,6 +8,8 @@ #include "win32.h" #include "window.h" +static thread_local const wchar_t* s_action; + std::wstring WideFromNarrow(const std::string_view src, const int cp) { int cchNarrow = src.length()+1; @@ -93,23 +95,30 @@ int EBMessageBox(const std::wstring_view text, const std::wstring_view caption, return MessageBox(hWnd, text.data(), caption.data(), uType); } +void Act(const wchar_t* action) +{ + s_action = action; +} + void ShowException(const wchar_t* const fmt, const wchar_t* const title, const UINT uType) noexcept { + if (!s_action) + s_action = L"performing an unknown action"; 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()); + std::wstring msg(wcslen(fmt)+wcslen(s_action)+wcslen(e.What()), 0); + Swprintf(msg, fmt, s_action, 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()); + std::wstring msg(wcslen(fmt)+wcslen(s_action)+what.length(), 0); + Swprintf(msg, fmt, s_action, 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); + std::wstring msg(wcslen(fmt)+wcslen(s_action)+wcslen(what), 0); + Swprintf(msg, fmt, s_action, what); EBMessageBox(msg, title, uType); } } @@ -15,6 +15,9 @@ void WithNextWindow(void (*proc)(HWND)); /* Display message box centered in main window. */ int EBMessageBox(std::wstring_view text, std::wstring_view data, UINT uType); +/* Specify current action (used by ShowException). */ +void Act(const wchar_t* action); + /* Show message box for current exception. */ void ShowException( const wchar_t* fmt = L"An error occurred: %s", @@ -41,7 +41,7 @@ struct Window void HandleMainMenu(HWND, WORD); /* Display text in status bar. */ - void Status(const wchar_t* msg, unsigned short i = 0); + void Status(const wchar_t* msg, unsigned short i = 0) noexcept; /* Try to style application according to current Windows theme. */ void UpdateTheme(); |