2 * Copyright (c) 2000, Red Hat, Inc.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by DJ Delorie <dj@cygnus.com>
16 /* The purpose of this file is to centralize all the message
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
);
38 unattended_result(int mb_type
)
40 // Return some default values.
41 switch (mb_type
& MB_TYPEMASK
)
51 case MB_ABORTRETRYIGNORE
:
58 Log (LOG_PLAIN
) << "unattended_mode failed for " << (mb_type
& MB_TYPEMASK
) << endLog
;
64 mbox (HWND owner
, const char *buf
, const char *name
, int type
)
66 // 'name' is not the mbox caption, just some text written to the log
67 Log (LOG_PLAIN
) << "mbox " << name
<< ": " << buf
<< endLog
;
70 Log (LOG_PLAIN
) << "unattended_mode is set at mbox: returning default value" << endLog
;
71 return unattended_result(type
);
75 LoadString (hinstance
, IDS_MBOX_CAPTION
, caption
, sizeof (caption
));
77 return MessageBox (owner
, buf
, caption
, type
);
81 mbox (HWND owner
, const char *name
, int type
, int id
, va_list args
)
83 char buf
[1000], fmt
[1000];
85 if (LoadString (hinstance
, id
, fmt
, sizeof (fmt
)) <= 0)
88 vsnprintf (buf
, 1000, fmt
, args
);
89 return mbox(owner
, buf
, name
, type
);
93 note (HWND owner
, int id
, ...)
97 mbox (owner
, "note", 0, id
, args
);
101 fatal (HWND owner
, int id
, ...)
105 mbox (owner
, "fatal", 0, id
, args
);
110 yesno (HWND owner
, int id
, ...)
114 return mbox (owner
, "yesno", MB_YESNO
, id
, args
);
117 static HHOOK hMsgBoxHook
;
119 LRESULT CALLBACK
CBTProc(int nCode
, WPARAM wParam
, LPARAM lParam
) {
124 if (GetDlgItem(hWnd
, IDCANCEL
) != NULL
)
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());
131 UnhookWindowsHookEx(hMsgBoxHook
);
133 return CallNextHookEx(hMsgBoxHook
, nCode
, wParam
, lParam
);
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";
140 mbox(HWND owner
, unsigned int format_id
, int mb_type
, ...)
142 std::wstring fmt
= LoadStringWEx(format_id
, MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
));
144 fmt
= L
"Internal error: format string resource not found";
147 va_start(args
, mb_type
);
148 std::wstring buf
= vformat(fmt
, args
);
151 // write unlocalized to log as UTF8
152 Log (LOG_PLAIN
) << "mbox " << ": " << wstring_to_string(buf
) << endLog
;
155 return unattended_result(mb_type
);
157 fmt
= LoadStringW(format_id
);
159 fmt
= L
"Internal error: format string resource not found";
161 va_start(args
, mb_type
);
162 buf
= vformat(fmt
, args
);
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());
175 std::wstring caption
= LoadStringW(IDS_MBOX_CAPTION
);
177 if (mb_type
& MB_DSA_CHECKBOX
)
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());
185 retval
= MessageBoxW(owner
, buf
.c_str(), caption
.c_str(), mb_type
);
187 // When the the retry_continue customization is active, adjust the return
188 // value for less confusing results
189 if (retry_continue
&& retval
== IDCANCEL
)