in shell/browser/ui/message_box_win.cc [142:256]
DialogResult ShowTaskDialogWstr(NativeWindow* parent,
MessageBoxType type,
const std::vector<std::wstring>& buttons,
int default_id,
int cancel_id,
bool no_link,
const std::u16string& title,
const std::u16string& message,
const std::u16string& detail,
const std::u16string& checkbox_label,
bool checkbox_checked,
const gfx::ImageSkia& icon,
HWND* hwnd) {
TASKDIALOG_FLAGS flags =
TDF_SIZE_TO_CONTENT | // Show all content.
TDF_ALLOW_DIALOG_CANCELLATION; // Allow canceling the dialog.
TASKDIALOGCONFIG config = {0};
config.cbSize = sizeof(config);
config.hInstance = GetModuleHandle(NULL);
config.dwFlags = flags;
if (parent) {
config.hwndParent = static_cast<electron::NativeWindowViews*>(parent)
->GetAcceleratedWidget();
}
if (default_id > 0)
config.nDefaultButton = kIDStart + default_id;
// TaskDialogIndirect doesn't allow empty name, if we set empty title it
// will show "electron.exe" in title.
std::wstring app_name;
if (title.empty()) {
app_name = base::UTF8ToWide(Browser::Get()->GetName());
config.pszWindowTitle = app_name.c_str();
} else {
config.pszWindowTitle = base::as_wcstr(title);
}
base::win::ScopedHICON hicon;
if (!icon.isNull()) {
hicon = IconUtil::CreateHICONFromSkBitmap(*icon.bitmap());
config.dwFlags |= TDF_USE_HICON_MAIN;
config.hMainIcon = hicon.get();
} else {
// Show icon according to dialog's type.
switch (type) {
case MessageBoxType::kInformation:
case MessageBoxType::kQuestion:
config.pszMainIcon = TD_INFORMATION_ICON;
break;
case MessageBoxType::kWarning:
config.pszMainIcon = TD_WARNING_ICON;
break;
case MessageBoxType::kError:
config.pszMainIcon = TD_ERROR_ICON;
break;
case MessageBoxType::kNone:
break;
}
}
// If "detail" is empty then don't make message highlighted.
if (detail.empty()) {
config.pszContent = base::as_wcstr(message);
} else {
config.pszMainInstruction = base::as_wcstr(message);
config.pszContent = base::as_wcstr(detail);
}
if (!checkbox_label.empty()) {
config.pszVerificationText = base::as_wcstr(checkbox_label);
if (checkbox_checked)
config.dwFlags |= TDF_VERIFICATION_FLAG_CHECKED;
}
// Iterate through the buttons, put common buttons in dwCommonButtons
// and custom buttons in pButtons.
std::map<int, int> id_map;
std::vector<TASKDIALOG_BUTTON> dialog_buttons;
if (no_link) {
for (size_t i = 0; i < buttons.size(); ++i)
dialog_buttons.push_back(
{static_cast<int>(i + kIDStart), buttons[i].c_str()});
} else {
MapToCommonID(buttons, &id_map, &config.dwCommonButtons, &dialog_buttons);
}
if (!dialog_buttons.empty()) {
config.pButtons = &dialog_buttons.front();
config.cButtons = dialog_buttons.size();
if (!no_link)
config.dwFlags |= TDF_USE_COMMAND_LINKS; // custom buttons as links.
}
// Pass a callback to receive the HWND of the message box.
if (hwnd) {
config.pfCallback = &TaskDialogCallback;
config.lpCallbackData = reinterpret_cast<LONG_PTR>(hwnd);
}
int id = 0;
BOOL verification_flag_checked = FALSE;
TaskDialogIndirect(&config, &id, nullptr, &verification_flag_checked);
int button_id;
if (id_map.find(id) != id_map.end()) // common button.
button_id = id_map[id];
else if (id >= kIDStart) // custom button.
button_id = id - kIDStart;
else
button_id = cancel_id;
return {button_id, static_cast<bool>(verification_flag_checked)};
}