blob: 17321e021547f2e26efa044bab572a7298cd325c [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome_frame/turndown_prompt/turndown_prompt_window.h"
#include <atlctrls.h>
#include <commctrl.h>
#include <shellapi.h>
#include "base/compiler_specific.h"
#include "chrome_frame/ready_mode/internal/url_launcher.h"
#include "chrome_frame/simple_resource_loader.h"
#include "chrome_frame/utils.h"
#include "grit/chrome_frame_dialogs.h"
#include "grit/chrome_frame_resources.h"
#include "grit/chromium_strings.h"
// atlctrlx.h requires 'min' and 'max' macros, the definition of which conflicts
// with STL headers. Hence we include them out of the order defined by style
// guidelines. As a result you may not refer to std::min or std::max in this
// file.
#include <minmax.h> // NOLINT
#include <atlctrlx.h> // NOLINT
namespace {
const uint32 kBitmapImageSize = 18;
} // namespace
// WTL's CBitmapButton's drawing code is horribly broken when using transparent
// images (specifically, it doesn't clear the background between redraws).
// Fix it here.
class CFBitmapButton: public CBitmapButtonImpl<CFBitmapButton>
{
public:
DECLARE_WND_SUPERCLASS(_T("WTL_BitmapButton"), GetWndClassName())
CFBitmapButton()
: CBitmapButtonImpl<CFBitmapButton>(BMPBTN_AUTOSIZE | BMPBTN_HOVER,
NULL) {}
// "Overridden" from CBitmapButtonImpl via template hackery. See
// CBitmapButtonImpl::OnPaint() in atlctrlx.h for details.
void DoPaint(CDCHandle dc) {
RECT rc = {0};
GetClientRect(&rc);
dc.FillRect(&rc, reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1));
// Call original implementation.
CBitmapButtonImpl<CFBitmapButton>::DoPaint(dc);
}
};
// static
base::WeakPtr<TurndownPromptWindow> TurndownPromptWindow::CreateInstance(
InfobarContent::Frame* frame,
UrlLauncher* url_launcher,
const base::Closure& uninstall_callback) {
DCHECK(frame != NULL);
DCHECK(url_launcher != NULL);
base::WeakPtr<TurndownPromptWindow> instance(
(new TurndownPromptWindow(frame, url_launcher, uninstall_callback))
->weak_ptr_factory_.GetWeakPtr());
DCHECK(!instance->IsWindow());
if (instance->Create(frame->GetFrameWindow()) == NULL) {
DPLOG(ERROR) << "Failed to create HWND for TurndownPromptWindow.";
return base::WeakPtr<TurndownPromptWindow>();
}
// Subclass the "Learn more." text to make it behave like a link. Clicks are
// routed to OnLearnMore().
CWindow rte = instance->GetDlgItem(IDC_TD_PROMPT_LINK);
instance->link_.reset(new CHyperLink());
instance->link_->SubclassWindow(rte);
instance->link_->SetHyperLinkExtendedStyle(HLINK_NOTIFYBUTTON,
HLINK_NOTIFYBUTTON);
SetupBitmapButton(instance.get());
// Substitute the proper text given the current IE version.
CWindow text = instance->GetDlgItem(IDC_TD_PROMPT_MESSAGE);
string16 prompt_text(GetPromptText());
if (!prompt_text.empty())
text.SetWindowText(prompt_text.c_str());
return instance;
}
TurndownPromptWindow::TurndownPromptWindow(
InfobarContent::Frame* frame,
UrlLauncher* url_launcher,
const base::Closure& uninstall_closure)
: frame_(frame),
url_launcher_(url_launcher),
uninstall_closure_(uninstall_closure),
weak_ptr_factory_(this) {
}
TurndownPromptWindow::~TurndownPromptWindow() {}
// static
void TurndownPromptWindow::SetupBitmapButton(TurndownPromptWindow* instance) {
DCHECK(instance);
CWindow close_window = instance->GetDlgItem(IDDISMISS);
instance->close_button_.reset(new CFBitmapButton());
// Set the resource instance to the current dll which contains the bitmap.
HINSTANCE old_res_module = _AtlBaseModule.GetResourceInstance();
HINSTANCE this_module = _AtlBaseModule.GetModuleInstance();
_AtlBaseModule.SetResourceInstance(this_module);
HBITMAP close_bitmap = static_cast<HBITMAP>(
LoadImage(this_module, MAKEINTRESOURCE(IDB_TURNDOWN_PROMPT_CLOSE_BUTTON),
IMAGE_BITMAP, 0, 0, 0));
// Restore the module's resource instance.
_AtlBaseModule.SetResourceInstance(old_res_module);
// Create the image list with the appropriate size and colour mask.
instance->close_button_->m_ImageList.Create(kBitmapImageSize,
kBitmapImageSize,
ILC_COLOR8 | ILC_MASK, 4, 0);
instance->close_button_->m_ImageList.Add(close_bitmap, RGB(255, 0, 255));
instance->close_button_->m_ImageList.SetBkColor(CLR_NONE);
// Free up the original bitmap.
DeleteObject(close_bitmap);
// Configure the button states and initialize the button.
instance->close_button_->SetImages(0, 1, 2, 3);
instance->close_button_->SubclassWindow(close_window);
// The CDialogResize() implementation incorrectly captures the size
// of the bitmap image button. Reset it here to ensure that resizing works
// as desired.
// Find the resize data. The parameters here must match the resize map in
// turndown_prompt_window.h.
_AtlDlgResizeData resize_params = { IDDISMISS, DLSZ_CENTER_Y | DLSZ_MOVE_X };
int resize_index = instance->m_arrData.Find(resize_params);
DCHECK(resize_index > -1 && resize_index < instance->m_arrData.GetSize());
// Fiddle CDialogResize's internal data to fix up the size for the image
// control.
_AtlDlgResizeData& resize_data = instance->m_arrData[resize_index];
resize_data.m_rect.right = resize_data.m_rect.left + kBitmapImageSize;
resize_data.m_rect.top = 0;
resize_data.m_rect.bottom = kBitmapImageSize;
}
void TurndownPromptWindow::OnFinalMessage(HWND) {
delete this;
}
void TurndownPromptWindow::OnDestroy() {
close_button_->m_ImageList.Destroy();
frame_ = NULL;
}
BOOL TurndownPromptWindow::OnInitDialog(CWindow wndFocus, LPARAM lInitParam) {
DlgResize_Init(false); // false => 'no gripper'
return TRUE;
}
LRESULT TurndownPromptWindow::OnLearnMore(WORD /*wParam*/,
LPNMHDR /*lParam*/,
BOOL& /*bHandled*/) {
url_launcher_->LaunchUrl(SimpleResourceLoader::Get(
IDS_CHROME_FRAME_TURNDOWN_LEARN_MORE_URL));
return 0;
}
LRESULT TurndownPromptWindow::OnUninstall(WORD /*wNotifyCode*/,
WORD /*wID*/,
HWND /*hWndCtl*/,
BOOL& /*bHandled*/) {
frame_->CloseInfobar();
if (!uninstall_closure_.is_null())
uninstall_closure_.Run();
return 0;
}
LRESULT TurndownPromptWindow::OnDismiss(WORD /*wNotifyCode*/,
WORD /*wID*/,
HWND /*hWndCtl*/,
BOOL& /*bHandled*/) {
frame_->CloseInfobar();
return 0;
}
// static
string16 TurndownPromptWindow::GetPromptText() {
IEVersion ie_version = GetIEVersion();
int message_id = IDS_CHROME_FRAME_TURNDOWN_TEXT_IE_NEWER;
if (ie_version == IE_6 || ie_version == IE_7 || ie_version == IE_8)
message_id = IDS_CHROME_FRAME_TURNDOWN_TEXT_IE_OLDER;
return SimpleResourceLoader::GetInstance()->Get(message_id);
}