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/controls/textfield/native_textfield_win.h" | 5 #include "views/controls/textfield/native_textfield_win.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/i18n/rtl.h" | 9 #include "base/i18n/rtl.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 CHILDID_SELF, PROPID_ACC_VALUE, value.c_str()); | 481 CHILDID_SELF, PROPID_ACC_VALUE, value.c_str()); |
482 | 482 |
483 ::NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, m_hWnd, OBJID_CLIENT, | 483 ::NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, m_hWnd, OBJID_CLIENT, |
484 CHILDID_SELF); | 484 CHILDID_SELF); |
485 } | 485 } |
486 | 486 |
487 //////////////////////////////////////////////////////////////////////////////// | 487 //////////////////////////////////////////////////////////////////////////////// |
488 // NativeTextfieldWin, private: | 488 // NativeTextfieldWin, private: |
489 | 489 |
490 void NativeTextfieldWin::OnChar(TCHAR ch, UINT repeat_count, UINT flags) { | 490 void NativeTextfieldWin::OnChar(TCHAR ch, UINT repeat_count, UINT flags) { |
491 HandleKeystroke(GetCurrentMessage()->message, ch, repeat_count, flags); | 491 HandleKeystroke(); |
492 } | 492 } |
493 | 493 |
494 void NativeTextfieldWin::OnContextMenu(HWND window, const POINT& point) { | 494 void NativeTextfieldWin::OnContextMenu(HWND window, const POINT& point) { |
495 POINT p(point); | 495 POINT p(point); |
496 if (point.x == -1 || point.y == -1) { | 496 if (point.x == -1 || point.y == -1) { |
497 GetCaretPos(&p); | 497 GetCaretPos(&p); |
498 MapWindowPoints(HWND_DESKTOP, &p, 1); | 498 MapWindowPoints(HWND_DESKTOP, &p, 1); |
499 } | 499 } |
500 BuildContextMenu(); | 500 BuildContextMenu(); |
501 context_menu_->RunContextMenuAt(gfx::Point(p)); | 501 context_menu_->RunContextMenuAt(gfx::Point(p)); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 | 680 |
681 case VK_PROCESSKEY: | 681 case VK_PROCESSKEY: |
682 // This key event is consumed by an IME. | 682 // This key event is consumed by an IME. |
683 // We ignore this event because an IME sends WM_IME_COMPOSITION messages | 683 // We ignore this event because an IME sends WM_IME_COMPOSITION messages |
684 // when it updates the CRichEditCtrl text. | 684 // when it updates the CRichEditCtrl text. |
685 return; | 685 return; |
686 } | 686 } |
687 | 687 |
688 // CRichEditCtrl changes its text on WM_KEYDOWN instead of WM_CHAR for many | 688 // CRichEditCtrl changes its text on WM_KEYDOWN instead of WM_CHAR for many |
689 // different keys (backspace, ctrl-v, ...), so we call this in both cases. | 689 // different keys (backspace, ctrl-v, ...), so we call this in both cases. |
690 HandleKeystroke(GetCurrentMessage()->message, key, repeat_count, flags); | 690 HandleKeystroke(); |
691 } | 691 } |
692 | 692 |
693 void NativeTextfieldWin::OnLButtonDblClk(UINT keys, const CPoint& point) { | 693 void NativeTextfieldWin::OnLButtonDblClk(UINT keys, const CPoint& point) { |
694 // Save the double click info for later triple-click detection. | 694 // Save the double click info for later triple-click detection. |
695 tracking_double_click_ = true; | 695 tracking_double_click_ = true; |
696 double_click_point_ = point; | 696 double_click_point_ = point; |
697 double_click_time_ = GetCurrentMessage()->time; | 697 double_click_time_ = GetCurrentMessage()->time; |
698 | 698 |
699 ScopedFreeze freeze(this, GetTextObjectModel()); | 699 ScopedFreeze freeze(this, GetTextObjectModel()); |
700 OnBeforePossibleChange(); | 700 OnBeforePossibleChange(); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 // useful, so we discard most. Exceptions: | 924 // useful, so we discard most. Exceptions: |
925 // * ctrl-alt-<xxx>, which is sometimes important, generates WM_CHAR instead | 925 // * ctrl-alt-<xxx>, which is sometimes important, generates WM_CHAR instead |
926 // of WM_SYSCHAR, so it doesn't need to be handled here. | 926 // of WM_SYSCHAR, so it doesn't need to be handled here. |
927 // * alt-space gets translated by the default WM_SYSCHAR handler to a | 927 // * alt-space gets translated by the default WM_SYSCHAR handler to a |
928 // WM_SYSCOMMAND to open the application context menu, so we need to allow | 928 // WM_SYSCOMMAND to open the application context menu, so we need to allow |
929 // it through. | 929 // it through. |
930 if (ch == VK_SPACE) | 930 if (ch == VK_SPACE) |
931 SetMsgHandled(false); | 931 SetMsgHandled(false); |
932 } | 932 } |
933 | 933 |
934 void NativeTextfieldWin::HandleKeystroke(UINT message, | 934 void NativeTextfieldWin::HandleKeystroke() { |
935 TCHAR key, | 935 const MSG* msg = GetCurrentMessage(); |
936 UINT repeat_count, | |
937 UINT flags) { | |
938 ScopedFreeze freeze(this, GetTextObjectModel()); | 936 ScopedFreeze freeze(this, GetTextObjectModel()); |
939 | 937 |
940 Textfield::Controller* controller = textfield_->GetController(); | 938 Textfield::Controller* controller = textfield_->GetController(); |
941 bool handled = false; | 939 bool handled = false; |
942 if (controller) { | 940 if (controller) { |
943 ui::EventType type; | 941 KeyEvent event(*msg); |
944 switch (message) { | 942 handled = controller->HandleKeyEvent(textfield_, event); |
945 case WM_KEYDOWN: | |
946 case WM_SYSKEYDOWN: | |
947 case WM_CHAR: | |
948 case WM_SYSCHAR: | |
949 type = ui::ET_KEY_PRESSED; | |
950 break; | |
951 case WM_KEYUP: | |
952 case WM_SYSKEYUP: | |
953 type = ui::ET_KEY_RELEASED; | |
954 break; | |
955 default: | |
956 NOTREACHED() << "Unknown message:" << message; | |
957 // Passing through to avoid crash on release build. | |
958 type = ui::ET_KEY_PRESSED; | |
959 } | |
960 KeyEvent key_event(type, | |
961 ui::KeyboardCodeForWindowsKeyCode(key), | |
962 KeyEvent::GetKeyStateFlags(), | |
963 repeat_count, | |
964 flags, | |
965 message); | |
966 handled = controller->HandleKeyEvent(textfield_, key_event); | |
967 } | 943 } |
968 | 944 |
969 if (!handled) { | 945 if (!handled) { |
970 OnBeforePossibleChange(); | 946 OnBeforePossibleChange(); |
971 | 947 |
972 if (key == ui::VKEY_HOME || key == ui::VKEY_END) { | 948 if (msg->wParam == ui::VKEY_HOME || msg->wParam == ui::VKEY_END) { |
973 // DefWindowProc() might reset the keyboard layout when it receives a | 949 // DefWindowProc() might reset the keyboard layout when it receives a |
974 // keydown event for VKEY_HOME or VKEY_END. When the window was created | 950 // keydown event for VKEY_HOME or VKEY_END. When the window was created |
975 // with WS_EX_LAYOUTRTL and the current keyboard layout is not a RTL one, | 951 // with WS_EX_LAYOUTRTL and the current keyboard layout is not a RTL one, |
976 // if the input text is pure LTR text, the layout changes to the first RTL | 952 // if the input text is pure LTR text, the layout changes to the first RTL |
977 // keyboard layout in keyboard layout queue; if the input text is | 953 // keyboard layout in keyboard layout queue; if the input text is |
978 // bidirectional text, the layout changes to the keyboard layout of the | 954 // bidirectional text, the layout changes to the keyboard layout of the |
979 // first RTL character in input text. When the window was created without | 955 // first RTL character in input text. When the window was created without |
980 // WS_EX_LAYOUTRTL and the current keyboard layout is not a LTR one, if | 956 // WS_EX_LAYOUTRTL and the current keyboard layout is not a LTR one, if |
981 // the input text is pure RTL text, the layout changes to English; if the | 957 // the input text is pure RTL text, the layout changes to English; if the |
982 // input text is bidirectional text, the layout changes to the keyboard | 958 // input text is bidirectional text, the layout changes to the keyboard |
983 // layout of the first LTR character in input text. Such keyboard layout | 959 // layout of the first LTR character in input text. Such keyboard layout |
984 // change behavior is surprising and inconsistent with keyboard behavior | 960 // change behavior is surprising and inconsistent with keyboard behavior |
985 // elsewhere, so reset the layout in this case. | 961 // elsewhere, so reset the layout in this case. |
986 HKL layout = GetKeyboardLayout(0); | 962 HKL layout = GetKeyboardLayout(0); |
987 DefWindowProc(message, key, MAKELPARAM(repeat_count, flags)); | 963 DefWindowProc(msg->message, msg->wParam, msg->lParam); |
988 ActivateKeyboardLayout(layout, KLF_REORDER); | 964 ActivateKeyboardLayout(layout, KLF_REORDER); |
989 } else { | 965 } else { |
990 DefWindowProc(message, key, MAKELPARAM(repeat_count, flags)); | 966 DefWindowProc(msg->message, msg->wParam, msg->lParam); |
991 } | 967 } |
992 | 968 |
993 // CRichEditCtrl automatically turns on IMF_AUTOKEYBOARD when the user | 969 // CRichEditCtrl automatically turns on IMF_AUTOKEYBOARD when the user |
994 // inputs an RTL character, making it difficult for the user to control | 970 // inputs an RTL character, making it difficult for the user to control |
995 // what language is set as they type. Force this off to make the edit's | 971 // what language is set as they type. Force this off to make the edit's |
996 // behavior more stable. | 972 // behavior more stable. |
997 const int lang_options = SendMessage(EM_GETLANGOPTIONS, 0, 0); | 973 const int lang_options = SendMessage(EM_GETLANGOPTIONS, 0, 0); |
998 if (lang_options & IMF_AUTOKEYBOARD) | 974 if (lang_options & IMF_AUTOKEYBOARD) |
999 SendMessage(EM_SETLANGOPTIONS, 0, lang_options & ~IMF_AUTOKEYBOARD); | 975 SendMessage(EM_SETLANGOPTIONS, 0, lang_options & ~IMF_AUTOKEYBOARD); |
1000 | 976 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper( | 1138 NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper( |
1163 Textfield* field) { | 1139 Textfield* field) { |
1164 if (NativeTextfieldViews::IsTextfieldViewsEnabled()) { | 1140 if (NativeTextfieldViews::IsTextfieldViewsEnabled()) { |
1165 return new NativeTextfieldViews(field); | 1141 return new NativeTextfieldViews(field); |
1166 } else { | 1142 } else { |
1167 return new NativeTextfieldWin(field); | 1143 return new NativeTextfieldWin(field); |
1168 } | 1144 } |
1169 } | 1145 } |
1170 | 1146 |
1171 } // namespace views | 1147 } // namespace views |
OLD | NEW |