A simple windows GDI question

Started by
2 comments, last by Colin Jeanne 17 years, 4 months ago
Hello, hello! Windows GDI uses "pens" (drawing lines) and "brushes" (filling areas with color). GDI also allows you to create as many styles and colors of pens and brushes beforehand, then select them as needed. (Convienent!) My documentation tell's be that as I create pens and brushes, I should destroy them at my earliest convience to keep things tidy. Problem is you can't destroy a brush you are currently using! So the DOCs suggest saving the original default brush, then when it comes time to destroy all other brushes, restore the original default brush so that none of my "created" brushes are in use (and so can be destroyed). Here's how the DOCs suggest doing this. //Create a red colored brush! HBRUSH red_brush = CreateSolidBrush(RGB(0,255,0)); //Now create another HBRUSH to store your old brush in! HBRUSH old_brush; Simple enough!!! Now there's a function that allows you to SELECT which brush you want to use (since you can create as many as you want) and this function is supposed to both select your brush and as a return value it's susposed to give you the last brush selected. (The old_brush) //Select red_pen as our brush and the return value should give us our last brush old_brush = SelectObject(hdc, red_brush); But HERE's where the problem lies!!!! This returns this compiler error: " Cannot convert 'void *' to 'struct HBRUSH__ *' " Suggesting that "SelectObject" is of the type void *? So to check this I tried casting the function "SelectObject" to an HBRUSH and this SEEMED to work. old_brush = (HBRUSH) SelectObject (hdc, red_brush); Even though this works, it's definitly not in the documentation, and it all seems fishy if you ask me. Is there just an easier way to do all of this besides all this saving "old brushes" and having to CAST things and all that? Thanks in advance as always!
Advertisement
Casting is fine. The problem is that SelectObject can take all kinds of different GDI objects (HBRUSH, HPEN, HFONT, etc). But it can only return one thing and with strict type checking it's pretty much always going to be wrong. More to the point, if you look at the docs again you'll see that SelectObject doesn't take (or return) an HBRUSH at all but instead something called an HGDIOBJ.

If you don't like the cast there are a couple options. One is to use HGDIOBJ as your "old_brush". Another is to #include <windowsx.h> which has a ton of macros to make the code prettier. In this case you'd use SelectBrush instead of SelectObject and the macro hides all the ugliness.

The reason this mess exists is historical. In the good old days neither the compilers nor the Windows headers did such strict type checking therefore there wasn't a problem (other than developers trying to pass fonts to API's that took brushes and the like). And MS didn't want to have eleventy-billion SelectWhatever API's because back when you need to run Windows in 1MB of memory the overhead could be significant.
-Mike
Best answer I've gotten from this form yet! Especially explaining the historical reason, my docs ARE old, so everything makes perfect sense now. Problem solved and thanks a million!
Quote:Original post by Anon Mike
The reason this mess exists is historical. In the good old days neither the compilers nor the Windows headers did such strict type checking therefore there wasn't a problem (other than developers trying to pass fonts to API's that took brushes and the like). And MS didn't want to have eleventy-billion SelectWhatever API's because back when you need to run Windows in 1MB of memory the overhead could be significant.

Actually, the Win32 API is C. In C the cast is not needed.

This topic is closed to new replies.

Advertisement