// CSlotTableCtrl.cpp #include "stdafx.h" #include "CSlotTableCtrl.h" BEGIN_MESSAGE_MAP(CSlotTableCtrl, CWnd) ON_WM_PAINT() ON_WM_ERASEBKGND() END_MESSAGE_MAP() BOOL CSlotTableCtrl::Create(CWnd* pParent, const RECT& rc, UINT nID) { CString className = AfxRegisterWndClass( CS_HREDRAW | CS_VREDRAW, ::LoadCursor(NULL, IDC_ARROW), (HBRUSH)::GetStockObject(WHITE_BRUSH), NULL); return CWnd::CreateEx(0, className, _T(""), WS_CHILD | WS_VISIBLE, rc, pParent, nID); } void CSlotTableCtrl::SetRows(const std::vector& rows) { m_rows = rows; if (m_rows.size() > 8) { m_rows.resize(8); } Invalidate(); } void CSlotTableCtrl::SetTitle(const CString& title) { m_title = title; Invalidate(); } void CSlotTableCtrl::SetRowHeight(int height) { if (height < 14) height = 14; if (height > 40) height = 40; m_rowHeight = height; Invalidate(); } void CSlotTableCtrl::SetPadding(int padding) { if (padding < 2) padding = 2; if (padding > 16) padding = 16; m_padding = padding; Invalidate(); } void CSlotTableCtrl::SetHeaderHeight(int height) { if (height < 16) height = 16; if (height > 40) height = 40; m_headerHeight = height; Invalidate(); } void CSlotTableCtrl::SetTitleHeight(int height) { if (height < 16) height = 16; if (height > 40) height = 40; m_titleHeight = height; Invalidate(); } void CSlotTableCtrl::SetLineColor(COLORREF color) { m_lineColor = color; Invalidate(); } void CSlotTableCtrl::SetHeaderBgColor(COLORREF color) { m_headerBgColor = color; Invalidate(); } void CSlotTableCtrl::Clear() { m_rows.clear(); m_title.Empty(); Invalidate(); } BOOL CSlotTableCtrl::OnEraseBkgnd(CDC* /*pDC*/) { return TRUE; } void CSlotTableCtrl::OnPaint() { CPaintDC dc(this); CRect rcClient; GetClientRect(&rcClient); CFont* pOldFont = (CFont*)dc.SelectStockObject(DEFAULT_GUI_FONT); dc.SetBkMode(TRANSPARENT); const COLORREF kBorder = m_lineColor; const COLORREF kHeaderBg = m_headerBgColor; const COLORREF kGrid = m_lineColor; const COLORREF kText = RGB(30, 30, 30); const COLORREF kTitle = RGB(80, 80, 80); dc.FillSolidRect(&rcClient, RGB(255, 255, 255)); dc.SetTextColor(kText); const int titleHeight = m_title.IsEmpty() ? 0 : m_titleHeight; const int headerHeight = m_headerHeight; const int rowHeight = m_rowHeight; CRect rcTitle = rcClient; rcTitle.bottom = rcTitle.top + titleHeight; if (titleHeight > 0) { dc.FillSolidRect(&rcTitle, RGB(250, 250, 250)); CRect rcTitleText = rcTitle; rcTitleText.DeflateRect(6, 2); dc.SetTextColor(kTitle); dc.DrawText(m_title, &rcTitleText, DT_LEFT | DT_VCENTER | DT_SINGLELINE); dc.SetTextColor(kText); } CRect rcHeader = rcClient; rcHeader.top += titleHeight; rcHeader.bottom = rcHeader.top + headerHeight; dc.FillSolidRect(&rcHeader, kHeaderBg); int totalW = rcClient.Width(); int col1 = max(40, totalW * 20 / 100); int col3 = max(40, totalW * 20 / 100); int col2 = totalW - col1 - col3; if (col2 < 60) col2 = 60; if (col1 + col2 + col3 > totalW) { col3 = max(30, totalW - col1 - col2); } int x1 = rcClient.left; int x2 = x1 + col1; int x3 = x2 + col2; CRect rc; rc = rcHeader; rc.right = x2; rc.DeflateRect(m_padding, 0); dc.DrawText(_T("Slot"), &rc, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); rc = rcHeader; rc.left = x2; rc.right = x3; rc.DeflateRect(m_padding, 0); dc.DrawText(_T("Glass ID"), &rc, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); rc = rcHeader; rc.left = x3; rc.DeflateRect(m_padding, 0); dc.DrawText(_T("G1/G2"), &rc, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); // grid lines dc.FillSolidRect(rcClient.left, rcHeader.bottom - 1, rcClient.Width(), 1, kGrid); dc.FillSolidRect(x2 - 1, rcHeader.top, 1, rcClient.bottom - rcHeader.top, kGrid); dc.FillSolidRect(x3 - 1, rcHeader.top, 1, rcClient.bottom - rcHeader.top, kGrid); int bodyTop = rcHeader.bottom; if (m_rows.empty()) { CRect rcBody = rcClient; rcBody.top = bodyTop + 4; dc.DrawText(_T("No slot data"), &rcBody, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } else { for (size_t i = 0; i < m_rows.size(); ++i) { CRect rcRow = rcClient; rcRow.top = bodyTop + static_cast(i) * rowHeight; rcRow.bottom = rcRow.top + rowHeight; if (rcRow.top >= rcClient.bottom) break; // 行分隔线(最后一行不画,避免底部多一条线) if (i + 1 < m_rows.size() && rcRow.bottom < rcClient.bottom - 1) { dc.FillSolidRect(rcRow.left, rcRow.bottom - 1, rcClient.Width(), 1, kGrid); } CRect rcCell; rcCell = rcRow; rcCell.right = x2; rcCell.DeflateRect(m_padding, 0); dc.DrawText(m_rows[i].slot, &rcCell, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); rcCell = rcRow; rcCell.left = x2; rcCell.right = x3; rcCell.DeflateRect(m_padding, 0); dc.DrawText(m_rows[i].glassId, &rcCell, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); rcCell = rcRow; rcCell.left = x3; rcCell.DeflateRect(m_padding, 0); dc.DrawText(m_rows[i].type, &rcCell, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); } } // border dc.Draw3dRect(&rcClient, kBorder, kBorder); dc.SelectObject(pOldFont); }