| 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.h" |
| 6 |
| 7 #include "chrome_frame/infobars/internal/displaced_window.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 |