OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome_frame/infobars/internal/host_window_manager.h" | |
6 | |
7 #include "chrome_frame/infobars/internal/displaced_window_manager.h" | |
8 | |
9 namespace { | |
10 | |
11 const wchar_t kIeTabContentParentWindowClass[] = L"Shell DocObject View"; | |
12 | |
13 } // namespace | |
14 | |
15 // Receives notification when the displaced window is destroyed, and forwards | |
16 // displaced window dimensions on to HostWindowManager::Delegate. | |
17 class HostWindowManager::DisplacedWindowDelegate | |
18 : public DisplacedWindowManager::Delegate { | |
19 public: | |
20 explicit DisplacedWindowDelegate(HostWindowManager* manager); | |
21 virtual ~DisplacedWindowDelegate(); | |
22 | |
23 // DisplacedWindowManager::Delegate implementation | |
24 virtual void AdjustDisplacedWindowDimensions(RECT* rect); | |
25 | |
26 private: | |
27 HostWindowManager* manager_; // Not owned by this instance | |
28 DISALLOW_COPY_AND_ASSIGN(DisplacedWindowDelegate); | |
29 }; // class HostWindowManager::DisplacedWindowDelegate | |
30 | |
31 HostWindowManager::DisplacedWindowDelegate::DisplacedWindowDelegate( | |
32 HostWindowManager* manager) : manager_(manager) { | |
33 } | |
34 | |
35 // Called when the displaced window is destroyed. Try to find a new displaced | |
36 // window. | |
37 HostWindowManager::DisplacedWindowDelegate::~DisplacedWindowDelegate() { | |
38 HWND old_window = *manager_->displaced_window_manager_; | |
39 // Will be deleted in its OnFinalMessage | |
40 manager_->displaced_window_manager_ = NULL; | |
41 | |
42 // Check to see if a new window has already been created. | |
43 if (manager_->FindDisplacedWindow(old_window)) | |
44 manager_->UpdateLayout(); | |
45 } | |
46 | |
47 // Forward this on to our delegate | |
48 void HostWindowManager::DisplacedWindowDelegate:: | |
49 AdjustDisplacedWindowDimensions(RECT* rect) { | |
50 manager_->delegate()->AdjustDisplacedWindowDimensions(rect); | |
51 } | |
52 | |
53 // Callback function for EnumChildWindows (looks for a window with class | |
54 // kIeTabContentParentWindowClass). | |
55 // | |
56 // lparam must point to an HWND that is either NULL or the HWND of the displaced | |
57 // window that is being destroyed. We will ignore that window if we come across | |
58 // it, and update lparam to point to the new displaced window if it is found. | |
59 static BOOL CALLBACK FindDisplacedWindowProc(HWND hwnd, LPARAM lparam) { | |
60 DCHECK(lparam != NULL); | |
61 HWND* window_handle = reinterpret_cast<HWND*>(lparam); | |
62 | |
63 if (hwnd == *window_handle) | |
64 return TRUE; // Skip this, it's the old displaced window. | |
65 | |
66 // Variable to hold the class name. The size does not matter as long as it | |
67 // is at least can hold kIeTabContentParentWindowClass. | |
68 wchar_t class_name[100]; | |
69 if (::GetClassName(hwnd, class_name, arraysize(class_name)) && | |
70 lstrcmpi(kIeTabContentParentWindowClass, class_name) == 0) { | |
71 // We found the window. Return its handle and stop enumeration. | |
72 *window_handle = hwnd; | |
73 return FALSE; | |
74 } | |
75 return TRUE; | |
76 } | |
77 | |
78 HostWindowManager::HostWindowManager() : displaced_window_manager_(NULL) { | |
79 } | |
80 | |
81 HostWindowManager::~HostWindowManager() { | |
82 // If we are holding a displaced_window_manager_, it means that | |
83 // OnDisplacedWindowManagerDestroyed has not been called yet, and therefore | |
84 // our DisplacedWindowDelegate might still be around, ready to invoke us. | |
85 // Fail fast to prevent a call into lala-land. | |
86 CHECK(displaced_window_manager_ == NULL); | |
87 } | |
88 | |
89 void HostWindowManager::UpdateLayout() { | |
90 if (FindDisplacedWindow(NULL)) | |
91 displaced_window_manager_->UpdateLayout(); | |
92 } | |
93 | |
94 bool HostWindowManager::FindDisplacedWindow(HWND old_window) { | |
95 if (displaced_window_manager_ == NULL || | |
96 *displaced_window_manager_ == old_window) { | |
97 // Find the window which is the container for the HTML view (parent of | |
98 // the content). When the displaced window is destroyed, the new one might | |
99 // already exist, so we say "find a displaced window that is not this | |
100 // (old) one". | |
101 HWND displaced_window = old_window; | |
102 ::EnumChildWindows(*this, FindDisplacedWindowProc, | |
103 reinterpret_cast<LPARAM>(&displaced_window)); | |
104 | |
105 if (displaced_window == old_window) { | |
106 LOG(ERROR) << "Failed to locate IE renderer HWND to displace for " | |
107 << "Infobar installation."; | |
108 } else { | |
109 scoped_ptr<DisplacedWindowManager> displaced_window_manager( | |
110 new DisplacedWindowManager()); | |
111 if (displaced_window_manager->Initialize( | |
112 displaced_window, new DisplacedWindowDelegate(this))) { | |
113 displaced_window_manager_ = displaced_window_manager.release(); | |
114 } | |
115 } | |
116 } | |
117 | |
118 return displaced_window_manager_ != NULL; | |
119 } | |
OLD | NEW |