You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WIN32如何将绘制结果缓存到位图以降低鼠标事件触发的重复绘制开销

实现方案

1. 新增必要变量定义

在全局或窗口类成员中新增缓存脏位标记,用来标识缓存内容是否需要更新:

  • BOOL g_bCacheDirty = TRUE; 初始值设为TRUE,保证程序启动时第一次绘制会生成缓存
  • 确保你已有的内存DC in_ghdc 和关联的HBITMAP要和窗口客户区尺寸匹配,窗口大小改变时也要同步更新缓存并标记脏位。

2. 界面变更通知触发逻辑

当业务逻辑触发界面内容需要更新时,仅执行两个操作即可:

  • 将g_bCacheDirty设置为TRUE
  • 调用InvalidateRect(hWnd, NULL, FALSE); 触发窗口重绘,不需要直接调用绘制函数

3. 调整现有绘制函数逻辑

将你现有的CreatePanelDynamic函数逻辑替换为脏位判断逻辑,参考代码如下:

int anistat = 0;
BOOL g_bCacheDirty = TRUE;

void CreatePanelDynamic(HWND h, HDC hdc, DRAWPANEL DrawFun, int Flag = 0)
{
    RECT rc;
    GetClientRect(h, &rc);
    int cx = rc.right - rc.left;
    int cy = rc.bottom - rc.top;

    if (PanelID == PrevPanelID)
    {
        // 面板ID未变化的场景
        if (g_bCacheDirty)
        {
            // 仅脏位为TRUE时,才重新绘制内容到缓存DC
            _CreatePanel(h, in_ghdc, DrawFun); 
            g_bCacheDirty = FALSE;
        }
        // 所有场景最终都直接将缓存内容复制到当前显示DC
        BitBlt(hdc, 0, 0, cx, cy, in_ghdc, 0, 0, SRCCOPY);
        anistat = 0;
        dystat = 0;
    }
    else // 切换面板需要执行动画的场景
    {
        if (Flag == 0)
        {
            CreatePanelAnimation(h, hdc, DrawFun);
            dystat = 1;
        }
        if (Flag == 1)
        {
            _CreatePanel(h, hdc, DrawFun);
            dystat = 1;
        }
        // 切换面板完成后,将新的面板内容同步到缓存
        BitBlt(in_ghdc, 0, 0, cx, cy, hdc, 0, 0, SRCCOPY);
        g_bCacheDirty = FALSE;
        PrevPanelID = PanelID;
        anistat = 0;
    }
}

4. 鼠标事件处理逻辑调整

鼠标hover、离开事件触发时,不需要调用任何绘制函数,也不需要修改脏位,仅调用InvalidateRect(h, NULL, FALSE);触发重绘即可,此时重绘流程会直接走BitBlt复制缓存的逻辑,不会触发重绘计算,资源占用极低。

注意事项

  • 如果窗口支持调整大小,需要在WM_SIZE消息回调中重新创建匹配新尺寸的in_ghdc和关联HBITMAP,同时将g_bCacheDirty设为TRUE触发缓存更新
  • 确保in_ghdc是全局或和窗口绑定的长期有效对象,程序退出时记得释放关联的HBITMAP和HDC,避免GDI资源泄漏
  • 鼠标事件中不需要调用UpdateWindow强制同步重绘,仅调用InvalidateRect即可满足需求

内容的提问来源于stack exchange,提问作者末影小末EnderMo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 15:15:02