From 32bb4696396e48521614d00e5b8f6e6586822f31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Wed, 3 Aug 2022 20:51:23 +0200 Subject: Minor improvements. --- c/common.cpp | 20 ++++++-------------- c/common.h | 31 +++++++++++++++++++++---------- c/layout.h | 16 +++++++++------- c/main.cpp | 11 ++++++----- 4 files changed, 42 insertions(+), 36 deletions(-) (limited to 'c') diff --git a/c/common.cpp b/c/common.cpp index 59f0fdc..0a54f69 100644 --- a/c/common.cpp +++ b/c/common.cpp @@ -3,13 +3,11 @@ #include "common.h" -/* wchar_ptr: Simple wrapper for wide C strings. */ +wchar_ptr::wchar_ptr() noexcept {} -wchar_ptr::wchar_ptr() {} +wchar_ptr::wchar_ptr(wchar_t* const s) noexcept : m_p(s) {} -wchar_ptr::wchar_ptr(wchar_t* const s) : m_p(s) {} - -wchar_ptr& wchar_ptr::operator=(wchar_t* const s) +wchar_ptr& wchar_ptr::operator=(wchar_t* const s) noexcept { if (m_p != s) { delete m_p; @@ -31,15 +29,14 @@ wchar_ptr::operator wchar_t*() noexcept return m_p; } -/* Return pointer, releasing ownership. */ -wchar_t* wchar_ptr::release() +wchar_t* wchar_ptr::release() noexcept { wchar_t* p2 = m_p; m_p = nullptr; return p2; } -wchar_ptr::~wchar_ptr() +wchar_ptr::~wchar_ptr() noexcept { delete m_p; } @@ -64,8 +61,6 @@ wchar_ptr wchar_ptr::copy(const wchar_t* const src) return dst; } -/* Win32Error: Exception for Windows API errors. */ - Win32Error::Win32Error() : code(GetLastError()) {} Win32Error::Win32Error(const DWORD code) : code(code) {} @@ -90,7 +85,7 @@ const char* Win32Error::what() const noexcept return m_szMsg; } -const wchar_t* Win32Error::WhatW() const noexcept +const wchar_t* Win32Error::What() const noexcept { if (!m_wszMsg) FormatMessage( @@ -103,8 +98,6 @@ const wchar_t* Win32Error::WhatW() const noexcept return m_wszMsg; } -/* Library: Wrapper for loading and freeing dynamically linked libraries. */ - std::optional Library::Maybe(const wchar_t* const lib) { HMODULE hModule = LoadLibrary(lib); @@ -126,7 +119,6 @@ Library::~Library() FreeLibrary(m_hModule); } -/* Show message box owned by and centered in the main window. */ int EBMessageBox(const wchar_t* const wszText, const wchar_t* const wszCaption, const unsigned uType) { extern HWND g_hWnd; diff --git a/c/common.h b/c/common.h index 9d322b3..70c2c32 100644 --- a/c/common.h +++ b/c/common.h @@ -8,37 +8,48 @@ int EBMessageBox(const wchar_t* wszText, const wchar_t* wszCaption, unsigned uType); int GetRelativeCursorPos(HWND hWnd, POINT* pt); +/* wchar_ptr: Simple wrapper for wide C strings. */ struct wchar_ptr { + /* Named copy constructors (expensive). */ static wchar_ptr from_narrow(const char* buf, int cp = CP_UTF8); static wchar_ptr copy(const wchar_t* s); - wchar_ptr(); - wchar_ptr(wchar_t* s); - wchar_ptr& operator=(wchar_t* s); + + /* Non-explicit copies are disabled. */ wchar_ptr(wchar_ptr& other) = delete; wchar_ptr& operator=(wchar_ptr& other) = delete; + + wchar_ptr() noexcept; + ~wchar_ptr(); + operator wchar_t*() noexcept; + + wchar_ptr(wchar_t* s) noexcept; + wchar_ptr& operator=(wchar_t* s) noexcept; + wchar_ptr(wchar_ptr&& other) noexcept; wchar_ptr& operator=(wchar_ptr&& other) noexcept; - operator wchar_t*() noexcept; - wchar_t *release(); - ~wchar_ptr(); + + /* Return pointer, releasing ownership. */ + wchar_t *release() noexcept; private: wchar_t* m_p = nullptr; }; +/* Win32Error: Exception for Windows API errors. */ struct Win32Error : public std::exception { Win32Error(); Win32Error(DWORD code); ~Win32Error(); - const char* what() const noexcept; - const wchar_t* WhatW() const noexcept; + const char* what() const noexcept override; + const wchar_t* What() const noexcept; DWORD code; private: char* m_szMsg = NULL; wchar_t* m_wszMsg = NULL; }; +/* Library: Wrapper for loading and freeing dynamically linked libraries. */ struct Library { static std::optional Maybe(const wchar_t* lib); @@ -57,7 +68,7 @@ T* Library::GetProcAddress(const char* const szProc) } template -inline int wszf(wchar_t (&buf)[N], const wchar_t* const fmt, T... xs) +inline int Swprintf(wchar_t (&buf)[N], const wchar_t* const fmt, T... xs) { return _snwprintf_s(buf, N, _TRUNCATE, fmt, xs...); } @@ -79,7 +90,7 @@ template inline T prefer(const T x) { if (!x) { - EBMessageBox(Win32Error().WhatW(), L"System Error", MB_ICONWARNING); + EBMessageBox(Win32Error().What(), L"System Error", MB_ICONWARNING); return (T)NULL; } return x; diff --git a/c/layout.h b/c/layout.h index 47702c4..752e660 100644 --- a/c/layout.h +++ b/c/layout.h @@ -9,11 +9,10 @@ void UpdateLayout(int w = 0, int h = 0); -/* Draggable portions of the client area, such as the split between - * two list views, are implemented in Dragger singletons. - * - * HandleDown and HandleMove are called by the relevant window - * procedures for WM_(NC)LBUTTONDOWN and WM_SETCURSOR. */ +/* Dragger objects implement draggable portions of the client area, + * such as the split between two list views. HandleDown and HandleMove + * are called by relevant window procedures upon WM_(NC)LBUTTONDOWN + * and WM_SETCURSOR. */ struct Dragger { @@ -24,14 +23,17 @@ protected: bool IsDouble(); virtual bool InDragArea(int x, int y); virtual void Drag(int x, int y); - virtual void Reset(); virtual void Done(); + + /* Reset dragger to automatic position. */ + virtual void Reset(); private: bool m_bActive = false; long m_time = 0; }; -/* Dragger for data list view (upper border). */ +/* DlvDragger implements the draggable split between the data list + * view and the episode list view. */ struct DlvDragger : public Dragger { diff --git a/c/main.cpp b/c/main.cpp index 79fb8eb..87b15be 100644 --- a/c/main.cpp +++ b/c/main.cpp @@ -67,16 +67,17 @@ void OnTerminate() noexcept try { why = PlString(t); } catch (...) {} } catch (const Win32Error& e) { what = L"a Windows error"; - try { why = wchar_ptr::copy(e.WhatW()); } catch (...) {} + try { why = wchar_ptr::copy(e.What()); } catch (...) {} } catch (const std::exception& e) { try { why = wchar_ptr::from_narrow(e.what()); } catch (...) {} } catch (...) {} wchar_t msg[256] = {0}; if (why) - wszf(msg, L"Episode Browser was terminated due to %s: %s", what, static_cast(why)); + Swprintf(msg, L"Episode Browser was terminated due to %s: %s", + what, static_cast(why)); else - wszf(msg, L"Episode Browser was terminated due to %s.", what); + Swprintf(msg, L"Episode Browser was terminated due to %s.", what); MessageBox(g_hWnd, msg, L"Fatal Error", MB_ICONERROR); _Exit(1); @@ -485,7 +486,7 @@ void HandleContextMenu(const HWND, unsigned short command) L"Error", MB_ICONWARNING); } else if (cNotFound) { wchar_t msg[64] = {0}; - wszf(msg, L"%d episodes could not be opened locally.", cNotFound); + Swprintf(msg, L"%d episodes could not be opened locally.", cNotFound); EBMessageBox(msg, L"Error", MB_ICONWARNING); } else if (ID_SUBGROUP(command) == IDG_CTX_RATE) { g_elv->Sort(); @@ -503,7 +504,7 @@ void WaitFor(const char* mod, const char* pred) if (bActive) { wchar_t msg[256] = {0}; - wszf(msg, L"Another task (%s) is active. " + Swprintf(msg, L"Another task (%s) is active. " L"Do you want to cancel the existing task and start a new one?", static_cast(activePred)); if (EBMessageBox(msg, L"Error", MB_YESNO|MB_ICONWARNING) != IDYES) -- cgit v1.2.3