// CEquipmentDlg.cpp: 实现文件 // #include "stdafx.h" #include "Servo.h" #include "CHMPropertyDlg.h" #include "afxdialogex.h" #include // CEquipmentDlg 对话框 IMPLEMENT_DYNAMIC(CHMPropertyDlg, CDialogEx) CHMPropertyDlg::CHMPropertyDlg(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_DIALOG_PROPERTY, pParent) { m_crBkgnd = APPDLG_BACKGROUND_COLOR; m_hbrBkgnd = nullptr; m_nWndWidth = 0; m_nWndHeight = 0; m_pTab = nullptr; } CHMPropertyDlg::CHMPropertyDlg(const char* pszTitle, int width, int height) : CDialogEx(IDD_DIALOG_PROPERTY, nullptr) { m_crBkgnd = APPDLG_BACKGROUND_COLOR; m_hbrBkgnd = nullptr; m_nWndWidth = width; m_nWndHeight = height; m_strTitle = pszTitle; m_pTab = nullptr; } CHMPropertyDlg::~CHMPropertyDlg() { } void CHMPropertyDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CHMPropertyDlg, CDialogEx) ON_WM_CTLCOLOR() ON_WM_DESTROY() ON_WM_SIZE() ON_NOTIFY(BYHMTAB_SEL_CHANGED, IDC_TAB1, &CHMPropertyDlg::OnTabSelChanged) ON_BN_CLICKED(IDOK, &CHMPropertyDlg::OnBnClickedOk) ON_BN_CLICKED(IDC_BUTTON_APPLY, &CHMPropertyDlg::OnBnClickedButtonApply) END_MESSAGE_MAP() // CEquipmentDlg 消息处理程序 void CHMPropertyDlg::addPage(CHMPropertyPage* pPage, const char* pszName) { pPage->SetWindowTextA(pszName); m_pages.push_back(pPage); } BOOL CHMPropertyDlg::OnInitDialog() { CDialogEx::OnInitDialog(); if (m_nWndWidth != 0 && m_nWndHeight != 0) { SetWindowPos(nullptr, 0, 0, m_nWndWidth, m_nWndHeight, SWP_NOMOVE); CenterWindow(); } SetWindowText(m_strTitle); // Tab CString strTitle; m_pTab = CHmTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd); m_pTab->SetPaddingLeft(20); m_pTab->SetItemMarginLeft(18); for (int i = 0; i < m_pages.size(); i++) { m_pages[i]->SetParent(this); m_pages[i]->GetWindowText(strTitle); m_pages[i]->OnCreateBtns(); m_pTab->AddItem(strTitle, i == m_pages.size() - 1); } m_pTab->SetCurSel(0); ShowChildPage(0); Resize(); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } HBRUSH CHMPropertyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); if (nCtlColor == CTLCOLOR_STATIC) { pDC->SetBkColor(m_crBkgnd); pDC->SetTextColor(RGB(0, 0, 0)); } if (m_hbrBkgnd == nullptr) { m_hbrBkgnd = CreateSolidBrush(m_crBkgnd); } return m_hbrBkgnd; } void CHMPropertyDlg::OnDestroy() { CDialogEx::OnDestroy(); for (auto item : m_pages) { item->DestroyWindow(); delete item; } if (m_hbrBkgnd != nullptr) { ::DeleteObject(m_hbrBkgnd); } } void CHMPropertyDlg::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); if (m_pTab == nullptr) return; Resize(); } void CHMPropertyDlg::Resize() { CWnd* pItem; CRect rcClient, rcItem; GetClientRect(&rcClient); int x2, y, y2; x2 = rcClient.right - 12; y = 0; y2 = rcClient.bottom - 12; pItem = GetDlgItem(IDC_TAB1); pItem->GetWindowRect(&rcItem); pItem->MoveWindow(0, y, rcClient.Width(), rcItem.Height()); y += rcItem.Height(); // [确定]按钮 pItem = GetDlgItem(IDOK); pItem->GetWindowRect(&rcItem); pItem->MoveWindow(x2 - rcItem.Width(), y2 - rcItem.Height(), rcItem.Width(), rcItem.Height()); x2 -= rcItem.Width(); x2 -= 8; // [应用]按钮 pItem = GetDlgItem(IDC_BUTTON_APPLY); pItem->GetWindowRect(&rcItem); pItem->MoveWindow(x2 - rcItem.Width(), y2 - rcItem.Height(), rcItem.Width(), rcItem.Height()); // 当前子页按钮(如果有) int btnY = y2 - rcItem.Height(); int btnX = 12; y2 -= rcItem.Height() + 12; int curIndex = (m_pTab != nullptr) ? m_pTab->GetCurSel() : 0; if (curIndex >= 0 && curIndex < (int)m_pages.size()) { auto& btnMap = m_pages[curIndex]->getBtns(); // 按 BTN_ORDER 排序 std::vector> ordered; for (auto& kv : btnMap) { CButton* btn = kv.second; if (btn == nullptr || !::IsWindow(btn->GetSafeHwnd())) continue; int order = (int)(INT_PTR)::GetProp(btn->GetSafeHwnd(), _T("BTN_ORDER")); ordered.emplace_back(order, btn); } std::sort(ordered.begin(), ordered.end(), [](const auto& a, const auto& b) { return a.first < b.first; }); for (auto& item : ordered) { CButton* btn = item.second; CRect rcBtn; btn->GetWindowRect(&rcBtn); if (rcBtn.Width() <= 0 || rcBtn.Height() <= 0) { rcBtn.SetRect(0, 0, 80, 28); } btn->MoveWindow(btnX, btnY, rcBtn.Width(), rcBtn.Height()); btnX += rcBtn.Width() + 8; } } // 分隔线 pItem = GetDlgItem(IDC_LINE1); pItem->GetWindowRect(&rcItem); pItem->MoveWindow(0, y2, rcClient.Width(), rcItem.Height()); for (auto item : m_pages) { item->MoveWindow(0, y, rcClient.Width(), y2 - y); } } void CHMPropertyDlg::OnTabSelChanged(NMHDR* nmhdr, LRESULT* result) { BYHMTAB_NMHDR* pNmhdrex = (BYHMTAB_NMHDR*)nmhdr; ShowChildPage((int)pNmhdrex->dwData); *result = 0; } void CHMPropertyDlg::ShowChildPage(unsigned int index) { ASSERT(index < m_pages.size()); for (int i = 0; i < m_pages.size(); i++) { m_pages[i]->ShowWindow(i == index ? SW_SHOW : SW_HIDE); } // 隐藏所有页面的按钮 for (auto page : m_pages) { for (auto& kv : page->getBtns()) { CButton* btn = kv.second; if (btn != nullptr && ::IsWindow(btn->GetSafeHwnd())) { btn->ShowWindow(SW_HIDE); } } } // 创建并显示当前页面的按钮 auto& btns = m_pages[index]->getBtns(); if (!btns.empty()) { CRect rcClient; GetClientRect(&rcClient); const int margin = 12; const int spacing = 8; int x = margin; int y = rcClient.bottom - 40; // 预留底部区域 // 按 BTN_ORDER 排序 std::vector> ordered; for (auto& kv : btns) { CButton* btn = kv.second; if (btn == nullptr || !::IsWindow(btn->GetSafeHwnd())) continue; int order = (int)(INT_PTR)::GetProp(btn->GetSafeHwnd(), _T("BTN_ORDER")); ordered.emplace_back(order, btn); } std::sort(ordered.begin(), ordered.end(), [](const auto& a, const auto& b) { return a.first < b.first; }); for (auto& item : ordered) { CButton* btn = item.second; CRect rc; btn->GetWindowRect(&rc); if (rc.Width() <= 0 || rc.Height() <= 0) { rc.SetRect(0, 0, 80, 28); } btn->MoveWindow(x, y, rc.Width(), rc.Height()); btn->ShowWindow(SW_SHOW); x += rc.Width() + spacing; } } } void CHMPropertyDlg::SetWindowSize(int width, int height) { m_nWndWidth = width; m_nWndHeight = height; } void CHMPropertyDlg::OnBnClickedOk() { for (auto item : m_pages) { item->OnApply(); } CDialogEx::OnOK(); } void CHMPropertyDlg::OnBnClickedButtonApply() { for (int i = 0; i < m_pages.size(); i++) { if (m_pages[i]->IsWindowVisible()) { m_pages[i]->OnApply(); } } } BOOL CHMPropertyDlg::OnCommand(WPARAM wParam, LPARAM lParam) { UINT code = HIWORD(wParam); HWND hCtrl = (HWND)lParam; if (code == BN_CLICKED && hCtrl != nullptr) { for (auto page : m_pages) { for (auto& kv : page->getBtns()) { if (kv.second != nullptr && kv.second->GetSafeHwnd() == hCtrl) { page->HandleBtnClick(hCtrl); return TRUE; } } } } return CDialogEx::OnCommand(wParam, lParam); }