aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--c/common.cpp8
-rw-r--r--c/common.h24
-rw-r--r--c/episodelistview.cpp6
-rw-r--r--c/listview.cpp5
-rw-r--r--c/main.cpp58
5 files changed, 60 insertions, 41 deletions
diff --git a/c/common.cpp b/c/common.cpp
index ba6593b..b85be49 100644
--- a/c/common.cpp
+++ b/c/common.cpp
@@ -61,7 +61,7 @@ Library::~Library()
}
/* Move message box to center of main window. */
-static LRESULT CALLBACK CBTProc(const int nCode, const WPARAM wParam, const LPARAM lParam)
+static LRESULT CALLBACK CBTProc(const int nCode, const WPARAM wParam, const LPARAM lParam) noexcept
{
extern HWND g_hWnd;
if (!g_hWnd || nCode < 0 || nCode != HCBT_ACTIVATE)
@@ -87,10 +87,8 @@ static LRESULT CALLBACK CBTProc(const int nCode, const WPARAM wParam, const LPAR
int EBMessageBox(const TCHAR* const tszText, const TCHAR* const tszCaption, const unsigned uType)
{
extern HWND g_hWnd;
- HHOOK hHook = SetWindowsHookEx(WH_CBT, CBTProc, 0, GetCurrentThreadId());
- if (!hHook) return 0;
+ HHOOK hHook = throw_nil<SetWindowsHookEx>(WH_CBT, CBTProc, (HINSTANCE)NULL, GetCurrentThreadId());
int r = MessageBox(g_hWnd, tszText, tszCaption, uType);
- UnhookWindowsHookEx(hHook);
- if (!hHook) throw Win32Error(GetLastError());
+ throw_nil<UnhookWindowsHookEx>(hHook);
return r;
}
diff --git a/c/common.h b/c/common.h
index bffc9e5..acb8f26 100644
--- a/c/common.h
+++ b/c/common.h
@@ -44,7 +44,7 @@ T* Library::GetProcAddress(const char* const szProc)
* return nothing. The returned value must be checked before being
* used, as dereferencing is undefined if the value is empty. */
template <class C, typename ...T>
-std::optional<C> try_make(T ...args)
+std::optional<C> maybe_make(T ...args)
{
try {
return C(args...);
@@ -53,6 +53,28 @@ std::optional<C> try_make(T ...args)
}
}
+/* Call Windows API function and throw error if NULL is returned. */
+template <auto f, typename ...T>
+inline auto throw_nil(T ...args)
+{
+ auto r = f(args...);
+ if (!r) throw Win32Error(GetLastError());
+ return r;
+}
+
+/* Call Windows API function and show a warning if NULL is returned. */
+template <auto f, typename ...T>
+inline auto warn_nil(T ...args)
+{
+ decltype(f(args...)) r;
+ try {
+ r = throw_nil<f>(args...);
+ } catch (Win32Error& e) {
+ EBMessageBox(e.twhat(), TEXT("System Error"), MB_ICONWARNING);
+ }
+ return r;
+}
+
/* Return integer scaled for current DPI. */
inline int Dpi(const int i)
{
diff --git a/c/episodelistview.cpp b/c/episodelistview.cpp
index c08e6f8..e70cc06 100644
--- a/c/episodelistview.cpp
+++ b/c/episodelistview.cpp
@@ -90,7 +90,7 @@ LRESULT EpisodeListView::HandleNotify(const LPARAM lParam)
{
extern HFONT g_hfBold;
if (!Pl("track_episodes","watched",pLvCd->nmcd.lItemlParam)) {
- SelectObject(pLvCd->nmcd.hdc, g_hfBold);
+ throw_nil<SelectObject>(pLvCd->nmcd.hdc, g_hfBold);
return CDRF_NEWFONT;
}
break;
@@ -125,9 +125,9 @@ LRESULT EpisodeListView::HandleNotify(const LPARAM lParam)
{
extern HMENU g_hPopupMenu;
const DWORD dwPos = GetMessagePos();
- TrackPopupMenu(g_hPopupMenu, TPM_RIGHTBUTTON,
+ throw_nil<TrackPopupMenu>(g_hPopupMenu, TPM_RIGHTBUTTON,
LOWORD(dwPos), HIWORD(dwPos), 0,
- m_hWndParent, NULL);
+ m_hWndParent, (const RECT*)NULL);
break;
}
}
diff --git a/c/listview.cpp b/c/listview.cpp
index 8f5da65..fa99793 100644
--- a/c/listview.cpp
+++ b/c/listview.cpp
@@ -13,16 +13,15 @@ ListView::ListView(const HWND hWndParent, const HMENU hMenu, const DWORD dwStyle
{
m_hWndParent = hWndParent;
m_bHeader = !(dwStyle & LVS_NOCOLUMNHEADER);
- hWnd = CreateWindowEx(
+ hWnd = throw_nil<CreateWindowEx>(
WS_EX_CLIENTEDGE,
WC_LISTVIEW,
TEXT(""),
dwStyle|WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP|LVS_REPORT|LVS_SHOWSELALWAYS,
0, 0, 0, 0,
m_hWndParent, hMenu, GetModuleHandle(NULL), this);
- if (!hWnd) throw Win32Error(GetLastError());
- if (SetProp(hWnd, TEXT("this"), (HANDLE)this))
+ if (throw_nil<SetProp>(hWnd, TEXT("this"), (HANDLE)this))
m_prevProc = (WNDPROC)SetWindowLongPtr(hWnd,
GWLP_WNDPROC, (LONG_PTR)::WndProc);
diff --git a/c/main.cpp b/c/main.cpp
index ae192dc..f9bdced 100644
--- a/c/main.cpp
+++ b/c/main.cpp
@@ -45,7 +45,7 @@ static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static INT_PTR CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
static void UpdateTheme();
-void OnTerminate()
+void OnTerminate() noexcept
{
try {
std::rethrow_exception(std::current_exception());
@@ -89,10 +89,10 @@ int WINAPI WinMain(const HINSTANCE hInstance, const HINSTANCE, char* const, cons
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_WIN95_CLASSES;
- if (!InitCommonControlsEx(&icc)) throw Win32Error(GetLastError());
+ throw_nil<InitCommonControlsEx>(&icc);
- g_hPopupMenu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_POPUPMENU));
- g_hPopupMenu = GetSubMenu(g_hPopupMenu, 0);
+ g_hPopupMenu = throw_nil<LoadMenu>((HINSTANCE)NULL, MAKEINTRESOURCE(IDR_POPUPMENU));
+ g_hPopupMenu = throw_nil<GetSubMenu>(g_hPopupMenu, 0);
WNDCLASSEX wc;
memset(&wc, 0, sizeof(WNDCLASSEX));
@@ -105,31 +105,29 @@ int WINAPI WinMain(const HINSTANCE hInstance, const HINSTANCE, char* const, cons
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.lpszClassName = TEXT("Episode Browser");
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
- if (!RegisterClassEx(&wc)) throw Win32Error(GetLastError());
+ throw_nil<RegisterClassEx>(&wc);
/* Create window. A CBT hook is used to initialize important
* global variables before any messages are sent to the new
* window. It is vital that the hook is set up correctly. */
- const HHOOK hHook = SetWindowsHookEx(WH_CBT, CBTProc, 0, GetCurrentThreadId());
- if (!hHook) throw Win32Error(GetLastError());
- const HWND hWnd = CreateWindowEx(
+ const HHOOK hHook = throw_nil<SetWindowsHookEx>(WH_CBT, CBTProc,
+ (HINSTANCE)NULL, GetCurrentThreadId());
+ const HWND hWnd = throw_nil<CreateWindowEx>(
0,
TEXT("Episode Browser"),
TEXT("Episode Browser"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,
- NULL, NULL, hInstance, NULL);
- if (!hHook) throw Win32Error(GetLastError());
- if (!hWnd) throw Win32Error(GetLastError());
- UnhookWindowsHookEx(hHook);
+ (HWND)NULL, (HMENU)NULL, hInstance, (void*)NULL);
+ throw_nil<UnhookWindowsHookEx>(hHook);
- g_hWndStatus = CreateWindowEx(
+ g_hWndStatus = throw_nil<CreateWindowEx>(
0,
STATUSCLASSNAME,
(const TCHAR*)NULL,
WS_CHILD|WS_VISIBLE|SBARS_SIZEGRIP,
0, 0, 0, 0,
- hWnd, (HMENU)ID_STATUS, hInstance, NULL);
+ hWnd, (HMENU)ID_STATUS, hInstance, (void*)NULL);
ShowWindow(hWnd, nCmdShow);
@@ -161,27 +159,29 @@ static LRESULT CALLBACK CBTProc(const int nCode, const WPARAM wParam, const LPAR
g_hWnd = (HWND)wParam;
/* Look up constants. */
- if (auto opLib = try_make<Library>(TEXT("User32.dll")))
+ if (auto opLib = maybe_make<Library>(TEXT("User32.dll")))
if (auto GetDpiForWindow = opLib->GetProcAddress<UINT(HWND)>("GetDpiForWindow"))
g_iDPI = GetDpiForWindow(g_hWnd);
- if (auto opLib = try_make<Library>(TEXT("uxtheme.dll")))
+ if (auto opLib = maybe_make<Library>(TEXT("uxtheme.dll")))
if (opLib->GetProcAddress<void>("SetWindowTheme"))
g_bThemes = 1;
- LOGFONT lf;
- if (auto opLib = try_make<Library>(TEXT("User32.dll"))) {
+ if (auto opLib = maybe_make<Library>(TEXT("User32.dll"))) {
if (opLib->GetProcAddress<void>("SystemParametersInfo" WA)) {
NONCLIENTMETRICS m;
m.cbSize = sizeof(NONCLIENTMETRICS);
- SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &m, 0);
- g_hfNormal = CreateFontIndirect(&m.lfMessageFont);
+ throw_nil<SystemParametersInfo>(SPI_GETNONCLIENTMETRICS,
+ sizeof(NONCLIENTMETRICS), &m, 0);
+ g_hfNormal = throw_nil<CreateFontIndirect>(&m.lfMessageFont);
}
} else
- g_hfNormal = static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT));
- GetObject(g_hfNormal, sizeof(LOGFONT), &lf);
+ g_hfNormal = static_cast<HFONT>(throw_nil<GetStockObject>(DEFAULT_GUI_FONT));
+
+ LOGFONT lf;
+ throw_nil<GetObject>(g_hfNormal, sizeof(LOGFONT), &lf);
lf.lfWeight = FW_BOLD;
- g_hfBold = CreateFontIndirect(&lf);
+ g_hfBold = throw_nil<CreateFontIndirect>(&lf);
/* Create child windows. */
g_pDlv = new DataListView(g_hWnd);
@@ -237,7 +237,7 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam,
{
const RECT* const lpr = (RECT*)lParam;
g_iDPI = HIWORD(wParam);
- SetWindowPos(hWnd, NULL,
+ warn_nil<SetWindowPos>(hWnd, (HWND)NULL,
lpr->left, lpr->top,
lpr->right-lpr->left,
lpr->bottom-lpr->top,
@@ -280,7 +280,7 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam,
TEXT("")));
} else {
i = 0;
- KillTimer(hWnd, IDT_TIMER);
+ warn_nil<KillTimer>(hWnd, IDT_TIMER);
g_pElv->Update();
}
break;
@@ -302,8 +302,8 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam,
case IDM_FILE_FETCH_SCREENWRITERS:
if (g_bThread) break;
Pl("episode_data","thread_create","update_screenwriters",&g_aThread);
- t: KillTimer(hWnd, IDT_TIMER);
- SetTimer(hWnd, IDT_TIMER, 500, NULL);
+ t: warn_nil<KillTimer>(hWnd, IDT_TIMER);
+ if (!SetTimer(hWnd, IDT_TIMER, 500, (TIMERPROC)NULL)) break;
SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)TEXT("."));
g_bThread = 1;
break;
@@ -514,14 +514,14 @@ void UpdateLayout()
/* Resize data list view. */
cyDlv = rc.bottom-yStatus-g_pDlv->Height();
- MoveWindow(g_pDlv->hWnd, 0, cyDlv, rc.right, rc.bottom-yStatus-cyDlv, TRUE);
+ throw_nil<MoveWindow>(g_pDlv->hWnd, 0, cyDlv, rc.right, rc.bottom-yStatus-cyDlv, TRUE);
ListView_SetColumnWidth(g_pDlv->hWnd, DLVSIKEY, LVSCW_AUTOSIZE);
cxColumn = ListView_GetColumnWidth(g_pDlv->hWnd, 0)+4;
ListView_SetColumnWidth(g_pDlv->hWnd, DLVSIKEY, cxColumn);
ListView_SetColumnWidth(g_pDlv->hWnd, DLVSIVALUE, rc.right-cxColumn-cxVScroll-4);
/* Resize episode list view. */
- MoveWindow(g_pElv->hWnd, 0, 0, rc.right, cyDlv+1, TRUE);
+ throw_nil<MoveWindow>(g_pElv->hWnd, 0, 0, rc.right, cyDlv+1, TRUE);
ListView_SetColumnWidth(g_pElv->hWnd, ELVSIEPISODE, LVSCW_AUTOSIZE);
cxColumn = ListView_GetColumnWidth(g_pElv->hWnd, ELVSIEPISODE)+4;
ListView_SetColumnWidth(g_pElv->hWnd, ELVSIEPISODE, cxColumn);