I'm currently learning to build game dev tools (specifically, a 2D level editor). I initially planned to do software rendering for the game (using OpenGL only to upscale and display the frame with vsync by copying the pixels to a texture and drawing a full screen quad textured with it - preserving image ratio with glViewport).
Now I need an editor to build tilemaps and place objects in the levels. I don't want to use ready-made ones like Tiled because I want to learn to build tools.
I already experimented with the native windows api gui (windows, child windows, window menus).
The thing puzzling me is the drawing. Right now I need (at minimum) to have two child windows. A Level Preview window when I can draw a view of the edited level and a Tile Palette one with a tileset to select tiles from. So two child windows I have to draw into.
I can use my software renderer code to display the level in the Level Preview child window. Here is how my render code (for the game and the editor) is structured now: I have a C-style Render module wich can draw to a buffer in ram. And a Video module wich can display such buffer to the screen using OpenGL internally.
But how to draw to the other child windows (Like the Tile Palette one) ? Using GDI ? Another native windows api ? What do well built programs use to draw in child windows when they use the windows native gui ? Do these program actually use the windows native gui or do they do everything with the GPU (including reimplementing a gui library) ?
Typically Windows applications process WM_PAINT message in their window proc callback - there you call BeginPaint, then the actual GDI calls to draw, then EndPaint. Any time somebody wants to repaint window they call InvalidateRect(hwnd, NULL, FALSE)
. This way even if window lost some part of image it internally produces WM_PAINT message and repaints the contents. And InvalidateRect can be called from anywhere, including other threads.
If you're doing constant redrawing based on timer/main loop, then you can get away without doing WM_PAINT message and instead just calling drawing functions on HDC for window. Disadvantage of this is the same as in hw accelerated rendering with main loop - it'll block in case modal message loop is executing, like when window is being moved or resized.