C++ 如何不放弃CDC路径?

C++ 如何不放弃CDC路径?,c++,mfc,path,gdi,region,C++,Mfc,Path,Gdi,Region,我在设备上下文中绘制了一些属于某些对象的符号,现在我希望能够稍后测试鼠标光标是否位于此类符号上方 为此,我的计划是首先创建一个CDC路径,并使用该路径创建一个CRgn区域对象 pDC->BeginPath(); pDC->Ellipse(ellipse[0], ellipse[1], ellipse[2], ellipse[3]); // Create path only pDC->EndPath(); // Actually draw the ellipse pDC->

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

为此,我的计划是首先创建一个
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.
}
如何使用路径来绘制和创建区域,而不必绘制两次?在调用StrokeAndFillPath之前,绘制两次会使绘制方法花费的时间增加一倍,这是我希望避免的。

region.CreateFromPath。这会将路径保存为一个区域——然后您可以选择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的状态似乎也相对耗时。我看不出与两次绘图相比性能有所提高。(如果您想要数字:我的测试中的持续时间在这两种情况下都在180ms到200ms之间,其中保存/恢复方法似乎稍慢。)在这种情况下,我想是时候考虑另一种方法了。一个明显的可能性是一些双缓冲,所以当你需要重画的时候,你只需要在屏幕上闪烁,而不是重新光栅化椭圆等等。然而,如果不知道更多的细节,很难说这有多有用(如果有的话)。