In particular, in the context of the Windows Device Context, the answer to the basic question you ask seems to be yes and no.
The device context basically creates a mode in which the drawing will be executed - that is, at any moment in time it will have the current settings for such things as:
- Background color
- foreground color
- line width
- line pattern
- font
(and so on for a few more things).
Now that there is a drawing surface: yes, I believe that in every device context there is always a drawing surface attached to it. In the general case of the device context for a window, this drawing surface will be part of the screen buffer where the window is displayed. In the case of a "compatible" device context (for example, the result of CreateCompatibleDC), this will be a rather useless drawing surface - in particular, this is a single monochrome pixel. It will be set both black and white, depending on whether the overall brightness level of what you draw on DC exceeds a certain threshold or not (and no, I donโt remember the exact threshold).
This has a (kind of) useful purpose, though: in particular, this means that DC is always โusableโ - there is never a situation where a drawing on a DC will fail only due to the absence of an attached drawing surface. There is no DeselectObject function to help maintain this - you can use SelectObject to select another bitmap in the device context (which will also distract the original one), but there is no way to cancel one bitmap from the device context without selecting another one in it - therefore, it always has an attached drawing surface.
At the same time, the default drawing surface for the context of a compatible device is so close to useless that it is almost considered to have no attached drawing surface.
Edit: I must also add that the default drawing surface selected in the context of a compatible device is the source of quite a few problems. In particular, when you create a compatible DC to create a double buffer, you should do something like this:
DC memDC = CreateCompatibleDC(windowDC); BITMAP bmp = CreateCompatibleBitmap(WindowDC, sizeX, sizeY); SelectObject(memDC, bmp);
If, however, you pretend to be a little and do it instead:
DC memDC = CreateCompatibleDC(windowDC); BITMAP bmp = CreateCompatibleBitmap(memDC, sizeX, sizeY); SelectObject(memDC, bmp);
... everything will be successful, and to some extent, all this will work, except that everything that you draw through a compatible DC will be monochrome. This goes back to a single-pixel monochrome bitmap. Since a compatible DC has a monochrome bitmap selected by default, when you request a compatible bitmap, you will get a monochrome bitmap of the specified size. In the first version, you request a bitmap compatible with the bitmap selected in the source DC, which will usually be a screen, so what you create will have the full color on which your screen is mounted.