aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--c/data.cpp26
-rw-r--r--c/data.h12
-rw-r--r--c/debug.cpp4
-rw-r--r--c/drag.cpp8
-rw-r--r--c/episodelistview.cpp4
-rw-r--r--c/err.cpp63
-rw-r--r--c/err.h4
-rw-r--r--c/ext.cpp10
-rw-r--r--c/listview.cpp4
-rw-r--r--c/main.cpp30
-rw-r--r--c/util.h18
-rw-r--r--c/win32.cpp12
-rw-r--r--c/window.h6
13 files changed, 110 insertions, 91 deletions
diff --git a/c/data.cpp b/c/data.cpp
index 47f032b..05de840 100644
--- a/c/data.cpp
+++ b/c/data.cpp
@@ -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)
diff --git a/c/data.h b/c/data.h
index b2eb2a0..0d1bee0 100644
--- a/c/data.h
+++ b/c/data.h
@@ -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;
}
diff --git a/c/drag.cpp b/c/drag.cpp
index f239eff..f3958a6 100644
--- a/c/drag.cpp
+++ b/c/drag.cpp
@@ -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;
}
diff --git a/c/err.cpp b/c/err.cpp
index 277bbce..dbbc6ae 100644
--- a/c/err.cpp
+++ b/c/err.cpp
@@ -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;
}
}
diff --git a/c/err.h b/c/err.h
index 73a5fc9..072e229 100644
--- a/c/err.h
+++ b/c/err.h
@@ -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. */
diff --git a/c/ext.cpp b/c/ext.cpp
index c1bcc48..3c9542b 100644
--- a/c/ext.cpp
+++ b/c/ext.cpp
@@ -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));
}
diff --git a/c/main.cpp b/c/main.cpp
index a988f9b..3219bd7 100644
--- a/c/main.cpp
+++ b/c/main.cpp
@@ -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);
diff --git a/c/util.h b/c/util.h
index 561e232..d214f9c 100644
--- a/c/util.h
+++ b/c/util.h
@@ -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()
diff --git a/c/window.h b/c/window.h
index 16ea48e..9f399ba 100644
--- a/c/window.h
+++ b/c/window.h
@@ -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;
}();