OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "win8/metro_driver/stdafx.h" |
| 6 |
| 7 #include "win8/metro_driver/chrome_app_view.h" |
| 8 #include "win8/metro_driver/metro_dialog_box.h" |
| 9 #include "win8/metro_driver/winrt_utils.h" |
| 10 |
| 11 typedef winfoundtn::Collections:: |
| 12 IVector<ABI::Windows::UI::Popups::IUICommand*> WindowsUICommands; |
| 13 |
| 14 typedef winfoundtn::IAsyncOperation<ABI::Windows::UI::Popups::IUICommand*> |
| 15 AsyncCommandStatus; |
| 16 |
| 17 MetroDialogBox::MetroDialogBox() { |
| 18 DVLOG(1) << __FUNCTION__; |
| 19 dialog_box_info_.button1_handler = NULL; |
| 20 dialog_box_info_.button2_handler = NULL; |
| 21 } |
| 22 |
| 23 MetroDialogBox::~MetroDialogBox() { |
| 24 DVLOG(1) << __FUNCTION__; |
| 25 } |
| 26 |
| 27 void MetroDialogBox::Show( |
| 28 const DialogBoxInfo& dialog_box_info) { |
| 29 DVLOG(1) << __FUNCTION__; |
| 30 |
| 31 // Only one dialog can be displayed at a given time. |
| 32 DCHECK(dialog_box_.Get() == NULL); |
| 33 |
| 34 // The message dialog display does not work correctly in snapped mode. |
| 35 mswr::ComPtr<winui::Popups::IMessageDialogFactory> message_dialog_factory; |
| 36 HRESULT hr = winrt_utils::CreateActivationFactory( |
| 37 RuntimeClass_Windows_UI_Popups_MessageDialog, |
| 38 message_dialog_factory.GetAddressOf()); |
| 39 CheckHR(hr, "Failed to activate IMessageDialogFactory"); |
| 40 |
| 41 mswrw::HString message_title; |
| 42 message_title.Attach(MakeHString(dialog_box_info.title)); |
| 43 |
| 44 mswrw::HString message_content; |
| 45 message_content.Attach(MakeHString(dialog_box_info.content)); |
| 46 |
| 47 hr = message_dialog_factory->CreateWithTitle( |
| 48 message_content.Get(), |
| 49 message_title.Get(), |
| 50 dialog_box_.GetAddressOf()); |
| 51 CheckHR(hr, "Failed to create message dialog"); |
| 52 |
| 53 mswr::ComPtr<WindowsUICommands> commands; |
| 54 hr = dialog_box_->get_Commands(commands.GetAddressOf()); |
| 55 CheckHR(hr, "Failed to create ui command collection"); |
| 56 |
| 57 mswr::ComPtr<winui::Popups::IUICommandFactory> ui_command_factory; |
| 58 hr = winrt_utils::CreateActivationFactory( |
| 59 RuntimeClass_Windows_UI_Popups_UICommand, |
| 60 ui_command_factory.GetAddressOf()); |
| 61 CheckHR(hr, "Failed to activate IUICommandFactory"); |
| 62 |
| 63 mswrw::HString label1; |
| 64 label1.Attach(MakeHString(dialog_box_info.button1_label)); |
| 65 |
| 66 mswr::ComPtr<winui::Popups::IUICommand> label1_command; |
| 67 hr = ui_command_factory->CreateWithHandler( |
| 68 label1.Get(), this, label1_command.GetAddressOf()); |
| 69 CheckHR(hr, "Failed to add button1"); |
| 70 |
| 71 mswrw::HString label2; |
| 72 label2.Attach(MakeHString(dialog_box_info.button2_label)); |
| 73 |
| 74 mswr::ComPtr<winui::Popups::IUICommand> label2_command; |
| 75 hr = ui_command_factory->CreateWithHandler(label2.Get(), this, |
| 76 label2_command.GetAddressOf()); |
| 77 CheckHR(hr, "Failed to add button2"); |
| 78 |
| 79 commands->Append(label1_command.Get()); |
| 80 commands->Append(label2_command.Get()); |
| 81 |
| 82 mswr::ComPtr<AsyncCommandStatus> ret; |
| 83 hr = dialog_box_->ShowAsync(ret.GetAddressOf()); |
| 84 CheckHR(hr, "Failed to show dialog"); |
| 85 |
| 86 dialog_box_info_ = dialog_box_info; |
| 87 } |
| 88 |
| 89 // The dialog box displayed via the MessageDialog interface has the class name |
| 90 // 'Shell_Dialog'. The dialog box is top level window. To find it we enumerate |
| 91 // all top level windows and compare the class names. If we find a matching |
| 92 // window class we compare its process id with ours and return the same. |
| 93 BOOL CALLBACK DialogBoxFinder(HWND hwnd, LPARAM lparam) { |
| 94 char classname[MAX_PATH] = {0}; |
| 95 |
| 96 if (::GetClassNameA(hwnd, classname, ARRAYSIZE(classname))) { |
| 97 if (lstrcmpiA("Shell_Dialog", classname) == 0) { |
| 98 if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) { |
| 99 DVLOG(1) << "Found top most dialog box: " << classname; |
| 100 DVLOG(1) << "HWND: " << hwnd; |
| 101 DWORD window_pid = 0; |
| 102 DWORD window_tid = GetWindowThreadProcessId(hwnd, &window_pid); |
| 103 DVLOG(1) << "Window tid: " << window_tid; |
| 104 DVLOG(1) << "Window pid: " << window_pid; |
| 105 |
| 106 if (window_pid == ::GetCurrentProcessId()) { |
| 107 HWND* dialog_window = reinterpret_cast<HWND*>(lparam); |
| 108 *dialog_window = hwnd; |
| 109 return FALSE; |
| 110 } |
| 111 } |
| 112 } |
| 113 } |
| 114 return TRUE; |
| 115 } |
| 116 |
| 117 void MetroDialogBox::Dismiss() { |
| 118 DVLOG(1) << __FUNCTION__; |
| 119 if (!dialog_box_) |
| 120 return; |
| 121 |
| 122 dialog_box_info_.button1_handler = NULL; |
| 123 dialog_box_info_.button2_handler = NULL; |
| 124 dialog_box_info_.button1_label.clear(); |
| 125 dialog_box_info_.button2_label.clear(); |
| 126 dialog_box_.Reset(); |
| 127 |
| 128 // We don't have a good way to dismiss the dialog box. Hack for now is to |
| 129 // find the dialog box class in our process and close it via the WM_CLOSE |
| 130 // message. |
| 131 HWND dialog_box = NULL; |
| 132 ::EnumWindows(&DialogBoxFinder, reinterpret_cast<LPARAM>(&dialog_box)); |
| 133 if (::IsWindow(dialog_box)) |
| 134 PostMessage(dialog_box, WM_CLOSE, 0, 0); |
| 135 } |
| 136 |
| 137 HRESULT STDMETHODCALLTYPE MetroDialogBox::Invoke( |
| 138 winui::Popups::IUICommand* command) { |
| 139 DVLOG(1) << __FUNCTION__; |
| 140 |
| 141 mswrw::HString label; |
| 142 command->get_Label(label.GetAddressOf()); |
| 143 |
| 144 string16 button_label = MakeStdWString(label.Get()); |
| 145 DVLOG(1) << "Clicked button label is : " << button_label; |
| 146 if (button_label == dialog_box_info_.button1_label) { |
| 147 DVLOG(1) << "Button1 clicked"; |
| 148 DCHECK(dialog_box_info_.button1_handler); |
| 149 dialog_box_info_.button1_handler(); |
| 150 } else if (button_label == dialog_box_info_.button2_label) { |
| 151 DVLOG(1) << "Button2 clicked"; |
| 152 DCHECK(dialog_box_info_.button2_handler); |
| 153 dialog_box_info_.button2_handler(); |
| 154 } |
| 155 // The dialog box is destroyed once we return from invoke. Go ahead and |
| 156 // dismiss it. |
| 157 Dismiss(); |
| 158 return S_OK; |
| 159 } |
| 160 |
OLD | NEW |