// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_UPDATER_WIN_UI_OWNER_DRAW_CONTROLS_H_
#define CHROME_UPDATER_WIN_UI_OWNER_DRAW_CONTROLS_H_
#include <windows.h>
#include "base/win/atl.h"
#include "chrome/updater/win/ui/ui_constants.h"
#include "third_party/wtl/include/atlapp.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
#pragma clang diagnostic ignored "-Wmissing-braces"
#include "third_party/wtl/include/atlctrls.h"
#include "third_party/wtl/include/atlframe.h"
#pragma clang diagnostic pop
namespace updater::ui {
class CaptionButton : public CWindowImpl<CaptionButton, WTL::CButton>,
public WTL::COwnerDraw<CaptionButton> {
public:
DECLARE_WND_CLASS_EX(_T("CaptionButton"),
CS_HREDRAW | CS_VREDRAW,
COLOR_WINDOW)
CaptionButton();
CaptionButton(const CaptionButton&) = delete;
CaptionButton& operator=(const CaptionButton&) = delete;
~CaptionButton() override;
void DrawItem(LPDRAWITEMSTRUCT draw_item_struct);
COLORREF bk_color() const;
void set_bk_color(COLORREF bk_color);
CString tool_tip_text() const;
void set_tool_tip_text(const CString& tool_tip_text);
BEGIN_MSG_MAP(CaptionButton)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
MESSAGE_HANDLER(WM_MOUSEHOVER, OnMouseHover)
MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
CHAIN_MSG_MAP_ALT(COwnerDraw<CaptionButton>, 1)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
private:
virtual HRGN GetButtonRgn(int rgn_width, int rgn_height) = 0;
LRESULT OnCreate(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnMouseMessage(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnEraseBkgnd(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnMouseMove(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnMouseHover(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnMouseLeave(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
COLORREF bk_color_ = RGB(0, 0, 0);
WTL::CBrush foreground_brush_ = ::CreateSolidBrush(kCaptionForegroundColor);
WTL::CBrush frame_brush_ = ::CreateSolidBrush(kCaptionFrameColor);
WTL::CToolTipCtrl tool_tip_window_;
CString tool_tip_text_;
bool is_tracking_mouse_events_ = false;
bool is_mouse_hovering_ = false;
};
class CloseButton : public CaptionButton {
public:
CloseButton();
CloseButton(const CloseButton&) = delete;
CloseButton& operator=(const CloseButton&) = delete;
private:
HRGN GetButtonRgn(int rgn_width, int rgn_height) override;
};
class MinimizeButton : public CaptionButton {
public:
MinimizeButton();
MinimizeButton(const MinimizeButton&) = delete;
MinimizeButton& operator=(const MinimizeButton&) = delete;
private:
HRGN GetButtonRgn(int rgn_width, int rgn_height) override;
};
class MaximizeButton : public CaptionButton {
public:
MaximizeButton();
MaximizeButton(const MaximizeButton&) = delete;
MaximizeButton& operator=(const MaximizeButton&) = delete;
private:
HRGN GetButtonRgn(int rgn_width, int rgn_height) override;
};
class OwnerDrawTitleBarWindow : public CWindowImpl<OwnerDrawTitleBarWindow> {
public:
enum ButtonIds {
kButtonClose = 1,
kButtonMaximize,
kButtonMinimize,
};
DECLARE_WND_CLASS_EX(_T("OwnerDrawTitleBarWindow"),
CS_HREDRAW | CS_VREDRAW,
COLOR_WINDOW)
BEGIN_MSG_MAP(OwnerDrawTitleBarWindow)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
COMMAND_ID_HANDLER(kButtonClose, OnClose)
COMMAND_ID_HANDLER(kButtonMaximize, OnMaximize)
COMMAND_ID_HANDLER(kButtonMinimize, OnMinimize)
REFLECT_NOTIFICATIONS()
END_MSG_MAP()
OwnerDrawTitleBarWindow();
OwnerDrawTitleBarWindow(const OwnerDrawTitleBarWindow&) = delete;
OwnerDrawTitleBarWindow& operator=(const OwnerDrawTitleBarWindow&) = delete;
~OwnerDrawTitleBarWindow() override;
void RecalcLayout();
COLORREF bk_color() const;
void set_bk_color(COLORREF bk_color);
private:
void CreateCaptionButtons();
void UpdateButtonState(const WTL::CMenuHandle& menu,
UINT button_sc_id,
const int button_margin,
CaptionButton* button,
CRect* button_rect);
void MoveWindowToDragPosition(HWND hwnd, int dx, int dy);
LRESULT OnCreate(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnDestroy(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnMouseMove(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnLButtonDown(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnLButtonUp(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnEraseBkgnd(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnClose(WORD notify_code,
WORD id,
HWND hwnd_ctrl,
BOOL& handled); // NOLINT
LRESULT OnMaximize(WORD notify_code,
WORD id,
HWND hwnd_ctrl,
BOOL& handled); // NOLINT
LRESULT OnMinimize(WORD notify_code,
WORD id,
HWND hwnd_ctrl,
BOOL& handled); // NOLINT
CPoint current_drag_position_ = {-1, -1};
COLORREF bk_color_ = RGB(0, 0, 0);
CloseButton close_button_;
MinimizeButton minimize_button_;
};
class OwnerDrawTitleBar {
public:
OwnerDrawTitleBar();
OwnerDrawTitleBar(const OwnerDrawTitleBar&) = delete;
OwnerDrawTitleBar& operator=(const OwnerDrawTitleBar&) = delete;
~OwnerDrawTitleBar();
void CreateOwnerDrawTitleBar(HWND parent_hwnd,
HWND title_bar_spacer_hwnd,
COLORREF bk_color);
void RecalcLayout();
BEGIN_MSG_MAP(OwnerDrawTitleBar)
END_MSG_MAP()
private:
CRect ComputeTitleBarClientRect(HWND parent_hwnd, HWND title_bar_spacer_hwnd);
OwnerDrawTitleBarWindow title_bar_window_;
};
// Customizes the text color and the background color for dialog elements.
//
// Steps:
// - Derive your ATL dialog class from CustomDlgColors.
// - Add a CHAIN_MSG_MAP in your ATL message map to CustomDlgColors.
// CustomDlgColors will handle WM_CTLCOLOR{XXX} in the chained message map.
// - Call SetCustomDlgColors() from OnInitDialog.
class CustomDlgColors {
public:
CustomDlgColors();
CustomDlgColors(const CustomDlgColors&) = delete;
CustomDlgColors& operator=(const CustomDlgColors&) = delete;
~CustomDlgColors();
void SetCustomDlgColors(COLORREF text_color, COLORREF bk_color);
BEGIN_MSG_MAP(CustomDlgColors)
MESSAGE_HANDLER(WM_CTLCOLORDLG, OnCtrlColor)
MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtrlColor)
END_MSG_MAP()
private:
LRESULT OnCtrlColor(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
COLORREF text_color_ = RGB(0xFF, 0xFF, 0xFF);
COLORREF bk_color_ = RGB(0, 0, 0);
WTL::CBrush bk_brush_;
};
class CustomProgressBarCtrl : public CWindowImpl<CustomProgressBarCtrl> {
public:
CustomProgressBarCtrl();
CustomProgressBarCtrl(const CustomProgressBarCtrl&) = delete;
CustomProgressBarCtrl& operator=(const CustomProgressBarCtrl&) = delete;
~CustomProgressBarCtrl() override;
BEGIN_MSG_MAP(CustomProgressBarCtrl)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_TIMER, OnTimer)
MESSAGE_HANDLER(PBM_SETPOS, OnSetPos)
MESSAGE_HANDLER(PBM_SETMARQUEE, OnSetMarquee)
MESSAGE_HANDLER(PBM_SETBARCOLOR, OnSetBarColor)
MESSAGE_HANDLER(PBM_SETBKCOLOR, OnSetBkColor)
END_MSG_MAP()
private:
void GradientFill(HDC dc,
const RECT& rect,
COLORREF top_color,
COLORREF bottom_color);
LRESULT OnEraseBkgnd(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnPaint(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnTimer(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnSetPos(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnSetMarquee(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnSetBarColor(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
LRESULT OnSetBkColor(UINT msg,
WPARAM wparam,
LPARAM lparam,
BOOL& handled); // NOLINT
static constexpr int kMinPosition = 0;
static constexpr int kMaxPosition = 100;
static constexpr int kMarqueeWidth = 20;
static constexpr UINT_PTR kMarqueeTimerId = 111;
bool is_marquee_mode_ = false;
int current_position_ = kMinPosition;
COLORREF bar_color_light_ = kProgressBarLightColor;
COLORREF bar_color_dark_ = kProgressBarDarkColor;
COLORREF empty_fill_color_ = kProgressEmptyFillColor;
WTL::CBrush empty_frame_brush_;
};
} // namespace updater::ui
#endif // CHROME_UPDATER_WIN_UI_OWNER_DRAW_CONTROLS_H_