#pragma once #define XTR_COMMAND_UPD(cmd) \ ON_UPDATE_COMMAND_UI(cmd, &ThisClass::OnUpdateCommandUI) \ ON_COMMAND_EX(cmd, &ThisClass::OnCommandRun) #define XTR_COMMAND(cmd) \ ON_COMMAND_EX(cmd, &ThisClass::OnCommandRun) namespace xtr::ui { static constexpr auto s_ScrollWidth = 22; static constexpr auto s_TooltipWidth = 400; TEXTMETRIC GlobalTextMetrics(); TEXTMETRIC TextMetricsOf(const CWnd& wndCtrl); CRect LocalCoordinatesFor(const CWnd& wndCtrl); CRect ClientRect(const CWnd& wndCtrl); CRect WindowRect(const CWnd& wndCtrl); CString WindowText(const CWnd& wndCtrl); CString TrimText(CString text); class Header { public: struct Column; private: std::vector columns{}; public: ~Header() = default; Header() = default; Header(const Header&) = delete; Header& operator=(const Header&) = delete; public: enum Alignment : uint8_t { left = LVCFMT_LEFT, right = LVCFMT_RIGHT, center = LVCFMT_CENTER}; struct Column { CString label; Alignment alignment; std::optional width; Column(CString label, Alignment alignment, std::optional width) : label{ label }, alignment{ alignment }, width{ width } {} Column(uint32_t sid, Alignment alignment, std::optional width) : label{ mfc::LoadSID(sid) }, alignment{ alignment }, width{ width } {} }; public: void AddColumn(const Column& newColumn) { columns.emplace_back(newColumn); } private: friend void InitHeaderFor(CListCtrl& listCtr, const Header& header); friend void InitReversedHeaderFor(CListCtrl& listCtr, const Header& header); }; void InitHeaderFor(CListCtrl& listCtr, const Header& header); void InitReversedHeaderFor(CListCtrl& listCtr, const Header& header); } // namespace xtr::ui