| RTL referenceGlossary|Tips/Tricks|FREE App/VCL|Best'O'Net|Books|Link To |
| GDI Graphics In Delphi | ||||||||||||||||||||||||||||||||||
| Page 8: GDI, The Hard Way | ||||||||||||||||||||||||||||||||||
GDI, The Hard Way We've explored the GDI a little bit, but only using the Delphi functions. Because the VCL gives (excellent) encapsulation of the GDI this should be enough for most cases. However, there are reasons for doing it the hard way, namely: you need to write a non-VCL (i.e. small) program; you want to learn stuff to transfer to other languages (e.g. C++); or you just like pain. So let's take a look at the basics.
Incidentally, I'll sometimes be using Win32 terminology (e.g. LOGFONT). You might find the types are renamed using the standard Delphi convention (e.g. TLogFont). If you get compiler errors this might be the cause.
GDI Objects 1. Get the DC Getting the DC Everything in Windows is a window (little 'w'). The method for identifying a window, as well as many other objects, is the Handle. This was discussed previously. It boils down to a pointer to your object. If you're using the VCL and want this handle you can use the "Handle" property for your object. Otherwise, the handle is returned when you use CreateWindow or CreateWindowEx. You should, of course, have stored these handles as they're pretty darned important. The final option is to pass in "0", as in "someDC := GetDC(0)", which gives you a DC for the entire screen (rather than just your wanted window).
Of course, you might not have the handle for the window (maybe if it's not one of yours). The solution is simple, provided you know the caption of the window: just use FindWindow or EnumWindows. These search for a given window and return its handle. Once you have that, you can get a DC for the window. However, I'm not going to explain how they work. You'll have to look at Win32.hlp yourself.
Selecting Objects Into the DC Each object is a "GDI Object" (of type HGDIOBJ). You use the same function, SelectObject, to choose your new object. The appropriate data type for your wanted object is just "H" + the object, for example "HPEN" or "HBRUSH". The H prefix indicates this is a Handle, which we've discussed previously. This just means you've got a pointer. What do you need to do with pointers? Yes, that's right, you need to allocate memory so it points to something, and deallocate that memory when finished. There are functions to do that, so lets look at them now.
Before using GDI objects you need to call the appropriate Create function. There are either of the form CreateXXX (e.g. CreatePen) or CreateXXXIndirect (e.g. CreateBrushIndirect). The first is pretty intuitive - you just say "someObj := CreateXXX({parameters});", and it creates the object as wanted. The "indirect" functions just require one extra step: filling out a structure. You use a LogXXX structure (e.g. LOGFONT) and fill out all its values. You then pass this structure into the CreateXXXIndirect function instead of the parameters directly. The Indirect functions are handy when there are lots of parameters in the CreateXXX version of your function.
After you've finished using your GDI object, you need to deallocate it. To do this, there's only one function you need to know about: DeleteObject. You use this for any HGDIOBJ, regardless. This means you have no excuses for forgetting this step, and will always do it in every program you make. Right? An (unnecessary) example: DeleteObject(SomeObj);
When you use a GDI function (e.g. FillRect) the DC uses the currently selected objects, as appropriate. It could use the Pen to draw a line, the Brush to fill an area, the region to define the clipping area (where drawing will take place), etc. Each of these is separate. However, you use the same function to change each attribute: SelectObject.
To change an attribute of the DC do this: Select your new object, use the DC, and select the old object again. It's important you follow this process. Other windows might use the same DC. If you don't restore the old value for your changed attribute these windows will get confused - for example, if they expect a grey brush and you change it to blue things could get messy. Luckily, SelectObject gives you the old value when you change the value, which allows you to easily restore it.
Here's a long-awaited example of using SelectObject:
This code, of course, assumes you have already nabbed a DC called "SomeDC". Anyway, it demonstrates the basics. The first part is to create your new object. You then select it into the DC so any drawing functions will use your new object instead of the old one. At the same time you keep the old value. You use the DC, select the old value back again then finally clear up any created objects.
Releasing the DC Question, Suggestions... |
||||||||||||||||||||||||||||||||||
All graphics (if any) in this feature created by Zarko Gajic.
| More Delphi |
|
· Learn another routine every day - RTL Quick Reference. · Download free source code applications and components. · Talk about Delphi Programming, real time. · Link to the Delphi Programming site from your Web pages. · Tutorials, articles, tech. tips by date: 2001|2000|1999|1998 or by TOPIC. |
|
· NEXT ARTICLE:
Articles. More Delphi articles |
| Stay informed with all new and interesting things about Delphi (for free). |
|
|
| Got some code to share? Got a question? Need some help? |

