From 547cbe578dcdb5aa5cfdac1cdb327f92bad21219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Tue, 26 Jul 2022 19:27:35 +0200 Subject: Remove ANSI compatibility. Even though it is a fun challange in many ways, I think that, realistically, it is probably not worth the complexity. The Prolog backend isn't ANSI-compatible either. --- c/common.cpp | 45 ++++++++++++------ c/common.h | 39 +++------------- c/datalistview.cpp | 14 +++--- c/episodelistview.cpp | 35 +++++++------- c/listview.cpp | 8 ++-- c/main.cpp | 125 +++++++++++++++++++++++++------------------------- c/pl.cpp | 16 ++----- c/pl.h | 6 +-- c/resource.rc | 2 +- 9 files changed, 135 insertions(+), 155 deletions(-) (limited to 'c') diff --git a/c/common.cpp b/c/common.cpp index c4624c0..ca8dfac 100644 --- a/c/common.cpp +++ b/c/common.cpp @@ -15,11 +15,37 @@ Win32Error::~Win32Error() 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, + dwErr, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + (char*)&m_szMsg, + 0, NULL); + return m_szMsg; +} + +const wchar_t* Win32Error::WhatW() const noexcept +{ + if (!m_wszMsg) + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dwErr, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + (wchar_t*)&m_wszMsg, + 0, NULL); + return m_wszMsg; +} + /* Library: Wrapper for loading and freeing dynamically linked libraries. */ -Library::Library(const TCHAR* const tszLibrary) +Library::Library(const wchar_t* const wszLibrary) { - m_hModule = LoadLibrary(tszLibrary); + m_hModule = LoadLibrary(wszLibrary); if (!m_hModule) throw Win32Error(); } @@ -29,15 +55,8 @@ Library::~Library() FreeLibrary(m_hModule); } -/* Convert narrow unmanaged string to narrow/wide basic string. */ -template <> -std::basic_string BstrFromSz(const char* sz, int) -{ - return std::string(sz); -} - -template <> -std::basic_string BstrFromSz(const char* sz, int iCp) +/* Convert narrow unmanaged string to wide managed string. */ +std::wstring WstrFromSz(const char* sz, int iCp) { int cbMultiByte = strlen(sz)+1; int cchWideChar = MultiByteToWideChar(iCp, 0, sz, cbMultiByte, NULL, 0); @@ -71,11 +90,11 @@ static LRESULT CALLBACK CBTProc(const int nCode, const WPARAM wParam, const LPAR } /* Show message box owned by and centered in the main window. */ -int EBMessageBox(const TCHAR* const tszText, const TCHAR* const tszCaption, const unsigned uType) +int EBMessageBox(const wchar_t* const wszText, const wchar_t* const wszCaption, const unsigned uType) { extern HWND g_hWnd; HHOOK hHook = require(SetWindowsHookEx(WH_CBT, CBTProc, (HINSTANCE)NULL, GetCurrentThreadId())); - int r = MessageBox(g_hWnd, tszText, tszCaption, uType); + int r = MessageBox(g_hWnd, wszText, wszCaption, uType); require(UnhookWindowsHookEx(hHook)); return r; } diff --git a/c/common.h b/c/common.h index 3f27ba4..9efaf59 100644 --- a/c/common.h +++ b/c/common.h @@ -11,51 +11,25 @@ #define WA "A" #endif -template std::basic_string BstrFromSz(const char* sz, int iCp = CP_UTF8); -int EBMessageBox(const TCHAR* tszText, const TCHAR* tszCaption, unsigned uType); - -/* Conditionally choose between two values. */ -template -constexpr std::enable_if_t choose(X x, Y) { return x; } -template -constexpr std::enable_if_t choose(X, Y y) { return y; } - -/* Conditionally choose between ANSI and wide string literal. */ -#define AWTEXT(t, s) choose>(L"" s, s) - -/* Conditionally choose between ANSI and wide Windows API function. */ -#define AWFUN(t, f) choose>(f##W, f##A) +std::wstring WstrFromSz(const char* sz, int iCp = CP_UTF8); +int EBMessageBox(const wchar_t* wszText, const wchar_t* wszCaption, unsigned uType); struct Win32Error : public std::exception { Win32Error(); Win32Error(DWORD dwErr); ~Win32Error(); - template const T* what() const noexcept; + const char* what() const noexcept; + const wchar_t* WhatW() const noexcept; DWORD dwErr; private: char* m_szMsg = NULL; wchar_t* m_wszMsg = NULL; }; -template -const T* Win32Error::what() const noexcept -{ - TCHAR* tszMsg = choose>(m_wszMsg, m_szMsg); - if (!tszMsg) - AWFUN(T, FormatMessage)( - FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - dwErr, - MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (TCHAR*)&tszMsg, - 0, NULL); - return tszMsg; -} - struct Library { - Library(const TCHAR* tszLibrary); + Library(const wchar_t* wszLibrary); ~Library(); template T* GetProcAddress(const char* szProc); private: @@ -98,8 +72,7 @@ template inline T prefer(const T x) { if (!x) { - EBMessageBox(Win32Error().what(), - TEXT("System Error"), MB_ICONWARNING); + EBMessageBox(Win32Error().WhatW(), L"System Error", MB_ICONWARNING); return (T)NULL; } return x; diff --git a/c/datalistview.cpp b/c/datalistview.cpp index a1bb255..e64f89a 100644 --- a/c/datalistview.cpp +++ b/c/datalistview.cpp @@ -19,13 +19,13 @@ DataListView::DataListView(const HWND hWndParent) lvc.mask = LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; lvc.iSubItem = DLVSIKEY; - lvc.pszText = (TCHAR*)TEXT("Key"); + lvc.pszText = (wchar_t*)L"Key"; lvc.cx = Dpi(42); ListView_InsertColumn(hWnd, DLVSIKEY, &lvc); lvc.iSubItem = DLVSIVALUE; - lvc.pszText = (TCHAR*)TEXT("Value"); + lvc.pszText = (wchar_t*)L"Value"; lvc.cx = 500; ListView_InsertColumn(hWnd, DLVSIVALUE, &lvc); } @@ -56,21 +56,21 @@ void DataListView::ShowEpisode(const int iEpisode) Query q (NULL, PL_predicate("episode_datum", iArity, "episode_data"), t); for (int i = 0; q.NextSolution(); i++) { - std::basic_string tstrKey; - std::basic_string tstrValue; + std::wstring wstrKey; + std::wstring wstrValue; - if (!(PlGet(t+1, &tstrKey) && PlGet(t+2, &tstrValue))) + if (!(PlGet(t+1, &wstrKey) && PlGet(t+2, &wstrValue))) continue; lviKey.mask = LVIF_TEXT; lviKey.iItem = i; lviKey.iSubItem = 0; - lviKey.pszText = tstrKey.data(); + lviKey.pszText = wstrKey.data(); ListView_InsertItem(hWnd, &lviKey); lviValue.iItem = i; lviValue.iSubItem = 1; - lviValue.pszText = tstrValue.data(); + lviValue.pszText = wstrValue.data(); ListView_SetItem(hWnd, &lviValue); } diff --git a/c/episodelistview.cpp b/c/episodelistview.cpp index 5de5e2e..49e59d1 100644 --- a/c/episodelistview.cpp +++ b/c/episodelistview.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include "resource.h" @@ -18,17 +17,17 @@ EpisodeListView::EpisodeListView(const HWND hWndParent) lvc.mask = LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; lvc.iSubItem = ELVSIEPISODE; - lvc.pszText = (TCHAR*)TEXT("#"); + lvc.pszText = (wchar_t*)L"#"; lvc.cx = Dpi(42); ListView_InsertColumn(hWnd, ELVSIEPISODE, &lvc); lvc.iSubItem = ELVSITITLE; - lvc.pszText = (TCHAR*)TEXT("Title"); + lvc.pszText = (wchar_t*)L"Title"; lvc.cx = 500; ListView_InsertColumn(hWnd, ELVSITITLE, &lvc); lvc.iSubItem = ELVSIRATING; - lvc.pszText = (TCHAR*)TEXT("/"); + lvc.pszText = (wchar_t*)L"/"; lvc.cx = Dpi(30); ListView_InsertColumn(hWnd, ELVSIRATING, &lvc); @@ -345,7 +344,7 @@ void EpisodeListView::Update() int cItem = 0; { - TCHAR tszEpisode[16]; + wchar_t wszEpisode[16]; LVITEM lviEpisode; lviEpisode.mask = LVIF_TEXT|LVIF_PARAM; for (int iEp = 1; iEp <= cEp; iEp++) { @@ -363,12 +362,12 @@ void EpisodeListView::Update() if (!g_bViewTVOriginal) if (Pl("episode_data","tv_original",iEp)) continue; - _stprintf_s(tszEpisode, sizeof(tszEpisode), TEXT("%d"), iEp); + swprintf_s(wszEpisode, sizeof(wszEpisode), L"%d", iEp); /* Insert item. */ lviEpisode.iItem = cItem++; lviEpisode.iSubItem = ELVSIEPISODE; - lviEpisode.pszText = tszEpisode; + lviEpisode.pszText = wszEpisode; lviEpisode.lParam = iEp; ListView_InsertItem(hWnd, &lviEpisode); UpdateItem(&lviEpisode); @@ -420,9 +419,9 @@ void EpisodeListView::Update() /* Show number of displayed items in status bar. */ extern HWND g_hWndStatus; - TCHAR tszDisp[16]; - _stprintf_s(tszDisp, sizeof(tszDisp), TEXT("%d"), cItem); - SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)tszDisp); + wchar_t wszDisp[16]; + swprintf_s(wszDisp, sizeof(wszDisp), L"%d", cItem); + SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)wszDisp); SendMessage(hWnd, WM_SETREDRAW, TRUE, 0); } @@ -430,22 +429,22 @@ void EpisodeListView::Update() /* Update episode name and rating. */ void EpisodeListView::UpdateItem(const LVITEM* const pLvi) { - std::basic_string tstrName; - if (!Pl("episode_data","episode_title",pLvi->lParam,&tstrName)) { + std::wstring wstrName; + if (!Pl("episode_data","episode_title",pLvi->lParam,&wstrName)) { if (!Pl("episode_data","update_episode_data")) goto r; - if (!Pl("episode_data","episode_title",pLvi->lParam,&tstrName)) goto r; + if (!Pl("episode_data","episode_title",pLvi->lParam,&wstrName)) goto r; } - ListView_SetItemText(hWnd, pLvi->iItem, ELVSITITLE, tstrName.data()); + ListView_SetItemText(hWnd, pLvi->iItem, ELVSITITLE, wstrName.data()); int iRating; r: if (!Pl("episode_data","episode_rating",pLvi->lParam,&iRating)) { - ListView_SetItemText(hWnd, pLvi->iItem, ELVSIRATING, (TCHAR*)TEXT("")); + ListView_SetItemText(hWnd, pLvi->iItem, ELVSIRATING, (wchar_t*)L""); return; } - TCHAR tszRating[3]; - _stprintf_s(tszRating, sizeof(tszRating), TEXT("%d"), iRating); - ListView_SetItemText(hWnd, pLvi->iItem, ELVSIRATING, tszRating); + wchar_t wszRating[3]; + swprintf_s(wszRating, sizeof(wszRating), L"%d", iRating); + ListView_SetItemText(hWnd, pLvi->iItem, ELVSIRATING, wszRating); } LRESULT CALLBACK EpisodeListView::WndProc(const HWND hWnd, const UINT uMsg, diff --git a/c/listview.cpp b/c/listview.cpp index 622ff87..62dfba8 100644 --- a/c/listview.cpp +++ b/c/listview.cpp @@ -16,12 +16,12 @@ ListView::ListView(const HWND hWndParent, const HMENU hMenu, const DWORD dwStyle hWnd = require(CreateWindowEx( WS_EX_CLIENTEDGE, WC_LISTVIEW, - TEXT(""), + L"", dwStyle|WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP|LVS_REPORT|LVS_SHOWSELALWAYS, 0, 0, 0, 0, m_hWndParent, hMenu, GetModuleHandle(NULL), this)); - if (require(SetProp(hWnd, TEXT("this"), (HANDLE)this))) + if (require(SetProp(hWnd, L"this", (HANDLE)this))) m_prevProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)::WndProc); @@ -87,10 +87,10 @@ LRESULT CALLBACK ListView::WndProc(const HWND hWnd, const UINT uMsg, LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, const LPARAM lParam) { - ListView* const pLv = (ListView*)GetProp(hWnd, TEXT("this")); + ListView* const pLv = (ListView*)GetProp(hWnd, L"this"); if (uMsg == WM_DESTROY) - RemoveProp(hWnd, TEXT("this")); + RemoveProp(hWnd, L"this"); return pLv? pLv->WndProc(hWnd, uMsg, wParam, lParam): FALSE; } diff --git a/c/main.cpp b/c/main.cpp index 2037578..00c9051 100644 --- a/c/main.cpp +++ b/c/main.cpp @@ -48,17 +48,16 @@ void WndProcContextMenu(const HWND, unsigned short); static INT_PTR CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); static void UpdateTheme(); -template -void TerminateMsg(const T* sz1, const T* sz2) noexcept +void TerminateMsg(const wchar_t* wsz1, const wchar_t* wsz2) noexcept { - std::basic_ostringstream ss; - ss << AWTEXT(T, "Episode Browser was terminated due to "); - ss << sz1; - if (sz2) - ss << ": " << sz2; + std::wstringstream wss; + wss << L"Episode Browser was terminated due to "; + wss << wsz1; + if (wsz2) + wss << ": " << wsz2; else - ss << "."; - AWFUN(T, MessageBox)(g_hWnd, ss.str().c_str(), AWTEXT(T, "Fatal Error"), MB_ICONERROR); + wss << "."; + MessageBox(g_hWnd, wss.str().c_str(), L"Fatal Error", MB_ICONERROR); } void OnTerminate() noexcept @@ -66,17 +65,17 @@ void OnTerminate() noexcept try { std::rethrow_exception(std::current_exception()); } catch (const term_t& t) { - std::basic_string tstr; - if (PlString(t, &tstr)) - TerminateMsg(TEXT("a Prolog exception"), tstr.c_str()); + std::wstring wstr; + if (PlString(t, &wstr)) + TerminateMsg(L"a Prolog exception", wstr.c_str()); else - TerminateMsg("a Prolog exception", NULL); + TerminateMsg(L"a Prolog exception", NULL); } catch (const Win32Error& e) { - TerminateMsg(TEXT("a Windows error"), e.what()); + TerminateMsg(L"a Windows error", e.WhatW()); } catch (const std::exception& e) { - TerminateMsg("an exception", e.what()); + TerminateMsg(L"an exception", WstrFromSz(e.what()).c_str()); } catch (...) { - TerminateMsg("an exception", NULL); + TerminateMsg(L"an exception", NULL); } _Exit(1); } @@ -111,7 +110,7 @@ int WINAPI WinMain(const HINSTANCE hInstance, const HINSTANCE, char* const, cons wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); - wc.lpszClassName = TEXT("Episode Browser"); + wc.lpszClassName = L"Episode Browser"; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); require(RegisterClassEx(&wc)); @@ -122,8 +121,8 @@ int WINAPI WinMain(const HINSTANCE hInstance, const HINSTANCE, char* const, cons (HINSTANCE)NULL, GetCurrentThreadId())); const HWND hWnd = require(CreateWindowEx( 0, - TEXT("Episode Browser"), - TEXT("Episode Browser"), + L"Episode Browser", + L"Episode Browser", WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, (HWND)NULL, (HMENU)NULL, hInstance, (void*)NULL)); @@ -132,7 +131,7 @@ int WINAPI WinMain(const HINSTANCE hInstance, const HINSTANCE, char* const, cons g_hWndStatus = require(CreateWindowEx( 0, STATUSCLASSNAME, - (const TCHAR*)NULL, + (const wchar_t*)NULL, WS_CHILD|WS_VISIBLE|SBARS_SIZEGRIP, 0, 0, 0, 0, hWnd, (HMENU)IDR_STATUS, hInstance, (void*)NULL)); @@ -167,15 +166,15 @@ static LRESULT CALLBACK CBTProc(const int nCode, const WPARAM wParam, const LPAR g_hWnd = (HWND)wParam; /* Look up constants. */ - if (auto opLib = maybe_make(TEXT("User32.dll")); + if (auto opLib = maybe_make(L"User32.dll"); auto GetDpiForWindow = opLib->GetProcAddress("GetDpiForWindow")) g_iDPI = GetDpiForWindow(g_hWnd); - if (auto opLib = maybe_make(TEXT("uxtheme.dll")); + if (auto opLib = maybe_make(L"uxtheme.dll"); opLib->GetProcAddress("SetWindowTheme")) g_bThemes = 1; - if (auto opLib = maybe_make(TEXT("User32.dll")); + if (auto opLib = maybe_make(L"User32.dll"); opLib->GetProcAddress("SystemParametersInfo" WA)) { NONCLIENTMETRICS m; m.cbSize = sizeof(NONCLIENTMETRICS); @@ -282,10 +281,10 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, if (Pl("episode_data","thread_running",g_aThread)) { i = (i+1)%4; SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), - (LPARAM)(i==0? TEXT("."): - i==1? TEXT(".."): - i==2? TEXT("..."): - TEXT(""))); + (LPARAM)(i==0? L".": + i==1? L"..": + i==2? L"...": + L"")); } else { i = 0; g_bThread = 0; @@ -309,46 +308,46 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, case WM_MENUSELECT: switch (LOWORD(wParam)) { #define TIP(s) SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(0,0), (LPARAM)(s)); -#define OF(m, s) IDM_##m: TIP(TEXT(s)); break; - case OF(FILE_EXIT, "Close Episode Browser."); - case OF(FILE_REFRESH, "Quickly refresh episode list."); - case OF(FILE_FETCH_DATA, "Fetch episode data from the web (may take a few seconds)."); - case OF(FILE_FETCH_SCREENWRITERS, "Fetch screenwriter data from the web (may take a minute)."); - case OF(FILE_ABOUT, "Show information about Episode Browser."); - case OF(WATCH_LOCALLY, "Open local copy of episode, if available."); - case OF(WATCH_ONLINE, "Open episode in the web browser."); - case OF(TOGGLE, "Toggle watched/unwatched status."); - case OF(FORGET, "Reset watched/unwatched status."); - case OF(LOOKUP, "Fetch episode data from the web, such as date, source and hint."); - case OF(WIKI, "Show Detective Conan Wiki entry for episode."); - case OF(RATE10, "Rate episode 10/10."); - case OF(RATE9, "Rate episode 9/10."); - case OF(RATE8, "Rate episode 8/10."); - case OF(RATE7, "Rate episode 7/10."); - case OF(RATE6, "Rate episode 6/10."); - case OF(RATE5, "Rate episode 5/10."); - case OF(RATE4, "Rate episode 4/10."); - case OF(RATE3, "Rate episode 3/10."); - case OF(RATE2, "Rate episode 2/10."); - case OF(RATE1, "Rate episode 1/10."); - case OF(RATE0, "Remove episode rating."); +#define OF(m, s) IDM_##m: TIP(s); break; + case OF(FILE_EXIT, L"Close Episode Browser."); + case OF(FILE_REFRESH, L"Quickly refresh episode list."); + case OF(FILE_FETCH_DATA, L"Fetch episode data from the web (may take a few seconds)."); + case OF(FILE_FETCH_SCREENWRITERS, L"Fetch screenwriter data from the web (may take a minute)."); + case OF(FILE_ABOUT, L"Show information about Episode Browser."); + case OF(WATCH_LOCALLY, L"Open local copy of episode, if available."); + case OF(WATCH_ONLINE, L"Open episode in the web browser."); + case OF(TOGGLE, L"Toggle watched/unwatched status."); + case OF(FORGET, L"Reset watched/unwatched status."); + case OF(LOOKUP, L"Fetch episode data from the web, such as date, source and hint."); + case OF(WIKI, L"Show Detective Conan Wiki entry for episode."); + case OF(RATE10, L"Rate episode 10/10."); + case OF(RATE9, L"Rate episode 9/10."); + case OF(RATE8, L"Rate episode 8/10."); + case OF(RATE7, L"Rate episode 7/10."); + case OF(RATE6, L"Rate episode 6/10."); + case OF(RATE5, L"Rate episode 5/10."); + case OF(RATE4, L"Rate episode 4/10."); + case OF(RATE3, L"Rate episode 3/10."); + case OF(RATE2, L"Rate episode 2/10."); + case OF(RATE1, L"Rate episode 1/10."); + case OF(RATE0, L"Remove episode rating."); case IDM_VIEW_WATCHED: TIP(g_bViewWatched? - TEXT("Click to hide watched episodes."): - TEXT("Click to show watched episodes.")); + L"Click to hide watched episodes.": + L"Click to show watched episodes."); break; case IDM_VIEW_TV_ORIGINAL: TIP(g_bViewTVOriginal? - TEXT("Click to hide TV original episodes."): - TEXT("Click to show TV original episodes.")); + L"Click to hide TV original episodes.": + L"Click to show TV original episodes."); break; case IDM_VIEW_OTHERS: TIP(g_szLimitScreenwriter? - TEXT("Click to hide episodes by other screenwriters."): - TEXT("Click to show episodes by other screenwriters.")); + L"Click to hide episodes by other screenwriters.": + L"Click to show episodes by other screenwriters."); break; default: - TIP(TEXT("")); + TIP(L""); break; #undef OF #undef TIP @@ -380,7 +379,7 @@ void WndProcMainMenu(const HWND hWnd, unsigned short wCommand) Pl("episode_data","thread_create","update_screenwriters",&g_aThread); t: KillTimer(hWnd, IDR_TIMER); if (!prefer(SetTimer(hWnd, IDR_TIMER, 500, (TIMERPROC)NULL))) break; - SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)TEXT(".")); + SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)L"."); g_bThread = 1; break; case IDM_FILE_ABOUT: @@ -486,12 +485,12 @@ void WndProcContextMenu(const HWND, unsigned short wCommand) g_pElv->Redraw(); if (cNotFound == 1) { - EBMessageBox(TEXT("Episode could not be opened locally."), - TEXT("Error"), MB_ICONWARNING); + EBMessageBox(L"Episode could not be opened locally.", + L"Error", MB_ICONWARNING); } else if (cNotFound) { - std::basic_ostringstream tss; - tss << cNotFound << TEXT(" episodes could not be opened locally."); - EBMessageBox(tss.str().c_str(), TEXT("Error"), MB_ICONWARNING); + std::wstringstream wss; + wss << cNotFound << L" episodes could not be opened locally."; + EBMessageBox(wss.str().c_str(), L"Error", MB_ICONWARNING); } else if (ID_SUBGROUP(wCommand) == IDG_CTX_RATE) { g_pElv->Sort(); g_pElv->ShowFocus(); diff --git a/c/pl.cpp b/c/pl.cpp index a1849db..0114454 100644 --- a/c/pl.cpp +++ b/c/pl.cpp @@ -77,21 +77,11 @@ int Query::NextSolution() return 0; } -/* Convert Prolog term to normal or wide characters. */ -template <> -int PlString(const term_t t, std::string* const pStr, const int iFlags) +/* Convert Prolog term to wide characters. */ +int PlString(const term_t t, std::wstring* const pWstr, const int iFlags) { char* sz; int r = PL_get_chars(t, &sz, iFlags); - if (r) *pStr = sz; - return r; -} - -template <> -int PlString(const term_t t, std::wstring* const pWstr, const int iFlags) -{ - char* sz; - int r = PL_get_chars(t, &sz, iFlags); - if (r) *pWstr = BstrFromSz(sz); + if (r) *pWstr = WstrFromSz(sz); return r; } diff --git a/c/pl.h b/c/pl.h index 4a44f72..5c67af6 100644 --- a/c/pl.h +++ b/c/pl.h @@ -7,6 +7,8 @@ #include "common.h" +int PlString(term_t t, std::wstring* pWstr, int iFlags = CVT_WRITE); + struct Frame { Frame(); @@ -37,8 +39,6 @@ private: qid_t m_q; }; -template int PlString(term_t t, std::basic_string* pBstr, int iFlags = CVT_WRITE); - /* Polymorphic aliases for PL_put_*, PL_get_*. */ inline int PlPut(term_t t, int x) { return PL_put_integer(t, x); } inline int PlPut(term_t t, long x) { return PL_put_integer(t, x); } @@ -76,7 +76,7 @@ inline int PlGet(term_t t, std::wstring* x) { Mark m; char* sz; if (!PlGet(t, &sz)) return 0; - *x = BstrFromSz(sz); + *x = WstrFromSz(sz); return 1; /* or catch potential exception from BstrFromSz? */ } diff --git a/c/resource.rc b/c/resource.rc index 8e96357..e3e0006 100644 --- a/c/resource.rc +++ b/c/resource.rc @@ -67,6 +67,6 @@ CAPTION "About" FONT 8, "MS Shell Dlg 2" BEGIN DEFPUSHBUTTON "&OK", IDOK, ABOUTW-OKW-HPAD, ABOUTH-OKH-VPAD, OKW, OKH - LTEXT TEXT("Episode Browser\r\nCopyright 2021 John Ankarström"), + LTEXT L"Episode Browser\r\nCopyright 2021 John Ankarström", IDC_ABOUTTEXT, HPAD, VPAD, ABOUTW-OKW-HPAD*2, ABOUTH-VPAD END \ No newline at end of file -- cgit v1.2.3