| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "views/window/window_win.h" | 5 #include "views/window/window_win.h" |
| 6 | 6 |
| 7 #include <shellapi.h> | 7 #include <shellapi.h> |
| 8 | 8 |
| 9 #include "app/gfx/chrome_canvas.h" | 9 #include "app/gfx/chrome_canvas.h" |
| 10 #include "app/gfx/chrome_font.h" | 10 #include "app/gfx/chrome_font.h" |
| 11 #include "app/gfx/icon_util.h" | 11 #include "app/gfx/icon_util.h" |
| 12 #include "app/gfx/path.h" | 12 #include "app/gfx/path.h" |
| 13 #include "app/l10n_util.h" | 13 #include "app/l10n_util.h" |
| 14 #include "app/resource_bundle.h" | 14 #include "app/resource_bundle.h" |
| 15 #include "app/win_util.h" | 15 #include "app/win_util.h" |
| 16 #include "base/win_util.h" | 16 #include "base/win_util.h" |
| 17 #include "chrome/app/chrome_dll_resource.h" | |
| 18 #include "grit/generated_resources.h" | 17 #include "grit/generated_resources.h" |
| 19 #include "views/widget/root_view.h" | 18 #include "views/widget/root_view.h" |
| 20 #include "views/window/client_view.h" | 19 #include "views/window/client_view.h" |
| 21 #include "views/window/custom_frame_view.h" | 20 #include "views/window/custom_frame_view.h" |
| 22 #include "views/window/native_frame_view.h" | 21 #include "views/window/native_frame_view.h" |
| 23 #include "views/window/non_client_view.h" | 22 #include "views/window/non_client_view.h" |
| 24 #include "views/window/window_delegate.h" | 23 #include "views/window/window_delegate.h" |
| 25 | 24 |
| 26 namespace { | 25 namespace { |
| 27 | 26 |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 if (old_icon) | 393 if (old_icon) |
| 395 DestroyIcon(old_icon); | 394 DestroyIcon(old_icon); |
| 396 old_icon = reinterpret_cast<HICON>( | 395 old_icon = reinterpret_cast<HICON>( |
| 397 SendMessage(GetNativeView(), WM_SETICON, ICON_BIG, | 396 SendMessage(GetNativeView(), WM_SETICON, ICON_BIG, |
| 398 reinterpret_cast<LPARAM>(windows_icon))); | 397 reinterpret_cast<LPARAM>(windows_icon))); |
| 399 if (old_icon) | 398 if (old_icon) |
| 400 DestroyIcon(old_icon); | 399 DestroyIcon(old_icon); |
| 401 } | 400 } |
| 402 } | 401 } |
| 403 | 402 |
| 403 void WindowWin::SetIsAlwaysOnTop(bool always_on_top) { |
| 404 ::SetWindowPos(GetNativeView(), |
| 405 always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, |
| 406 0, 0, 0, 0, |
| 407 SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); |
| 408 } |
| 409 |
| 404 NonClientFrameView* WindowWin::CreateFrameViewForWindow() { | 410 NonClientFrameView* WindowWin::CreateFrameViewForWindow() { |
| 405 if (non_client_view_->UseNativeFrame()) | 411 if (non_client_view_->UseNativeFrame()) |
| 406 return new NativeFrameView(this); | 412 return new NativeFrameView(this); |
| 407 return new CustomFrameView(this); | 413 return new CustomFrameView(this); |
| 408 } | 414 } |
| 409 | 415 |
| 410 void WindowWin::UpdateFrameAfterFrameChange() { | 416 void WindowWin::UpdateFrameAfterFrameChange() { |
| 411 // We've either gained or lost a custom window region, so reset it now. | 417 // We've either gained or lost a custom window region, so reset it now. |
| 412 ResetWindowRegion(true); | 418 ResetWindowRegion(true); |
| 413 } | 419 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 433 | 439 |
| 434 WindowWin::WindowWin(WindowDelegate* window_delegate) | 440 WindowWin::WindowWin(WindowDelegate* window_delegate) |
| 435 : WidgetWin(), | 441 : WidgetWin(), |
| 436 focus_on_creation_(true), | 442 focus_on_creation_(true), |
| 437 window_delegate_(window_delegate), | 443 window_delegate_(window_delegate), |
| 438 non_client_view_(new NonClientView(this)), | 444 non_client_view_(new NonClientView(this)), |
| 439 owning_hwnd_(NULL), | 445 owning_hwnd_(NULL), |
| 440 minimum_size_(100, 100), | 446 minimum_size_(100, 100), |
| 441 is_modal_(false), | 447 is_modal_(false), |
| 442 restored_enabled_(false), | 448 restored_enabled_(false), |
| 443 is_always_on_top_(false), | |
| 444 fullscreen_(false), | 449 fullscreen_(false), |
| 445 window_closed_(false), | 450 window_closed_(false), |
| 446 disable_inactive_rendering_(false), | 451 disable_inactive_rendering_(false), |
| 447 is_active_(false), | 452 is_active_(false), |
| 448 lock_updates_(false), | 453 lock_updates_(false), |
| 449 saved_window_style_(0), | 454 saved_window_style_(0), |
| 450 saved_maximized_state_(0), | 455 saved_maximized_state_(0), |
| 451 ignore_window_pos_changes_(false), | 456 ignore_window_pos_changes_(false), |
| 452 ignore_pos_changes_factory_(this), | 457 ignore_pos_changes_factory_(this), |
| 453 force_hidden_count_(0), | 458 force_hidden_count_(0), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 464 | 469 |
| 465 void WindowWin::Init(HWND parent, const gfx::Rect& bounds) { | 470 void WindowWin::Init(HWND parent, const gfx::Rect& bounds) { |
| 466 // We need to save the parent window, since later calls to GetParent() will | 471 // We need to save the parent window, since later calls to GetParent() will |
| 467 // return NULL. | 472 // return NULL. |
| 468 owning_hwnd_ = parent; | 473 owning_hwnd_ = parent; |
| 469 // We call this after initializing our members since our implementations of | 474 // We call this after initializing our members since our implementations of |
| 470 // assorted WidgetWin functions may be called during initialization. | 475 // assorted WidgetWin functions may be called during initialization. |
| 471 is_modal_ = window_delegate_->IsModal(); | 476 is_modal_ = window_delegate_->IsModal(); |
| 472 if (is_modal_) | 477 if (is_modal_) |
| 473 BecomeModal(); | 478 BecomeModal(); |
| 474 is_always_on_top_ = window_delegate_->IsAlwaysOnTop(); | |
| 475 | 479 |
| 476 if (window_style() == 0) | 480 if (window_style() == 0) |
| 477 set_window_style(CalculateWindowStyle()); | 481 set_window_style(CalculateWindowStyle()); |
| 478 if (window_ex_style() == 0) | 482 if (window_ex_style() == 0) |
| 479 set_window_ex_style(CalculateWindowExStyle()); | 483 set_window_ex_style(CalculateWindowExStyle()); |
| 480 | 484 |
| 481 WidgetWin::Init(parent, bounds, true); | 485 WidgetWin::Init(parent, bounds, true); |
| 482 win_util::SetWindowUserData(GetNativeView(), this); | 486 win_util::SetWindowUserData(GetNativeView(), this); |
| 483 | 487 |
| 484 // Create the ClientView, add it to the NonClientView and add the | 488 // Create the ClientView, add it to the NonClientView and add the |
| 485 // NonClientView to the RootView. This will cause everything to be parented. | 489 // NonClientView to the RootView. This will cause everything to be parented. |
| 486 non_client_view_->set_client_view(window_delegate_->CreateClientView(this)); | 490 non_client_view_->set_client_view(window_delegate_->CreateClientView(this)); |
| 487 WidgetWin::SetContentsView(non_client_view_); | 491 WidgetWin::SetContentsView(non_client_view_); |
| 488 | 492 |
| 489 UpdateWindowTitle(); | 493 UpdateWindowTitle(); |
| 490 | 494 |
| 491 SetInitialBounds(bounds); | 495 SetInitialBounds(bounds); |
| 492 InitAlwaysOnTopState(); | |
| 493 | 496 |
| 494 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, | 497 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, |
| 495 &last_work_area_); | 498 &last_work_area_); |
| 496 ResetWindowRegion(false); | 499 ResetWindowRegion(false); |
| 497 } | 500 } |
| 498 | 501 |
| 499 void WindowWin::SizeWindowToDefault() { | 502 void WindowWin::SizeWindowToDefault() { |
| 500 win_util::CenterAndSizeWindow(owning_window(), GetNativeView(), | 503 win_util::CenterAndSizeWindow(owning_window(), GetNativeView(), |
| 501 non_client_view_->GetPreferredSize().ToSIZE(), | 504 non_client_view_->GetPreferredSize().ToSIZE(), |
| 502 false); | 505 false); |
| (...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 // sizing/moving feedback can be continuous. | 1052 // sizing/moving feedback can be continuous. |
| 1050 UnlockUpdates(); | 1053 UnlockUpdates(); |
| 1051 } | 1054 } |
| 1052 } | 1055 } |
| 1053 } | 1056 } |
| 1054 | 1057 |
| 1055 // First see if the delegate can handle it. | 1058 // First see if the delegate can handle it. |
| 1056 if (window_delegate_->ExecuteWindowsCommand(notification_code)) | 1059 if (window_delegate_->ExecuteWindowsCommand(notification_code)) |
| 1057 return; | 1060 return; |
| 1058 | 1061 |
| 1059 if (notification_code == IDC_ALWAYS_ON_TOP) { | 1062 if ((notification_code == SC_KEYMENU) && (click.x == VK_SPACE)) { |
| 1060 is_always_on_top_ = !is_always_on_top_; | |
| 1061 | |
| 1062 // Change the menu check state. | |
| 1063 HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE); | |
| 1064 MENUITEMINFO menu_info; | |
| 1065 memset(&menu_info, 0, sizeof(MENUITEMINFO)); | |
| 1066 menu_info.cbSize = sizeof(MENUITEMINFO); | |
| 1067 BOOL r = GetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, | |
| 1068 FALSE, &menu_info); | |
| 1069 DCHECK(r); | |
| 1070 menu_info.fMask = MIIM_STATE; | |
| 1071 if (is_always_on_top_) | |
| 1072 menu_info.fState = MFS_CHECKED; | |
| 1073 r = SetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, FALSE, &menu_info); | |
| 1074 | |
| 1075 // Now change the actual window's behavior. | |
| 1076 AlwaysOnTopChanged(); | |
| 1077 } else if ((notification_code == SC_KEYMENU) && (click.x == VK_SPACE)) { | |
| 1078 // Run the system menu at the NonClientView's desired location. | 1063 // Run the system menu at the NonClientView's desired location. |
| 1079 RunSystemMenu(non_client_view_->GetSystemMenuPoint()); | 1064 RunSystemMenu(non_client_view_->GetSystemMenuPoint()); |
| 1080 } else { | 1065 } else { |
| 1081 // Use the default implementation for any other command. | 1066 // Use the default implementation for any other command. |
| 1082 DefWindowProc(GetNativeView(), WM_SYSCOMMAND, notification_code, | 1067 DefWindowProc(GetNativeView(), WM_SYSCOMMAND, notification_code, |
| 1083 MAKELPARAM(click.y, click.x)); | 1068 MAKELPARAM(click.y, click.x)); |
| 1084 } | 1069 } |
| 1085 } | 1070 } |
| 1086 | 1071 |
| 1087 void WindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) { | 1072 void WindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) { |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1222 // No initial bounds supplied, so size the window to its content and | 1207 // No initial bounds supplied, so size the window to its content and |
| 1223 // center over its parent. | 1208 // center over its parent. |
| 1224 SizeWindowToDefault(); | 1209 SizeWindowToDefault(); |
| 1225 } else { | 1210 } else { |
| 1226 // Use the supplied initial bounds. | 1211 // Use the supplied initial bounds. |
| 1227 SetBounds(create_bounds); | 1212 SetBounds(create_bounds); |
| 1228 } | 1213 } |
| 1229 } | 1214 } |
| 1230 } | 1215 } |
| 1231 | 1216 |
| 1232 void WindowWin::InitAlwaysOnTopState() { | |
| 1233 is_always_on_top_ = false; | |
| 1234 if (window_delegate_->GetSavedAlwaysOnTopState(&is_always_on_top_) && | |
| 1235 is_always_on_top_ != window_delegate_->IsAlwaysOnTop()) { | |
| 1236 AlwaysOnTopChanged(); | |
| 1237 } | |
| 1238 | |
| 1239 if (window_delegate_->HasAlwaysOnTopMenu()) | |
| 1240 AddAlwaysOnTopSystemMenuItem(); | |
| 1241 } | |
| 1242 | |
| 1243 void WindowWin::AddAlwaysOnTopSystemMenuItem() { | |
| 1244 // The Win32 API requires that we own the text. | |
| 1245 always_on_top_menu_text_ = l10n_util::GetString(IDS_ALWAYS_ON_TOP); | |
| 1246 | |
| 1247 // Let's insert a menu to the window. | |
| 1248 HMENU system_menu = ::GetSystemMenu(GetNativeView(), FALSE); | |
| 1249 int index = ::GetMenuItemCount(system_menu) - 1; | |
| 1250 if (index < 0) { | |
| 1251 // Paranoia check. | |
| 1252 NOTREACHED(); | |
| 1253 index = 0; | |
| 1254 } | |
| 1255 // First we add the separator. | |
| 1256 MENUITEMINFO menu_info; | |
| 1257 memset(&menu_info, 0, sizeof(MENUITEMINFO)); | |
| 1258 menu_info.cbSize = sizeof(MENUITEMINFO); | |
| 1259 menu_info.fMask = MIIM_FTYPE; | |
| 1260 menu_info.fType = MFT_SEPARATOR; | |
| 1261 ::InsertMenuItem(system_menu, index, TRUE, &menu_info); | |
| 1262 | |
| 1263 // Then the actual menu. | |
| 1264 menu_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_STATE; | |
| 1265 menu_info.fType = MFT_STRING; | |
| 1266 menu_info.fState = MFS_ENABLED; | |
| 1267 if (is_always_on_top_) | |
| 1268 menu_info.fState |= MFS_CHECKED; | |
| 1269 menu_info.wID = IDC_ALWAYS_ON_TOP; | |
| 1270 menu_info.dwTypeData = const_cast<wchar_t*>(always_on_top_menu_text_.c_str()); | |
| 1271 ::InsertMenuItem(system_menu, index, TRUE, &menu_info); | |
| 1272 } | |
| 1273 | |
| 1274 void WindowWin::RestoreEnabledIfNecessary() { | 1217 void WindowWin::RestoreEnabledIfNecessary() { |
| 1275 if (is_modal_ && !restored_enabled_) { | 1218 if (is_modal_ && !restored_enabled_) { |
| 1276 restored_enabled_ = true; | 1219 restored_enabled_ = true; |
| 1277 // If we were run modally, we need to undo the disabled-ness we inflicted on | 1220 // If we were run modally, we need to undo the disabled-ness we inflicted on |
| 1278 // the owner's parent hierarchy. | 1221 // the owner's parent hierarchy. |
| 1279 HWND start = owning_hwnd_; | 1222 HWND start = owning_hwnd_; |
| 1280 while (start != NULL) { | 1223 while (start != NULL) { |
| 1281 ::EnableWindow(start, TRUE); | 1224 ::EnableWindow(start, TRUE); |
| 1282 start = ::GetParent(start); | 1225 start = ::GetParent(start); |
| 1283 } | 1226 } |
| 1284 } | 1227 } |
| 1285 } | 1228 } |
| 1286 | 1229 |
| 1287 void WindowWin::AlwaysOnTopChanged() { | |
| 1288 ::SetWindowPos(GetNativeView(), | |
| 1289 is_always_on_top_ ? HWND_TOPMOST : HWND_NOTOPMOST, | |
| 1290 0, 0, 0, 0, | |
| 1291 SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); | |
| 1292 } | |
| 1293 | |
| 1294 DWORD WindowWin::CalculateWindowStyle() { | 1230 DWORD WindowWin::CalculateWindowStyle() { |
| 1295 DWORD window_styles = | 1231 DWORD window_styles = |
| 1296 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_SYSMENU | WS_CAPTION; | 1232 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_SYSMENU | WS_CAPTION; |
| 1297 bool can_resize = window_delegate_->CanResize(); | 1233 bool can_resize = window_delegate_->CanResize(); |
| 1298 bool can_maximize = window_delegate_->CanMaximize(); | 1234 bool can_maximize = window_delegate_->CanMaximize(); |
| 1299 if (can_maximize) { | 1235 if (can_maximize) { |
| 1300 window_styles |= WS_OVERLAPPEDWINDOW; | 1236 window_styles |= WS_OVERLAPPEDWINDOW; |
| 1301 } else if (can_resize) { | 1237 } else if (can_resize) { |
| 1302 window_styles |= WS_OVERLAPPED | WS_THICKFRAME; | 1238 window_styles |= WS_OVERLAPPED | WS_THICKFRAME; |
| 1303 } | 1239 } |
| 1304 if (window_delegate_->AsDialogDelegate()) { | 1240 if (window_delegate_->AsDialogDelegate()) { |
| 1305 window_styles |= DS_MODALFRAME; | 1241 window_styles |= DS_MODALFRAME; |
| 1306 // NOTE: Turning this off means we lose the close button, which is bad. | 1242 // NOTE: Turning this off means we lose the close button, which is bad. |
| 1307 // Turning it on though means the user can maximize or size the window | 1243 // Turning it on though means the user can maximize or size the window |
| 1308 // from the system menu, which is worse. We may need to provide our own | 1244 // from the system menu, which is worse. We may need to provide our own |
| 1309 // menu to get the close button to appear properly. | 1245 // menu to get the close button to appear properly. |
| 1310 // window_styles &= ~WS_SYSMENU; | 1246 // window_styles &= ~WS_SYSMENU; |
| 1311 } | 1247 } |
| 1312 return window_styles; | 1248 return window_styles; |
| 1313 } | 1249 } |
| 1314 | 1250 |
| 1315 DWORD WindowWin::CalculateWindowExStyle() { | 1251 DWORD WindowWin::CalculateWindowExStyle() { |
| 1316 DWORD window_ex_styles = 0; | 1252 DWORD window_ex_styles = 0; |
| 1317 if (window_delegate_->AsDialogDelegate()) | 1253 if (window_delegate_->AsDialogDelegate()) |
| 1318 window_ex_styles |= WS_EX_DLGMODALFRAME; | 1254 window_ex_styles |= WS_EX_DLGMODALFRAME; |
| 1319 if (window_delegate_->IsAlwaysOnTop()) | |
| 1320 window_ex_styles |= WS_EX_TOPMOST; | |
| 1321 return window_ex_styles; | 1255 return window_ex_styles; |
| 1322 } | 1256 } |
| 1323 | 1257 |
| 1324 void WindowWin::SaveWindowPosition() { | 1258 void WindowWin::SaveWindowPosition() { |
| 1325 // The window delegate does the actual saving for us. It seems like (judging | 1259 // The window delegate does the actual saving for us. It seems like (judging |
| 1326 // by go/crash) that in some circumstances we can end up here after | 1260 // by go/crash) that in some circumstances we can end up here after |
| 1327 // WM_DESTROY, at which point the window delegate is likely gone. So just | 1261 // WM_DESTROY, at which point the window delegate is likely gone. So just |
| 1328 // bail. | 1262 // bail. |
| 1329 if (!window_delegate_) | 1263 if (!window_delegate_) |
| 1330 return; | 1264 return; |
| 1331 | 1265 |
| 1332 WINDOWPLACEMENT win_placement = { 0 }; | 1266 WINDOWPLACEMENT win_placement = { 0 }; |
| 1333 win_placement.length = sizeof(WINDOWPLACEMENT); | 1267 win_placement.length = sizeof(WINDOWPLACEMENT); |
| 1334 | 1268 |
| 1335 BOOL r = GetWindowPlacement(GetNativeView(), &win_placement); | 1269 BOOL r = GetWindowPlacement(GetNativeView(), &win_placement); |
| 1336 DCHECK(r); | 1270 DCHECK(r); |
| 1337 | 1271 |
| 1338 bool maximized = (win_placement.showCmd == SW_SHOWMAXIMIZED); | 1272 bool maximized = (win_placement.showCmd == SW_SHOWMAXIMIZED); |
| 1339 CRect window_bounds(win_placement.rcNormalPosition); | 1273 CRect window_bounds(win_placement.rcNormalPosition); |
| 1340 window_delegate_->SaveWindowPlacement( | 1274 window_delegate_->SaveWindowPlacement( |
| 1341 gfx::Rect(win_placement.rcNormalPosition), maximized, is_always_on_top_); | 1275 gfx::Rect(win_placement.rcNormalPosition), maximized); |
| 1342 } | 1276 } |
| 1343 | 1277 |
| 1344 void WindowWin::LockUpdates() { | 1278 void WindowWin::LockUpdates() { |
| 1345 lock_updates_ = true; | 1279 lock_updates_ = true; |
| 1346 saved_window_style_ = GetWindowLong(GWL_STYLE); | 1280 saved_window_style_ = GetWindowLong(GWL_STYLE); |
| 1347 SetWindowLong(GWL_STYLE, saved_window_style_ & ~WS_VISIBLE); | 1281 SetWindowLong(GWL_STYLE, saved_window_style_ & ~WS_VISIBLE); |
| 1348 } | 1282 } |
| 1349 | 1283 |
| 1350 void WindowWin::UnlockUpdates() { | 1284 void WindowWin::UnlockUpdates() { |
| 1351 SetWindowLong(GWL_STYLE, saved_window_style_); | 1285 SetWindowLong(GWL_STYLE, saved_window_style_); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1437 } | 1371 } |
| 1438 return TRUE; | 1372 return TRUE; |
| 1439 } | 1373 } |
| 1440 } // namespace | 1374 } // namespace |
| 1441 | 1375 |
| 1442 void Window::CloseAllSecondaryWindows() { | 1376 void Window::CloseAllSecondaryWindows() { |
| 1443 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); | 1377 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); |
| 1444 } | 1378 } |
| 1445 | 1379 |
| 1446 } // namespace views | 1380 } // namespace views |
| OLD | NEW |