aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--c/common.cpp44
-rw-r--r--c/common.h4
-rw-r--r--c/listview.cpp2
-rw-r--r--c/main.cpp18
4 files changed, 46 insertions, 22 deletions
diff --git a/c/common.cpp b/c/common.cpp
index f0b5d34..a5b7316 100644
--- a/c/common.cpp
+++ b/c/common.cpp
@@ -2,30 +2,50 @@
#include "common.h"
-Win32Error::Win32Error(const DWORD dwErr)
-{
- m_dwErr = dwErr;
- FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- m_dwErr,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (char*)&m_szMsg,
- 0, NULL
- );
-}
+Win32Error::Win32Error(const DWORD dwErr) : m_dwErr(dwErr) {}
Win32Error::~Win32Error()
{
if (m_szMsg)
HeapFree(GetProcessHeap(), 0, m_szMsg);
+ if (m_wszMsg)
+ HeapFree(GetProcessHeap(), 0, m_wszMsg);
}
const char* Win32Error::what() const noexcept
{
+ if (!m_szMsg)
+ FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ m_dwErr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (char*)&m_szMsg,
+ 0, NULL
+ );
return m_szMsg;
}
+const TCHAR* Win32Error::twhat() const noexcept
+{
+#ifdef UNICODE
+#define M m_wszMsg
+#else
+#define M m_szMsg
+#endif
+ if (!M)
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ m_dwErr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (TCHAR*)&M,
+ 0, NULL
+ );
+ return M;
+#undef M
+}
+
Library::Library(const TCHAR* const tszLibrary)
{
m_hModule = LoadLibrary(tszLibrary);
diff --git a/c/common.h b/c/common.h
index 515c75c..2b3c331 100644
--- a/c/common.h
+++ b/c/common.h
@@ -16,9 +16,11 @@ struct Win32Error : public std::exception
Win32Error(DWORD dwErr);
~Win32Error();
virtual const char* what() const noexcept override;
+ virtual const TCHAR* twhat() const noexcept;
private:
DWORD m_dwErr;
- char* const m_szMsg = NULL;
+ char* m_szMsg = NULL;
+ wchar_t* m_wszMsg = NULL;
};
struct Library
diff --git a/c/listview.cpp b/c/listview.cpp
index 6c0185d..27dc7ac 100644
--- a/c/listview.cpp
+++ b/c/listview.cpp
@@ -21,6 +21,8 @@ ListView::ListView(const HWND hWndParent, const HMENU hMenu, const DWORD dwStyle
0, 0, 0, 0,
m_hWndParent, hMenu, GetModuleHandle(NULL), this
);
+ if (!hWnd) throw Win32Error(GetLastError());
+
if (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 951770a..4b42317 100644
--- a/c/main.cpp
+++ b/c/main.cpp
@@ -59,6 +59,10 @@ void OnTerminate()
} else
MessageBoxA(NULL, "The program was terminated due to a Prolog exception.",
"Fatal Error", MB_ICONERROR);
+ } catch (Win32Error& e) {
+ std::basic_string<TCHAR> tstr = TEXT("The program was terminated due to a Windows error: ");
+ tstr += e.twhat();
+ MessageBox(NULL, tstr.c_str(), TEXT("Fatal Error"), MB_ICONERROR);
} catch (std::exception& e) {
std::string str = "The program was terminated due to an exception: ";
str += e.what();
@@ -86,8 +90,7 @@ 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 std::runtime_error("Could not initialize common controls.");
+ if (!InitCommonControlsEx(&icc)) throw Win32Error(GetLastError());
g_hPopupMenu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_POPUPMENU));
g_hPopupMenu = GetSubMenu(g_hPopupMenu, 0);
@@ -103,14 +106,11 @@ 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 std::runtime_error("Could not register window class.");
+ if (!RegisterClassEx(&wc)) throw Win32Error(GetLastError());
/* 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 and torn down
- * correctly. Note that if the unhook fails, it is useless to
- * try to show an error dialog. */
+ * 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(
@@ -121,9 +121,9 @@ int WINAPI WinMain(const HINSTANCE hInstance, const HINSTANCE, char* const, cons
CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,
NULL, NULL, hInstance, NULL
);
+ if (!hHook) throw Win32Error(GetLastError());
+ if (!hWnd) throw Win32Error(GetLastError());
UnhookWindowsHookEx(hHook);
- if (!hHook) _Exit(1);
- if (!hWnd) throw std::runtime_error("Could not create main window.");
g_hWndStatus = CreateStatusBar(hWnd, hInstance);
ShowWindow(hWnd, nCmdShow);