2

I'm using MFC (but this would also apply to Win32) and I have a view I want to draw. So I am overriding the OnDraw method. Here's a bit of psuedocode, I'm coding like this:

void OnDraw(DC* pDC)
{
  foreach(Node n in nodes)
  { 
    n->DrawOnCanvas(pDC)
  }
}

I thought this was a nice OO solution. But I've run into a problem. I now want to draw a border around the initial DC, but I don't want the nodes to know about this. I want the nodes to still draw relative to a full canvas size starting from 0,0 (and not know about an offset). If I give the nodes knowledge about the border in the parent window it seems messy.
How do you solve problems like this? How can I define a new DC that is relative to an existing one?

DanDan
  • 10,462
  • 8
  • 53
  • 69
  • 1
    The trick is to pass the entire drawing rectangle to each node but before doing so, clip the DC's 'invalid' rectangle to the reduced size. This allows the nodes to draw to the full rectangle and leaves GDI to clip out the bits that would overwrite the border. Lookup functions such as `CDC::Set/GetBoundsRect` and `CDC::ExcludeClipRect`. – user1793036 Feb 05 '14 at 04:45
  • I've never seen these functions before, and after a bit of a play I could not get them to do anything useful. This looks really interesting though, do you have any sample code? – DanDan Feb 05 '14 at 21:08

1 Answers1

3

You don't make a new DC, you set the origin on the existing one. So in your loop, before DrawOnCanvas(), you'd use CDC::SetViewportOrg() and friends. See http://msdn.microsoft.com/en-us/library/46t66w7t.aspx . You can also implement scaling, scrolling etc this way.

Roel
  • 19,338
  • 6
  • 61
  • 90
  • This helped, thanks. It did play havoc with my existing CScrollView, so you have to add what the current origin may be first: CPoint currentOrigin; GetViewportOrgEx(pDC->GetSafeHdc(), &currentOrigin); SetViewportOrgEx(pDC->GetSafeHdc(), currentOrigin.x + XBorder, currentOrigin.y + YBorder, NULL); – DanDan Feb 05 '14 at 21:10
  • 1
    Yeah that's right, CScrollView uses that same mechanism for scrolling. Good you got it working - that is some hairy stuff that can cause a lot of grief :) – Roel Feb 07 '14 at 16:52