diff options
Diffstat (limited to 'c')
-rw-r--r-- | c/util.h | 45 | ||||
-rw-r--r-- | c/win.cpp | 45 | ||||
-rw-r--r-- | c/win.h | 4 |
3 files changed, 54 insertions, 40 deletions
@@ -4,42 +4,51 @@ #include <algorithm> #include <cstring> #include <memory> +#include <string> #include <SWI-Prolog.h> #include <windows.h> -#define CAT(a, b) a##b -#define APPLY(a, ...) a(__VA_ARGS__) -#define UNUSED APPLY(CAT, unused_, __COUNTER__) +/* Buf is a span-like structure of a buffer and its size. */ +template <typename T> +struct Buf +{ + T* data; + size_t size; + Buf(T* data, size_t size) : data(data), size(size) {} + Buf(std::basic_string<T>& s) : data(s.data()), size(s.capacity()) {} + template <size_t N> Buf(T (&data)[N]) : data(data), size(N) {} + operator T*() { return data; } + T& operator *() { return *data; } + T& operator [](size_t i) { return data[i]; } +}; -/* Format static wide string. */ -template<size_t N, typename... T> -inline int Swprintf(wchar_t (&buf)[N], const wchar_t* const fmt, T... xs) +/* Format wide string. */ +template<typename... T> +inline int Swprintf(Buf<wchar_t> buf, const wchar_t* const fmt, T... xs) { - return _snwprintf_s(buf, N, _TRUNCATE, fmt, xs...); + return _snwprintf_s(buf, buf.size, _TRUNCATE, fmt, xs...); } /* Format static narrow string. */ -template<size_t N, typename... T> -inline int Sprintf(char (&buf)[N], const char* const fmt, T... xs) +template<typename... T> +inline int Sprintf(Buf<char> buf, const char* const fmt, T... xs) { - return _snprintf_s(buf, N, _TRUNCATE, fmt, xs...); + return _snprintf_s(buf, buf.size, _TRUNCATE, fmt, xs...); } /* Copy to static wide string buffer. */ -template <size_t N> -inline wchar_t* Wcscpy(wchar_t (&dst)[N], const wchar_t* const src) +inline wchar_t* Wcscpy(Buf<wchar_t> dst, const wchar_t* const src) { - const size_t len = std::min(N, wcslen(src)+1); + const size_t len = std::min(dst.size, wcslen(src)+1); memcpy(dst, src, len*sizeof(wchar_t)); dst[len-1] = 0; return dst; } /* Copy to static narrow string buffer. */ -template <size_t N> -inline char* Strcpy(char (&dst)[N], const char* const src) +inline char* Strcpy(Buf<char> dst, const char* const src) { - const size_t len = std::min(N, strlen(src)+1); + const size_t len = std::min(dst.size, strlen(src)+1); memcpy(dst, src, len); dst[len-1] = 0; return dst; @@ -52,4 +61,8 @@ inline int Cmp(const int a, const int b) return -1; } +#define CAT(a, b) a##b +#define APPLY(a, ...) a(__VA_ARGS__) +#define UNUSED APPLY(CAT, unused_, __COUNTER__) + #endif @@ -1,4 +1,5 @@ #include <utility> +#include <string> #include <SWI-Prolog.h> #include <windows.h> @@ -7,28 +8,6 @@ #include "win.h" #include "wcharptr.h" -void ShowException(const wchar_t* const fmt, const wchar_t* const title, const UINT uType) noexcept -{ - const wchar_t* what = L"an exception"; - WcharPtr why; - - try { - std::rethrow_exception(std::current_exception()); - } catch (const term_t& t) { - what = L"a Prolog exception"; - try { why = PlString(t); } catch (...) {} - } catch (const Win32Error& e) { - what = L"a Windows error"; - try { why = WcharPtr::Copy(e.What()); } catch (...) {} - } catch (const std::exception& e) { - try { why = WcharPtr::FromNarrow(e.what()); } catch (...) {} - } catch (...) {} - - wchar_t msg[512]; - Swprintf(msg, fmt, what, static_cast<wchar_t*>(why)); - EBMessageBox(msg, title, uType); -} - void WithNextWindow(void (*proc)(HWND)) { /* WithNextWindow uses a CBT hook to call an arbitrary @@ -103,6 +82,28 @@ int EBMessageBox(const std::wstring_view text, const std::wstring_view caption, return MessageBox(g_hWnd, text.data(), caption.data(), uType); } +void ShowException(const wchar_t* const fmt, const wchar_t* const title, const UINT uType) noexcept +{ + const wchar_t* what = L"an exception"; + WcharPtr why; + + try { + std::rethrow_exception(std::current_exception()); + } catch (const term_t& t) { + what = L"a Prolog exception"; + try { why = PlString(t); } catch (...) {} + } catch (const Win32Error& e) { + what = L"a Windows error"; + try { why = WcharPtr::Copy(e.What()); } catch (...) {} + } catch (const std::exception& e) { + try { why = WcharPtr::FromNarrow(e.what()); } catch (...) {} + } catch (...) {} + + std::wstring msg(wcslen(fmt)+wcslen(what)+wcslen(why), 0); + Swprintf(msg, fmt, what, static_cast<wchar_t*>(why)); + EBMessageBox(msg, title, uType); +} + int GetRelativeCursorPos(const HWND hWnd, POINT* const pt) noexcept { RECT rc; @@ -5,12 +5,12 @@ #include <string_view> #include <windows.h> -/* Show message box for current exception. */ -void ShowException(const wchar_t* fmt, const wchar_t* title, UINT uType = MB_ICONWARNING) noexcept; /* Run given procedure at creation of next window. */ void WithNextWindow(void (*proc)(HWND)); /* Display message box centered in main window. */ int EBMessageBox(std::wstring_view text, std::wstring_view data, UINT uType); +/* Show message box for current exception. */ +void ShowException(const wchar_t* fmt, const wchar_t* title, UINT uType = MB_ICONWARNING) noexcept; /* Retrieve mouse position relative to given window's client area. */ int GetRelativeCursorPos(HWND hWnd, POINT* pt) noexcept; /* Cached values from GetSystemMetrics. */ |