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 unattended_result(int mb_type
)
34 // Return some default values.
35 switch (mb_type
& MB_TYPEMASK
)
45 case MB_ABORTRETRYIGNORE
:
52 Log (LOG_PLAIN
) << "unattended_mode failed for " << (mb_type
& MB_TYPEMASK
) << endLog
;
58 mbox (HWND owner
, const char *buf
, const char *name
, int type
)
60 // 'name' is not the mbox caption, just some text written to the log
61 Log (LOG_PLAIN
) << "mbox " << name
<< ": " << buf
<< endLog
;
64 Log (LOG_PLAIN
) << "unattended_mode is set at mbox: returning default value" << endLog
;
65 return unattended_result(type
);
69 LoadString (hinstance
, IDS_MBOX_CAPTION
, caption
, sizeof (caption
));
71 return MessageBox (owner
, buf
, caption
, type
);
75 mbox (HWND owner
, const char *name
, int type
, int id
, va_list args
)
77 char buf
[1000], fmt
[1000];
79 if (LoadString (hinstance
, id
, fmt
, sizeof (fmt
)) <= 0)
82 vsnprintf (buf
, 1000, fmt
, args
);
83 return mbox(owner
, buf
, name
, type
);
87 note (HWND owner
, int id
, ...)
91 mbox (owner
, "note", 0, id
, args
);
95 fatal (HWND owner
, int id
, ...)
99 mbox (owner
, "fatal", 0, id
, args
);
104 yesno (HWND owner
, int id
, ...)
108 return mbox (owner
, "yesno", MB_YESNO
, id
, args
);
111 static HHOOK hMsgBoxHook
;
113 LRESULT CALLBACK
CBTProc(int nCode
, WPARAM wParam
, LPARAM lParam
) {
118 if (GetDlgItem(hWnd
, IDCANCEL
) != NULL
)
120 // XXX: ideally we'd discover the text used for 'Continue' buttons in
121 // MessageBoxes, rather than having our own translation.
122 std::wstring cont
= LoadStringW(IDS_CONTINUE
);
123 SetDlgItemTextW(hWnd
, IDCANCEL
, cont
.c_str());
125 UnhookWindowsHookEx(hMsgBoxHook
);
127 return CallNextHookEx(hMsgBoxHook
, nCode
, wParam
, lParam
);
130 // registry key to store "don't show this again" state, made unique by including a GUID
131 static const char *regkey
= "Cygwin-Setup-d975d7b8-8c44-44a1-915a-7cf44b79cd88";
134 mbox(HWND owner
, unsigned int format_id
, int mb_type
, ...)
136 std::wstring fmt
= LoadStringWEx(format_id
, MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
));
138 fmt
= L
"Internal error: format string resource not found";
141 va_start(args
, mb_type
);
142 std::wstring buf
= vformat(fmt
, args
);
145 // write unlocalized to log as UTF8
146 Log (LOG_PLAIN
) << "mbox " << ": " << wstring_to_string(buf
) << endLog
;
149 return unattended_result(mb_type
);
151 fmt
= LoadStringW(format_id
);
153 fmt
= L
"Internal error: format string resource not found";
155 va_start(args
, mb_type
);
156 buf
= vformat(fmt
, args
);
159 bool retry_continue
= (mb_type
& MB_TYPEMASK
) == MB_RETRYCONTINUE
;
160 if (retry_continue
) {
161 mb_type
&= ~MB_TYPEMASK
;
162 mb_type
|= MB_RETRYCANCEL
;
163 // Install a window hook, so we can intercept the message-box creation, and
164 // customize it (replacing the text on the 'cancel' button with 'continue')
165 // Only install for THIS thread!!!
166 hMsgBoxHook
= SetWindowsHookEx(WH_CBT
, CBTProc
, NULL
, GetCurrentThreadId());
169 typedef int (WINAPI
*PFNSHMESSAGEBOXCHECKW
)(HWND
, LPCWSTR
, LPCWSTR
, UINT
, int, LPCWSTR
);
170 static PFNSHMESSAGEBOXCHECKW pfnSHMessageBoxCheckW
= 0;
171 static bool doOnce
= FALSE
;
176 pfnSHMessageBoxCheckW
= (PFNSHMESSAGEBOXCHECKW
)GetProcAddress(GetModuleHandle("shlwapi.dll"), "SHMessageBoxCheckW");
179 std::wstring caption
= LoadStringW(IDS_MBOX_CAPTION
);
181 if (pfnSHMessageBoxCheckW
&& (mb_type
& MB_DSA_CHECKBOX
))
183 mb_type
&= ~MB_DSA_CHECKBOX
;
184 std::wstring regkey_msg
= format(L
"%s-%d", regkey
, format_id
);
185 retval
= pfnSHMessageBoxCheckW(owner
, buf
.c_str(), caption
.c_str(), mb_type
,
186 unattended_result(mb_type
), regkey_msg
.c_str());
189 retval
= MessageBoxW(owner
, buf
.c_str(), caption
.c_str(), mb_type
);
191 // When the the retry_continue customization is active, adjust the return
192 // value for less confusing results
193 if (retry_continue
&& retval
== IDCANCEL
)