DC stands for "device context" which is about as descriptive as it can be. It basically holds state information for GDI drawing tools like bitmaps, brushes, pens, etc.
Think of it like an art easel. Each easel is assigned a bunch of pens (HPEN), some paint cans (HBRUSH), a canvas (HBITMAP), and some other junk. Drawing operations that use a DC may use one or more of these assigned drawing tools. But the drawing tools themselves can be moved to and from other DCs.
The "display DC" is the DC used by the current display. IE whatever is visible on that DC is what is visible on the window.
This is constrast to an "offscreen DC" which retrains drawing and state information but isn't visible on the window.
It is perfectly OK to have a separate function for the actual drawing code, and it is actually the best practice. This is because it is expected that your window also handles WM_PRINT (and WM_PRINTCLIENT). These messages carry their own HDC in the wParam parameter that you must use.
Note that you don't need to pass the HDC by reference or by pointer because it is simply a number. A copy of the HDC is really nothing of concern.
WM_PRINT doesn't provide a PAINTSTRUCT structure. If you are passing something to the function, pass the HDC, the update rectangle/region, and a boolean for the background erasing and make the last two optional.