aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--c/common.cpp26
-rw-r--r--c/defs.h14
-rw-r--r--c/main.cpp52
3 files changed, 61 insertions, 31 deletions
diff --git a/c/common.cpp b/c/common.cpp
index dd84742..3a99769 100644
--- a/c/common.cpp
+++ b/c/common.cpp
@@ -29,11 +29,35 @@ TCHAR *TszFromSz(const char *sz, int iCp)
return tsz;
}
+Win32Error::Win32Error(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),
+ (LPSTR)&m_szMsg,
+ 0, NULL
+ );
+}
+
+Win32Error::~Win32Error()
+{
+ if (m_szMsg)
+ HeapFree(GetProcessHeap(), 0, m_szMsg);
+}
+
+const char *Win32Error::what(void) const noexcept
+{
+ return m_szMsg;
+}
+
Library::Library(const TCHAR *tszLibrary)
{
m_hModule = LoadLibrary(tszLibrary);
if (!m_hModule)
- throw std::invalid_argument("Library not found.");
+ throw Win32Error(GetLastError());
}
Library::~Library()
diff --git a/c/defs.h b/c/defs.h
index 5a6a25a..102dce2 100644
--- a/c/defs.h
+++ b/c/defs.h
@@ -3,16 +3,26 @@
#include <memory>
#include <optional>
+#include <stdexcept>
#include <windows.h>
#include <commctrl.h>
#include <SWI-Prolog.h>
/* common.cpp */
TCHAR *TszFromSz(const char *, int);
+struct Win32Error : public std::exception
+{
+ Win32Error(DWORD);
+ ~Win32Error(void);
+ virtual const char *what(void) const noexcept override;
+private:
+ DWORD m_dwErr;
+ char *m_szMsg = NULL;
+};
struct Library
{
Library(const TCHAR *);
- ~Library();
+ ~Library(void);
FARPROC GetProcAddress(const char *);
private:
HMODULE m_hModule;
@@ -70,7 +80,7 @@ int Plx(const char *, const char *);
struct Query
{
Query(module_t ctx, predicate_t p, term_t t0);
- ~Query();
+ ~Query(void);
int Cut();
int Close();
int NextSolution();
diff --git a/c/main.cpp b/c/main.cpp
index 90f828d..82c95ba 100644
--- a/c/main.cpp
+++ b/c/main.cpp
@@ -33,21 +33,18 @@ static void UpdateTheme(void);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, INT nCmdShow)
{
- LPTSTR tszErr;
-
/* Exit gracefully on uncaught exception. */
std::set_terminate(OnTerminate);
/* Set constant values. */
- if (auto upLib = try_make<Library>(TEXT("uxtheme.dll")))
- if (upLib->GetProcAddress("SetWindowTheme")) {
+ if (auto opLib = try_make<Library>(TEXT("uxtheme.dll")))
+ if (opLib->GetProcAddress("SetWindowTheme"))
g_bThemes = 1;
- }
g_cxVScroll = GetSystemMetrics(SM_CXVSCROLL);
/* Setup fonts. */
- if (auto upLib = try_make<Library>(TEXT("User32.dll"))) {
- if (upLib->GetProcAddress("SystemParametersInfo" WA)) {
+ if (auto opLib = try_make<Library>(TEXT("User32.dll"))) {
+ if (opLib->GetProcAddress("SystemParametersInfo" WA)) {
NONCLIENTMETRICS m;
m.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &m, 0);
@@ -63,18 +60,17 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
/* Initialize Prolog. */
char *argv[] = { (char *)"EpisodeBrowser", NULL };
- tszErr = TEXT("Could not initialize Prolog.");
- if (!PL_initialise(1, argv)) goto f;
- tszErr = TEXT("Could not attach databases.");
- if (!Pl("track_episodes","attach")) goto f;
- if (!Pl("episode_data","attach")) goto f;
+ if (!PL_initialise(1, argv))
+ throw std::runtime_error("Could not initialize Prolog.");
+ if (!Pl("track_episodes","attach") || !Pl("episode_data","attach"))
+ throw std::runtime_error("Could not attach databases.");
/* Initialize common controls, load menu and register window class. */
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_WIN95_CLASSES;
- tszErr = TEXT("Could not initialize common controls.");
- if (!InitCommonControlsEx(&icc)) goto f;
+ if (!InitCommonControlsEx(&icc))
+ throw std::runtime_error("Could not initialize common controls.");
g_hPopupMenu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_POPUPMENU));
g_hPopupMenu = GetSubMenu(g_hPopupMenu, 0);
@@ -90,8 +86,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.lpszClassName = TEXT("Episode Browser");
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
- tszErr = TEXT("Could not register window class.");
- if (!RegisterClassEx(&wc)) goto f;
+ if (!RegisterClassEx(&wc))
+ throw std::runtime_error("Could not register window class.");
/* Create window. Note that a CBT hook is used to initialize
* important global variables before any messages are sent to
@@ -108,8 +104,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
NULL, NULL, hInstance, NULL
);
UnhookWindowsHookEx(hHook);
- tszErr = TEXT("Could not create main window.");
- if (!hWnd) goto f;
+ if (!hWnd) throw std::runtime_error("Could not create main window.");
g_hWndStatus = CreateStatusBar(hWnd, hInstance);
ShowWindow(hWnd, nCmdShow);
@@ -127,9 +122,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PL_halt(0);
return 0;
-f: MessageBox(NULL, tszErr, TEXT("Fatal Error"), MB_ICONERROR);
- PL_halt(1);
- return 1;
}
void OnTerminate()
@@ -139,14 +131,18 @@ void OnTerminate()
} catch (term_t &t) {
char *sz;
TCHAR *tsz;
- if (PL_get_chars(t, &sz, CVT_WRITE)) /* TODO: PL_get_wchars */
- tsz = TszFromSz(sz, CP_UTF8);
- else
- tsz = TEXT("The program was terminated due to an exception.");
- MessageBox(NULL, tsz, TEXT("Fatal Error"), MB_ICONERROR);
+ /* TODO: PL_get_wchars */
+ if (PL_get_chars(t, &sz, CVT_WRITE) && (tsz = TszFromSz(sz, CP_UTF8))) {
+ MessageBox(NULL, tsz, TEXT("Fatal Error"), MB_ICONERROR);
+ free(tsz);
+ } else
+ MessageBoxA(NULL, "The program was terminated due to a Prolog exception.",
+ "Fatal Error", MB_ICONERROR);
+ } catch (std::exception &e) {
+ MessageBoxA(NULL, e.what(), "Fatal Error", MB_ICONERROR);
} catch (...) {
- MessageBox(NULL, TEXT("The program was terminated due to an exception."),
- TEXT("Fatal Error"), MB_ICONERROR);
+ MessageBoxA(NULL, "The program was terminated due to an exception.",
+ "Fatal Error", MB_ICONERROR);
}
std::_Exit(1);
}