1 // Copyright 2013 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.
5 #include "chrome_frame/turndown_prompt/turndown_prompt_window.h"
11 #include "base/compiler_specific.h"
12 #include "chrome_frame/ready_mode/internal/url_launcher.h"
13 #include "chrome_frame/simple_resource_loader.h"
14 #include "chrome_frame/utils.h"
15 #include "grit/chrome_frame_dialogs.h"
16 #include "grit/chrome_frame_resources.h"
17 #include "grit/chromium_strings.h"
19 // atlctrlx.h requires 'min' and 'max' macros, the definition of which conflicts
20 // with STL headers. Hence we include them out of the order defined by style
21 // guidelines. As a result you may not refer to std::min or std::max in this
23 #include <minmax.h> // NOLINT
24 #include <atlctrlx.h> // NOLINT
27 const uint32 kBitmapImageSize
= 18;
30 // WTL's CBitmapButton's drawing code is horribly broken when using transparent
31 // images (specifically, it doesn't clear the background between redraws).
33 class CFBitmapButton
: public CBitmapButtonImpl
<CFBitmapButton
>
36 DECLARE_WND_SUPERCLASS(_T("WTL_BitmapButton"), GetWndClassName())
39 : CBitmapButtonImpl
<CFBitmapButton
>(BMPBTN_AUTOSIZE
| BMPBTN_HOVER
,
42 // "Overridden" from CBitmapButtonImpl via template hackery. See
43 // CBitmapButtonImpl::OnPaint() in atlctrlx.h for details.
44 void DoPaint(CDCHandle dc
) {
47 dc
.FillRect(&rc
, reinterpret_cast<HBRUSH
>(COLOR_BTNFACE
+ 1));
49 // Call original implementation.
50 CBitmapButtonImpl
<CFBitmapButton
>::DoPaint(dc
);
55 base::WeakPtr
<TurndownPromptWindow
> TurndownPromptWindow::CreateInstance(
56 InfobarContent::Frame
* frame
,
57 UrlLauncher
* url_launcher
,
58 const base::Closure
& uninstall_callback
) {
59 DCHECK(frame
!= NULL
);
60 DCHECK(url_launcher
!= NULL
);
62 base::WeakPtr
<TurndownPromptWindow
> instance(
63 (new TurndownPromptWindow(frame
, url_launcher
, uninstall_callback
))
64 ->weak_ptr_factory_
.GetWeakPtr());
66 DCHECK(!instance
->IsWindow());
68 if (instance
->Create(frame
->GetFrameWindow()) == NULL
) {
69 DPLOG(ERROR
) << "Failed to create HWND for TurndownPromptWindow.";
70 return base::WeakPtr
<TurndownPromptWindow
>();
73 // Subclass the "Learn more." text to make it behave like a link. Clicks are
74 // routed to OnLearnMore().
75 CWindow rte
= instance
->GetDlgItem(IDC_TD_PROMPT_LINK
);
76 instance
->link_
.reset(new CHyperLink());
77 instance
->link_
->SubclassWindow(rte
);
78 instance
->link_
->SetHyperLinkExtendedStyle(HLINK_NOTIFYBUTTON
,
81 SetupBitmapButton(instance
.get());
83 // Substitute the proper text given the current IE version.
84 CWindow text
= instance
->GetDlgItem(IDC_TD_PROMPT_MESSAGE
);
85 string16
prompt_text(GetPromptText());
86 if (!prompt_text
.empty())
87 text
.SetWindowText(prompt_text
.c_str());
92 TurndownPromptWindow::TurndownPromptWindow(
93 InfobarContent::Frame
* frame
,
94 UrlLauncher
* url_launcher
,
95 const base::Closure
& uninstall_closure
)
97 url_launcher_(url_launcher
),
98 uninstall_closure_(uninstall_closure
),
99 weak_ptr_factory_(this) {
102 TurndownPromptWindow::~TurndownPromptWindow() {}
105 void TurndownPromptWindow::SetupBitmapButton(TurndownPromptWindow
* instance
) {
107 CWindow close_window
= instance
->GetDlgItem(IDDISMISS
);
108 instance
->close_button_
.reset(new CFBitmapButton());
110 // Set the resource instance to the current dll which contains the bitmap.
111 HINSTANCE old_res_module
= _AtlBaseModule
.GetResourceInstance();
112 HINSTANCE this_module
= _AtlBaseModule
.GetModuleInstance();
113 _AtlBaseModule
.SetResourceInstance(this_module
);
115 HBITMAP close_bitmap
= static_cast<HBITMAP
>(
116 LoadImage(this_module
, MAKEINTRESOURCE(IDB_TURNDOWN_PROMPT_CLOSE_BUTTON
),
117 IMAGE_BITMAP
, 0, 0, 0));
119 // Restore the module's resource instance.
120 _AtlBaseModule
.SetResourceInstance(old_res_module
);
122 // Create the image list with the appropriate size and colour mask.
123 instance
->close_button_
->m_ImageList
.Create(kBitmapImageSize
,
125 ILC_COLOR8
| ILC_MASK
, 4, 0);
126 instance
->close_button_
->m_ImageList
.Add(close_bitmap
, RGB(255, 0, 255));
127 instance
->close_button_
->m_ImageList
.SetBkColor(CLR_NONE
);
129 // Free up the original bitmap.
130 DeleteObject(close_bitmap
);
132 // Configure the button states and initialize the button.
133 instance
->close_button_
->SetImages(0, 1, 2, 3);
134 instance
->close_button_
->SubclassWindow(close_window
);
136 // The CDialogResize() implementation incorrectly captures the size
137 // of the bitmap image button. Reset it here to ensure that resizing works
140 // Find the resize data. The parameters here must match the resize map in
141 // turndown_prompt_window.h.
142 _AtlDlgResizeData resize_params
= { IDDISMISS
, DLSZ_CENTER_Y
| DLSZ_MOVE_X
};
143 int resize_index
= instance
->m_arrData
.Find(resize_params
);
144 DCHECK(resize_index
> -1 && resize_index
< instance
->m_arrData
.GetSize());
146 // Fiddle CDialogResize's internal data to fix up the size for the image
148 _AtlDlgResizeData
& resize_data
= instance
->m_arrData
[resize_index
];
149 resize_data
.m_rect
.right
= resize_data
.m_rect
.left
+ kBitmapImageSize
;
150 resize_data
.m_rect
.top
= 0;
151 resize_data
.m_rect
.bottom
= kBitmapImageSize
;
154 void TurndownPromptWindow::OnFinalMessage(HWND
) {
158 void TurndownPromptWindow::OnDestroy() {
159 close_button_
->m_ImageList
.Destroy();
163 BOOL
TurndownPromptWindow::OnInitDialog(CWindow wndFocus
, LPARAM lInitParam
) {
164 DlgResize_Init(false); // false => 'no gripper'
168 LRESULT
TurndownPromptWindow::OnLearnMore(WORD
/*wParam*/,
170 BOOL
& /*bHandled*/) {
171 url_launcher_
->LaunchUrl(SimpleResourceLoader::Get(
172 IDS_CHROME_FRAME_TURNDOWN_LEARN_MORE_URL
));
176 LRESULT
TurndownPromptWindow::OnUninstall(WORD
/*wNotifyCode*/,
179 BOOL
& /*bHandled*/) {
180 frame_
->CloseInfobar();
181 if (!uninstall_closure_
.is_null())
182 uninstall_closure_
.Run();
186 LRESULT
TurndownPromptWindow::OnDismiss(WORD
/*wNotifyCode*/,
189 BOOL
& /*bHandled*/) {
190 frame_
->CloseInfobar();
195 string16
TurndownPromptWindow::GetPromptText() {
196 IEVersion ie_version
= GetIEVersion();
197 int message_id
= IDS_CHROME_FRAME_TURNDOWN_TEXT_IE_NEWER
;
198 if (ie_version
== IE_6
|| ie_version
== IE_7
|| ie_version
== IE_8
)
199 message_id
= IDS_CHROME_FRAME_TURNDOWN_TEXT_IE_OLDER
;
200 return SimpleResourceLoader::GetInstance()->Get(message_id
);