diff options
-rw-r--r-- | c/data.cpp | 26 | ||||
-rw-r--r-- | c/data.h | 12 | ||||
-rw-r--r-- | c/debug.cpp | 4 | ||||
-rw-r--r-- | c/drag.cpp | 8 | ||||
-rw-r--r-- | c/episodelistview.cpp | 4 | ||||
-rw-r--r-- | c/err.cpp | 63 | ||||
-rw-r--r-- | c/err.h | 4 | ||||
-rw-r--r-- | c/ext.cpp | 10 | ||||
-rw-r--r-- | c/listview.cpp | 4 | ||||
-rw-r--r-- | c/main.cpp | 30 | ||||
-rw-r--r-- | c/util.h | 18 | ||||
-rw-r--r-- | c/win32.cpp | 12 | ||||
-rw-r--r-- | c/window.h | 6 |
13 files changed, 110 insertions, 91 deletions
@@ -20,18 +20,18 @@ UniqueOk<htmlParserCtxtPtr, xmlFreeParserCtxt> RemoteParserCtxt(const wchar_t* w static Unique<HINTERNET, InternetCloseHandle> hi = InternetOpenW(L"Episode Browser", INTERNET_OPEN_TYPE_DIRECT, nullptr, nullptr, 0); if (hi.Bad(0)) - throw Err(WINDOWS, L"Internet handle could not be opened: %s."); + throw Err(WINDOWS, L"Internet handle could not be opened"); Unique<HINTERNET, InternetCloseHandle> hiUrl = InternetOpenUrlW( hi.v, wszUrl, nullptr, 0, INTERNET_FLAG_NO_UI, 0); if (hiUrl.Bad(0)) - throw Err(WININET, L"Could not open "s + wszUrl + L": %s."); + throw Err(WININET, L"Could not open "s + wszUrl + L""); char bufX[1024]; Unique<htmlParserCtxtPtr, xmlFreeParserCtxt> ctx = htmlCreatePushParserCtxt( nullptr, nullptr, bufX, sizeof(bufX), szUrl, XML_CHAR_ENCODING_UTF8); if (ctx.Bad(0)) - throw Err(LIBXML2, L"HTML parser context could not be created: %s."); + throw Err(LIBXML2, L"HTML parser context could not be created"); htmlCtxtUseOptions(ctx.v, HTML_PARSE_RECOVER|HTML_PARSE_NOERROR|HTML_PARSE_NOWARNING); @@ -40,9 +40,9 @@ UniqueOk<htmlParserCtxtPtr, xmlFreeParserCtxt> RemoteParserCtxt(const wchar_t* w char bufI[1024]; while (r = InternetReadFile(hiUrl.v, bufI, sizeof(bufI), &cbRead), cbRead) { if (!r) - throw Err(WININET, L"HTML could not be retrieved: %s."); + throw Err(WININET, L"HTML could not be retrieved"); if (!htmlParseChunk(ctx.v, bufI, cbRead, 0)) - throw Err(LIBXML2, L"HTML could not be parsed: %s."); + throw Err(LIBXML2, L"HTML could not be parsed"); } htmlParseChunk(ctx.v, bufI, 0, 1); /* Stop parsing. */ @@ -55,7 +55,7 @@ template <size_t N> bool WcharsFromXmlchars(wchar_t (&dst)[N], Unique<xmlChar*, XmlFree> utf8) { if (utf8.Bad(0)) - throw Err(LIBXML2, L"Node content could not be retrieved: %s."); + throw Err(LIBXML2, L"Node content could not be retrieved"); /* Truncate if source is larger than destination. */ int lenUtf8 = xmlStrlen(utf8.v); @@ -153,7 +153,7 @@ void WaitFor(Window& window, void (*f)(unsigned char*)) std::thread(procThread, f).detach(); s_window->Status(L".", 1); if (!(iTimer = SetTimer(nullptr, iTimer, 500, procTimer))) - throw Err(WINDOWS, L"Timer could not be started: %s."); + throw Err(WINDOWS, L"Timer could not be started"); } void FetchData(unsigned char* sig) @@ -173,18 +173,18 @@ void FetchData(unsigned char* sig) Unique<xmlXPathContextPtr, xmlXPathFreeContext> xpathCtx = xmlXPathNewContext(ctx.v->myDoc); if (xpathCtx.Bad(0)) - throw Err(LIBXML2, L"XPath context could not be created: %s."); + throw Err(LIBXML2, L"XPath context could not be created"); Unique<xmlXPathObjectPtr, xmlXPathFreeObject> xpathObj = xmlXPathEvalExpression( reinterpret_cast<const xmlChar*>("//tr[./td[1] != '' and ./td[3][@style='background:#f2fde9;']]"), xpathCtx.v); if (xpathObj.Bad(0)) - throw Err(LIBXML2, L"XPath object could not be created: %s."); + throw Err(LIBXML2, L"XPath object could not be created"); xmlNodeSetPtr nodes = xpathObj.v->nodesetval; if (!nodes || !nodes->nodeNr) - throw Err(GENERIC, L"Data retrieval failed: No matching HTML nodes found."); + throw Err(GENERIC, L"Data retrieval failed: No matching HTML nodes found"); for (int i = 0; i < nodes->nodeNr; i++) { if (*sig & ABORT) @@ -192,7 +192,7 @@ void FetchData(unsigned char* sig) const xmlNodePtr node = nodes->nodeTab[i]; if (xmlChildElementCount(node) != 8) - throw Err(GENERIC, L"Data retrieval failed: Unexcepted number of columns in table."); + throw Err(GENERIC, L"Data retrieval failed: Unexcepted number of columns in table"); ElvDataA& e = s_window->fvElv.At(i); DlvDataA& d = s_window->fvDlv.At(i); @@ -270,13 +270,13 @@ void FetchScreenwriters(unsigned char* sig) UniqueOk<htmlParserCtxtPtr, xmlFreeParserCtxt> ctx = RemoteParserCtxt(url, nullptr); xpathCtx = xmlXPathNewContext(ctx.v->myDoc); if (xpathCtx.Bad(0)) - throw Err(LIBXML2, L"XPath context could not be created: %s."); + throw Err(LIBXML2, L"XPath context could not be created"); xpathObj = xmlXPathEvalExpression(reinterpret_cast<const xmlChar*>( "//th[contains(text(), 'Screenplay:')]/following-sibling::td"), xpathCtx.v); if (xpathObj.Bad(0)) - throw Err(LIBXML2, L"XPath object could not be created: %s."); + throw Err(LIBXML2, L"XPath object could not be created"); xmlNodeSetPtr nodes = xpathObj.v->nodesetval; if (nodes && nodes->nodeNr) @@ -131,9 +131,9 @@ struct FileView hf = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr); if (hf.Bad(INVALID_HANDLE_VALUE)) - throw Err(WINDOWS, L"File "s + filename + L" could not be created: %s."); + throw Err(WINDOWS, L"File "s + filename + L" could not be created"); } else - throw Err(WINDOWS, L"File "s + filename + L" could not be opened: %s."); + throw Err(WINDOWS, L"File "s + filename + L" could not be opened"); } LARGE_INTEGER cbMap; @@ -141,11 +141,11 @@ struct FileView hm = CreateFileMapping(hf.v, nullptr, PAGE_READWRITE, cbMap.HighPart, cbMap.LowPart, nullptr); if (hm.Bad(0)) - throw Err(WINDOWS, L"File mapping for "s + filename + L" could not be created: %s."); + throw Err(WINDOWS, L"File mapping for "s + filename + L" could not be created"); view = reinterpret_cast<T*>(MapViewOfFile(hm.v, FILE_MAP_ALL_ACCESS, 0, 0, 0)); if (view.Bad(0)) - throw Err(WINDOWS, L"View for "s + filename + L"could not be mapped: %s."); + throw Err(WINDOWS, L"View for "s + filename + L"could not be mapped"); } /* Access element by index, performing bounds check and, if @@ -155,7 +155,7 @@ struct FileView { if (i >= c) throw Err(GENERIC, L"Element in "s + filename + - L" could not be accessed: Index larger than buffer."); + L" could not be accessed: Index larger than buffer"); T& t = view.v[i]; @@ -165,7 +165,7 @@ struct FileView memcpy(&t, &t_, sizeof(T)); } else if (t.version != Version<T>) throw Err(GENERIC, L"Element in "s + filename + - L" could not be accessed: Invalid format version."); + L" could not be accessed: Invalid format version"); } /* TODO: Use a custom exception type that informs the diff --git a/c/debug.cpp b/c/debug.cpp index dbd536e..aa61c9c 100644 --- a/c/debug.cpp +++ b/c/debug.cpp @@ -20,13 +20,13 @@ Benchmark::Benchmark(const char* const name, const int id, const int avgmax) { if (!freq) { if (!QueryPerformanceFrequency(&liFreq)) - throw Err(WINDOWS, L"Tick frequency could not be queried: %s."); + throw Err(WINDOWS, L"Tick frequency could not be queried"); freq = liFreq.QuadPart; } LARGE_INTEGER liTicks; if (!QueryPerformanceCounter(&liTicks)) - throw Err(WINDOWS, L"Ticks could not be retrieved: %s."); + throw Err(WINDOWS, L"Ticks could not be retrieved"); ticks = liTicks.QuadPart; } @@ -25,7 +25,7 @@ bool Dragger::HandleLButtonDown() { POINT pt; if (!GetRelativeCursorPos(parent.hWnd, &pt)) - throw Err(WINDOWS, L"Mouse cursor position could not be retrieved: %s."); + throw Err(WINDOWS, L"Mouse cursor position could not be retrieved"); if (!InDragArea(pt.x, pt.y)) return false; if (IsDouble(GetMessageTime(), pt)) { @@ -41,7 +41,7 @@ bool Dragger::HandleSetCursor() { POINT pt; if (!GetRelativeCursorPos(parent.hWnd, &pt)) - throw Err(WINDOWS, L"Mouse cursor position could not be retrieved: %s."); + throw Err(WINDOWS, L"Mouse cursor position could not be retrieved"); extern HCURSOR g_hcSizeNs; bool r = true; @@ -63,7 +63,7 @@ bool DlvDragger::InDragArea(const int x, const int y) const { RECT rrDlv; if (!GetRelativeRect(parent.dlv.hWnd, &rrDlv)) - throw Err(WINDOWS, L"Data list view rectangle could not be retrieved: %s."); + throw Err(WINDOWS, L"Data list view rectangle could not be retrieved"); const int pad = EBIsThemeActive()? Dpi(6): 0; const int extra = EBIsThemeActive()? 0: Dpi(2); @@ -76,7 +76,7 @@ void DlvDragger::Drag(const int, const int y) const { RECT rrDlv; if (!GetRelativeRect(parent.dlv.hWnd, &rrDlv)) - throw Err(WINDOWS, L"Data list view rectangle could not be retrieved: %s."); + throw Err(WINDOWS, L"Data list view rectangle could not be retrieved"); if (y < Dpi(50) || y > rrDlv.bottom-Dpi(20)) return; diff --git a/c/episodelistview.cpp b/c/episodelistview.cpp index 7d77331..320f98f 100644 --- a/c/episodelistview.cpp +++ b/c/episodelistview.cpp @@ -163,7 +163,7 @@ LRESULT EpisodeListView::HandleNotify(const LPARAM lParam) if (!e.bWatched) { extern HFONT g_hfBold; if (!SelectObject(nm->nmcd.hdc, g_hfBold)) - throw Err(WINDOWS, L"Bold font could not be selected: %s."); + throw Err(WINDOWS, L"Bold font could not be selected"); return CDRF_NEWFONT; } break; @@ -186,7 +186,7 @@ LRESULT EpisodeListView::HandleNotify(const LPARAM lParam) const DWORD pos = GetMessagePos(); if (!TrackPopupMenu(parent.hMenuPopup, TPM_RIGHTBUTTON, LOWORD(pos), HIWORD(pos), 0, parent.hWnd, nullptr)) - throw Err(WINDOWS, L"Context menu could not be opened: %s."); + throw Err(WINDOWS, L"Context menu could not be opened"); return 0; } @@ -8,53 +8,58 @@ #include "win32.h" /* Strip trailing punctuation. */ -static void Strip(wchar_t* s, size_t len = -1) +static void Strip(wchar_t* s, DWORD* len) { - for (int i = len-1; i >= 0; i--) + int i; + for (i = *len-1; i >= 0; i--) if (s[i] == '\r' || s[i] == '\n' || s[i] == '.') s[i] = 0; + *len = i+1; } -Err::Err(ErrType t, const wchar_t* fmt) +Err::Err(ErrType t, Buf<const wchar_t> msg) { + const wchar_t fmt[] = L"%s: %s."; + switch (t) { case GENERIC: - assert(wcscmp(fmt, L"%s.") != 0); - what = fmt; + what = std::wstring(Len(msg)+2, 0); + Swprintf(what, L"%s.", msg.data); break; case WINDOWS: { - wchar_t* msg; - DWORD lenMsg = FormatMessageW( + wchar_t* err; + DWORD lenErr = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, GetLastError(), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (wchar_t*)&msg, + (wchar_t*)&err, 0, nullptr); - Strip(msg, lenMsg); - what = std::wstring(lenMsg+wcslen(fmt), 0); - Swprintf(what, fmt, msg); - HeapFree(GetProcessHeap(), 0, msg); + Strip(err, &lenErr); + what = std::wstring(Len(fmt)+Len(msg)+lenErr, 0); + Swprintf(what, fmt, msg.data, err); + HeapFree(GetProcessHeap(), 0, err); break; } case WININET: { DWORD code = GetLastError(); if (code == ERROR_INTERNET_EXTENDED_ERROR) { - DWORD lenMsg; - InternetGetLastResponseInfo(&code, nullptr, &lenMsg); - std::wstring msg(lenMsg, 0); - if (InternetGetLastResponseInfoW(&code, msg.data(), &lenMsg)) { - what = std::wstring(lenMsg+wcslen(fmt), 0); - Swprintf(what, fmt, msg.c_str()); + DWORD lenErr; + InternetGetLastResponseInfo(&code, nullptr, &lenErr); + std::wstring err(lenErr, 0); + if (InternetGetLastResponseInfoW(&code, err.data(), &lenErr)) { + Strip(err.data(), &lenErr); + what = std::wstring(Len(fmt)+Len(msg)+lenErr, 0); + Swprintf(what, fmt, msg.data, err.c_str()); } else - what = Err(WINDOWS, fmt).what; + what = Err(WINDOWS, msg).what; } else { - wchar_t* msg; - DWORD lenMsg = FormatMessageW( + wchar_t* err; + DWORD lenErr = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_FROM_HMODULE @@ -62,20 +67,20 @@ Err::Err(ErrType t, const wchar_t* fmt) GetModuleHandle(L"wininet.dll"), code, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (wchar_t*)&msg, + (wchar_t*)&err, 0, nullptr); - Strip(msg, lenMsg); - what = std::wstring(lenMsg+wcslen(fmt), 0); - Swprintf(what, fmt, msg); - HeapFree(GetProcessHeap(), 0, msg); + Strip(err, &lenErr); + what = std::wstring(Len(fmt)+Len(msg)+lenErr, 0); + Swprintf(what, fmt, msg.data, err); + HeapFree(GetProcessHeap(), 0, err); } break; } case LIBXML2: { - std::wstring msg = WideFromNarrow(xmlGetLastError()->message); - what = std::wstring(msg.size()+wcslen(fmt), 0); - Swprintf(what, fmt, msg.c_str()); + std::wstring err = WideFromNarrow(xmlGetLastError()->message); + what = std::wstring(Len(fmt)+Len(msg)+err.size(), 0); + Swprintf(what, fmt, msg.data, err.c_str()); break; } } @@ -4,6 +4,7 @@ #include <exception> #include <string> +#include "util.h" #include "win32.h" enum ErrType : unsigned char @@ -17,8 +18,7 @@ enum ErrType : unsigned char struct Err { std::wstring what; - Err(ErrType t, const wchar_t* fmt = L"%s."); - inline Err(ErrType t, std::wstring fmt) : Err(t, fmt.c_str()) {} + Err(ErrType t, Buf<const wchar_t> msg = L""); }; /* Return a wide string describing exception. */ @@ -12,7 +12,7 @@ bool OpenOnline(const CfgA& cfg, int iEp) INT_PTR r = reinterpret_cast<INT_PTR>( ShellExecuteW(nullptr, L"open", url, nullptr, nullptr, SW_SHOWNORMAL)); if (r <= 32) - throw Err(WINDOWS, L"Address "s + url + L" could not be opened: %s."); + throw Err(WINDOWS, L"Address "s + url + L" could not be opened"); return true; } @@ -23,7 +23,7 @@ bool OpenWiki(const DlvDataA& d) INT_PTR r = reinterpret_cast<INT_PTR>( ShellExecuteW(nullptr, L"open", url, nullptr, nullptr, SW_SHOWNORMAL)); if (r <= 32) - throw Err(WINDOWS, L"Address "s + url + L" could not be opened: %s."); + throw Err(WINDOWS, L"Address "s + url + L" could not be opened"); return true; } @@ -84,7 +84,7 @@ static bool FindMatchingFile(wchar_t (&file)[MAX_PATH], const wchar_t* const roo WIN32_FIND_DATA fdata; Unique<HANDLE, FindClose> h = FindFirstFileW(pat, &fdata); if (h.Bad(INVALID_HANDLE_VALUE)) - throw Err(WINDOWS, L"Directory "s + root + L" could not be traversed: %s."); + throw Err(WINDOWS, L"Directory "s + root + L" could not be traversed"); do if (fdata.cFileName[0] == L'.') @@ -102,7 +102,7 @@ static bool FindMatchingFile(wchar_t (&file)[MAX_PATH], const wchar_t* const roo while (FindNextFileW(h.v, &fdata)); if (GetLastError() != ERROR_NO_MORE_FILES) - throw Err(WINDOWS, L"Next file in "s + root + L" could not be accessed: %s."); + throw Err(WINDOWS, L"Next file in "s + root + L" could not be accessed"); return false; } @@ -114,7 +114,7 @@ bool OpenLocally(CfgA& cfg, const ElvDataA& e) INT_PTR r = reinterpret_cast<INT_PTR>( ShellExecuteW(nullptr, L"open", file, nullptr, nullptr, SW_SHOWNORMAL)); if (r <= 32) - throw Err(WINDOWS, L"File "s + file + L" could not be opened: %s."); + throw Err(WINDOWS, L"File "s + file + L" could not be opened"); return true; } else return false; diff --git a/c/listview.cpp b/c/listview.cpp index 537dbce..278d59d 100644 --- a/c/listview.cpp +++ b/c/listview.cpp @@ -22,12 +22,12 @@ ListView::ListView(Window& parent, const HMENU hMenu, const DWORD dwStyle) : par dwStyle|WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP|LVS_REPORT|LVS_SHOWSELALWAYS, 0, 0, 0, 0, parent.hWnd, hMenu, GetModuleHandle(nullptr), this))) - throw Err(WINDOWS, L"List view could not be created: %s."); + throw Err(WINDOWS, L"List view could not be created"); m_proc0 = reinterpret_cast<WNDPROC>(SetWindowLongPtr( hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(Except<::WndProc>))); if (!SetPropW(hWnd, L"this", reinterpret_cast<HANDLE>(this))) - throw Err(WINDOWS, L"List view property could not be set: %s."); + throw Err(WINDOWS, L"List view property could not be set"); ListView_SetExtendedListViewStyle(hWnd, LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER); SendMessageW(hWnd, WM_SETFONT, reinterpret_cast<WPARAM>(g_hfNormal), MAKELPARAM(FALSE, 0)); } @@ -64,7 +64,7 @@ int WINAPI WinMain( icc.dwSize = sizeof(icc); icc.dwICC = ICC_WIN95_CLASSES; if (!InitCommonControlsEx(&icc)) - return EBMessageBox(Err(WINDOWS, L"Common controls could not be initialized: %s.").what, + return EBMessageBox(Err(WINDOWS, L"Common controls could not be initialized").what, L"Initialization Error", MB_ICONERROR), 1; if (CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED) != S_OK) @@ -83,7 +83,7 @@ int WINAPI WinMain( wc.lpszClassName = L"Episode Browser"; wc.hIconSm = LoadIconW(nullptr, IDI_APPLICATION); if (!RegisterClassExW(&wc)) - return EBMessageBox(Err(WINDOWS, L"Window class could not be registered: %s.").what, + return EBMessageBox(Err(WINDOWS, L"Window class could not be registered").what, L"Initialization Error", MB_ICONERROR), 1; /* InitializeMainWindow is called before the first message is @@ -98,7 +98,7 @@ int WINAPI WinMain( WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN, XMAIN, YMAIN, 0, 0, nullptr, nullptr, hInstance, nullptr))) - return EBMessageBox(Err(WINDOWS, L"Main window could not be created: %s.").what, + return EBMessageBox(Err(WINDOWS, L"Main window could not be created").what, L"Initialization Error", MB_ICONERROR), 1; if (!(g_window->hWndStatus = CreateWindowExW( @@ -108,7 +108,7 @@ int WINAPI WinMain( WS_CHILD|WS_VISIBLE|SBARS_SIZEGRIP, 0, 0, 0, 0, hWnd, reinterpret_cast<HMENU>(IDR_STATUS), hInstance, nullptr))) - return EBMessageBox(Err(WINDOWS, L"Status bar could not be created: %s.").what, + return EBMessageBox(Err(WINDOWS, L"Status bar could not be created").what, L"Initialization Error", MB_ICONERROR), 1; ShowWindow(hWnd, nCmdShow); @@ -153,21 +153,21 @@ static void InitializeMainWindow(const HWND hWnd) #endif if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &m, 0)) - throw Err(WINDOWS, L"Non-client metrics could not be queried: %s."); + throw Err(WINDOWS, L"Non-client metrics could not be queried"); if (!(g_hfNormal = CreateFontIndirectW(&m.lfMessageFont))) - throw Err(WINDOWS, L"System message font could not be loaded: %s."); + throw Err(WINDOWS, L"System message font could not be loaded"); } else if (!(g_hfNormal = static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT)))) - throw Err(WINDOWS, L"System GUI font could not be loaded: %s."); + throw Err(WINDOWS, L"System GUI font could not be loaded"); /* Load bold font. */ { LOGFONTW lf; if (!GetObjectW(g_hfNormal, sizeof(LOGFONTW), &lf)) - throw Err(WINDOWS, L"Logical system font could not be loaded: %s."); + throw Err(WINDOWS, L"Logical system font could not be loaded"); lf.lfWeight = FW_BOLD; if (!(g_hfBold = CreateFontIndirectW(&lf))) - throw Err(WINDOWS, L"Bold font could not be loaded: %s."); + throw Err(WINDOWS, L"Bold font could not be loaded"); } /* Load theme functions, if available. */ @@ -221,7 +221,7 @@ INT_PTR CALLBACK PreferencesDlgProc(const HWND hWnd, const UINT uMsg, const WPAR BIF_EDITBOX|BIF_NEWDIALOGSTYLE|BIF_NONEWFOLDERBUTTON}; if (auto pidl = SHBrowseForFolderW(&bi)) { if (!SHGetPathFromIDListW(pidl, path)) - throw Err(GENERIC, L"Invalid path selected."); + throw Err(GENERIC, L"Invalid path selected"); EBMessageBox(path, L"You Chose"); } return TRUE; @@ -287,7 +287,7 @@ LRESULT CALLBACK Window::WndProc(const HWND hWnd, const UINT uMsg, const WPARAM r->right-r->left, r->bottom-r->top, SWP_NOZORDER|SWP_NOACTIVATE)) - throw Err(WINDOWS, L"."); + throw Err(WINDOWS, L""); UpdateLayout(r->right-r->left, r->bottom-r->top); } return 0; @@ -484,9 +484,9 @@ void Window::UpdateLayout(int w, int h) RECT rc, rrStatus; if (w && h) rc = {0, 0, w, h}; else if (!GetClientRect(hWnd, &rc)) - throw Err(WINDOWS, L"Window rectangle could not be retrieved: %s."); + throw Err(WINDOWS, L"Window rectangle could not be retrieved"); if (!GetRelativeRect(hWndStatus, &rrStatus)) - throw Err(WINDOWS, L"Status bar rectangle could not be retrieved: %s."); + throw Err(WINDOWS, L"Status bar rectangle could not be retrieved"); SendMessageW(hWnd, WM_SETREDRAW, FALSE, 0); @@ -494,9 +494,9 @@ void Window::UpdateLayout(int w, int h) const long pad = EBIsThemeActive()? Dpi(6): 0; /* Add padding in modern themes. */ const long cyDlv = rrStatus.top-dlv.Height()-pad; if (!SetWindowRect(dlv.hWnd, pad, cyDlv, rc.right-pad, rrStatus.top-pad)) - throw Err(WINDOWS, L"Data list view rectangle could not be updated: %s."); + throw Err(WINDOWS, L"Data list view rectangle could not be updated"); if (!SetWindowRect(elv.hWnd, pad, pad, rc.right-pad, cyDlv-pad)) - throw Err(WINDOWS, L"Episode list view rectangle could not be updated: %s."); + throw Err(WINDOWS, L"Episode list view rectangle could not be updated"); dlv.ResizeColumns(rc.right-pad-pad); elv.ResizeColumns(rc.right-pad-pad); @@ -112,11 +112,19 @@ struct UniqueOk template <typename T> struct Buf { + using U = std::remove_const_t<T>; + T* data; size_t c; + Buf(T* data, size_t c) noexcept : data(data), c(c) {} - Buf(std::basic_string<T>& s) noexcept : data(s.data()), c(s.capacity()) {} - template <size_t N> Buf(T (&data)[N]) noexcept : data(data), c(N) {} + Buf(std::enable_if<!std::is_same_v<T, U>, U*> data, size_t c) noexcept + : data(data), c(c) {} + + Buf(std::basic_string<U>& s) noexcept : data(s.data()), c(s.capacity()+1) {} + + template <size_t N> inline Buf(T (&data)[N]) noexcept : data(data), c(N) {} + operator T*() const noexcept { return data; } T& operator *() const noexcept { return *data; } T& operator [](size_t i) const noexcept { return data[i]; } @@ -142,6 +150,12 @@ inline size_t Len(T (&)[N]) return N-1; } +template <typename T> +inline size_t Len(Buf<T> buf) +{ + return buf.c-1; +} + /* Format wide string. */ template<typename... T> inline std::enable_if_t<!std::disjunction_v<std::is_class<T>...>, int> diff --git a/c/win32.cpp b/c/win32.cpp index e1053a3..83488d4 100644 --- a/c/win32.cpp +++ b/c/win32.cpp @@ -17,7 +17,7 @@ std::wstring WideFromNarrow(const std::string_view src, const int cp) 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 Err(WINDOWS, L"Narrow string could not be converted to wide string: %s."); + throw Err(WINDOWS, L"Narrow string could not be converted to wide string"); return dst; } @@ -37,7 +37,7 @@ void WithNextWindow(void (*proc)(HWND)) { if (nCode == HCBT_CREATEWND) { if (!UnhookWindowsHookEx(hHook)) - throw Err(WINDOWS, L"Window hook could not be removed: %s."); + throw Err(WINDOWS, L"Window hook could not be removed"); procNext(reinterpret_cast<HWND>(wParam)); return 0; } else @@ -46,7 +46,7 @@ void WithNextWindow(void (*proc)(HWND)) procNext = proc; if (!(hHook = SetWindowsHookExW(WH_CBT, procCBT, nullptr, GetCurrentThreadId()))) - throw Err(WINDOWS, L"Window hook could not be set: %s."); + throw Err(WINDOWS, L"Window hook could not be set"); } /* Display next created window in the center of given window. */ @@ -72,7 +72,7 @@ static void CenterNextWindow(HWND hWnd) } else if (nCode == HCBT_ACTIVATE && reinterpret_cast<HWND>(wParam) == hWndNext) { if (!UnhookWindowsHookEx(hHook)) - throw Err(WINDOWS, L"Window hook could not be removed: %s."); + throw Err(WINDOWS, L"Window hook could not be removed"); long lStyle = GetWindowLongW(hWndNext, GWL_STYLE); if (!(lStyle & WS_POPUP)) return 0; @@ -94,7 +94,7 @@ static void CenterNextWindow(HWND hWnd) hWndParent = hWnd; hWndNext = nullptr; if (!(hHook = SetWindowsHookExW(WH_CBT, procCBT, nullptr, GetCurrentThreadId()))) - throw Err(WINDOWS, L"Window hook could not be set: %s."); + throw Err(WINDOWS, L"Window hook could not be set"); } int EBMessageBox(const std::wstring_view text, const std::wstring_view caption, const UINT uType) @@ -133,7 +133,7 @@ Library::Library(const wchar_t* const lib) { m_hModule = LoadLibraryW(lib); if (!m_hModule) - throw Err(WINDOWS, L"Library "s + lib + L" could not be loaded: %s."); + throw Err(WINDOWS, L"Library "s + lib + L" could not be loaded"); } Library::~Library() @@ -19,9 +19,9 @@ struct Window { HMENU hm; if (!(hm = LoadMenuW(nullptr, MAKEINTRESOURCE(IDR_POPUPMENU)))) - throw Err(WINDOWS, L"Context menu could not be loaded: %s."); - if (!GetSubMenu(hm, 0)) - throw Err(WINDOWS, L"Submenu could not be retrieved: %s."); + throw Err(WINDOWS, L"Context menu could not be loaded"); + if (!(hm = GetSubMenu(hm, 0))) + throw Err(WINDOWS, L"Submenu could not be retrieved"); return hm; }(); |