aboutsummaryrefslogtreecommitdiff
path: root/c
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2022-07-29 15:31:26 +0200
committerJohn Ankarström <john@ankarstrom.se>2022-07-29 15:31:26 +0200
commitc883d9cf5673fe0af8d69120b048d642e122bdbb (patch)
treee657e8375be9e881492bc05b15b036ed633a7765 /c
parenta67d7ca9e69799728801e30eff6af1adc7d2e53b (diff)
downloadEpisodeBrowser-c883d9cf5673fe0af8d69120b048d642e122bdbb.tar.gz
Use swprintf_s instead of string streams.
I find it much simpler. It is very safe, as wszf only accepts fixed-size arrays. There is, of course, the chance that swprintf_s fails and writes nothing into the array. This can be handled by the caller, if desired.
Diffstat (limited to 'c')
-rw-r--r--c/common.h8
-rw-r--r--c/main.cpp30
2 files changed, 23 insertions, 15 deletions
diff --git a/c/common.h b/c/common.h
index 3a2d598..8b88635 100644
--- a/c/common.h
+++ b/c/common.h
@@ -42,6 +42,12 @@ T* Library::GetProcAddress(const char* const szProc)
return (T*)(void*)::GetProcAddress(m_hModule, szProc);
}
+template<size_t N, typename... T>
+inline auto wszf(wchar_t (&wsz)[N], const wchar_t* wszFmt, T... xs)
+{
+ return swprintf_s(wsz, N, wszFmt, xs...);
+}
+
/* Create and return an object of type C. If construction fails,
* return nothing. The returned value must be checked before being
* used, as dereferencing is undefined if the value is empty. */
@@ -57,7 +63,7 @@ std::optional<T> maybe_make(U... xs)
/* Variable template for caching values from GetSystemMetrics. */
template <int I>
-const auto Metric = GetSystemMetrics(I);
+auto Metric = GetSystemMetrics(I);
/* Check result of Windows API call, throwing error on NULL. */
template <typename T>
diff --git a/c/main.cpp b/c/main.cpp
index 29a4d46..673affe 100644
--- a/c/main.cpp
+++ b/c/main.cpp
@@ -1,5 +1,4 @@
#include <exception>
-#include <sstream>
#include <windows.h>
#include <commctrl.h>
#include <uxtheme.h>
@@ -47,14 +46,12 @@ static void UpdateTheme();
void TerminateMsg(const wchar_t* wsz1, const wchar_t* wsz2) noexcept
{
- std::wstringstream wss;
- wss << L"Episode Browser was terminated due to ";
- wss << wsz1;
+ wchar_t wsz[256] = {0};
if (wsz2)
- wss << ": " << wsz2;
+ wszf(wsz, L"Episode Browser was terminated due to %s: %s.", wsz1, wsz2);
else
- wss << ".";
- MessageBox(g_hWnd, wss.str().c_str(), L"Fatal Error", MB_ICONERROR);
+ wszf(wsz, L"Episode Browser was terminated due to %s.", wsz1);
+ MessageBox(g_hWnd, wsz, L"Fatal Error", MB_ICONERROR);
}
void OnTerminate() noexcept
@@ -240,7 +237,11 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam,
case 0x02E0: /* WM_DPICHANGED */
{
const RECT* const lpr = (RECT*)lParam;
+
+ /* Update DPI and cached metrics. */
g_iDPI = HIWORD(wParam);
+ Metric<SM_CXVSCROLL> = GetSystemMetrics(SM_CXVSCROLL);
+
prefer(SetWindowPos(hWnd, (HWND)NULL,
lpr->left, lpr->top,
lpr->right-lpr->left,
@@ -455,9 +456,9 @@ void WndProcContextMenu(const HWND, unsigned short wCommand)
EBMessageBox(L"Episode could not be opened locally.",
L"Error", MB_ICONWARNING);
} else if (cNotFound) {
- std::wstringstream wss;
- wss << cNotFound << L" episodes could not be opened locally.";
- EBMessageBox(wss.str().c_str(), L"Error", MB_ICONWARNING);
+ wchar_t wsz[64] = {0};
+ wszf(wsz, L"%d episodes could not be opened locally.", cNotFound);
+ EBMessageBox(wsz, L"Error", MB_ICONWARNING);
} else if (ID_SUBGROUP(wCommand) == IDG_CTX_RATE) {
g_pElv->Sort();
g_pElv->ShowFocus();
@@ -473,10 +474,11 @@ void WaitFor(const char* szMod, const char* szPred)
static std::wstring wsPred;
if (bActive) {
- std::wstringstream wss;
- wss << L"Another task (" << wsPred.c_str() << ") is active. "
- << "Do you want to cancel the existing task and start a new one?";
- if (EBMessageBox(wss.str().c_str(), L"Error", MB_YESNO|MB_ICONWARNING) != IDYES)
+ wchar_t wsz[128] = {0};
+ wszf(wsz, L"Another task (%s) is active. "
+ L"Do you want to cancel the existing task and start a new one?",
+ wsPred.c_str());
+ if (EBMessageBox(wsz, L"Error", MB_YESNO|MB_ICONWARNING) != IDYES)
return;
KillTimer(NULL, iTimer);
bActive = 0;