619 lines
18 KiB
C++
619 lines
18 KiB
C++
#include "stdafx.h"
|
|
#include "CIconButton.h"
|
|
|
|
IMPLEMENT_DYNAMIC(CIconButton, CButton)
|
|
|
|
BEGIN_MESSAGE_MAP(CIconButton, CButton)
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_MOUSELEAVE()
|
|
ON_WM_ERASEBKGND()
|
|
END_MESSAGE_MAP()
|
|
|
|
// Colors
|
|
static const COLORREF CLR_NORMAL = RGB(50, 50, 50);
|
|
static const COLORREF CLR_HOVER = RGB(70, 70, 70);
|
|
static const COLORREF CLR_PRESSED = RGB(90, 90, 90);
|
|
static const COLORREF CLR_CLOSE_HOVER = RGB(196, 43, 28);
|
|
static const COLORREF CLR_ICON = RGB(255, 255, 255);
|
|
|
|
CIconButton::CIconButton()
|
|
: m_fnDrawIcon(nullptr)
|
|
, m_bHover(false)
|
|
, m_bIsCloseButton(false)
|
|
, m_bTracking(false)
|
|
{
|
|
}
|
|
|
|
CIconButton::~CIconButton()
|
|
{
|
|
}
|
|
|
|
void CIconButton::PreSubclassWindow()
|
|
{
|
|
// Ensure BS_OWNERDRAW is set
|
|
ModifyStyle(0, BS_OWNERDRAW);
|
|
CButton::PreSubclassWindow();
|
|
}
|
|
|
|
void CIconButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
|
|
{
|
|
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
|
|
CRect rc(lpDIS->rcItem);
|
|
bool bPressed = (lpDIS->itemState & ODS_SELECTED) != 0;
|
|
|
|
// Pick background color
|
|
COLORREF clrBg = CLR_NORMAL;
|
|
if (bPressed) {
|
|
clrBg = CLR_PRESSED;
|
|
} else if (m_bHover) {
|
|
clrBg = m_bIsCloseButton ? CLR_CLOSE_HOVER : CLR_HOVER;
|
|
}
|
|
|
|
// Draw rounded-rect background
|
|
CBrush brush(clrBg);
|
|
CPen pen(PS_SOLID, 1, clrBg);
|
|
CPen* pOldPen = pDC->SelectObject(&pen);
|
|
CBrush* pOldBrush = pDC->SelectObject(&brush);
|
|
pDC->RoundRect(rc, CPoint(4, 4));
|
|
pDC->SelectObject(pOldBrush);
|
|
pDC->SelectObject(pOldPen);
|
|
|
|
// Draw icon in a centered 16x16 area
|
|
if (m_fnDrawIcon) {
|
|
int iconSize = 16;
|
|
CRect rcIcon;
|
|
rcIcon.left = rc.left + (rc.Width() - iconSize) / 2;
|
|
rcIcon.top = rc.top + (rc.Height() - iconSize) / 2;
|
|
rcIcon.right = rcIcon.left + iconSize;
|
|
rcIcon.bottom = rcIcon.top + iconSize;
|
|
m_fnDrawIcon(pDC, rcIcon);
|
|
}
|
|
}
|
|
|
|
void CIconButton::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
if (!m_bTracking) {
|
|
TRACKMOUSEEVENT tme = {};
|
|
tme.cbSize = sizeof(tme);
|
|
tme.dwFlags = TME_LEAVE;
|
|
tme.hwndTrack = m_hWnd;
|
|
TrackMouseEvent(&tme);
|
|
m_bTracking = true;
|
|
}
|
|
if (!m_bHover) {
|
|
m_bHover = true;
|
|
Invalidate(FALSE);
|
|
}
|
|
CButton::OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
void CIconButton::OnMouseLeave()
|
|
{
|
|
m_bHover = false;
|
|
m_bTracking = false;
|
|
Invalidate(FALSE);
|
|
CButton::OnMouseLeave();
|
|
}
|
|
|
|
BOOL CIconButton::OnEraseBkgnd(CDC* pDC)
|
|
{
|
|
return TRUE; // prevent flicker
|
|
}
|
|
|
|
// ====================================================================
|
|
// Static icon drawing functions
|
|
// All draw white shapes within the given 16x16 CRect.
|
|
// ====================================================================
|
|
|
|
static CPen* SelectWhitePen(CDC* pDC, CPen& pen, int width = 2)
|
|
{
|
|
pen.CreatePen(PS_SOLID, width, CLR_ICON);
|
|
return pDC->SelectObject(&pen);
|
|
}
|
|
|
|
// Exit Fullscreen: 4 inward-pointing corner arrows
|
|
void CIconButton::DrawIconExitFullscreen(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
int m = 3; // margin from edge
|
|
|
|
// Top-left corner L-shape (pointing inward)
|
|
pDC->MoveTo(rc.left + m, rc.top + m + 5);
|
|
pDC->LineTo(rc.left + m, rc.top + m);
|
|
pDC->LineTo(rc.left + m + 5, rc.top + m);
|
|
|
|
// Top-right corner
|
|
pDC->MoveTo(rc.right - m - 5, rc.top + m);
|
|
pDC->LineTo(rc.right - m, rc.top + m);
|
|
pDC->LineTo(rc.right - m, rc.top + m + 5);
|
|
|
|
// Bottom-left corner
|
|
pDC->MoveTo(rc.left + m, rc.bottom - m - 5);
|
|
pDC->LineTo(rc.left + m, rc.bottom - m);
|
|
pDC->LineTo(rc.left + m + 5, rc.bottom - m);
|
|
|
|
// Bottom-right corner
|
|
pDC->MoveTo(rc.right - m - 5, rc.bottom - m);
|
|
pDC->LineTo(rc.right - m, rc.bottom - m);
|
|
pDC->LineTo(rc.right - m, rc.bottom - m - 5);
|
|
|
|
// Inner square
|
|
int inset = 5;
|
|
CRect inner(rc.left + inset, rc.top + inset, rc.right - inset, rc.bottom - inset);
|
|
pDC->SelectStockObject(NULL_BRUSH);
|
|
pDC->Rectangle(inner);
|
|
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Play: filled right-pointing triangle
|
|
void CIconButton::DrawIconPlay(CDC* pDC, const CRect& rc)
|
|
{
|
|
CBrush brush(CLR_ICON);
|
|
CBrush* pOldBrush = pDC->SelectObject(&brush);
|
|
CPen pen(PS_SOLID, 1, CLR_ICON);
|
|
CPen* pOldPen = pDC->SelectObject(&pen);
|
|
|
|
int cx = rc.CenterPoint().x;
|
|
int cy = rc.CenterPoint().y;
|
|
POINT pts[3] = {
|
|
{ rc.left + 3, rc.top + 2 },
|
|
{ rc.right - 2, cy },
|
|
{ rc.left + 3, rc.bottom - 2 }
|
|
};
|
|
pDC->Polygon(pts, 3);
|
|
|
|
pDC->SelectObject(pOldBrush);
|
|
pDC->SelectObject(pOldPen);
|
|
}
|
|
|
|
// Pause: two vertical bars
|
|
void CIconButton::DrawIconPause(CDC* pDC, const CRect& rc)
|
|
{
|
|
CBrush brush(CLR_ICON);
|
|
int barW = 3;
|
|
int gap = 3;
|
|
int totalW = barW * 2 + gap;
|
|
int x = rc.left + (rc.Width() - totalW) / 2;
|
|
int y1 = rc.top + 2;
|
|
int y2 = rc.bottom - 2;
|
|
|
|
pDC->FillSolidRect(x, y1, barW, y2 - y1, CLR_ICON);
|
|
pDC->FillSolidRect(x + barW + gap, y1, barW, y2 - y1, CLR_ICON);
|
|
}
|
|
|
|
// Lock: closed padlock (U-shackle + body)
|
|
void CIconButton::DrawIconLock(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
|
|
int cx = rc.CenterPoint().x;
|
|
// Shackle (arc)
|
|
pDC->Arc(cx - 4, rc.top + 1, cx + 4, rc.top + 9, cx + 4, rc.top + 5, cx - 4, rc.top + 5);
|
|
|
|
// Body rectangle
|
|
CBrush brush(CLR_ICON);
|
|
CBrush* pOldBrush = pDC->SelectObject(&brush);
|
|
pDC->Rectangle(cx - 5, rc.top + 7, cx + 5, rc.bottom - 1);
|
|
pDC->SelectObject(pOldBrush);
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Unlock: open padlock
|
|
void CIconButton::DrawIconUnlock(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
|
|
int cx = rc.CenterPoint().x;
|
|
// Shackle (open - shifted up and right)
|
|
pDC->Arc(cx - 4, rc.top - 1, cx + 4, rc.top + 7, cx + 4, rc.top + 3, cx - 4, rc.top + 3);
|
|
|
|
// Body rectangle
|
|
CBrush brush(CLR_ICON);
|
|
CBrush* pOldBrush = pDC->SelectObject(&brush);
|
|
pDC->Rectangle(cx - 5, rc.top + 7, cx + 5, rc.bottom - 1);
|
|
pDC->SelectObject(pOldBrush);
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Arrow Down: chevron pointing down
|
|
void CIconButton::DrawIconArrowDown(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
int cx = rc.CenterPoint().x;
|
|
int cy = rc.CenterPoint().y;
|
|
pDC->MoveTo(rc.left + 3, cy - 3);
|
|
pDC->LineTo(cx, cy + 3);
|
|
pDC->LineTo(rc.right - 3, cy - 3);
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Arrow Up: chevron pointing up
|
|
void CIconButton::DrawIconArrowUp(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
int cx = rc.CenterPoint().x;
|
|
int cy = rc.CenterPoint().y;
|
|
pDC->MoveTo(rc.left + 3, cy + 3);
|
|
pDC->LineTo(cx, cy - 3);
|
|
pDC->LineTo(rc.right - 3, cy + 3);
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Arrow Left: chevron pointing left
|
|
void CIconButton::DrawIconArrowLeft(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
int cx = rc.CenterPoint().x;
|
|
int cy = rc.CenterPoint().y;
|
|
pDC->MoveTo(cx + 3, rc.top + 3);
|
|
pDC->LineTo(cx - 3, cy);
|
|
pDC->LineTo(cx + 3, rc.bottom - 3);
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Arrow Right: chevron pointing right
|
|
void CIconButton::DrawIconArrowRight(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
int cx = rc.CenterPoint().x;
|
|
int cy = rc.CenterPoint().y;
|
|
pDC->MoveTo(cx - 3, rc.top + 3);
|
|
pDC->LineTo(cx + 3, cy);
|
|
pDC->LineTo(cx - 3, rc.bottom - 3);
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Opacity Full: filled circle
|
|
void CIconButton::DrawIconOpacityFull(CDC* pDC, const CRect& rc)
|
|
{
|
|
CBrush brush(CLR_ICON);
|
|
CPen pen(PS_SOLID, 1, CLR_ICON);
|
|
CPen* pOldPen = pDC->SelectObject(&pen);
|
|
CBrush* pOldBrush = pDC->SelectObject(&brush);
|
|
int inset = 3;
|
|
pDC->Ellipse(rc.left + inset, rc.top + inset, rc.right - inset, rc.bottom - inset);
|
|
pDC->SelectObject(pOldBrush);
|
|
pDC->SelectObject(pOldPen);
|
|
}
|
|
|
|
// Opacity Medium: circle outline + center dot
|
|
void CIconButton::DrawIconOpacityMedium(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
pDC->SelectStockObject(NULL_BRUSH);
|
|
int inset = 3;
|
|
pDC->Ellipse(rc.left + inset, rc.top + inset, rc.right - inset, rc.bottom - inset);
|
|
|
|
// Center dot
|
|
int cx = rc.CenterPoint().x;
|
|
int cy = rc.CenterPoint().y;
|
|
CBrush dotBrush(CLR_ICON);
|
|
CRect dotRc(cx - 2, cy - 2, cx + 2, cy + 2);
|
|
pDC->FillSolidRect(dotRc, CLR_ICON);
|
|
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Opacity Low: circle outline only
|
|
void CIconButton::DrawIconOpacityLow(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
pDC->SelectStockObject(NULL_BRUSH);
|
|
int inset = 3;
|
|
pDC->Ellipse(rc.left + inset, rc.top + inset, rc.right - inset, rc.bottom - inset);
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Screenshot: camera outline
|
|
void CIconButton::DrawIconScreenshot(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
pDC->SelectStockObject(NULL_BRUSH);
|
|
|
|
// Camera body
|
|
pDC->RoundRect(rc.left + 1, rc.top + 4, rc.right - 1, rc.bottom - 1, 3, 3);
|
|
|
|
// Lens (circle)
|
|
int cx = rc.CenterPoint().x;
|
|
int cy = (rc.top + 4 + rc.bottom - 1) / 2;
|
|
pDC->Ellipse(cx - 3, cy - 3, cx + 3, cy + 3);
|
|
|
|
// Flash bump on top
|
|
pDC->MoveTo(cx - 2, rc.top + 4);
|
|
pDC->LineTo(cx - 4, rc.top + 1);
|
|
pDC->LineTo(cx + 4, rc.top + 1);
|
|
pDC->LineTo(cx + 2, rc.top + 4);
|
|
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Switch Screen: two overlapping rectangles with arrow
|
|
void CIconButton::DrawIconSwitchScreen(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
pDC->SelectStockObject(NULL_BRUSH);
|
|
|
|
// Back rectangle (offset top-left)
|
|
pDC->Rectangle(rc.left + 1, rc.top + 1, rc.right - 4, rc.bottom - 4);
|
|
// Front rectangle (offset bottom-right)
|
|
pDC->Rectangle(rc.left + 4, rc.top + 4, rc.right - 1, rc.bottom - 1);
|
|
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Block Input: mouse with X overlay
|
|
void CIconButton::DrawIconBlockInput(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
|
|
// Mouse body outline
|
|
int cx = rc.CenterPoint().x;
|
|
pDC->SelectStockObject(NULL_BRUSH);
|
|
pDC->RoundRect(cx - 4, rc.top + 1, cx + 4, rc.bottom - 1, 4, 4);
|
|
// Mouse wheel line
|
|
pDC->MoveTo(cx, rc.top + 4);
|
|
pDC->LineTo(cx, rc.top + 7);
|
|
|
|
// X overlay (block)
|
|
pDC->MoveTo(rc.left + 2, rc.top + 2);
|
|
pDC->LineTo(rc.right - 2, rc.bottom - 2);
|
|
pDC->MoveTo(rc.right - 2, rc.top + 2);
|
|
pDC->LineTo(rc.left + 2, rc.bottom - 2);
|
|
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Unblock Input: mouse without X
|
|
void CIconButton::DrawIconUnblockInput(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
|
|
// Mouse body outline
|
|
int cx = rc.CenterPoint().x;
|
|
pDC->SelectStockObject(NULL_BRUSH);
|
|
pDC->RoundRect(cx - 4, rc.top + 1, cx + 4, rc.bottom - 1, 4, 4);
|
|
// Mouse wheel line
|
|
pDC->MoveTo(cx, rc.top + 4);
|
|
pDC->LineTo(cx, rc.top + 7);
|
|
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Quality: gear/cog shape (simplified as sliders icon)
|
|
void CIconButton::DrawIconQuality(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
|
|
// Three horizontal slider lines with knobs at different positions
|
|
int x1 = rc.left + 2, x2 = rc.right - 2;
|
|
int y1 = rc.top + 3, y2 = rc.CenterPoint().y, y3 = rc.bottom - 3;
|
|
|
|
// Line 1 with knob left
|
|
pDC->MoveTo(x1, y1); pDC->LineTo(x2, y1);
|
|
pDC->FillSolidRect(x1 + 2, y1 - 2, 4, 4, CLR_ICON);
|
|
|
|
// Line 2 with knob right
|
|
pDC->MoveTo(x1, y2); pDC->LineTo(x2, y2);
|
|
pDC->FillSolidRect(x2 - 6, y2 - 2, 4, 4, CLR_ICON);
|
|
|
|
// Line 3 with knob middle
|
|
pDC->MoveTo(x1, y3); pDC->LineTo(x2, y3);
|
|
int mid = (x1 + x2) / 2;
|
|
pDC->FillSolidRect(mid - 2, y3 - 2, 4, 4, CLR_ICON);
|
|
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Restore Console: Letter "R" (for RDP session restore)
|
|
void CIconButton::DrawIconRestoreConsole(CDC* pDC, const CRect& rc)
|
|
{
|
|
// 创建字体绘制 "R"
|
|
CFont font;
|
|
font.CreateFont(
|
|
rc.Height() + 2, // height - 字体更大
|
|
0, 0, 0, // width, escapement, orientation
|
|
FW_BOLD, // weight - 更粗
|
|
FALSE, FALSE, FALSE, // italic, underline, strikeout
|
|
DEFAULT_CHARSET,
|
|
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY,
|
|
DEFAULT_PITCH | FF_SWISS,
|
|
_T("Arial Black")
|
|
);
|
|
|
|
CFont* pOldFont = pDC->SelectObject(&font);
|
|
pDC->SetTextColor(CLR_ICON);
|
|
pDC->SetBkMode(TRANSPARENT);
|
|
pDC->DrawText(_T("R"), -1, (LPRECT)&rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
|
pDC->SelectObject(pOldFont);
|
|
}
|
|
|
|
// Minimize: horizontal dash
|
|
void CIconButton::DrawIconMinimize(CDC* pDC, const CRect& rc)
|
|
{
|
|
int cy = rc.CenterPoint().y;
|
|
pDC->FillSolidRect(rc.left + 3, cy - 1, rc.Width() - 6, 2, CLR_ICON);
|
|
}
|
|
|
|
// Close: X mark
|
|
void CIconButton::DrawIconClose(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
int m = 3;
|
|
pDC->MoveTo(rc.left + m, rc.top + m);
|
|
pDC->LineTo(rc.right - m, rc.bottom - m);
|
|
pDC->MoveTo(rc.right - m, rc.top + m);
|
|
pDC->LineTo(rc.left + m, rc.bottom - m);
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Info: circle with "i" letter (status info visible)
|
|
void CIconButton::DrawIconInfo(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
|
|
int cx = rc.CenterPoint().x;
|
|
int cy = rc.CenterPoint().y;
|
|
int r = min(rc.Width(), rc.Height()) / 2 - 2;
|
|
|
|
// Circle
|
|
pDC->SelectStockObject(NULL_BRUSH);
|
|
pDC->Ellipse(cx - r, cy - r, cx + r, cy + r);
|
|
|
|
// "i" letter - dot and line
|
|
pDC->FillSolidRect(cx - 1, cy - r + 3, 2, 2, CLR_ICON); // dot
|
|
pDC->MoveTo(cx, cy - 2);
|
|
pDC->LineTo(cx, cy + r - 3); // vertical line
|
|
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Info Hide: circle with "i" and diagonal line (status info hidden)
|
|
void CIconButton::DrawIconInfoHide(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
|
|
int cx = rc.CenterPoint().x;
|
|
int cy = rc.CenterPoint().y;
|
|
int r = min(rc.Width(), rc.Height()) / 2 - 2;
|
|
|
|
// Circle
|
|
pDC->SelectStockObject(NULL_BRUSH);
|
|
pDC->Ellipse(cx - r, cy - r, cx + r, cy + r);
|
|
|
|
// "i" letter - dot and line
|
|
pDC->FillSolidRect(cx - 1, cy - r + 3, 2, 2, CLR_ICON); // dot
|
|
pDC->MoveTo(cx, cy - 2);
|
|
pDC->LineTo(cx, cy + r - 3); // vertical line
|
|
|
|
// Diagonal strike-through
|
|
pDC->MoveTo(rc.left + 2, rc.bottom - 2);
|
|
pDC->LineTo(rc.right - 2, rc.top + 2);
|
|
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Helper function to draw a letter icon (similar to DrawIconRestoreConsole)
|
|
static void DrawLetterIcon(CDC* pDC, const CRect& rc, LPCTSTR letter)
|
|
{
|
|
CFont font;
|
|
font.CreateFont(
|
|
rc.Height() + 2, // height
|
|
0, 0, 0, // width, escapement, orientation
|
|
FW_BOLD, // weight
|
|
FALSE, FALSE, FALSE, // italic, underline, strikeout
|
|
DEFAULT_CHARSET,
|
|
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY,
|
|
DEFAULT_PITCH | FF_SWISS,
|
|
_T("Arial Black")
|
|
);
|
|
|
|
CFont* pOldFont = pDC->SelectObject(&font);
|
|
pDC->SetTextColor(CLR_ICON);
|
|
pDC->SetBkMode(TRANSPARENT);
|
|
pDC->DrawText(letter, -1, (LPRECT)&rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
|
pDC->SelectObject(pOldFont);
|
|
}
|
|
|
|
// Letter X icon
|
|
void CIconButton::DrawIconLetterX(CDC* pDC, const CRect& rc)
|
|
{
|
|
DrawLetterIcon(pDC, rc, _T("X"));
|
|
}
|
|
|
|
// Letter Y icon
|
|
void CIconButton::DrawIconLetterY(CDC* pDC, const CRect& rc)
|
|
{
|
|
DrawLetterIcon(pDC, rc, _T("Y"));
|
|
}
|
|
|
|
// Letter Z icon
|
|
void CIconButton::DrawIconLetterZ(CDC* pDC, const CRect& rc)
|
|
{
|
|
DrawLetterIcon(pDC, rc, _T("Z"));
|
|
}
|
|
|
|
// Audio On: speaker with sound waves
|
|
void CIconButton::DrawIconAudioOn(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
CBrush brush(CLR_ICON);
|
|
CBrush* pOldBrush = pDC->SelectObject(&brush);
|
|
|
|
int cx = rc.CenterPoint().x;
|
|
int cy = rc.CenterPoint().y;
|
|
|
|
// Speaker body (trapezoid shape)
|
|
POINT speaker[6] = {
|
|
{ rc.left + 2, cy - 2 }, // top-left of rectangle
|
|
{ rc.left + 5, cy - 2 }, // top-right of rectangle
|
|
{ rc.left + 8, cy - 5 }, // top of cone
|
|
{ rc.left + 8, cy + 5 }, // bottom of cone
|
|
{ rc.left + 5, cy + 2 }, // bottom-right of rectangle
|
|
{ rc.left + 2, cy + 2 } // bottom-left of rectangle
|
|
};
|
|
pDC->Polygon(speaker, 6);
|
|
|
|
pDC->SelectObject(pOldBrush);
|
|
|
|
// Sound waves (arcs on the right side)
|
|
pDC->SelectStockObject(NULL_BRUSH);
|
|
pDC->Arc(rc.left + 9, cy - 3, rc.left + 13, cy + 3,
|
|
rc.left + 13, cy - 3, rc.left + 13, cy + 3);
|
|
pDC->Arc(rc.left + 11, cy - 5, rc.right - 1, cy + 5,
|
|
rc.right - 1, cy - 5, rc.right - 1, cy + 5);
|
|
|
|
pDC->SelectObject(pOld);
|
|
}
|
|
|
|
// Audio Off: speaker with slash
|
|
void CIconButton::DrawIconAudioOff(CDC* pDC, const CRect& rc)
|
|
{
|
|
CPen pen;
|
|
CPen* pOld = SelectWhitePen(pDC, pen, 2);
|
|
CBrush brush(CLR_ICON);
|
|
CBrush* pOldBrush = pDC->SelectObject(&brush);
|
|
|
|
int cx = rc.CenterPoint().x;
|
|
int cy = rc.CenterPoint().y;
|
|
|
|
// Speaker body (trapezoid shape)
|
|
POINT speaker[6] = {
|
|
{ rc.left + 2, cy - 2 }, // top-left of rectangle
|
|
{ rc.left + 5, cy - 2 }, // top-right of rectangle
|
|
{ rc.left + 8, cy - 5 }, // top of cone
|
|
{ rc.left + 8, cy + 5 }, // bottom of cone
|
|
{ rc.left + 5, cy + 2 }, // bottom-right of rectangle
|
|
{ rc.left + 2, cy + 2 } // bottom-left of rectangle
|
|
};
|
|
pDC->Polygon(speaker, 6);
|
|
|
|
pDC->SelectObject(pOldBrush);
|
|
|
|
// X mark on the right side (muted)
|
|
pDC->MoveTo(rc.left + 10, cy - 3);
|
|
pDC->LineTo(rc.right - 2, cy + 3);
|
|
pDC->MoveTo(rc.right - 2, cy - 3);
|
|
pDC->LineTo(rc.left + 10, cy + 3);
|
|
|
|
pDC->SelectObject(pOld);
|
|
}
|