]> cygwin.com Git - cygwin-apps/setup.git/commitdiff
Add a more generic mbox wrapper
authorJon Turney <jon.turney@dronecode.org.uk>
Mon, 10 May 2021 21:35:32 +0000 (22:35 +0100)
committerJon Turney <jon.turney@dronecode.org.uk>
Fri, 26 Nov 2021 15:08:56 +0000 (15:08 +0000)
This mbox wrapper understands loading format strings from string
resources and unattended mode.

Factor out the unattended_result logic from the existing mbox wrapper,
so it can be shared with that.

String++.cc
String++.h
msg.cc
msg.h
res.rc
resource.h

index 0f88c61da7dfbe31c857572eca82d19444f722db..0984c1664efa1d5f094f1917ea9dbcccc9acb546 100644 (file)
@@ -114,3 +114,37 @@ std::wstring string_to_wstring(const std::string &s)
 
   return w;
 }
+
+// convert a UTF-16 wstring to a UTF-8 string
+std::string wstring_to_string(const std::wstring &w)
+{
+  int n = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, NULL, 0, NULL, NULL);
+
+  if (n <= 0)
+    return "conversion failed";
+
+  char *buf = new char[n+1];
+  WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, buf, n, NULL, NULL);
+
+  std::string s(buf);
+  delete[] buf;
+
+  return s;
+}
+
+std::wstring
+vformat(const std::wstring &fmt, va_list ap)
+{
+  va_list apc;
+  va_copy(apc, ap);
+
+  int n = vsnwprintf(NULL, 0, fmt.c_str(), ap);
+
+  std::wstring str;
+  str.resize(n+1);
+  vsnwprintf(&str[0], n+1, fmt.c_str(), apc);
+
+  va_end(apc);
+
+  return str;
+}
index 3d977e9e2d3e2039685790f83a1f28663938c45f..0851f4e8d411750f97260cbceb5db6c69bda19a4 100644 (file)
@@ -43,5 +43,9 @@ inline std::string operator+ (const char *a, const std::string& b)
 { return std::string(a) + b; }
 
 std::wstring string_to_wstring(const std::string &s);
+std::string wstring_to_string(const std::wstring &w);
+
+// produce a std::string using formatting like sprintf
+std::wstring vformat(const std::wstring &fmt, va_list ap);
 
 #endif /* SETUP_STRING___H */
diff --git a/msg.cc b/msg.cc
index 403e78aab1b9df8e297fc0879fbe242224a0698b..ac0dbc63598fd0c1ed60b83464a85f0816b3cb3a 100644 (file)
--- a/msg.cc
+++ b/msg.cc
 #include <stdarg.h>
 #include "dialog.h"
 #include "state.h"
+#include "String++.h"
+#include "resource.h"
+
+static int
+unattended_result(int mb_type)
+{
+  // Return some default values.
+  Log (LOG_PLAIN) << "unattended_mode is set at mbox: returning default value" << endLog;
+
+  switch (mb_type & MB_TYPEMASK)
+    {
+    case MB_OK:
+    case MB_OKCANCEL:
+      return IDOK;
+      break;
+    case MB_YESNO:
+    case MB_YESNOCANCEL:
+      return IDYES;
+      break;
+    case MB_ABORTRETRYIGNORE:
+      return IDIGNORE;
+      break;
+    case MB_RETRYCANCEL:
+      return IDCANCEL;
+      break;
+    default:
+      Log (LOG_PLAIN) << "unattended_mode failed for " << (mb_type & MB_TYPEMASK) << endLog;
+      return 0;
+    }
+}
 
 int
 mbox (HWND owner, const char *buf, const char *name, int type)
 {
+  // 'name' is not the mbox caption, just some text written to the log
   Log (LOG_PLAIN) << "mbox " << name << ": " << buf << endLog;
   if (unattended_mode)
-    {
-      // Return some default values.
-      Log (LOG_PLAIN) << "unattended_mode is set at mbox: returning default value" << endLog;
-      switch (type & MB_TYPEMASK)
-       {
-         case MB_OK:
-         case MB_OKCANCEL:
-           return IDOK;
-           break;
-         case MB_YESNO:
-         case MB_YESNOCANCEL:
-           return IDYES;
-           break;
-         case MB_ABORTRETRYIGNORE:
-           return IDIGNORE;
-           break;
-         case MB_RETRYCANCEL:
-           return IDCANCEL;
-           break;
-         default:
-           Log (LOG_PLAIN) << "unattended_mode failed for " << (type & MB_TYPEMASK) << endLog;
-           return 0;
-       }
-    }
-  return MessageBox (owner, buf, "Cygwin Setup", type);
+      return unattended_result(type);
+
+  char caption[32];
+  LoadString (hinstance, IDS_MBOX_CAPTION, caption, sizeof (caption));
+
+  return MessageBox (owner, buf, caption, type);
 }
 
 static int
@@ -94,3 +106,25 @@ yesno (HWND owner, int id, ...)
   va_start (args, id);
   return mbox (owner, "yesno", MB_YESNO, id, args);
 }
+
+int
+mbox(HWND owner, unsigned int format_id, int mb_type, ...)
+{
+  std::wstring fmt = LoadStringW(format_id);
+  if (fmt.empty())
+    fmt = L"Internal error: format string resource not found";
+
+  va_list args;
+  va_start(args, mb_type);
+  std::wstring buf = vformat(fmt, args);
+  va_end(args);
+
+  // write to log as UTF8
+  Log (LOG_PLAIN) << "mbox " << ": " << wstring_to_string(buf) << endLog;
+
+  if (unattended_mode)
+    return unattended_result(mb_type);
+
+  std::wstring caption = LoadStringW(IDS_MBOX_CAPTION);
+  return MessageBoxW(owner, buf.c_str(), caption.c_str(), mb_type);
+}
diff --git a/msg.h b/msg.h
index 4810057984387306bf50330fb62d968151d5db31..7ff706e1bba0303a19ddbfce697881d7b56bb745 100644 (file)
--- a/msg.h
+++ b/msg.h
@@ -34,4 +34,7 @@ int yesno (HWND owner, int id, ...);
 /* general MessageBox() wrapper which understands unattended mode */
 int mbox (HWND owner, const char *buf, const char *name, int type);
 
+/* MessageBox() wrapper which understands format string and unattended mode */
+int mbox(HWND owner, unsigned int format_id, int mb_type, ...);
+
 #endif /* SETUP_MSG_H */
diff --git a/res.rc b/res.rc
index 7fc0ee578f2c6e3debceddfc6302283c6cc30d43..f177b7f0994b61a9091a855b4ebb3a0e7310993c 100644 (file)
--- a/res.rc
+++ b/res.rc
@@ -645,4 +645,5 @@ BEGIN
     IDS_COLUMN_CATEGORIES "Categories"
     IDS_COLUMN_SIZE "Size"
     IDS_COLUMN_DESCR "Description"
+    IDS_MBOX_CAPTION "Cygwin Setup"
 END
index 4f1c3cf8114eaab92cf151ecda185f78b67e28d8..727c8189be5b7bbff86ee312ab508a56ec866f71 100644 (file)
@@ -76,6 +76,7 @@
 #define IDS_COLUMN_CATEGORIES             176
 #define IDS_COLUMN_SIZE                   177
 #define IDS_COLUMN_DESCR                  178
+#define IDS_MBOX_CAPTION                  179
 
 // Dialogs
 
This page took 0.043892 seconds and 5 git commands to generate.