• 12
• 12
• 9
• 10
• 13

# Win32 GDI Device Context Questions. Paint-like application.

This topic is 4787 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello all I have a few questions about GDI DC's. I'm trying to write a mini painting application. And im trying to program the tools found in MS Paint. Im doing it in C++ and pure Win32. What I did is create a DIB, and assicated that with a DC. When I draw to the DC it gets applied to DIB. This is so i can output the file to BMP/JPEG/etc... What is really giving me problems is how am I going to do 'history management' so I can undo drawing mistakes. I thought that for a set amount of 'history steps' I would draw to the Window's DC instead of the DIB's DC. When the history goes over the defined history steps amount I would then write the 'drawing object' (for example, some scribbling with a pencil tool ) to the DIB's DC in FIFO order. If anyone has a better system for managing undo/redo or history please tell me about it. My problem is storing the 'drawing object's. I thought I would store them in their own DC's until the time comes to write it to the DIB DC. What I do is get a handle to the window DC using GetDC() and CreateCompatibleDC() for the drawing object data. But it's just not displaying. : Ok anyway, heres my questions: 1. When i call GetDC on a window am I getting the DC to paint on the actual window? 2. How would I create a DC for a drawing object as explained above? Basically it could be anything from a few white squares on the DC ( eraser tool ) or random scribbling ( pencil tool ) so I can temporarily display it. Thanks P.s : Sorry if this doesn't make any sense, im confused too !! :\

##### Share on other sites
Quote:
 Original post by Shock1. When i call GetDC on a window am I getting the DC to paint on the actual window?
Yes, but you usally only want to paint on the window in WM_PAINT.

Quote:
 Original post by Shock2. How would I create a DC for a drawing object as explained above? Basically it could be anything from a few white squares on the DC ( eraser tool ) or random scribbling ( pencil tool ) so I can temporarily display it.

A DC is a way to draw onto a surface. If you just call CreateCompatibleDC(), you'll be given a DC which is linked to a 1x1 monocrome bitmap. Which isn't usually very useful.
You'll need to create anothe DIB or bitmap, and call SelectObject() to select it into the DC you created with CreateCompatibleDC(). Then you can draw whatever you like to the DC and when you're done, call SelectObject() to restore the original 1x1 monocrome surface, then destroy the DC and the DIB/bitmap.

As for your question about an undo buffer, I'd do it like this:
* Keep a backbuffer, which is a fully drawn DC, and just BitBlt that to the window in WM_PAINT - Just to keep the speed up.
* Keep a DC with anything that's not in your history buffer drawn onto it (I.e. commands that are so old they're not in the history)
* Keep a list of commands (your history steps), e.g. "Line from (0,0) to (50,50)", "Penicil along (0,0), (3,5), (8,7)", etc.
* When the user selects undo, you can BitBlt the DC with old history stuff onto your backbuffer, and then draw all your drawing commands except the last one to it.
Here's some pseudocode to show what I mean:
HDC hdcBackBuffer;                    // Your backbufferHDC hdcOldDrawing;                    // DC of stuff not in history bufferstd::list<DrawingCommand> liCommands; // Your sdrawing commands// In WM_PAINT...HDC hdcWindow = BeginPaint(...);BitBlt(hdcWindow,...,hdcBackBuffer,...); // Copy hdcBackbuffer into hdcWindowEndPaint(...);// When the user selects undo:liCommands.erase(liCommands.end()-1);  // Remove last commandfor(std::list<DrawingCommand>::iterator it=liCommands.begin(); BitBlt(hdcBackBuffer,...,hdcOldDrawing,...); // Copy hdcOldDrawing into hdcBackBufferit!=liCommands.end(); ++it)   DrawCommand(hdcBackBuffer,*it);

Or something along those lines anyway...