1. 解决自定义按钮资源泄露问题
2. 增加Slot点击回调和鼠标悬停/点击高亮效果
已修改4个文件
136 ■■■■■ 文件已修改
SourceCode/Bond/Servo/BlButton.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGraph2.cpp 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/JobSlotGrid.cpp 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/JobSlotGrid.h 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/BlButton.cpp
@@ -219,8 +219,7 @@
        hFont = (HFONT)pFont->GetSafeHandle();
    }
    ::SelectObject(hDC, hFont);
    HFONT hOldFont = (HFONT)::SelectObject(hDC, hFont);
    ::SetBkMode(hDC, TRANSPARENT);
    ::SetTextColor(hDC, m_crText[state]);
@@ -237,6 +236,7 @@
        }
        DrawTextA(hDC, szText, (int)strlen(szText), &rcText, DT_VCENTER | DT_CENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
    }
    ::SelectObject(hDC, hOldFont);
    // 是否有小圆点
@@ -283,8 +283,8 @@
        ::Polygon(hDC, pt, 3);
        ::SelectObject(hDC, hOldBrush);
        ::SelectObject(hDC, hOldPen);
        ::DeleteObject(hBrush);
        ::DeleteObject(hPen);
        ::DeleteObject(hbrDrop);     // 正确释放小三角使用的画刷
        ::DeleteObject(hPenDrop);    // 正确释放小三角的笔
    }
}
SourceCode/Bond/Servo/CPageGraph2.cpp
@@ -128,6 +128,11 @@
        CHMPropertyDlg dlg(pEquipment->getName().c_str(), 658, 788);
        CEquipmentPage1* pPage1 = new CEquipmentPage1();
        pPage1->setEquipment(pEquipment);
        pPage1->Create(IDD_PAGE_EQUIPMENT1);
        dlg.addPage(pPage1, "Link Signal");
        if (_strcmpi(pEquipment->getClassName(), "CLoadPort") == 0) {
            CPagePortProperty* pPageA = new CPagePortProperty();
            pPageA->setLoadPort((SERVO::CLoadPort*)pEquipment);
SourceCode/Bond/Servo/JobSlotGrid.cpp
@@ -10,6 +10,10 @@
BEGIN_MESSAGE_MAP(CJobSlotGrid, CWnd)
    ON_WM_PAINT()
    ON_WM_ERASEBKGND()
    ON_WM_MOUSEMOVE()
    ON_WM_MOUSELEAVE()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
END_MESSAGE_MAP()
CJobSlotGrid::CJobSlotGrid() {
@@ -48,6 +52,7 @@
    m_nRows = nRows;
    m_nCols = nCols;
    m_vSlotStatus.assign(nRows, std::vector<bool>(nCols, false));
    m_vSlotClickable.assign(nRows, std::vector<bool>(nCols, false));
    // 初始化文本数组
    m_vSlotText.assign(nRows, std::vector<CString>(nCols));
@@ -130,8 +135,88 @@
    Invalidate();
}
void CJobSlotGrid::SetSlotClickable(int nRow, int nCol, bool bClickable)
{
    if (nRow >= 0 && nRow < m_nRows && nCol >= 0 && nCol < m_nCols) {
        m_vSlotClickable[nRow][nCol] = bClickable;
    }
}
bool CJobSlotGrid::IsSlotClickable(int nRow, int nCol) const
{
    if (nRow >= 0 && nRow < m_nRows && nCol >= 0 && nCol < m_nCols) {
        return m_vSlotClickable[nRow][nCol];
    }
    return false;
}
void CJobSlotGrid::SetSlotClickCallback(SlotClickCallback fnCallback)
{
    m_fnSlotClickCallback = fnCallback;
}
BOOL CJobSlotGrid::OnEraseBkgnd(CDC* pDC) {
    return TRUE;
}
void CJobSlotGrid::OnMouseMove(UINT nFlags, CPoint point)
{
    TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd };
    ::TrackMouseEvent(&tme);
    CRect rect;
    GetClientRect(&rect);
    int nCellWidth = rect.Width() / m_nCols;
    int nCellHeight = rect.Height() / m_nRows;
    int nCol = point.x / nCellWidth;
    int nRow = point.y / nCellHeight;
    if (nRow != m_ptHover.y || nCol != m_ptHover.x) {
        m_ptHover = CPoint(nCol, nRow);
        Invalidate();
    }
    CWnd::OnMouseMove(nFlags, point);
}
void CJobSlotGrid::OnMouseLeave()
{
    m_ptHover = CPoint(-1, -1);
    Invalidate();
    CWnd::OnMouseLeave();
}
void CJobSlotGrid::OnLButtonDown(UINT nFlags, CPoint point)
{
    m_bLButtonDown = true;
    Invalidate();
    CWnd::OnLButtonDown(nFlags, point);
}
void CJobSlotGrid::OnLButtonUp(UINT nFlags, CPoint point)
{
    m_bLButtonDown = false;
    Invalidate();
    // 保持原有逻辑不变
    CRect rect;
    GetClientRect(&rect);
    int nCellWidth = rect.Width() / m_nCols;
    int nCellHeight = rect.Height() / m_nRows;
    int nCol = point.x / nCellWidth;
    int nRow = point.y / nCellHeight;
    if (IsSlotClickable(nRow, nCol)) {
        if (m_fnSlotClickCallback) {
            m_fnSlotClickCallback(nRow, nCol);
        }
    }
    CWnd::OnLButtonUp(nFlags, point);
}
void CJobSlotGrid::OnPaint() {
@@ -152,14 +237,30 @@
        for (int j = 0; j < m_nCols; ++j) {
            CRect cellRect(j * nCellWidth, i * nCellHeight, (j + 1) * nCellWidth, (i + 1) * nCellHeight);
            // 背景
            CBrush* pBrush = m_vSlotStatus[i][j] ? &m_brushHasJob : &m_brushNoJob;
            pDC->FillRect(&cellRect, pBrush);
            // 判断状态:悬停 / 按下
            bool bIsHover = (m_ptHover.x == j && m_ptHover.y == i);
            bool bIsClicking = bIsHover && m_bLButtonDown;
            // 选择颜色
            COLORREF fillColor;
            if (bIsClicking) {
                fillColor = RGB(0, 120, 215);   // 鼠标按下色
            }
            else if (bIsHover) {
                fillColor = RGB(200, 230, 255); // 悬停高亮
            }
            else {
                fillColor = m_vSlotStatus[i][j] ? m_colorHasJob : m_colorNoJob;
            }
            // 画背景
            CBrush brush(fillColor);
            pDC->FillRect(&cellRect, &brush);
            // 边框
            pDC->DrawEdge(&cellRect, EDGE_SUNKEN, BF_RECT);
            // 文字(居中)
            // 文本
            pDC->SetBkMode(TRANSPARENT);
            pDC->SetTextColor(RGB(0, 0, 0));
            pDC->DrawText(m_vSlotText[i][j], &cellRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
SourceCode/Bond/Servo/JobSlotGrid.h
@@ -1,6 +1,9 @@
#pragma once
#include <afxwin.h>
#include <vector>
#include <functional>
using SlotClickCallback = std::function<void(int nRow, int nCol)>;
class CJobSlotGrid : public CWnd
{
@@ -16,15 +19,24 @@
    void SetSlotText(int nRow, int nCol, const CString& strText);
    void SetTextFont(const CString& strFontName, int nPointSize);
    void ClearAll();
    void SetSlotClickable(int nRow, int nCol, bool bClickable);
    bool IsSlotClickable(int nRow, int nCol) const;
    void SetSlotClickCallback(SlotClickCallback fnCallback);
protected:
    afx_msg void OnPaint();
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg void OnMouseLeave();
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
    DECLARE_MESSAGE_MAP()
private:
    int m_nRows;
    int m_nCols;
    bool m_bLButtonDown = false;             // 鼠标是否按下
    CPoint m_ptHover{ -1, -1 };   // 当前悬停的 cell 索引(row, col)
    CFont m_fontText;
    COLORREF m_colorHasJob;
    COLORREF m_colorNoJob;
@@ -32,6 +44,8 @@
    CBrush m_brushNoJob;
    std::vector<std::vector<bool>> m_vSlotStatus;
    std::vector<std::vector<CString>> m_vSlotText;
    std::vector<std::vector<bool>> m_vSlotClickable;
    SlotClickCallback m_fnSlotClickCallback;
    void DrawGrid(CDC* pDC);
};