| 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 |