diff options
Diffstat (limited to 'views/controls/native/native_view_host_win.cc')
-rw-r--r-- | views/controls/native/native_view_host_win.cc | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/views/controls/native/native_view_host_win.cc b/views/controls/native/native_view_host_win.cc index d1a5217..3c05e2a 100644 --- a/views/controls/native/native_view_host_win.cc +++ b/views/controls/native/native_view_host_win.cc @@ -6,10 +6,13 @@ #include "app/gfx/canvas.h" #include "base/logging.h" +#include "base/win_util.h" #include "views/controls/native/native_view_host.h" #include "views/focus/focus_manager.h" #include "views/widget/widget.h" +const wchar_t* kNativeViewHostWinKey = L"__NATIVE_VIEW_HOST_WIN__"; + namespace views { //////////////////////////////////////////////////////////////////////////////// @@ -17,7 +20,8 @@ namespace views { NativeViewHostWin::NativeViewHostWin(NativeViewHost* host) : host_(host), - installed_clip_(false) { + installed_clip_(false), + original_wndproc_(NULL) { } NativeViewHostWin::~NativeViewHostWin() { @@ -37,10 +41,32 @@ void NativeViewHostWin::NativeViewAttached() { // Need to set the HWND's parent before changing its size to avoid flashing. SetParent(host_->native_view(), host_->GetWidget()->GetNativeView()); host_->Layout(); + + // Subclass the appropriate HWND to get focus notifications. + HWND focus_hwnd = host_->focus_native_view(); + DCHECK(focus_hwnd == host_->native_view() || + ::IsChild(host_->native_view(), focus_hwnd)); + original_wndproc_ = + win_util::SetWindowProc(focus_hwnd, + &NativeViewHostWin::NativeViewHostWndProc); + + // We use a property to retrieve the NativeViewHostWin from the window + // procedure. + ::SetProp(focus_hwnd, kNativeViewHostWinKey, this); } void NativeViewHostWin::NativeViewDetaching() { installed_clip_ = false; + + // Restore the original Windows procedure. + DCHECK(original_wndproc_); + WNDPROC wndproc = win_util::SetWindowProc(host_->focus_native_view(), + original_wndproc_); + DCHECK(wndproc == &NativeViewHostWin::NativeViewHostWndProc); + + // Also remove the property, it's not needed anymore. + HANDLE h = ::RemoveProp(host_->focus_native_view(), kNativeViewHostWinKey); + DCHECK(h == this); } void NativeViewHostWin::AddedToWidget() { @@ -116,8 +142,22 @@ void NativeViewHostWin::HideWidget() { SWP_NOREDRAW | SWP_NOOWNERZORDER); } -void NativeViewHostWin::SetFocus() { - ::SetFocus(host_->native_view()); +// static +LRESULT CALLBACK NativeViewHostWin::NativeViewHostWndProc(HWND window, + UINT message, + WPARAM w_param, + LPARAM l_param) { + NativeViewHostWin* native_view_host = + static_cast<NativeViewHostWin*>(::GetProp(window, kNativeViewHostWinKey)); + DCHECK(native_view_host); + + if (message == WM_SETFOCUS) + native_view_host->host_->GotNativeFocus(); + if (message == WM_DESTROY) + native_view_host->host_->Detach(); + + return CallWindowProc(native_view_host->original_wndproc_, + window, message, w_param, l_param); } //////////////////////////////////////////////////////////////////////////////// |