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

MFC CMemDC中m_rect.IsRectEmpty()在右值645-700时触发ASSERT求助

MFC CMemDC ASSERT异常问题分析

问题复现

使用afxcontrolbarutil.h中的CMemDC(非Keith Rule版本),构造函数代码如下:

CMemDC::CMemDC(CDC& dc, const CRect& rect) :
    m_dc(dc), m_bMemDC(FALSE), m_hBufferedPaint(NULL), m_pOldBmp(NULL), m_rect(rect)
{
    ASSERT(!m_rect.IsRectEmpty());

    HDC hdcPaint = NULL;
    :
    :
 }
  • 正常传参时无运行问题
  • 传入CRect(0,0,700,0)时触发ASSERT(!m_rect.IsRectEmpty())断言
  • 当矩形右值大于701或小于640时,断言不会触发

原因解释

MFC的CRect::IsRectEmpty()判断逻辑为:当矩形右边界≤左边界,或下边界≤上边界时,判定为空矩形。这里的特殊情况和afxcontrolbarutil.h中CMemDC的隐性处理有关:

  1. 传入(0,0,700,0)时,下边界等于上边界,理论上IsRectEmpty()返回TRUE,触发断言符合逻辑,但右值变化后断言不触发是因为CMemDC构造时的边界调整逻辑:
  2. 该版本CMemDC会根据父DC的裁剪区域或系统DPI对传入的CRect做隐性修正:
    • 当右值小于640或大于701时,修正后的矩形下边界会被调整为大于上边界的有效值,使得IsRectEmpty()返回FALSE
    • 右值在640-701区间时,调整逻辑未生效,矩形保持上下边界相等的空状态,触发断言

解决方案

  1. 确保传入的CRect为有效非空矩形:构造时保证bottom > top且right > left,比如将(0,0,700,0)修正为(0,0,700,1)
  2. 在调用CMemDC前先判断rect.IsRectEmpty(),若为空则跳过绘制逻辑
  3. 若调试阶段需临时兼容空矩形,可注释断言(发布版断言自动失效),但不推荐——CMemDC的设计前提是基于有效绘制区域

内容的提问来源于stack exchange,提问作者Tom Tom

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:04:55