15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/stdafx.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/chrome_app_view.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/metro_dialog_box.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/winrt_utils.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef winfoundtn::Collections:: 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IVector<ABI::Windows::UI::Popups::IUICommand*> WindowsUICommands; 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef winfoundtn::IAsyncOperation<ABI::Windows::UI::Popups::IUICommand*> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsyncCommandStatus; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MetroDialogBox::MetroDialogBox() { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << __FUNCTION__; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_box_info_.button1_handler = NULL; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_box_info_.button2_handler = NULL; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MetroDialogBox::~MetroDialogBox() { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << __FUNCTION__; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MetroDialogBox::Show( 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DialogBoxInfo& dialog_box_info) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << __FUNCTION__; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only one dialog can be displayed at a given time. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(dialog_box_.Get() == NULL); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The message dialog display does not work correctly in snapped mode. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswr::ComPtr<winui::Popups::IMessageDialogFactory> message_dialog_factory; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = winrt_utils::CreateActivationFactory( 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RuntimeClass_Windows_UI_Popups_MessageDialog, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_dialog_factory.GetAddressOf()); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckHR(hr, "Failed to activate IMessageDialogFactory"); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswrw::HString message_title; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_title.Attach(MakeHString(dialog_box_info.title)); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswrw::HString message_content; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_content.Attach(MakeHString(dialog_box_info.content)); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = message_dialog_factory->CreateWithTitle( 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_content.Get(), 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_title.Get(), 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_box_.GetAddressOf()); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckHR(hr, "Failed to create message dialog"); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswr::ComPtr<WindowsUICommands> commands; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = dialog_box_->get_Commands(commands.GetAddressOf()); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckHR(hr, "Failed to create ui command collection"); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswr::ComPtr<winui::Popups::IUICommandFactory> ui_command_factory; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = winrt_utils::CreateActivationFactory( 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RuntimeClass_Windows_UI_Popups_UICommand, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_command_factory.GetAddressOf()); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckHR(hr, "Failed to activate IUICommandFactory"); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswrw::HString label1; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label1.Attach(MakeHString(dialog_box_info.button1_label)); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswr::ComPtr<winui::Popups::IUICommand> label1_command; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = ui_command_factory->CreateWithHandler( 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label1.Get(), this, label1_command.GetAddressOf()); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckHR(hr, "Failed to add button1"); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswrw::HString label2; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label2.Attach(MakeHString(dialog_box_info.button2_label)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswr::ComPtr<winui::Popups::IUICommand> label2_command; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = ui_command_factory->CreateWithHandler(label2.Get(), this, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label2_command.GetAddressOf()); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckHR(hr, "Failed to add button2"); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) commands->Append(label1_command.Get()); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) commands->Append(label2_command.Get()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswr::ComPtr<AsyncCommandStatus> ret; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = dialog_box_->ShowAsync(ret.GetAddressOf()); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckHR(hr, "Failed to show dialog"); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_box_info_ = dialog_box_info; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The dialog box displayed via the MessageDialog interface has the class name 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'Shell_Dialog'. The dialog box is top level window. To find it we enumerate 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// all top level windows and compare the class names. If we find a matching 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// window class we compare its process id with ours and return the same. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BOOL CALLBACK DialogBoxFinder(HWND hwnd, LPARAM lparam) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char classname[MAX_PATH] = {0}; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::GetClassNameA(hwnd, classname, ARRAYSIZE(classname))) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lstrcmpiA("Shell_Dialog", classname) == 0) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Found top most dialog box: " << classname; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "HWND: " << hwnd; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD window_pid = 0; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD window_tid = GetWindowThreadProcessId(hwnd, &window_pid); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Window tid: " << window_tid; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Window pid: " << window_pid; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_pid == ::GetCurrentProcessId()) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HWND* dialog_window = reinterpret_cast<HWND*>(lparam); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dialog_window = hwnd; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FALSE; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRUE; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MetroDialogBox::Dismiss() { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << __FUNCTION__; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dialog_box_) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_box_info_.button1_handler = NULL; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_box_info_.button2_handler = NULL; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_box_info_.button1_label.clear(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_box_info_.button2_label.clear(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_box_.Reset(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't have a good way to dismiss the dialog box. Hack for now is to 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // find the dialog box class in our process and close it via the WM_CLOSE 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HWND dialog_box = NULL; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::EnumWindows(&DialogBoxFinder, reinterpret_cast<LPARAM>(&dialog_box)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::IsWindow(dialog_box)) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostMessage(dialog_box, WM_CLOSE, 0, 0); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT STDMETHODCALLTYPE MetroDialogBox::Invoke( 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) winui::Popups::IUICommand* command) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << __FUNCTION__; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswrw::HString label; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command->get_Label(label.GetAddressOf()); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 button_label = MakeStdWString(label.Get()); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Clicked button label is : " << button_label; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (button_label == dialog_box_info_.button1_label) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Button1 clicked"; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(dialog_box_info_.button1_handler); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_box_info_.button1_handler(); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (button_label == dialog_box_info_.button2_label) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Button2 clicked"; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(dialog_box_info_.button2_handler); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_box_info_.button2_handler(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The dialog box is destroyed once we return from invoke. Go ahead and 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dismiss it. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dismiss(); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return S_OK; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 161