OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this |
2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
3 // LICENSE file. | 3 // LICENSE file. |
4 | 4 |
5 #include "views/controls/native_control_win.h" | 5 #include "views/controls/native_control_win.h" |
6 | 6 |
7 #include "app/l10n_util_win.h" | 7 #include "app/l10n_util_win.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/win_util.h" | 9 #include "base/win_util.h" |
10 #include "views/focus/focus_manager.h" | 10 #include "views/focus/focus_manager.h" |
11 | 11 |
12 namespace views { | 12 namespace views { |
13 | 13 |
14 // static | 14 // static |
15 const wchar_t* NativeControlWin::kNativeControlWinKey = | 15 const wchar_t* NativeControlWin::kNativeControlWinKey = |
16 L"__NATIVE_CONTROL_WIN__"; | 16 L"__NATIVE_CONTROL_WIN__"; |
17 | 17 |
18 //////////////////////////////////////////////////////////////////////////////// | 18 //////////////////////////////////////////////////////////////////////////////// |
19 // NativeControlWin, public: | 19 // NativeControlWin, public: |
20 | 20 |
21 NativeControlWin::NativeControlWin() { | 21 NativeControlWin::NativeControlWin() { |
22 } | 22 } |
23 | 23 |
24 NativeControlWin::~NativeControlWin() { | 24 NativeControlWin::~NativeControlWin() { |
25 HWND hwnd = native_view(); | 25 HWND hwnd = native_view(); |
26 if (hwnd) { | 26 if (hwnd) { |
27 // Destroy the hwnd if it still exists. Otherwise we won't shut things down | 27 // Destroy the hwnd if it still exists. Otherwise we won't have shut things |
28 // correctly, leading to leaking and crashing if another message comes in | 28 // down correctly, leading to leaking and crashing if another message |
29 // for the hwnd. | 29 // comes in for the hwnd. |
| 30 Detach(); |
30 DestroyWindow(hwnd); | 31 DestroyWindow(hwnd); |
31 } | 32 } |
32 } | 33 } |
33 | 34 |
34 bool NativeControlWin::ProcessMessage(UINT message, WPARAM w_param, | 35 bool NativeControlWin::ProcessMessage(UINT message, WPARAM w_param, |
35 LPARAM l_param, LRESULT* result) { | 36 LPARAM l_param, LRESULT* result) { |
36 switch (message) { | 37 switch (message) { |
37 case WM_CONTEXTMENU: | 38 case WM_CONTEXTMENU: |
38 ShowContextMenu(gfx::Point(LOWORD(l_param), HIWORD(l_param))); | 39 ShowContextMenu(gfx::Point(LOWORD(l_param), HIWORD(l_param))); |
39 *result = 0; | 40 *result = 0; |
(...skipping 26 matching lines...) Expand all Loading... |
66 // Create the HWND when we're added to a valid Widget. Many controls need a | 67 // Create the HWND when we're added to a valid Widget. Many controls need a |
67 // parent HWND to function properly. | 68 // parent HWND to function properly. |
68 if (is_add && GetWidget() && !native_view()) | 69 if (is_add && GetWidget() && !native_view()) |
69 CreateNativeControl(); | 70 CreateNativeControl(); |
70 } | 71 } |
71 | 72 |
72 void NativeControlWin::VisibilityChanged(View* starting_from, bool is_visible) { | 73 void NativeControlWin::VisibilityChanged(View* starting_from, bool is_visible) { |
73 if (!is_visible) { | 74 if (!is_visible) { |
74 // We destroy the child control HWND when we become invisible because of the | 75 // We destroy the child control HWND when we become invisible because of the |
75 // performance cost of maintaining many HWNDs. | 76 // performance cost of maintaining many HWNDs. |
76 DestroyWindow(native_view()); | 77 HWND hwnd = native_view(); |
| 78 Detach(); |
| 79 DestroyWindow(hwnd); |
77 } else if (!native_view()) { | 80 } else if (!native_view()) { |
78 if (GetWidget()) | 81 if (GetWidget()) |
79 CreateNativeControl(); | 82 CreateNativeControl(); |
80 } else { | 83 } else { |
81 // The view becomes visible after native control is created. | 84 // The view becomes visible after native control is created. |
82 // Layout now. | 85 // Layout now. |
83 Layout(); | 86 Layout(); |
84 } | 87 } |
85 } | 88 } |
86 | 89 |
(...skipping 20 matching lines...) Expand all Loading... |
107 } | 110 } |
108 View::ShowContextMenu(x, y, is_mouse); | 111 View::ShowContextMenu(x, y, is_mouse); |
109 } | 112 } |
110 | 113 |
111 void NativeControlWin::NativeControlCreated(HWND native_control) { | 114 void NativeControlWin::NativeControlCreated(HWND native_control) { |
112 // Associate this object with the control's HWND so that WidgetWin can find | 115 // Associate this object with the control's HWND so that WidgetWin can find |
113 // this object when it receives messages from it. | 116 // this object when it receives messages from it. |
114 // Note that we never unset this property. We don't have to. | 117 // Note that we never unset this property. We don't have to. |
115 SetProp(native_control, kNativeControlWinKey, this); | 118 SetProp(native_control, kNativeControlWinKey, this); |
116 | 119 |
| 120 // Subclass so we get WM_KEYDOWN and WM_SETFOCUS messages. |
| 121 original_wndproc_ = |
| 122 win_util::SetWindowProc(native_control, |
| 123 &NativeControlWin::NativeControlWndProc); |
| 124 |
117 Attach(native_control); | 125 Attach(native_control); |
118 // native_view() is now valid. | 126 // native_view() is now valid. |
119 | 127 |
120 // Subclass so we get WM_KEYDOWN message. | |
121 original_wndproc_ = | |
122 win_util::SetWindowProc(native_control, | |
123 &NativeControlWin::NativeControlWndProc); | |
124 | |
125 // Update the newly created HWND with any resident enabled state. | 128 // Update the newly created HWND with any resident enabled state. |
126 EnableWindow(native_view(), IsEnabled()); | 129 EnableWindow(native_view(), IsEnabled()); |
127 | 130 |
128 // This message ensures that the focus border is shown. | 131 // This message ensures that the focus border is shown. |
129 SendMessage(native_view(), WM_CHANGEUISTATE, | 132 SendMessage(native_view(), WM_CHANGEUISTATE, |
130 MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0); | 133 MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0); |
131 } | 134 } |
132 | 135 |
133 DWORD NativeControlWin::GetAdditionalExStyle() const { | 136 DWORD NativeControlWin::GetAdditionalExStyle() const { |
134 // If the UI for the view is mirrored, we should make sure we add the | 137 // If the UI for the view is mirrored, we should make sure we add the |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 UINT message, | 179 UINT message, |
177 WPARAM w_param, | 180 WPARAM w_param, |
178 LPARAM l_param) { | 181 LPARAM l_param) { |
179 NativeControlWin* native_control = | 182 NativeControlWin* native_control = |
180 static_cast<NativeControlWin*>(GetProp(window, kNativeControlWinKey)); | 183 static_cast<NativeControlWin*>(GetProp(window, kNativeControlWinKey)); |
181 DCHECK(native_control); | 184 DCHECK(native_control); |
182 | 185 |
183 if (message == WM_KEYDOWN && | 186 if (message == WM_KEYDOWN && |
184 native_control->OnKeyDown(static_cast<int>(w_param))) { | 187 native_control->OnKeyDown(static_cast<int>(w_param))) { |
185 return 0; | 188 return 0; |
| 189 } else if (message == WM_SETFOCUS) { |
| 190 // Let the focus manager know that the focus changed. |
| 191 FocusManager* focus_manager = native_control->GetFocusManager(); |
| 192 if (focus_manager) { |
| 193 focus_manager->SetFocusedView(native_control->focus_view()); |
| 194 } else { |
| 195 NOTREACHED(); |
| 196 } |
186 } else if (message == WM_DESTROY) { | 197 } else if (message == WM_DESTROY) { |
187 WNDPROC old_wndproc = | 198 win_util::SetWindowProc(window, native_control->original_wndproc_); |
188 win_util::SetWindowProc(window, native_control->original_wndproc_); | |
189 DCHECK(old_wndproc == &NativeControlWin::NativeControlWndProc); | |
190 } | 199 } |
191 | 200 |
192 return CallWindowProc(native_control->original_wndproc_, window, message, | 201 return CallWindowProc(native_control->original_wndproc_, window, message, |
193 w_param, l_param); | 202 w_param, l_param); |
194 } | 203 } |
195 | 204 |
196 } // namespace views | 205 } // namespace views |
OLD | NEW |