Ah, crap. Sorry, I just realized what part of the problem is. I was lifting code from a utility class we use to manage the DC stuff and internally it called CreateDC(), but it only took a reference to an HDC. I thought that was the Windows API, but it was actually a private method that does a little more.
Replace CreateDC(dc); in my original post with this:
__CreateDC(dc);
and add this function:
void CreateDC(HDC& outDC)
{
HDC screenDC = 0;
HDC memoryDC = 0;
GetDC(0, screenDC);
memoryDC = CreateCompatibleDC(screenDC);
ReleaseDC(0, screenDC);
outDC = memoryDC;
}
Again, obviously that lacks any error checking, but hopefully it works fine