【问题标题】:How to not discard a CDC path?如何不丢弃 CDC 路径?
【发布时间】:2010-12-09 12:12:42
【问题描述】:

我在设备上下文中绘制了一些属于某些对象的符号,现在希望能够稍后测试鼠标光标是否在此类符号上方。

为此,我的计划是首先创建一个CDC 路径并使用它来创建一个CRgn 区域对象。

pDC->BeginPath();
pDC->Ellipse(ellipse[0], ellipse[1], ellipse[2], ellipse[3]); // Create path only
pDC->EndPath();

// Actually draw the ellipse
pDC->StrokeAndFillPath(); // Apparently removes the path from the DC

CRgn region;
if (region.CreateFromPath(pDC)) // Would also remove the path from the DC
{
    // We never get here :-/

    // Here I would copy the region's data,
    // attach it to the object being drawn and
    // destroy the region.
    // That way I can create a region later on and do the hit-testing.
}

如何在绘制和创建区域时同时使用路径,而不必绘制两次?绘制两次几乎使我的绘制方法所花费的时间翻了一番,这是我想避免的。

【问题讨论】:

    标签: c++ mfc path gdi region


    【解决方案1】:

    region.CreateFromPath 之前 调用 StrokeAndFillPath。这会将路径保存为区域 - 然后您可以 StrokeAndFillPath,然后使用该区域。

    编辑:糟糕,完全正确。幸运的是,似乎也有解决该问题的方法:尽管文档没有直接说明,但 SaveDC/RestoreDC 似乎与其他“东西”一起保存并恢复了路径,因此您可以执行以下操作:

    pDC->BeginPath();
    pDC->Ellipse(ellipse[0], ellipse[1], ellipse[2], ellipse[3]);
    pDC->EndPath();
    
    int dc_id = pDC->SaveDC();
    
    pDC->StrokeAndFillPath();
    
    pDC->RestoreDC(dc_id);
    
    CRgn region;
    if (region.CreateFromPath(pDC))
    {
                // Now we do get here...
        MessageBox(L"Region Created");
    }
    

    【讨论】:

    • 在这里不起作用(VC9)... MSDN 说:“在 CreateFromPath 将路径转换为区域后,Windows 会从设备上下文中丢弃关闭的路径。”
    • 我不确定您是否会自动收到编辑通知,但以防万一,请查看编辑后的答案。
    • 好的,现在可以了。但是保存和恢复 DC 的状态似乎也比较耗时。与两次绘制相比,我看不到性能提升。 (如果你想要数字:在这两种情况下,我的测试持续时间从 180 毫秒到 200 毫秒不等,其中保存/恢复方法似乎稍慢。)
    • 在这种情况下,我想是时候考虑一​​种不同的方法了。一种明显的可能性是一些双缓冲,因此当您需要重绘时,您只需在屏幕上闪烁,而不是重新光栅化椭圆等。然而,如果不知道更多细节,很难说它会有多大用处(如果有的话)。
    猜你喜欢
    • 1970-01-01
    • 2022-08-06
    • 1970-01-01
    • 2017-07-22
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多