| Index: win8/metro_driver/metro_dialog_box.cc
|
| diff --git a/win8/metro_driver/metro_dialog_box.cc b/win8/metro_driver/metro_dialog_box.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..25e70827710326f905bc8c3f7fe9a40e6f9aead3
|
| --- /dev/null
|
| +++ b/win8/metro_driver/metro_dialog_box.cc
|
| @@ -0,0 +1,160 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "win8/metro_driver/stdafx.h"
|
| +
|
| +#include "win8/metro_driver/chrome_app_view.h"
|
| +#include "win8/metro_driver/metro_dialog_box.h"
|
| +#include "win8/metro_driver/winrt_utils.h"
|
| +
|
| +typedef winfoundtn::Collections::
|
| + IVector<ABI::Windows::UI::Popups::IUICommand*> WindowsUICommands;
|
| +
|
| +typedef winfoundtn::IAsyncOperation<ABI::Windows::UI::Popups::IUICommand*>
|
| + AsyncCommandStatus;
|
| +
|
| +MetroDialogBox::MetroDialogBox() {
|
| + DVLOG(1) << __FUNCTION__;
|
| + dialog_box_info_.button1_handler = NULL;
|
| + dialog_box_info_.button2_handler = NULL;
|
| +}
|
| +
|
| +MetroDialogBox::~MetroDialogBox() {
|
| + DVLOG(1) << __FUNCTION__;
|
| +}
|
| +
|
| +void MetroDialogBox::Show(
|
| + const DialogBoxInfo& dialog_box_info) {
|
| + DVLOG(1) << __FUNCTION__;
|
| +
|
| + // Only one dialog can be displayed at a given time.
|
| + DCHECK(dialog_box_.Get() == NULL);
|
| +
|
| + // The message dialog display does not work correctly in snapped mode.
|
| + mswr::ComPtr<winui::Popups::IMessageDialogFactory> message_dialog_factory;
|
| + HRESULT hr = winrt_utils::CreateActivationFactory(
|
| + RuntimeClass_Windows_UI_Popups_MessageDialog,
|
| + message_dialog_factory.GetAddressOf());
|
| + CheckHR(hr, "Failed to activate IMessageDialogFactory");
|
| +
|
| + mswrw::HString message_title;
|
| + message_title.Attach(MakeHString(dialog_box_info.title));
|
| +
|
| + mswrw::HString message_content;
|
| + message_content.Attach(MakeHString(dialog_box_info.content));
|
| +
|
| + hr = message_dialog_factory->CreateWithTitle(
|
| + message_content.Get(),
|
| + message_title.Get(),
|
| + dialog_box_.GetAddressOf());
|
| + CheckHR(hr, "Failed to create message dialog");
|
| +
|
| + mswr::ComPtr<WindowsUICommands> commands;
|
| + hr = dialog_box_->get_Commands(commands.GetAddressOf());
|
| + CheckHR(hr, "Failed to create ui command collection");
|
| +
|
| + mswr::ComPtr<winui::Popups::IUICommandFactory> ui_command_factory;
|
| + hr = winrt_utils::CreateActivationFactory(
|
| + RuntimeClass_Windows_UI_Popups_UICommand,
|
| + ui_command_factory.GetAddressOf());
|
| + CheckHR(hr, "Failed to activate IUICommandFactory");
|
| +
|
| + mswrw::HString label1;
|
| + label1.Attach(MakeHString(dialog_box_info.button1_label));
|
| +
|
| + mswr::ComPtr<winui::Popups::IUICommand> label1_command;
|
| + hr = ui_command_factory->CreateWithHandler(
|
| + label1.Get(), this, label1_command.GetAddressOf());
|
| + CheckHR(hr, "Failed to add button1");
|
| +
|
| + mswrw::HString label2;
|
| + label2.Attach(MakeHString(dialog_box_info.button2_label));
|
| +
|
| + mswr::ComPtr<winui::Popups::IUICommand> label2_command;
|
| + hr = ui_command_factory->CreateWithHandler(label2.Get(), this,
|
| + label2_command.GetAddressOf());
|
| + CheckHR(hr, "Failed to add button2");
|
| +
|
| + commands->Append(label1_command.Get());
|
| + commands->Append(label2_command.Get());
|
| +
|
| + mswr::ComPtr<AsyncCommandStatus> ret;
|
| + hr = dialog_box_->ShowAsync(ret.GetAddressOf());
|
| + CheckHR(hr, "Failed to show dialog");
|
| +
|
| + dialog_box_info_ = dialog_box_info;
|
| +}
|
| +
|
| +// The dialog box displayed via the MessageDialog interface has the class name
|
| +// 'Shell_Dialog'. The dialog box is top level window. To find it we enumerate
|
| +// all top level windows and compare the class names. If we find a matching
|
| +// window class we compare its process id with ours and return the same.
|
| +BOOL CALLBACK DialogBoxFinder(HWND hwnd, LPARAM lparam) {
|
| + char classname[MAX_PATH] = {0};
|
| +
|
| + if (::GetClassNameA(hwnd, classname, ARRAYSIZE(classname))) {
|
| + if (lstrcmpiA("Shell_Dialog", classname) == 0) {
|
| + if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) {
|
| + DVLOG(1) << "Found top most dialog box: " << classname;
|
| + DVLOG(1) << "HWND: " << hwnd;
|
| + DWORD window_pid = 0;
|
| + DWORD window_tid = GetWindowThreadProcessId(hwnd, &window_pid);
|
| + DVLOG(1) << "Window tid: " << window_tid;
|
| + DVLOG(1) << "Window pid: " << window_pid;
|
| +
|
| + if (window_pid == ::GetCurrentProcessId()) {
|
| + HWND* dialog_window = reinterpret_cast<HWND*>(lparam);
|
| + *dialog_window = hwnd;
|
| + return FALSE;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return TRUE;
|
| +}
|
| +
|
| +void MetroDialogBox::Dismiss() {
|
| + DVLOG(1) << __FUNCTION__;
|
| + if (!dialog_box_)
|
| + return;
|
| +
|
| + dialog_box_info_.button1_handler = NULL;
|
| + dialog_box_info_.button2_handler = NULL;
|
| + dialog_box_info_.button1_label.clear();
|
| + dialog_box_info_.button2_label.clear();
|
| + dialog_box_.Reset();
|
| +
|
| + // We don't have a good way to dismiss the dialog box. Hack for now is to
|
| + // find the dialog box class in our process and close it via the WM_CLOSE
|
| + // message.
|
| + HWND dialog_box = NULL;
|
| + ::EnumWindows(&DialogBoxFinder, reinterpret_cast<LPARAM>(&dialog_box));
|
| + if (::IsWindow(dialog_box))
|
| + PostMessage(dialog_box, WM_CLOSE, 0, 0);
|
| +}
|
| +
|
| +HRESULT STDMETHODCALLTYPE MetroDialogBox::Invoke(
|
| + winui::Popups::IUICommand* command) {
|
| + DVLOG(1) << __FUNCTION__;
|
| +
|
| + mswrw::HString label;
|
| + command->get_Label(label.GetAddressOf());
|
| +
|
| + string16 button_label = MakeStdWString(label.Get());
|
| + DVLOG(1) << "Clicked button label is : " << button_label;
|
| + if (button_label == dialog_box_info_.button1_label) {
|
| + DVLOG(1) << "Button1 clicked";
|
| + DCHECK(dialog_box_info_.button1_handler);
|
| + dialog_box_info_.button1_handler();
|
| + } else if (button_label == dialog_box_info_.button2_label) {
|
| + DVLOG(1) << "Button2 clicked";
|
| + DCHECK(dialog_box_info_.button2_handler);
|
| + dialog_box_info_.button2_handler();
|
| + }
|
| + // The dialog box is destroyed once we return from invoke. Go ahead and
|
| + // dismiss it.
|
| + Dismiss();
|
| + return S_OK;
|
| +}
|
| +
|
|
|