| OLD | NEW |
| (Empty) |
| 1 // Copyright 2007-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 | |
| 16 | |
| 17 #include "omaha/ui/ui.h" | |
| 18 #include "base/basictypes.h" | |
| 19 #include "omaha/base/constants.h" | |
| 20 #include "omaha/base/debug.h" | |
| 21 #include "omaha/base/error.h" | |
| 22 #include "omaha/base/logging.h" | |
| 23 #include "omaha/base/system_info.h" | |
| 24 #include "omaha/base/window_utils.h" | |
| 25 #include "omaha/client/client_utils.h" | |
| 26 #include "omaha/google_update/resource.h" // For the IDI_APP | |
| 27 #include "omaha/ui/ui_displayed_event.h" | |
| 28 #include "omaha/ui/ui_metrics.h" | |
| 29 | |
| 30 namespace omaha { | |
| 31 | |
| 32 const OmahaWnd::ControlAttributes OmahaWnd::kVisibleTextAttributes = | |
| 33 { true, true, false, false }; | |
| 34 const OmahaWnd::ControlAttributes OmahaWnd::kDefaultActiveButtonAttributes = | |
| 35 { true, true, true, true }; | |
| 36 const OmahaWnd::ControlAttributes OmahaWnd::kNonDefaultActiveButtonAttributes = | |
| 37 { true, true, true, false }; | |
| 38 const OmahaWnd::ControlAttributes OmahaWnd::kVisibleImageAttributes = | |
| 39 { true, false, false, false }; | |
| 40 const OmahaWnd::ControlAttributes OmahaWnd::kDisabledNonButtonAttributes = | |
| 41 { false, false, false, false }; | |
| 42 | |
| 43 OmahaWnd::OmahaWnd(int dialog_id, CMessageLoop* message_loop, HWND parent) | |
| 44 : IDD(dialog_id), | |
| 45 message_loop_(message_loop), | |
| 46 parent_(parent), | |
| 47 thread_id_(::GetCurrentThreadId()), | |
| 48 is_complete_(false), | |
| 49 is_close_enabled_(true), | |
| 50 events_sink_(NULL), | |
| 51 is_machine_(false) { | |
| 52 ASSERT1(message_loop); | |
| 53 CORE_LOG(L3, (_T("[OmahaWnd::OmahaWnd]"))); | |
| 54 } | |
| 55 | |
| 56 OmahaWnd::~OmahaWnd() { | |
| 57 CORE_LOG(L3, (_T("[OmahaWnd::~OmahaWnd]"))); | |
| 58 ASSERT1(thread_id_ == ::GetCurrentThreadId()); | |
| 59 ASSERT1(!IsWindow()); | |
| 60 } | |
| 61 | |
| 62 HRESULT OmahaWnd::Initialize() { | |
| 63 CORE_LOG(L3, (_T("[OmahaWnd::Initialize]"))); | |
| 64 ASSERT1(thread_id_ == ::GetCurrentThreadId()); | |
| 65 | |
| 66 if (!Create(parent_)) { | |
| 67 CORE_LOG(LEVEL_ERROR, (_T("[Failed to create the window]"))); | |
| 68 return GOOPDATE_E_UI_INTERNAL_ERROR; | |
| 69 } | |
| 70 VERIFY1(message_loop_->AddMessageFilter(this)); | |
| 71 | |
| 72 return S_OK; | |
| 73 } | |
| 74 | |
| 75 void OmahaWnd::InitializeDialog() { // NOLINT | |
| 76 CORE_LOG(L3, (_T("[OmahaWnd::InitializeDialog]"))); | |
| 77 | |
| 78 VERIFY1(SetWindowText(client_utils::GetInstallerDisplayName(bundle_name_))); | |
| 79 | |
| 80 VERIFY1(CenterWindow(NULL)); | |
| 81 VERIFY1(SUCCEEDED(WindowUtils::SetWindowIcon(m_hWnd, | |
| 82 IDI_APP, | |
| 83 address(hicon_)))); | |
| 84 } | |
| 85 | |
| 86 LRESULT OmahaWnd::OnClose(UINT, | |
| 87 WPARAM, | |
| 88 LPARAM, | |
| 89 BOOL& handled) { // NOLINT | |
| 90 CORE_LOG(L3, (_T("[OmahaWnd::OnClose]"))); | |
| 91 | |
| 92 ++metric_worker_ui_click_x; | |
| 93 | |
| 94 MaybeCloseWindow(); | |
| 95 handled = true; | |
| 96 return 0; | |
| 97 } | |
| 98 | |
| 99 HRESULT OmahaWnd::CloseWindow() { | |
| 100 HRESULT hr = DestroyWindow() ? S_OK : HRESULTFromLastError(); | |
| 101 if (events_sink_) { | |
| 102 events_sink_->DoClose(); | |
| 103 } | |
| 104 return hr; | |
| 105 } | |
| 106 | |
| 107 void OmahaWnd::MaybeRequestExitProcess() { | |
| 108 CORE_LOG(L3, (_T("[OmahaWnd::MaybeRequestExitProcess]"))); | |
| 109 if (!is_complete_) { | |
| 110 return; | |
| 111 } | |
| 112 | |
| 113 RequestExitProcess(); | |
| 114 } | |
| 115 | |
| 116 void OmahaWnd::RequestExitProcess() { | |
| 117 CORE_LOG(L3, (_T("[OmahaWnd::RequestExitProcess]"))); | |
| 118 | |
| 119 if (events_sink_) { | |
| 120 events_sink_->DoExit(); | |
| 121 } | |
| 122 } | |
| 123 | |
| 124 LRESULT OmahaWnd::OnNCDestroy(UINT, WPARAM, LPARAM, BOOL& handled) { // NOLINT | |
| 125 CORE_LOG(L3, (_T("[OmahaWnd::OnNCDestroy]"))); | |
| 126 VERIFY1(message_loop_->RemoveMessageFilter(this)); | |
| 127 MaybeRequestExitProcess(); | |
| 128 handled = false; // Let ATL default processing handle the WM_NCDESTROY. | |
| 129 return 0; | |
| 130 } | |
| 131 | |
| 132 // Called when esc key is hit. | |
| 133 // If close is disabled, does nothing because we don't want the window to close. | |
| 134 LRESULT OmahaWnd::OnCancel(WORD, WORD id, HWND, BOOL& handled) { // NOLINT | |
| 135 VERIFY1(id == IDCANCEL); | |
| 136 | |
| 137 if (!is_close_enabled_) { | |
| 138 return 0; | |
| 139 } | |
| 140 | |
| 141 ++metric_worker_ui_esc_key_total; | |
| 142 MaybeCloseWindow(); | |
| 143 handled = true; | |
| 144 return 0; | |
| 145 } | |
| 146 | |
| 147 void OmahaWnd::Show() { | |
| 148 CORE_LOG(L3, (_T("[OmahaWnd::Show]"))); | |
| 149 ASSERT1(thread_id_ == ::GetCurrentThreadId()); | |
| 150 if (!IsWindow() || IsWindowVisible()) { | |
| 151 return; | |
| 152 } | |
| 153 | |
| 154 CenterWindow(NULL); | |
| 155 SetVisible(true); | |
| 156 | |
| 157 if (!::SetForegroundWindow(*this)) { | |
| 158 CORE_LOG(LW, (_T("[::SetForegroundWindow failed %d]"), ::GetLastError())); | |
| 159 } | |
| 160 | |
| 161 UIDisplayedEventManager::SignalEvent(is_machine_); | |
| 162 } | |
| 163 | |
| 164 bool OmahaWnd::OnComplete() { | |
| 165 CORE_LOG(L3, (_T("[OmahaWnd::OnComplete]"))); | |
| 166 ASSERT1(thread_id_ == ::GetCurrentThreadId()); | |
| 167 | |
| 168 if (!IsWindow()) { | |
| 169 RequestExitProcess(); | |
| 170 return false; | |
| 171 } | |
| 172 | |
| 173 is_complete_ = true; | |
| 174 | |
| 175 VERIFY1(SUCCEEDED(EnableClose(true))); | |
| 176 | |
| 177 return true; | |
| 178 } | |
| 179 | |
| 180 void OmahaWnd::SetControlAttributes(int control_id, | |
| 181 const ControlAttributes& attributes) { | |
| 182 HWND hwnd = GetDlgItem(control_id); | |
| 183 ASSERT1(hwnd); | |
| 184 ::ShowWindow(hwnd, attributes.is_visible_ ? SW_SHOW : SW_HIDE); | |
| 185 ::EnableWindow(hwnd, attributes.is_enabled_ ? true : false); | |
| 186 if (attributes.is_button_ && attributes.is_default_) { | |
| 187 // We ask the dialog manager to give the default push button the focus, so | |
| 188 // for instance the <Enter> key works as expected. | |
| 189 GotoDlgCtrl(hwnd); | |
| 190 LONG style = ::GetWindowLong(hwnd, GWL_STYLE); | |
| 191 if (style) { | |
| 192 style |= BS_DEFPUSHBUTTON; | |
| 193 ::SetWindowLong(hwnd, GWL_STYLE, style); | |
| 194 } | |
| 195 } | |
| 196 } | |
| 197 | |
| 198 HRESULT OmahaWnd::EnableClose(bool enable) { | |
| 199 is_close_enabled_ = enable; | |
| 200 return EnableSystemCloseButton(is_close_enabled_); | |
| 201 } | |
| 202 | |
| 203 HRESULT OmahaWnd::EnableSystemCloseButton(bool enable) { | |
| 204 HMENU menu = ::GetSystemMenu(*this, false); | |
| 205 ASSERT1(menu); | |
| 206 uint32 flags = MF_BYCOMMAND; | |
| 207 flags |= enable ? MF_ENABLED : MF_GRAYED; | |
| 208 VERIFY1(::EnableMenuItem(menu, SC_CLOSE, flags) != -1); | |
| 209 return S_OK; | |
| 210 } | |
| 211 | |
| 212 // For the InitCommonControlsEx call to succeed on XP, a manifest is needed to | |
| 213 // declare "Microsoft.Windows.Common-Controls" as a dependent assembly. | |
| 214 // Further work may be needed to ensure W2K compatibility. | |
| 215 HRESULT InitializeCommonControls(DWORD control_classes) { | |
| 216 INITCOMMONCONTROLSEX init_ctrls = { sizeof(INITCOMMONCONTROLSEX), 0 }; | |
| 217 ASSERT1(init_ctrls.dwSize == sizeof(init_ctrls)); | |
| 218 init_ctrls.dwICC = control_classes; | |
| 219 if (!::InitCommonControlsEx(&init_ctrls)) { | |
| 220 // In the case of XP RTM and XP SP1, InitCommonControlsEx is failing but | |
| 221 // the UI initializes fine and works correctly. Because of this we only log | |
| 222 // the failure and do not error out. | |
| 223 const DWORD error = ::GetLastError(); | |
| 224 CORE_LOG(LEVEL_ERROR, (_T("[InitCommonControlsEx failed][%u]"), error)); | |
| 225 ASSERT1(ERROR_CLASS_ALREADY_EXISTS == error); | |
| 226 if (ERROR_CLASS_ALREADY_EXISTS != error) { | |
| 227 return HRESULT_FROM_WIN32(error); | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 return S_OK; | |
| 232 } | |
| 233 | |
| 234 } // namespace omaha | |
| OLD | NEW |