DialogResult ShowTaskDialogWstr()

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)};
}