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 "chrome/views/window.h" | 5 #include "chrome/views/window.h" |
6 | 6 |
7 #include "base/win_util.h" | 7 #include "base/win_util.h" |
8 #include "chrome/app/chrome_dll_resource.h" | 8 #include "chrome/app/chrome_dll_resource.h" |
9 #include "chrome/common/gfx/chrome_font.h" | 9 #include "chrome/common/gfx/chrome_font.h" |
10 #include "chrome/common/gfx/icon_util.h" | 10 #include "chrome/common/gfx/icon_util.h" |
11 #include "chrome/common/gfx/path.h" | 11 #include "chrome/common/gfx/path.h" |
12 #include "chrome/common/l10n_util.h" | 12 #include "chrome/common/l10n_util.h" |
13 #include "chrome/common/notification_service.h" | 13 #include "chrome/common/notification_service.h" |
14 #include "chrome/common/pref_service.h" | 14 #include "chrome/common/pref_service.h" |
15 #include "chrome/common/resource_bundle.h" | 15 #include "chrome/common/resource_bundle.h" |
16 #include "chrome/common/win_util.h" | 16 #include "chrome/common/win_util.h" |
17 #include "chrome/views/client_view.h" | 17 #include "chrome/views/client_view.h" |
18 #include "chrome/views/custom_frame_window.h" | 18 #include "chrome/views/custom_frame_view.h" |
19 #include "chrome/views/default_non_client_view.h" | 19 #include "chrome/views/native_frame_view.h" |
20 #include "chrome/views/non_client_view.h" | 20 #include "chrome/views/non_client_view.h" |
21 #include "chrome/views/root_view.h" | 21 #include "chrome/views/root_view.h" |
22 #include "chrome/views/window_delegate.h" | 22 #include "chrome/views/window_delegate.h" |
23 #include "grit/generated_resources.h" | 23 #include "grit/generated_resources.h" |
24 | 24 |
25 namespace views { | 25 namespace views { |
26 | 26 |
27 // A scoping class that prevents a window from being able to redraw in response | 27 // A scoping class that prevents a window from being able to redraw in response |
28 // to invalidations that may occur within it for the lifetime of the object. | 28 // to invalidations that may occur within it for the lifetime of the object. |
29 // | 29 // |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 //////////////////////////////////////////////////////////////////////////////// | 74 //////////////////////////////////////////////////////////////////////////////// |
75 // Window, public: | 75 // Window, public: |
76 | 76 |
77 Window::~Window() { | 77 Window::~Window() { |
78 } | 78 } |
79 | 79 |
80 // static | 80 // static |
81 Window* Window::CreateChromeWindow(HWND parent, | 81 Window* Window::CreateChromeWindow(HWND parent, |
82 const gfx::Rect& bounds, | 82 const gfx::Rect& bounds, |
83 WindowDelegate* window_delegate) { | 83 WindowDelegate* window_delegate) { |
84 Window* window = NULL; | 84 Window* window = new Window(window_delegate); |
85 if (win_util::ShouldUseVistaFrame()) { | 85 window->non_client_view_->SetFrameView(window->CreateFrameViewForWindow()); |
86 window = new Window(window_delegate); | |
87 } else { | |
88 window = new CustomFrameWindow(window_delegate); | |
89 } | |
90 window->Init(parent, bounds); | 86 window->Init(parent, bounds); |
91 return window; | 87 return window; |
92 } | 88 } |
93 | 89 |
94 gfx::Size Window::CalculateMaximumSize() const { | 90 gfx::Size Window::CalculateMaximumSize() const { |
95 // If this is a top level window, the maximum size is the size of the working | 91 // If this is a top level window, the maximum size is the size of the working |
96 // rect of the display the window is on, less padding. If this is a child | 92 // rect of the display the window is on, less padding. If this is a child |
97 // (constrained) window, the maximum size of this Window are the bounds of the | 93 // (constrained) window, the maximum size of this Window are the bounds of the |
98 // parent window, less padding. | 94 // parent window, less padding. |
99 DCHECK(GetHWND()) << "Cannot calculate maximum size before Init() is called"; | 95 DCHECK(GetHWND()) << "Cannot calculate maximum size before Init() is called"; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 EnableMenuItem(GetSystemMenu(GetHWND(), false), | 193 EnableMenuItem(GetSystemMenu(GetHWND(), false), |
198 SC_CLOSE, enable ? MF_ENABLED : MF_GRAYED); | 194 SC_CLOSE, enable ? MF_ENABLED : MF_GRAYED); |
199 | 195 |
200 // Let the window know the frame changed. | 196 // Let the window know the frame changed. |
201 SetWindowPos(NULL, 0, 0, 0, 0, | 197 SetWindowPos(NULL, 0, 0, 0, 0, |
202 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | | 198 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | |
203 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | | 199 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | |
204 SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); | 200 SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); |
205 } | 201 } |
206 | 202 |
207 void Window::DisableInactiveRendering(bool disable) { | 203 void Window::DisableInactiveRendering() { |
208 disable_inactive_rendering_ = disable; | 204 disable_inactive_rendering_ = true; |
209 if (!disable_inactive_rendering_) | 205 non_client_view_->DisableInactiveRendering(disable_inactive_rendering_); |
210 DefWindowProc(GetHWND(), WM_NCACTIVATE, FALSE, 0); | |
211 | |
212 if (!non_client_view_->UseNativeFrame()) { | |
213 // If the non-client view is rendering its own frame, we need to forcibly | |
214 // schedule a paint so it updates when we unset this mode. | |
215 non_client_view_->set_paint_as_active(disable); | |
216 if (!disable) | |
217 non_client_view_->SchedulePaint(); | |
218 } | |
219 } | 206 } |
220 | 207 |
221 void Window::UpdateWindowTitle() { | 208 void Window::UpdateWindowTitle() { |
222 // If the non-client view is rendering its own title, it'll need to relayout | 209 // If the non-client view is rendering its own title, it'll need to relayout |
223 // now. | 210 // now. |
224 non_client_view_->Layout(); | 211 non_client_view_->Layout(); |
225 | 212 |
226 // Update the native frame's text. We do this regardless of whether or not | 213 // Update the native frame's text. We do this regardless of whether or not |
227 // the native frame is being used, since this also updates the taskbar, etc. | 214 // the native frame is being used, since this also updates the taskbar, etc. |
228 std::wstring window_title = window_delegate_->GetWindowTitle(); | 215 std::wstring window_title = window_delegate_->GetWindowTitle(); |
(...skipping 25 matching lines...) Expand all Loading... |
254 if (old_icon) | 241 if (old_icon) |
255 DestroyIcon(old_icon); | 242 DestroyIcon(old_icon); |
256 } | 243 } |
257 } | 244 } |
258 | 245 |
259 void Window::ExecuteSystemMenuCommand(int command) { | 246 void Window::ExecuteSystemMenuCommand(int command) { |
260 if (command) | 247 if (command) |
261 SendMessage(GetHWND(), WM_SYSCOMMAND, command, 0); | 248 SendMessage(GetHWND(), WM_SYSCOMMAND, command, 0); |
262 } | 249 } |
263 | 250 |
| 251 gfx::Rect Window::GetWindowBoundsForClientBounds( |
| 252 const gfx::Rect& client_bounds) { |
| 253 return non_client_view_->GetWindowBoundsForClientBounds(client_bounds); |
| 254 } |
| 255 |
264 // static | 256 // static |
265 int Window::GetLocalizedContentsWidth(int col_resource_id) { | 257 int Window::GetLocalizedContentsWidth(int col_resource_id) { |
266 double chars = _wtof(l10n_util::GetString(col_resource_id).c_str()); | 258 double chars = _wtof(l10n_util::GetString(col_resource_id).c_str()); |
267 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 259 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
268 ChromeFont font = rb.GetFont(ResourceBundle::BaseFont); | 260 ChromeFont font = rb.GetFont(ResourceBundle::BaseFont); |
269 int width = font.GetExpectedTextWidth(static_cast<int>(chars)); | 261 int width = font.GetExpectedTextWidth(static_cast<int>(chars)); |
270 DCHECK(width > 0); | 262 DCHECK(width > 0); |
271 return width; | 263 return width; |
272 } | 264 } |
273 | 265 |
(...skipping 27 matching lines...) Expand all Loading... |
301 Close(); | 293 Close(); |
302 } | 294 } |
303 | 295 |
304 /////////////////////////////////////////////////////////////////////////////// | 296 /////////////////////////////////////////////////////////////////////////////// |
305 // Window, protected: | 297 // Window, protected: |
306 | 298 |
307 Window::Window(WindowDelegate* window_delegate) | 299 Window::Window(WindowDelegate* window_delegate) |
308 : WidgetWin(), | 300 : WidgetWin(), |
309 focus_on_creation_(true), | 301 focus_on_creation_(true), |
310 window_delegate_(window_delegate), | 302 window_delegate_(window_delegate), |
311 non_client_view_(new NonClientView), | 303 non_client_view_(new NonClientView(this)), |
312 owning_hwnd_(NULL), | 304 owning_hwnd_(NULL), |
313 minimum_size_(100, 100), | 305 minimum_size_(100, 100), |
314 is_modal_(false), | 306 is_modal_(false), |
315 restored_enabled_(false), | 307 restored_enabled_(false), |
316 is_always_on_top_(false), | 308 is_always_on_top_(false), |
317 window_closed_(false), | 309 window_closed_(false), |
318 disable_inactive_rendering_(false), | 310 disable_inactive_rendering_(false), |
319 is_active_(false), | 311 is_active_(false), |
320 lock_updates_(false), | 312 lock_updates_(false), |
321 saved_window_style_(0), | 313 saved_window_style_(0), |
(...skipping 19 matching lines...) Expand all Loading... |
341 is_always_on_top_ = window_delegate_->IsAlwaysOnTop(); | 333 is_always_on_top_ = window_delegate_->IsAlwaysOnTop(); |
342 | 334 |
343 if (window_style() == 0) | 335 if (window_style() == 0) |
344 set_window_style(CalculateWindowStyle()); | 336 set_window_style(CalculateWindowStyle()); |
345 if (window_ex_style() == 0) | 337 if (window_ex_style() == 0) |
346 set_window_ex_style(CalculateWindowExStyle()); | 338 set_window_ex_style(CalculateWindowExStyle()); |
347 | 339 |
348 WidgetWin::Init(parent, bounds, true); | 340 WidgetWin::Init(parent, bounds, true); |
349 win_util::SetWindowUserData(GetHWND(), this); | 341 win_util::SetWindowUserData(GetHWND(), this); |
350 | 342 |
351 std::wstring window_title = window_delegate_->GetWindowTitle(); | 343 // Create the ClientView, add it to the NonClientView and add the |
352 std::wstring localized_text; | 344 // NonClientView to the RootView. This will cause everything to be parented. |
353 if (l10n_util::AdjustStringForLocaleDirection(window_title, &localized_text)) | 345 non_client_view_->set_client_view(window_delegate_->CreateClientView(this)); |
354 window_title.assign(localized_text); | 346 WidgetWin::SetContentsView(non_client_view_); |
355 SetWindowText(GetHWND(), window_title.c_str()); | |
356 | 347 |
357 SetClientView(window_delegate_->CreateClientView(this)); | 348 UpdateWindowTitle(); |
| 349 |
358 SetInitialBounds(bounds); | 350 SetInitialBounds(bounds); |
359 InitAlwaysOnTopState(); | 351 InitAlwaysOnTopState(); |
360 | 352 |
361 if (!IsAppWindow()) { | 353 if (!IsAppWindow()) { |
362 notification_registrar_.Add( | 354 notification_registrar_.Add( |
363 this, | 355 this, |
364 NotificationType::ALL_APPWINDOWS_CLOSED, | 356 NotificationType::ALL_APPWINDOWS_CLOSED, |
365 NotificationService::AllSources()); | 357 NotificationService::AllSources()); |
366 } | 358 } |
367 | 359 |
368 ResetWindowRegion(); | 360 ResetWindowRegion(false); |
| 361 } |
| 362 |
| 363 NonClientFrameView* Window::CreateFrameViewForWindow() { |
| 364 if (non_client_view_->UseNativeFrame()) |
| 365 return new NativeFrameView(this); |
| 366 return new CustomFrameView(this); |
| 367 } |
| 368 |
| 369 void Window::UpdateFrameAfterFrameChange() { |
| 370 // We've either gained or lost a custom window region, so reset it now. |
| 371 ResetWindowRegion(true); |
369 } | 372 } |
370 | 373 |
371 void Window::SizeWindowToDefault() { | 374 void Window::SizeWindowToDefault() { |
372 // CenterAndSizeWindow adjusts the window size to accommodate the non-client | 375 // CenterAndSizeWindow adjusts the window size to accommodate the non-client |
373 // area if we're using a native frame. | 376 // area if we're using a native frame. |
374 win_util::CenterAndSizeWindow(owning_window(), GetHWND(), | 377 win_util::CenterAndSizeWindow(owning_window(), GetHWND(), |
375 non_client_view_->GetPreferredSize().ToSIZE(), | 378 non_client_view_->GetPreferredSize().ToSIZE(), |
376 non_client_view_->UseNativeFrame()); | 379 non_client_view_->UseNativeFrame()); |
377 } | 380 } |
378 | 381 |
(...skipping 11 matching lines...) Expand all Loading... |
390 } | 393 } |
391 | 394 |
392 /////////////////////////////////////////////////////////////////////////////// | 395 /////////////////////////////////////////////////////////////////////////////// |
393 // Window, WidgetWin overrides: | 396 // Window, WidgetWin overrides: |
394 | 397 |
395 void Window::OnActivate(UINT action, BOOL minimized, HWND window) { | 398 void Window::OnActivate(UINT action, BOOL minimized, HWND window) { |
396 if (action == WA_INACTIVE) | 399 if (action == WA_INACTIVE) |
397 SaveWindowPosition(); | 400 SaveWindowPosition(); |
398 } | 401 } |
399 | 402 |
| 403 void Window::OnActivateApp(BOOL active, DWORD thread_id) { |
| 404 if (!active && thread_id != GetCurrentThreadId()) { |
| 405 // Another application was activated, we should reset any state that |
| 406 // disables inactive rendering now. |
| 407 disable_inactive_rendering_ = false; |
| 408 non_client_view_->DisableInactiveRendering(false); |
| 409 } |
| 410 } |
| 411 |
400 LRESULT Window::OnAppCommand(HWND window, short app_command, WORD device, | 412 LRESULT Window::OnAppCommand(HWND window, short app_command, WORD device, |
401 int keystate) { | 413 int keystate) { |
402 // We treat APPCOMMAND ids as an extension of our command namespace, and just | 414 // We treat APPCOMMAND ids as an extension of our command namespace, and just |
403 // let the delegate figure out what to do... | 415 // let the delegate figure out what to do... |
404 if (!window_delegate_->ExecuteWindowsCommand(app_command)) | 416 if (!window_delegate_->ExecuteWindowsCommand(app_command)) |
405 return WidgetWin::OnAppCommand(window, app_command, device, keystate); | 417 return WidgetWin::OnAppCommand(window, app_command, device, keystate); |
406 return 0; | 418 return 0; |
407 } | 419 } |
408 | 420 |
409 void Window::OnCommand(UINT notification_code, int command_id, HWND window) { | 421 void Window::OnCommand(UINT notification_code, int command_id, HWND window) { |
410 // We NULL check |window_delegate_| here because we can be sent WM_COMMAND | 422 // We NULL check |window_delegate_| here because we can be sent WM_COMMAND |
411 // messages even after the window is destroyed. | 423 // messages even after the window is destroyed. |
412 // If the notification code is > 1 it means it is control specific and we | 424 // If the notification code is > 1 it means it is control specific and we |
413 // should ignore it. | 425 // should ignore it. |
414 if (notification_code > 1 || !window_delegate_ || | 426 if (notification_code > 1 || !window_delegate_ || |
415 window_delegate_->ExecuteWindowsCommand(command_id)) { | 427 window_delegate_->ExecuteWindowsCommand(command_id)) { |
416 WidgetWin::OnCommand(notification_code, command_id, window); | 428 WidgetWin::OnCommand(notification_code, command_id, window); |
417 } | 429 } |
418 } | 430 } |
419 | 431 |
420 void Window::OnDestroy() { | 432 void Window::OnDestroy() { |
421 non_client_view_->WindowClosing(); | 433 non_client_view_->WindowClosing(); |
422 window_delegate_ = NULL; | 434 window_delegate_ = NULL; |
423 RestoreEnabledIfNecessary(); | 435 RestoreEnabledIfNecessary(); |
424 WidgetWin::OnDestroy(); | 436 WidgetWin::OnDestroy(); |
425 } | 437 } |
426 | 438 |
427 namespace { | 439 namespace { |
| 440 static BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { |
| 441 SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0); |
| 442 return TRUE; |
| 443 } |
| 444 } // namespace |
| 445 |
| 446 LRESULT Window::OnDwmCompositionChanged(UINT msg, WPARAM w_param, |
| 447 LPARAM l_param) { |
| 448 // We respond to this in response to WM_DWMCOMPOSITIONCHANGED since that is |
| 449 // the only thing we care about - we don't actually respond to WM_THEMECHANGED |
| 450 // messages. |
| 451 non_client_view_->SystemThemeChanged(); |
| 452 |
| 453 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want |
| 454 // to notify our children too, since we can have MDI child windows who need to |
| 455 // update their appearance. |
| 456 EnumChildWindows(GetHWND(), &SendDwmCompositionChanged, NULL); |
| 457 return 0; |
| 458 } |
| 459 |
| 460 namespace { |
428 static void EnableMenuItem(HMENU menu, UINT command, bool enabled) { | 461 static void EnableMenuItem(HMENU menu, UINT command, bool enabled) { |
429 UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED); | 462 UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED); |
430 EnableMenuItem(menu, command, flags); | 463 EnableMenuItem(menu, command, flags); |
431 } | 464 } |
432 } // namespace | 465 } // namespace |
433 | 466 |
434 void Window::OnInitMenu(HMENU menu) { | 467 void Window::OnInitMenu(HMENU menu) { |
435 // We only need to manually enable the system menu if we're not using a native | 468 // We only need to manually enable the system menu if we're not using a native |
436 // frame. | 469 // frame. |
437 if (non_client_view_->UseNativeFrame()) { | 470 if (non_client_view_->UseNativeFrame()) |
438 SetMsgHandled(FALSE); | 471 WidgetWin::OnInitMenu(menu); |
439 return; | |
440 } | |
441 | 472 |
442 bool is_minimized = IsMinimized(); | 473 bool is_minimized = IsMinimized(); |
443 bool is_maximized = IsMaximized(); | 474 bool is_maximized = IsMaximized(); |
444 bool is_restored = !is_minimized && !is_maximized; | 475 bool is_restored = !is_minimized && !is_maximized; |
445 | 476 |
446 ScopedRedrawLock lock(this); | 477 ScopedRedrawLock lock(this); |
447 EnableMenuItem(menu, SC_RESTORE, !is_restored); | 478 EnableMenuItem(menu, SC_RESTORE, !is_restored); |
448 EnableMenuItem(menu, SC_MOVE, is_restored); | 479 EnableMenuItem(menu, SC_MOVE, is_restored); |
449 EnableMenuItem(menu, SC_SIZE, window_delegate()->CanResize() && is_restored); | 480 EnableMenuItem(menu, SC_SIZE, window_delegate()->CanResize() && is_restored); |
450 EnableMenuItem(menu, SC_MAXIMIZE, | 481 EnableMenuItem(menu, SC_MAXIMIZE, |
(...skipping 23 matching lines...) Expand all Loading... |
474 // mouse really will have left the bounds of the RootView. | 505 // mouse really will have left the bounds of the RootView. |
475 process_mouse_exited = false; | 506 process_mouse_exited = false; |
476 } | 507 } |
477 } | 508 } |
478 | 509 |
479 if (process_mouse_exited) | 510 if (process_mouse_exited) |
480 ProcessMouseExited(); | 511 ProcessMouseExited(); |
481 } | 512 } |
482 | 513 |
483 LRESULT Window::OnNCActivate(BOOL active) { | 514 LRESULT Window::OnNCActivate(BOOL active) { |
| 515 is_active_ = !!active; |
| 516 |
484 // If we're not using the native frame, we need to force a synchronous repaint | 517 // If we're not using the native frame, we need to force a synchronous repaint |
485 // otherwise we'll be left in the wrong activation state until something else | 518 // otherwise we'll be left in the wrong activation state until something else |
486 // causes a repaint later. | 519 // causes a repaint later. |
487 if (!non_client_view_->UseNativeFrame()) { | 520 if (!non_client_view_->UseNativeFrame()) { |
488 is_active_ = !!active; | |
489 | |
490 // We can get WM_NCACTIVATE before we're actually visible. If we're not | 521 // We can get WM_NCACTIVATE before we're actually visible. If we're not |
491 // visible, no need to paint. | 522 // visible, no need to paint. |
492 if (IsWindowVisible(GetHWND())) { | 523 if (IsWindowVisible(GetHWND())) { |
493 non_client_view_->SchedulePaint(); | 524 non_client_view_->SchedulePaint(); |
494 // We need to force a paint now, as a user dragging a window will block | 525 // We need to force a paint now, as a user dragging a window will block |
495 // painting operations while the move is in progress. | 526 // painting operations while the move is in progress. |
496 PaintNow(root_view_->GetScheduledPaintRect()); | 527 PaintNow(root_view_->GetScheduledPaintRect()); |
497 } | 528 } |
498 } | 529 } |
499 | 530 |
| 531 // If we're active again, we should be allowed to render as inactive, so |
| 532 // tell the non-client view. This must be done independently of the check for |
| 533 // disable_inactive_rendering_ since that check is valid even if the frame |
| 534 // is not active, but this can only be done if we've become active. |
| 535 if (is_active_) |
| 536 non_client_view_->DisableInactiveRendering(false); |
| 537 |
| 538 // Reset the disable inactive rendering state since activation has changed. |
500 if (disable_inactive_rendering_) { | 539 if (disable_inactive_rendering_) { |
501 disable_inactive_rendering_ = false; | 540 disable_inactive_rendering_ = false; |
502 return DefWindowProc(GetHWND(), WM_NCACTIVATE, TRUE, 0); | 541 return CallDefaultNCActivateHandler(TRUE); |
503 } | 542 } |
504 // Otherwise just do the default thing. | 543 return CallDefaultNCActivateHandler(active); |
505 return WidgetWin::OnNCActivate(active); | |
506 } | 544 } |
507 | 545 |
508 LRESULT Window::OnNCCalcSize(BOOL mode, LPARAM l_param) { | 546 LRESULT Window::OnNCCalcSize(BOOL mode, LPARAM l_param) { |
509 // We only need to adjust the client size/paint handling when we're not using | 547 // We only need to adjust the client size/paint handling when we're not using |
510 // the native frame. | 548 // the native frame. |
511 if (non_client_view_->UseNativeFrame()) { | 549 if (non_client_view_->UseNativeFrame()) |
512 SetMsgHandled(FALSE); | 550 return WidgetWin::OnNCCalcSize(mode, l_param); |
513 return 0; | |
514 } | |
515 | 551 |
516 // We need to repaint all when the window bounds change. | 552 // We need to repaint all when the window bounds change. |
517 return WVR_REDRAW; | 553 return WVR_REDRAW; |
518 } | 554 } |
519 | 555 |
520 LRESULT Window::OnNCHitTest(const CPoint& point) { | 556 LRESULT Window::OnNCHitTest(const CPoint& point) { |
521 // First, give the NonClientView a chance to test the point to see if it | 557 // First, give the NonClientView a chance to test the point to see if it |
522 // provides any of the non-client area. | 558 // provides any of the non-client area. |
523 CPoint temp = point; | 559 CPoint temp = point; |
524 MapWindowPoints(HWND_DESKTOP, GetHWND(), &temp, 1); | 560 MapWindowPoints(HWND_DESKTOP, GetHWND(), &temp, 1); |
525 int component = non_client_view_->NonClientHitTest(gfx::Point(temp)); | 561 int component = non_client_view_->NonClientHitTest(gfx::Point(temp)); |
526 if (component != HTNOWHERE) | 562 if (component != HTNOWHERE) |
527 return component; | 563 return component; |
528 | 564 |
529 // Otherwise, we let Windows do all the native frame non-client handling for | 565 // Otherwise, we let Windows do all the native frame non-client handling for |
530 // us. | 566 // us. |
531 SetMsgHandled(FALSE); | 567 return WidgetWin::OnNCHitTest(point); |
532 return 0; | |
533 } | 568 } |
534 | 569 |
535 namespace { | 570 namespace { |
536 struct ClipState { | 571 struct ClipState { |
537 // The window being painted. | 572 // The window being painted. |
538 HWND parent; | 573 HWND parent; |
539 | 574 |
540 // DC painting to. | 575 // DC painting to. |
541 HDC dc; | 576 HDC dc; |
542 | 577 |
(...skipping 13 matching lines...) Expand all Loading... |
556 bounds.top - clip_state->y, | 591 bounds.top - clip_state->y, |
557 bounds.right - clip_state->x, | 592 bounds.right - clip_state->x, |
558 bounds.bottom - clip_state->y); | 593 bounds.bottom - clip_state->y); |
559 } | 594 } |
560 return TRUE; | 595 return TRUE; |
561 } | 596 } |
562 } // namespace | 597 } // namespace |
563 | 598 |
564 void Window::OnNCPaint(HRGN rgn) { | 599 void Window::OnNCPaint(HRGN rgn) { |
565 // We only do non-client painting if we're not using the native frame. | 600 // We only do non-client painting if we're not using the native frame. |
566 if (non_client_view_->UseNativeFrame()) { | 601 if (non_client_view_->UseNativeFrame()) |
567 SetMsgHandled(FALSE); | 602 return WidgetWin::OnNCPaint(rgn); |
568 return; | |
569 } | |
570 | 603 |
571 // We have an NC region and need to paint it. We expand the NC region to | 604 // We have an NC region and need to paint it. We expand the NC region to |
572 // include the dirty region of the root view. This is done to minimize | 605 // include the dirty region of the root view. This is done to minimize |
573 // paints. | 606 // paints. |
574 CRect window_rect; | 607 CRect window_rect; |
575 GetWindowRect(&window_rect); | 608 GetWindowRect(&window_rect); |
576 | 609 |
577 if (window_rect.Width() != root_view_->width() || | 610 if (window_rect.Width() != root_view_->width() || |
578 window_rect.Height() != root_view_->height()) { | 611 window_rect.Height() != root_view_->height()) { |
579 // If the size of the window differs from the size of the root view it | 612 // If the size of the window differs from the size of the root view it |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 void Window::OnSize(UINT size_param, const CSize& new_size) { | 790 void Window::OnSize(UINT size_param, const CSize& new_size) { |
758 // Don't no-op if the new_size matches current size. If our normal bounds | 791 // Don't no-op if the new_size matches current size. If our normal bounds |
759 // and maximized bounds are the same, then we need to layout (because we | 792 // and maximized bounds are the same, then we need to layout (because we |
760 // layout differently when maximized). | 793 // layout differently when maximized). |
761 SaveWindowPosition(); | 794 SaveWindowPosition(); |
762 ChangeSize(size_param, new_size); | 795 ChangeSize(size_param, new_size); |
763 RedrawWindow(GetHWND(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); | 796 RedrawWindow(GetHWND(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); |
764 | 797 |
765 // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've | 798 // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've |
766 // invoked OnSize we ensure the RootView has been laid out. | 799 // invoked OnSize we ensure the RootView has been laid out. |
767 ResetWindowRegion(); | 800 ResetWindowRegion(false); |
768 } | 801 } |
769 | 802 |
770 void Window::OnSysCommand(UINT notification_code, CPoint click) { | 803 void Window::OnSysCommand(UINT notification_code, CPoint click) { |
771 if (!non_client_view_->UseNativeFrame()) { | 804 if (!non_client_view_->UseNativeFrame()) { |
772 // Windows uses the 4 lower order bits of |notification_code| for type- | 805 // Windows uses the 4 lower order bits of |notification_code| for type- |
773 // specific information so we must exclude this when comparing. | 806 // specific information so we must exclude this when comparing. |
774 static const int sc_mask = 0xFFF0; | 807 static const int sc_mask = 0xFFF0; |
775 if ((notification_code & sc_mask) == SC_MINIMIZE || | 808 if ((notification_code & sc_mask) == SC_MINIMIZE || |
776 (notification_code & sc_mask) == SC_MAXIMIZE || | 809 (notification_code & sc_mask) == SC_MAXIMIZE || |
777 (notification_code & sc_mask) == SC_RESTORE) { | 810 (notification_code & sc_mask) == SC_RESTORE) { |
(...skipping 10 matching lines...) Expand all Loading... |
788 } | 821 } |
789 | 822 |
790 // First see if the delegate can handle it. | 823 // First see if the delegate can handle it. |
791 if (window_delegate_->ExecuteWindowsCommand(notification_code)) | 824 if (window_delegate_->ExecuteWindowsCommand(notification_code)) |
792 return; | 825 return; |
793 | 826 |
794 if (notification_code == IDC_ALWAYS_ON_TOP) { | 827 if (notification_code == IDC_ALWAYS_ON_TOP) { |
795 is_always_on_top_ = !is_always_on_top_; | 828 is_always_on_top_ = !is_always_on_top_; |
796 | 829 |
797 // Change the menu check state. | 830 // Change the menu check state. |
798 HMENU system_menu = ::GetSystemMenu(GetHWND(), FALSE); | 831 HMENU system_menu = GetSystemMenu(GetHWND(), FALSE); |
799 MENUITEMINFO menu_info; | 832 MENUITEMINFO menu_info; |
800 memset(&menu_info, 0, sizeof(MENUITEMINFO)); | 833 memset(&menu_info, 0, sizeof(MENUITEMINFO)); |
801 menu_info.cbSize = sizeof(MENUITEMINFO); | 834 menu_info.cbSize = sizeof(MENUITEMINFO); |
802 BOOL r = ::GetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, | 835 BOOL r = GetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, |
803 FALSE, &menu_info); | 836 FALSE, &menu_info); |
804 DCHECK(r); | 837 DCHECK(r); |
805 menu_info.fMask = MIIM_STATE; | 838 menu_info.fMask = MIIM_STATE; |
806 if (is_always_on_top_) | 839 if (is_always_on_top_) |
807 menu_info.fState = MFS_CHECKED; | 840 menu_info.fState = MFS_CHECKED; |
808 r = ::SetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, FALSE, &menu_info); | 841 r = SetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, FALSE, &menu_info); |
809 | 842 |
810 // Now change the actual window's behavior. | 843 // Now change the actual window's behavior. |
811 AlwaysOnTopChanged(); | 844 AlwaysOnTopChanged(); |
812 } else if ((notification_code == SC_KEYMENU) && (click.x == VK_SPACE)) { | 845 } else if ((notification_code == SC_KEYMENU) && (click.x == VK_SPACE)) { |
813 // Run the system menu at the NonClientView's desired location. | 846 // Run the system menu at the NonClientView's desired location. |
814 RunSystemMenu(non_client_view_->GetSystemMenuPoint()); | 847 RunSystemMenu(non_client_view_->GetSystemMenuPoint()); |
815 } else { | 848 } else { |
816 // Use the default implementation for any other command. | 849 // Use the default implementation for any other command. |
817 DefWindowProc(GetHWND(), WM_SYSCOMMAND, notification_code, | 850 DefWindowProc(GetHWND(), WM_SYSCOMMAND, notification_code, |
818 MAKELPARAM(click.y, click.x)); | 851 MAKELPARAM(click.y, click.x)); |
819 } | 852 } |
820 } | 853 } |
821 | 854 |
822 //////////////////////////////////////////////////////////////////////////////// | 855 //////////////////////////////////////////////////////////////////////////////// |
823 // Window, private: | 856 // Window, private: |
824 | 857 |
825 void Window::SetClientView(ClientView* client_view) { | |
826 DCHECK(client_view && GetHWND()); | |
827 non_client_view_->set_client_view(client_view); | |
828 // This will trigger the ClientView to be added by the non-client view. | |
829 WidgetWin::SetContentsView(non_client_view_); | |
830 } | |
831 | |
832 void Window::BecomeModal() { | 858 void Window::BecomeModal() { |
833 // We implement modality by crawling up the hierarchy of windows starting | 859 // We implement modality by crawling up the hierarchy of windows starting |
834 // at the owner, disabling all of them so that they don't receive input | 860 // at the owner, disabling all of them so that they don't receive input |
835 // messages. | 861 // messages. |
836 DCHECK(owning_hwnd_) << "Can't create a modal dialog without an owner"; | 862 DCHECK(owning_hwnd_) << "Can't create a modal dialog without an owner"; |
837 HWND start = owning_hwnd_; | 863 HWND start = owning_hwnd_; |
838 while (start != NULL) { | 864 while (start != NULL) { |
839 ::EnableWindow(start, FALSE); | 865 ::EnableWindow(start, FALSE); |
840 start = ::GetParent(start); | 866 start = ::GetParent(start); |
841 } | 867 } |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 lock_updates_ = true; | 1041 lock_updates_ = true; |
1016 saved_window_style_ = GetWindowLong(GetHWND(), GWL_STYLE); | 1042 saved_window_style_ = GetWindowLong(GetHWND(), GWL_STYLE); |
1017 SetWindowLong(GetHWND(), GWL_STYLE, saved_window_style_ & ~WS_VISIBLE); | 1043 SetWindowLong(GetHWND(), GWL_STYLE, saved_window_style_ & ~WS_VISIBLE); |
1018 } | 1044 } |
1019 | 1045 |
1020 void Window::UnlockUpdates() { | 1046 void Window::UnlockUpdates() { |
1021 SetWindowLong(GetHWND(), GWL_STYLE, saved_window_style_); | 1047 SetWindowLong(GetHWND(), GWL_STYLE, saved_window_style_); |
1022 lock_updates_ = false; | 1048 lock_updates_ = false; |
1023 } | 1049 } |
1024 | 1050 |
1025 void Window::ResetWindowRegion() { | 1051 void Window::ResetWindowRegion(bool force) { |
1026 // A native frame uses the native window region, and we don't want to mess | 1052 // A native frame uses the native window region, and we don't want to mess |
1027 // with it. | 1053 // with it. |
1028 if (non_client_view_->UseNativeFrame()) | 1054 if (non_client_view_->UseNativeFrame()) { |
| 1055 if (force) |
| 1056 SetWindowRgn(NULL, TRUE); |
1029 return; | 1057 return; |
| 1058 } |
1030 | 1059 |
1031 // Changing the window region is going to force a paint. Only change the | 1060 // Changing the window region is going to force a paint. Only change the |
1032 // window region if the region really differs. | 1061 // window region if the region really differs. |
1033 HRGN current_rgn = CreateRectRgn(0, 0, 0, 0); | 1062 HRGN current_rgn = CreateRectRgn(0, 0, 0, 0); |
1034 int current_rgn_result = GetWindowRgn(GetHWND(), current_rgn); | 1063 int current_rgn_result = GetWindowRgn(GetHWND(), current_rgn); |
1035 | 1064 |
1036 CRect window_rect; | 1065 CRect window_rect; |
1037 GetWindowRect(&window_rect); | 1066 GetWindowRect(&window_rect); |
1038 HRGN new_region; | 1067 HRGN new_region; |
1039 if (IsMaximized()) { | 1068 if (IsMaximized()) { |
(...skipping 27 matching lines...) Expand all Loading... |
1067 MapWindowPoints(HWND_DESKTOP, GetHWND(), &temp, 1); | 1096 MapWindowPoints(HWND_DESKTOP, GetHWND(), &temp, 1); |
1068 UINT message_flags = 0; | 1097 UINT message_flags = 0; |
1069 if ((GetKeyState(VK_CONTROL) & 0x80) == 0x80) | 1098 if ((GetKeyState(VK_CONTROL) & 0x80) == 0x80) |
1070 message_flags |= MK_CONTROL; | 1099 message_flags |= MK_CONTROL; |
1071 if ((GetKeyState(VK_SHIFT) & 0x80) == 0x80) | 1100 if ((GetKeyState(VK_SHIFT) & 0x80) == 0x80) |
1072 message_flags |= MK_SHIFT; | 1101 message_flags |= MK_SHIFT; |
1073 message_flags |= flags; | 1102 message_flags |= flags; |
1074 ProcessMousePressed(temp, message_flags, false, false); | 1103 ProcessMousePressed(temp, message_flags, false, false); |
1075 } | 1104 } |
1076 | 1105 |
| 1106 LRESULT Window::CallDefaultNCActivateHandler(BOOL active) { |
| 1107 // The DefWindowProc handling for WM_NCACTIVATE renders the classic-look |
| 1108 // window title bar directly, so we need to use a redraw lock here to prevent |
| 1109 // it from doing so. |
| 1110 ScopedRedrawLock lock(this); |
| 1111 return DefWindowProc(GetHWND(), WM_NCACTIVATE, active, 0); |
| 1112 } |
| 1113 |
1077 void Window::InitClass() { | 1114 void Window::InitClass() { |
1078 static bool initialized = false; | 1115 static bool initialized = false; |
1079 if (!initialized) { | 1116 if (!initialized) { |
1080 resize_cursors_[RC_NORMAL] = LoadCursor(NULL, IDC_ARROW); | 1117 resize_cursors_[RC_NORMAL] = LoadCursor(NULL, IDC_ARROW); |
1081 resize_cursors_[RC_VERTICAL] = LoadCursor(NULL, IDC_SIZENS); | 1118 resize_cursors_[RC_VERTICAL] = LoadCursor(NULL, IDC_SIZENS); |
1082 resize_cursors_[RC_HORIZONTAL] = LoadCursor(NULL, IDC_SIZEWE); | 1119 resize_cursors_[RC_HORIZONTAL] = LoadCursor(NULL, IDC_SIZEWE); |
1083 resize_cursors_[RC_NESW] = LoadCursor(NULL, IDC_SIZENESW); | 1120 resize_cursors_[RC_NESW] = LoadCursor(NULL, IDC_SIZENESW); |
1084 resize_cursors_[RC_NWSE] = LoadCursor(NULL, IDC_SIZENWSE); | 1121 resize_cursors_[RC_NWSE] = LoadCursor(NULL, IDC_SIZENWSE); |
1085 initialized = true; | 1122 initialized = true; |
1086 } | 1123 } |
1087 } | 1124 } |
1088 | 1125 |
1089 } // namespace views | 1126 } // namespace views |
1090 | 1127 |
OLD | NEW |