mrDarker
2025-06-06 c643599414d93afcdc1e504abd036c0ded899aac
1. 通过双缓冲解决CJobSlotGrid控件闪烁问题
已添加2个文件
已修改3个文件
95 ■■■■■ 文件已修改
SourceCode/Bond/Servo/JobSlotGrid.cpp 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.filters 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoMemDC.cpp 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoMemDC.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/JobSlotGrid.cpp
@@ -1,5 +1,6 @@
#include "stdafx.h"
#include "JobSlotGrid.h"
#include "ServoMemDC.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@@ -221,13 +222,15 @@
void CJobSlotGrid::OnPaint() {
    CPaintDC dc(this);
    DrawGrid(&dc);
    CServoMemDC memDC(&dc);
    DrawGrid(&memDC);
}
void CJobSlotGrid::DrawGrid(CDC* pDC)
{
    CRect rect;
    GetClientRect(&rect);
    pDC->FillSolidRect(&rect, ::GetSysColor(COLOR_3DFACE)); // å®‰å…¨èƒŒæ™¯è‰²ï¼Œä»…内存绘制
    if (m_nCols == 0 || m_nRows == 0) {
        return;
@@ -257,10 +260,12 @@
            // é€‰æ‹©å¡«å……颜色
            COLORREF fillColor = m_vSlotStatus[i][j] ? m_colorHasJob : m_colorNoJob;
            if (IsSlotClickable(i, j)) {
                if (bIsClicking)
                if (bIsClicking) {
                    fillColor = COLOR_CLICK;
                else if (bIsHover)
                }
                else if (bIsHover) {
                    fillColor = COLOR_HOVER;
                }
            }
            // ç»˜åˆ¶èƒŒæ™¯ï¼ˆé«˜æ•ˆæ›¿ä»£ CBrush)
@@ -269,6 +274,26 @@
            // ç»˜åˆ¶è¾¹æ¡†
            pDC->DrawEdge(&cellRect, EDGE_SUNKEN, BF_RECT);
            // å¦‚果是可点击格子,在左上角画一个小圆点
            if (IsSlotClickable(i, j)) {
                constexpr int DOT_RADIUS = 3;
                int cx = cellRect.left + 5;
                int cy = cellRect.top + 5;
                // ä¿å­˜æ—§ç¬”和刷子
                CBrush brushDot(RGB(0, 120, 215));
                CBrush* pOldBrush = pDC->SelectObject(&brushDot);
                CPen penDot(PS_SOLID, 1, RGB(0, 120, 215));
                CPen* pOldPen = pDC->SelectObject(&penDot);
                // ç»˜åˆ¶åœ†ç‚¹
                pDC->Ellipse(cx - DOT_RADIUS, cy - DOT_RADIUS, cx + DOT_RADIUS, cy + DOT_RADIUS);
                // æ¢å¤
                pDC->SelectObject(pOldBrush);
                pDC->SelectObject(pOldPen);
            }
            // èŽ·å–æ–‡å­—ï¼ˆå®‰å…¨ï¼‰
            CString strText;
            if (i < m_vSlotText.size() && j < m_vSlotText[i].size()) {
SourceCode/Bond/Servo/Servo.vcxproj
@@ -319,6 +319,7 @@
    <ClInclude Include="ServoCommo.h" />
    <ClInclude Include="ServoDlg.h" />
    <ClInclude Include="ServoGraph.h" />
    <ClInclude Include="ServoMemDC.h" />
    <ClInclude Include="stdafx.h" />
    <ClInclude Include="targetver.h" />
    <ClInclude Include="TerminalDisplayDlg.h" />
@@ -444,6 +445,7 @@
    <ClCompile Include="Servo.cpp" />
    <ClCompile Include="ServoDlg.cpp" />
    <ClCompile Include="ServoGraph.cpp" />
    <ClCompile Include="ServoMemDC.cpp" />
    <ClCompile Include="stdafx.cpp">
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -157,6 +157,7 @@
    <ClCompile Include="CSlot.cpp" />
    <ClCompile Include="CRobotTaskDlg.cpp" />
    <ClCompile Include="PageTransferLog.cpp" />
    <ClCompile Include="ServoMemDC.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="AlarmManager.h" />
@@ -319,6 +320,7 @@
    <ClInclude Include="CSlot.h" />
    <ClInclude Include="CRobotTaskDlg.h" />
    <ClInclude Include="PageTransferLog.h" />
    <ClInclude Include="ServoMemDC.h" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="Servo.rc" />
SourceCode/Bond/Servo/ServoMemDC.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
#include "stdafx.h"
#include "ServoMemDC.h"
CServoMemDC::CServoMemDC(CDC* pDC, const CRect* pRect)
    : CDC(), m_pOldBitmap(nullptr), m_pDC(pDC), m_bMemDC(FALSE)
{
    ASSERT(pDC != nullptr);
    if (pRect == nullptr)
        pDC->GetClipBox(&m_rect);
    else
        m_rect = *pRect;
    if (CreateCompatibleDC(pDC)) {
        m_bMemDC = TRUE;
        m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
        m_pOldBitmap = SelectObject(&m_bitmap);
        SetWindowOrg(m_rect.left, m_rect.top);
    }
}
CServoMemDC::~CServoMemDC()
{
    if (m_bMemDC) {
        // å°†å†…å­˜ DC æ‹·è´å›žåŽŸå§‹çª—å£ DC
        m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
            this, m_rect.left, m_rect.top, SRCCOPY);
        SelectObject(m_pOldBitmap);
    }
}
CServoMemDC* CServoMemDC::operator->()
{
    return this;
}
CServoMemDC::operator CDC* ()
{
    return this;
}
SourceCode/Bond/Servo/ServoMemDC.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
#pragma once
#include <afxwin.h>  // MFC æ ¸å¿ƒå¤´æ–‡ä»¶
// CServoMemDC:双缓冲绘图封装类(消除闪烁)
class CServoMemDC : public CDC
{
public:
    CServoMemDC(CDC* pDC, const CRect* pRect = nullptr); // æž„造:传入目标 DC å’ŒåŒºåŸŸ
    ~CServoMemDC();                                      // æžæž„:自动拷贝到目标 DC
    CServoMemDC* operator->();
    operator CDC* ();
private:
    CBitmap m_bitmap;        // ç”¨äºŽå†…å­˜ DC çš„位图
    CBitmap* m_pOldBitmap;   // æ—§ä½å›¾
    CDC* m_pDC;              // åŽŸå§‹ç»˜å›¾ DC(窗口)
    CRect m_rect;            // ç»˜å›¾åŒºåŸŸ
    BOOL m_bMemDC;           // æ˜¯å¦å¯ç”¨äº†å†…å­˜ DC(CreateCompatibleDC æˆåŠŸï¼‰
};