Review URL: http://codereview.chromium.org/12434
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5990 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@ -257,6 +257,12 @@ void* GetWindowUserData(HWND hwnd) {
|
||||
// installed.
|
||||
static const wchar_t* const kHandlerKey = L"__ORIGINAL_MESSAGE_HANDLER__";
|
||||
|
||||
bool IsSubclassed(HWND window, WNDPROC subclass_proc) {
|
||||
WNDPROC original_handler =
|
||||
reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC));
|
||||
return original_handler == subclass_proc;
|
||||
}
|
||||
|
||||
bool Subclass(HWND window, WNDPROC subclass_proc) {
|
||||
WNDPROC original_handler =
|
||||
reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC));
|
||||
|
@ -50,6 +50,9 @@ bool GetLogonSessionOnlyDACL(SECURITY_DESCRIPTOR** security_descriptor);
|
||||
// Useful for subclassing a HWND. Returns the previous window procedure.
|
||||
WNDPROC SetWindowProc(HWND hwnd, WNDPROC wndproc);
|
||||
|
||||
// Returns true if the existing window procedure is the same as |subclass_proc|.
|
||||
bool IsSubclassed(HWND window, WNDPROC subclass_proc);
|
||||
|
||||
// Subclasses a window, replacing its existing window procedure with the
|
||||
// specified one. Returns true if the current window procedure was replaced,
|
||||
// false if the window has already been subclassed with the specified
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/histogram.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/win_util.h"
|
||||
#include "chrome/browser/render_widget_host_view_win.h"
|
||||
@ -30,6 +31,16 @@ static const wchar_t* const kFocusManagerKey = L"__VIEW_CONTAINER__";
|
||||
// - prevent tab key events from being sent to views.
|
||||
static const wchar_t* const kViewKey = L"__CHROME_VIEW__";
|
||||
|
||||
// A property set to 1 to indicate whether the focus manager has subclassed that
|
||||
// window. We are doing this to ensure we are not subclassing several times.
|
||||
// Subclassing twice is not a problem if no one is subclassing the HWND between
|
||||
// the 2 subclassings (the 2nd subclassing is ignored since the WinProc is the
|
||||
// same as the current one). However if some other app goes and subclasses the
|
||||
// HWND between the 2 subclassings, we will end up subclassing twice.
|
||||
// This flag lets us test that whether we have or not subclassed yet.
|
||||
static const wchar_t* const kFocusSubclassInstalled =
|
||||
L"__FOCUS_SUBCLASS_INSTALLED__";
|
||||
|
||||
namespace views {
|
||||
|
||||
static bool IsCompatibleWithMouseWheelRedirection(HWND window) {
|
||||
@ -209,15 +220,29 @@ FocusManager* FocusManager::CreateFocusManager(HWND window,
|
||||
// static
|
||||
void FocusManager::InstallFocusSubclass(HWND window, View* view) {
|
||||
DCHECK(window);
|
||||
win_util::Subclass(window, &FocusWindowCallback);
|
||||
|
||||
bool already_subclassed =
|
||||
reinterpret_cast<bool>(GetProp(window,
|
||||
kFocusSubclassInstalled));
|
||||
if (already_subclassed &&
|
||||
!win_util::IsSubclassed(window, &FocusWindowCallback)) {
|
||||
NOTREACHED() << "window sub-classed by someone other than the FocusManager";
|
||||
// Track in UMA so we know if this case happens.
|
||||
UMA_HISTOGRAM_COUNTS(L"FocusManager.MultipleSubclass", 1);
|
||||
} else {
|
||||
win_util::Subclass(window, &FocusWindowCallback);
|
||||
SetProp(window, kFocusSubclassInstalled, reinterpret_cast<HANDLE>(true));
|
||||
}
|
||||
if (view)
|
||||
SetProp(window, kViewKey, view);
|
||||
}
|
||||
|
||||
void FocusManager::UninstallFocusSubclass(HWND window) {
|
||||
DCHECK(window);
|
||||
if (win_util::Unsubclass(window, &FocusWindowCallback))
|
||||
if (win_util::Unsubclass(window, &FocusWindowCallback)) {
|
||||
RemoveProp(window, kViewKey);
|
||||
RemoveProp(window, kFocusSubclassInstalled);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
|
Reference in New Issue
Block a user