views:

67

answers:

1

I draw some symbols, that belong to certain objects, into a device context and now want to be able to later test if the mouse cursor is above such a symbol.

To do this, my plan was to first create a CDC path and use that to create a CRgn region object.

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.
}

How can I use the path for both, drawing and creating the region, without having to draw twice? Drawing twice pretty much doubles the time spent in my drawing method, which is something I'd like to avoid.

+1  A: 

region.CreateFromPath before calling StrokeAndFillPath. That saves the path as a region -- then you can StrokeAndFillPath, and after that use the region.

Edit: Oops, quite right. Fortunately, there seems to be a way around that problem too though: although the documentation doesn't directly say so, it appears that SaveDC/RestoreDC saves and restores the path along with the other "stuff", so you can do something like:

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");
}
Jerry Coffin
Doesn't work here (VC9)... MSDN says: "After CreateFromPath converts a path into a region, Windows discards the closed path from the device context."
mxp
I'm not sure if you're automatically notified of edits, but just in case you're not, take a look at the edited answer.
Jerry Coffin
Okay this works now. But saving and restoring the DC's state seems to be relatively time consuming, too. I can see no performance gain compared to drawing twice. (If you want numbers: The durations in my test range from 180ms to 200ms in both cases, where the save/restore method appears to be slightly slower.)
mxp
In that case, I'd guess it's time to think about a different approach. One obvious possibility would be some double-buffering so when you need to redraw, you just blit to the screen instead of re-rasterizing ellipses and such. Without knowing more details, however, it's hard to say how useful that would be (if at all).
Jerry Coffin