OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <dwmapi.h> | 7 #include <dwmapi.h> |
8 #include <shellapi.h> | 8 #include <shellapi.h> |
9 | 9 |
10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 GetWindow()->window_delegate()->CanMaximize() && | 465 GetWindow()->window_delegate()->CanMaximize() && |
466 !is_minimized); | 466 !is_minimized); |
467 } | 467 } |
468 | 468 |
469 LRESULT WindowWin::OnMouseActivate(UINT message, WPARAM w_param, | 469 LRESULT WindowWin::OnMouseActivate(UINT message, WPARAM w_param, |
470 LPARAM l_param) { | 470 LPARAM l_param) { |
471 return delegate_->CanActivate() ? MA_ACTIVATE : MA_NOACTIVATEANDEAT; | 471 return delegate_->CanActivate() ? MA_ACTIVATE : MA_NOACTIVATEANDEAT; |
472 } | 472 } |
473 | 473 |
474 LRESULT WindowWin::OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) { | 474 LRESULT WindowWin::OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) { |
475 if (message == WM_RBUTTONUP) { | 475 if (message == WM_RBUTTONUP && is_right_mouse_pressed_on_caption_) { |
476 if (is_right_mouse_pressed_on_caption_) { | 476 is_right_mouse_pressed_on_caption_ = false; |
477 is_right_mouse_pressed_on_caption_ = false; | 477 ReleaseCapture(); |
478 ReleaseCapture(); | 478 // |point| is in window coordinates, but WM_NCHITTEST and TrackPopupMenu() |
479 // |point| is in window coordinates, but WM_NCHITTEST and TrackPopupMenu() | 479 // expect screen coordinates. |
480 // expect screen coordinates. | 480 CPoint screen_point(l_param); |
481 CPoint screen_point(l_param); | 481 MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_point, 1); |
482 MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_point, 1); | 482 w_param = SendMessage(GetNativeView(), WM_NCHITTEST, 0, |
483 w_param = SendMessage(GetNativeView(), WM_NCHITTEST, 0, | 483 MAKELPARAM(screen_point.x, screen_point.y)); |
484 MAKELPARAM(screen_point.x, screen_point.y)); | 484 if (w_param == HTCAPTION || w_param == HTSYSMENU) { |
485 if (w_param == HTCAPTION || w_param == HTSYSMENU) { | 485 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; |
486 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; | 486 if (base::i18n::IsRTL()) |
487 if (base::i18n::IsRTL()) | 487 flags |= TPM_RIGHTALIGN; |
488 flags |= TPM_RIGHTALIGN; | 488 HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE); |
489 HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE); | 489 int id = TrackPopupMenu(system_menu, flags, screen_point.x, |
490 int id = TrackPopupMenu(system_menu, flags, screen_point.x, | 490 screen_point.y, 0, GetNativeView(), NULL); |
491 screen_point.y, 0, GetNativeView(), NULL); | 491 ExecuteSystemMenuCommand(id); |
492 ExecuteSystemMenuCommand(id); | 492 return 0; |
| 493 } |
| 494 } else if (message == WM_NCLBUTTONDOWN && !delegate_->IsUsingNativeFrame()) { |
| 495 switch (w_param) { |
| 496 case HTCLOSE: |
| 497 case HTMINBUTTON: |
| 498 case HTMAXBUTTON: { |
| 499 // When the mouse is pressed down in these specific non-client areas, |
| 500 // we need to tell the RootView to send the mouse pressed event (which |
| 501 // sets capture, allowing subsequent WM_LBUTTONUP (note, _not_ |
| 502 // WM_NCLBUTTONUP) to fire so that the appropriate WM_SYSCOMMAND can be |
| 503 // sent by the applicable button's ButtonListener. We _have_ to do this |
| 504 // way rather than letting Windows just send the syscommand itself (as |
| 505 // would happen if we never did this dance) because for some insane |
| 506 // reason DefWindowProc for WM_NCLBUTTONDOWN also renders the pressed |
| 507 // window control button appearance, in the Windows classic style, over |
| 508 // our view! Ick! By handling this message we prevent Windows from |
| 509 // doing this undesirable thing, but that means we need to roll the |
| 510 // sys-command handling ourselves. |
| 511 // Combine |w_param| with common key state message flags. |
| 512 w_param |= ((GetKeyState(VK_CONTROL) & 0x80) == 0x80)? MK_CONTROL : 0; |
| 513 w_param |= ((GetKeyState(VK_SHIFT) & 0x80) == 0x80)? MK_SHIFT : 0; |
| 514 WidgetWin::OnMouseRange(message, w_param, l_param); |
493 return 0; | 515 return 0; |
494 } | 516 } |
495 } | 517 } |
| 518 } else if (message == WM_NCRBUTTONDOWN && |
| 519 (w_param == HTCAPTION || w_param == HTSYSMENU)) { |
| 520 is_right_mouse_pressed_on_caption_ = true; |
| 521 // We SetMouseCapture() to ensure we only show the menu when the button |
| 522 // down and up are both on the caption. Note: this causes the button up to |
| 523 // be WM_RBUTTONUP instead of WM_NCRBUTTONUP. |
| 524 SetMouseCapture(); |
496 } | 525 } |
497 | 526 |
| 527 /* TODO(beng): Fix the standard non-client over-painting bug. This code |
| 528 doesn't work but identifies the problem. |
| 529 if (message == WM_NCLBUTTONDOWN && !IsMsgHandled()) { |
| 530 // WindowWin::OnNCLButtonDown set the message as unhandled. This normally |
| 531 // means WidgetWin::ProcessWindowMessage will pass it to |
| 532 // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird |
| 533 // non-client painting, so we need to call it directly here inside a |
| 534 // scoped update lock. |
| 535 ScopedRedrawLock lock(this); |
| 536 DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, w_param, l_param); |
| 537 SetMsgHandled(TRUE); |
| 538 } |
| 539 */ |
| 540 |
498 WidgetWin::OnMouseRange(message, w_param, l_param); | 541 WidgetWin::OnMouseRange(message, w_param, l_param); |
499 return 0; | 542 return 0; |
500 } | 543 } |
501 | 544 |
502 | 545 |
503 LRESULT WindowWin::OnNCActivate(BOOL active) { | 546 LRESULT WindowWin::OnNCActivate(BOOL active) { |
504 if (!delegate_->CanActivate()) | 547 if (!delegate_->CanActivate()) |
505 return TRUE; | 548 return TRUE; |
506 | 549 |
507 is_active_ = !!active; | 550 is_active_ = !!active; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 MapWindowPoints(HWND_DESKTOP, GetNativeView(), &temp, 1); | 662 MapWindowPoints(HWND_DESKTOP, GetNativeView(), &temp, 1); |
620 int component = delegate_->GetNonClientComponent(gfx::Point(temp)); | 663 int component = delegate_->GetNonClientComponent(gfx::Point(temp)); |
621 if (component != HTNOWHERE) | 664 if (component != HTNOWHERE) |
622 return component; | 665 return component; |
623 | 666 |
624 // Otherwise, we let Windows do all the native frame non-client handling for | 667 // Otherwise, we let Windows do all the native frame non-client handling for |
625 // us. | 668 // us. |
626 return WidgetWin::OnNCHitTest(point); | 669 return WidgetWin::OnNCHitTest(point); |
627 } | 670 } |
628 | 671 |
629 LRESULT WindowWin::OnNCMouseRange(UINT message, | |
630 WPARAM w_param, | |
631 LPARAM l_param) { | |
632 // When we're using a native frame, window controls work without us | |
633 // interfering. | |
634 if (message == WM_NCLBUTTONDOWN && !delegate_->IsUsingNativeFrame()) { | |
635 switch (w_param) { | |
636 case HTCLOSE: | |
637 case HTMINBUTTON: | |
638 case HTMAXBUTTON: { | |
639 // When the mouse is pressed down in these specific non-client areas, | |
640 // we need to tell the RootView to send the mouse pressed event (which | |
641 // sets capture, allowing subsequent WM_LBUTTONUP (note, _not_ | |
642 // WM_NCLBUTTONUP) to fire so that the appropriate WM_SYSCOMMAND can be | |
643 // sent by the applicable button's ButtonListener. We _have_ to do this | |
644 // way rather than letting Windows just send the syscommand itself (as | |
645 // would happen if we never did this dance) because for some insane | |
646 // reason DefWindowProc for WM_NCLBUTTONDOWN also renders the pressed | |
647 // window control button appearance, in the Windows classic style, over | |
648 // our view! Ick! By handling this message we prevent Windows from | |
649 // doing this undesirable thing, but that means we need to roll the | |
650 // sys-command handling ourselves. | |
651 // Combine |w_param| with common key state message flags. | |
652 w_param |= ((GetKeyState(VK_CONTROL) & 0x80) == 0x80)? MK_CONTROL : 0; | |
653 w_param |= ((GetKeyState(VK_SHIFT) & 0x80) == 0x80)? MK_SHIFT : 0; | |
654 ProcessMousePressed(message, w_param, l_param); | |
655 return 0; | |
656 } | |
657 } | |
658 } else if (message == WM_NCRBUTTONDOWN && | |
659 (w_param == HTCAPTION || w_param == HTSYSMENU)) { | |
660 is_right_mouse_pressed_on_caption_ = true; | |
661 // We SetCapture() to ensure we only show the menu when the button down and | |
662 // up are both on the caption. Note: this causes the button up to be | |
663 // WM_RBUTTONUP instead of WM_NCRBUTTONUP. | |
664 SetNativeCapture(); | |
665 } | |
666 | |
667 WidgetWin::OnNCMouseRange(message, w_param, l_param); | |
668 | |
669 /* TODO(beng): Fix the standard non-client over-painting bug. This code | |
670 doesn't work but identifies the problem. | |
671 if (message == WM_NCLBUTTONDOWN && !IsMsgHandled()) { | |
672 // WindowWin::OnNCLButtonDown set the message as unhandled. This normally | |
673 // means WidgetWin::ProcessWindowMessage will pass it to | |
674 // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird | |
675 // non-client painting, so we need to call it directly here inside a | |
676 // scoped update lock. | |
677 ScopedRedrawLock lock(this); | |
678 DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, w_param, l_param); | |
679 SetMsgHandled(TRUE); | |
680 } | |
681 */ | |
682 | |
683 return 0; | |
684 } | |
685 | |
686 void WindowWin::OnNCPaint(HRGN rgn) { | 672 void WindowWin::OnNCPaint(HRGN rgn) { |
687 // When using a custom frame, we want to avoid calling DefWindowProc() since | 673 // When using a custom frame, we want to avoid calling DefWindowProc() since |
688 // that may render artifacts. | 674 // that may render artifacts. |
689 SetMsgHandled(!delegate_->IsUsingNativeFrame()); | 675 SetMsgHandled(!delegate_->IsUsingNativeFrame()); |
690 } | 676 } |
691 | 677 |
692 LRESULT WindowWin::OnNCUAHDrawCaption(UINT msg, WPARAM w_param, | 678 LRESULT WindowWin::OnNCUAHDrawCaption(UINT msg, WPARAM w_param, |
693 LPARAM l_param) { | 679 LPARAM l_param) { |
694 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for | 680 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for |
695 // an explanation about why we need to handle this message. | 681 // an explanation about why we need to handle this message. |
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1366 Window::CloseSecondaryWidget(native_widget->GetWidget()); | 1352 Window::CloseSecondaryWidget(native_widget->GetWidget()); |
1367 return TRUE; | 1353 return TRUE; |
1368 } | 1354 } |
1369 } // namespace | 1355 } // namespace |
1370 | 1356 |
1371 void Window::CloseAllSecondaryWindows() { | 1357 void Window::CloseAllSecondaryWindows() { |
1372 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); | 1358 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); |
1373 } | 1359 } |
1374 | 1360 |
1375 } // namespace views | 1361 } // namespace views |
OLD | NEW |