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