]> cygwin.com Git - cygwin-apps/setup.git/blob - msg.cc
Suppress bogus free-nonheap-object warning in iniparse.cc
[cygwin-apps/setup.git] / msg.cc
1 /*
2 * Copyright (c) 2000, Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by DJ Delorie <dj@cygnus.com>
13 *
14 */
15
16 /* The purpose of this file is to centralize all the message
17 functions. */
18
19 #include "msg.h"
20
21 #include "LogFile.h"
22 #include "win32.h"
23 #include <shlwapi.h>
24
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include "dialog.h"
28 #include "state.h"
29 #include "String++.h"
30 #include "resource.h"
31
32 // no prototype in shlwapi.h until MinGW64 headers 9.0.0
33 #if __MINGW64_VERSION_MAJOR < 9
34 extern "C" int WINAPI SHMessageBoxCheckW(HWND hwnd, LPCWSTR pszText, LPCWSTR pszCaption, UINT uType, int iDefault, LPCWSTR pszRegVal);
35 #endif
36
37 static int
38 unattended_result(int mb_type)
39 {
40 // Return some default values.
41 switch (mb_type & MB_TYPEMASK)
42 {
43 case MB_OK:
44 case MB_OKCANCEL:
45 return IDOK;
46 break;
47 case MB_YESNO:
48 case MB_YESNOCANCEL:
49 return IDYES;
50 break;
51 case MB_ABORTRETRYIGNORE:
52 return IDIGNORE;
53 break;
54 case MB_RETRYCANCEL:
55 return IDCANCEL;
56 break;
57 default:
58 Log (LOG_PLAIN) << "unattended_mode failed for " << (mb_type & MB_TYPEMASK) << endLog;
59 return 0;
60 }
61 }
62
63 int
64 mbox (HWND owner, const char *buf, const char *name, int type)
65 {
66 // 'name' is not the mbox caption, just some text written to the log
67 Log (LOG_PLAIN) << "mbox " << name << ": " << buf << endLog;
68 if (unattended_mode)
69 {
70 Log (LOG_PLAIN) << "unattended_mode is set at mbox: returning default value" << endLog;
71 return unattended_result(type);
72 }
73
74 char caption[32];
75 LoadString (hinstance, IDS_MBOX_CAPTION, caption, sizeof (caption));
76
77 return MessageBox (owner, buf, caption, type);
78 }
79
80 static int
81 mbox (HWND owner, const char *name, int type, int id, va_list args)
82 {
83 char buf[1000], fmt[1000];
84
85 if (LoadString (hinstance, id, fmt, sizeof (fmt)) <= 0)
86 ExitProcess (0);
87
88 vsnprintf (buf, 1000, fmt, args);
89 return mbox(owner, buf, name, type);
90 }
91
92 void
93 note (HWND owner, int id, ...)
94 {
95 va_list args;
96 va_start (args, id);
97 mbox (owner, "note", 0, id, args);
98 }
99
100 void
101 fatal (HWND owner, int id, ...)
102 {
103 va_list args;
104 va_start (args, id);
105 mbox (owner, "fatal", 0, id, args);
106 Logger ().exit (1);
107 }
108
109 int
110 yesno (HWND owner, int id, ...)
111 {
112 va_list args;
113 va_start (args, id);
114 return mbox (owner, "yesno", MB_YESNO, id, args);
115 }
116
117 static HHOOK hMsgBoxHook;
118
119 LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam) {
120 HWND hWnd;
121 switch (nCode) {
122 case HCBT_ACTIVATE:
123 hWnd = (HWND)wParam;
124 if (GetDlgItem(hWnd, IDCANCEL) != NULL)
125 {
126 // XXX: ideally we'd discover the text used for 'Continue' buttons in
127 // MessageBoxes, rather than having our own translation.
128 std::wstring cont = LoadStringW(IDS_CONTINUE);
129 SetDlgItemTextW(hWnd, IDCANCEL, cont.c_str());
130 }
131 UnhookWindowsHookEx(hMsgBoxHook);
132 }
133 return CallNextHookEx(hMsgBoxHook, nCode, wParam, lParam);
134 }
135
136 // registry key to store "don't show this again" state, made unique by including a GUID
137 static const char *regkey = "Cygwin-Setup-d975d7b8-8c44-44a1-915a-7cf44b79cd88";
138
139 int
140 mbox(HWND owner, unsigned int format_id, int mb_type, ...)
141 {
142 std::wstring fmt = LoadStringWEx(format_id, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
143 if (fmt.empty())
144 fmt = L"Internal error: format string resource not found";
145
146 va_list args;
147 va_start(args, mb_type);
148 std::wstring buf = vformat(fmt, args);
149 va_end(args);
150
151 // write unlocalized to log as UTF8
152 Log (LOG_PLAIN) << "mbox " << ": " << wstring_to_string(buf) << endLog;
153
154 if (unattended_mode)
155 return unattended_result(mb_type);
156
157 fmt = LoadStringW(format_id);
158 if (fmt.empty())
159 fmt = L"Internal error: format string resource not found";
160
161 va_start(args, mb_type);
162 buf = vformat(fmt, args);
163 va_end(args);
164
165 bool retry_continue = (mb_type & MB_TYPEMASK) == MB_RETRYCONTINUE;
166 if (retry_continue) {
167 mb_type &= ~MB_TYPEMASK;
168 mb_type |= MB_RETRYCANCEL;
169 // Install a window hook, so we can intercept the message-box creation, and
170 // customize it (replacing the text on the 'cancel' button with 'continue')
171 // Only install for THIS thread!!!
172 hMsgBoxHook = SetWindowsHookEx(WH_CBT, CBTProc, NULL, GetCurrentThreadId());
173 }
174
175 std::wstring caption = LoadStringW(IDS_MBOX_CAPTION);
176 int retval;
177 if (mb_type & MB_DSA_CHECKBOX)
178 {
179 mb_type &= ~MB_DSA_CHECKBOX;
180 std::wstring regkey_msg = format(L"%s-%d", regkey, format_id);
181 retval = SHMessageBoxCheckW(owner, buf.c_str(), caption.c_str(), mb_type,
182 unattended_result(mb_type), regkey_msg.c_str());
183 }
184 else
185 retval = MessageBoxW(owner, buf.c_str(), caption.c_str(), mb_type);
186
187 // When the the retry_continue customization is active, adjust the return
188 // value for less confusing results
189 if (retry_continue && retval == IDCANCEL)
190 retval = IDCONTINUE;
191
192 return retval;
193 }
This page took 0.044785 seconds and 5 git commands to generate.