2014-10-31 18:17:05 +00:00
|
|
|
// Copyright (c) 2013 GitHub, Inc.
|
2014-04-25 09:49:37 +00:00
|
|
|
// Use of this source code is governed by the MIT license that can be
|
2013-07-05 01:59:53 +00:00
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2014-03-16 00:30:26 +00:00
|
|
|
#include "atom/browser/ui/message_box.h"
|
2013-07-05 01:59:53 +00:00
|
|
|
|
2015-07-08 06:12:11 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#include <commctrl.h>
|
|
|
|
|
|
|
|
#include "atom/browser/native_window_views.h"
|
2013-09-22 09:11:09 +00:00
|
|
|
#include "base/callback.h"
|
2013-12-17 06:01:40 +00:00
|
|
|
#include "base/strings/utf_string_conversions.h"
|
2015-07-08 06:12:11 +00:00
|
|
|
#include "base/threading/thread.h"
|
|
|
|
#include "content/public/browser/browser_thread.h"
|
2014-11-05 08:05:11 +00:00
|
|
|
|
2013-07-05 01:59:53 +00:00
|
|
|
namespace atom {
|
|
|
|
|
2013-07-24 10:34:50 +00:00
|
|
|
namespace {
|
|
|
|
|
2015-07-08 06:35:28 +00:00
|
|
|
// Small command ID values are already taken by Windows, we have to start from
|
|
|
|
// a large number to avoid conflicts with Windows.
|
|
|
|
const int kIDStart = 100;
|
|
|
|
|
2015-07-08 06:12:11 +00:00
|
|
|
int ShowMessageBoxUTF16(HWND parent,
|
|
|
|
const std::vector<base::string16>& buttons,
|
|
|
|
int cancel_id,
|
|
|
|
const base::string16& title,
|
|
|
|
const base::string16& message,
|
|
|
|
const base::string16& detail) {
|
|
|
|
std::vector<TASKDIALOG_BUTTON> dialog_buttons;
|
|
|
|
for (size_t i = 0; i < buttons.size(); ++i)
|
2015-07-08 06:35:28 +00:00
|
|
|
dialog_buttons.push_back({i + kIDStart, buttons[i].c_str()});
|
|
|
|
|
2015-07-08 06:41:19 +00:00
|
|
|
TASKDIALOG_FLAGS flags = TDF_SIZE_TO_CONTENT; // show all content.
|
2015-07-08 06:35:28 +00:00
|
|
|
if (cancel_id != 0)
|
2015-07-08 06:41:19 +00:00
|
|
|
flags |= TDF_ALLOW_DIALOG_CANCELLATION; // allow dialog to be cancelled.
|
2015-07-08 06:12:11 +00:00
|
|
|
|
|
|
|
TASKDIALOGCONFIG config = { 0 };
|
2015-07-08 06:41:19 +00:00
|
|
|
config.cbSize = sizeof(config);
|
|
|
|
config.hwndParent = parent;
|
|
|
|
config.hInstance = GetModuleHandle(NULL);
|
|
|
|
config.dwFlags = flags;
|
|
|
|
config.pszWindowTitle = title.c_str();
|
|
|
|
config.pButtons = &dialog_buttons.front();
|
|
|
|
config.cButtons = dialog_buttons.size();
|
|
|
|
|
|
|
|
// If "detail" is empty then don't make message hilighted.
|
|
|
|
if (detail.empty()) {
|
|
|
|
config.pszContent = message.c_str();
|
|
|
|
} else {
|
|
|
|
config.pszMainInstruction = message.c_str();
|
|
|
|
config.pszContent = detail.c_str();
|
|
|
|
}
|
2015-07-08 06:12:11 +00:00
|
|
|
|
|
|
|
int id = 0;
|
|
|
|
TaskDialogIndirect(&config, &id, NULL, NULL);
|
2015-07-08 06:35:28 +00:00
|
|
|
if (id == 0 || id == IDCANCEL)
|
|
|
|
return cancel_id;
|
|
|
|
else
|
|
|
|
return id - kIDStart;
|
2015-07-08 06:12:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void RunMessageBoxInNewThread(base::Thread* thread,
|
|
|
|
NativeWindow* parent,
|
|
|
|
MessageBoxType type,
|
|
|
|
const std::vector<std::string>& buttons,
|
|
|
|
int cancel_id,
|
|
|
|
const std::string& title,
|
|
|
|
const std::string& message,
|
|
|
|
const std::string& detail,
|
|
|
|
const gfx::ImageSkia& icon,
|
|
|
|
const MessageBoxCallback& callback) {
|
|
|
|
int result = ShowMessageBox(parent, type, buttons, cancel_id, title, message,
|
|
|
|
detail, icon);
|
|
|
|
content::BrowserThread::PostTask(
|
|
|
|
content::BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
|
|
|
|
content::BrowserThread::DeleteSoon(
|
|
|
|
content::BrowserThread::UI, FROM_HERE, thread);
|
2013-07-24 10:34:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2015-07-08 06:12:11 +00:00
|
|
|
int ShowMessageBox(NativeWindow* parent,
|
2013-07-05 01:59:53 +00:00
|
|
|
MessageBoxType type,
|
|
|
|
const std::vector<std::string>& buttons,
|
2015-07-07 10:26:50 +00:00
|
|
|
int cancel_id,
|
2013-07-05 01:59:53 +00:00
|
|
|
const std::string& title,
|
|
|
|
const std::string& message,
|
2015-01-05 23:08:42 +00:00
|
|
|
const std::string& detail,
|
|
|
|
const gfx::ImageSkia& icon) {
|
2015-07-08 06:12:11 +00:00
|
|
|
std::vector<base::string16> utf16_buttons;
|
|
|
|
for (const auto& button : buttons)
|
|
|
|
utf16_buttons.push_back(base::UTF8ToUTF16(button));
|
|
|
|
|
|
|
|
HWND hwnd_parent = parent ?
|
|
|
|
static_cast<atom::NativeWindowViews*>(parent)->GetAcceleratedWidget() :
|
|
|
|
NULL;
|
2013-07-25 08:56:02 +00:00
|
|
|
|
2015-07-08 06:12:11 +00:00
|
|
|
NativeWindow::DialogScope dialog_scope(parent);
|
|
|
|
return ShowMessageBoxUTF16(hwnd_parent,
|
|
|
|
utf16_buttons,
|
|
|
|
cancel_id,
|
|
|
|
base::UTF8ToUTF16(title),
|
|
|
|
base::UTF8ToUTF16(message),
|
|
|
|
base::UTF8ToUTF16(detail));
|
2013-07-05 01:59:53 +00:00
|
|
|
}
|
|
|
|
|
2015-07-08 06:12:11 +00:00
|
|
|
void ShowMessageBox(NativeWindow* parent,
|
2013-09-22 09:11:09 +00:00
|
|
|
MessageBoxType type,
|
|
|
|
const std::vector<std::string>& buttons,
|
2015-07-07 10:26:50 +00:00
|
|
|
int cancel_id,
|
2013-09-22 09:11:09 +00:00
|
|
|
const std::string& title,
|
|
|
|
const std::string& message,
|
|
|
|
const std::string& detail,
|
2015-01-05 23:08:42 +00:00
|
|
|
const gfx::ImageSkia& icon,
|
2013-09-22 09:11:09 +00:00
|
|
|
const MessageBoxCallback& callback) {
|
2015-07-08 06:12:11 +00:00
|
|
|
scoped_ptr<base::Thread> thread(
|
|
|
|
new base::Thread(ATOM_PRODUCT_NAME "MessageBoxThread"));
|
|
|
|
thread->init_com_with_mta(false);
|
|
|
|
if (!thread->Start()) {
|
|
|
|
callback.Run(cancel_id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
base::Thread* unretained = thread.release();
|
|
|
|
unretained->message_loop()->PostTask(
|
|
|
|
FROM_HERE,
|
|
|
|
base::Bind(&RunMessageBoxInNewThread, base::Unretained(unretained),
|
|
|
|
parent, type, buttons, cancel_id, title, message, detail, icon,
|
|
|
|
callback));
|
2013-09-22 09:11:09 +00:00
|
|
|
}
|
|
|
|
|
2014-11-05 08:05:11 +00:00
|
|
|
void ShowErrorBox(const base::string16& title, const base::string16& content) {
|
|
|
|
}
|
|
|
|
|
2013-07-05 01:59:53 +00:00
|
|
|
} // namespace atom
|