GDI: a drawing in Delphi - the Part I. Slang GDI. Let's begin with that GDI normally do not use for creation of abrupt graphic effects, for this purpose there are DirectX, OpenGL, or any graphic libraries (such as: DelphiX, FastLib, DIBUltra, Graphics32...). However, for creation of simple effects with the minimum efforts GDI quite fits. With GDI one more abbreviation - DC ("Device Context" - a device context) is tightly connected. It on what we draw, and in Delphi the device context is presented as TCanvas. The idea of a context of the device consists that this general-purpose output device, therefore it is possible to use identical functions both for the screen, and for the printer. All graphic functions in Delphi are superstructures over standard GDI functions Windows. Later we talk about these functions. And now it is a high time to start reviewing of how it is arranged GDI. More low, in the table, some important classes are presented:
However, it is time to pass from words to business, namely, to start to draw lines and figures. Drawing of lines At first it is necessary to understand accurately that the coordinate (0,0) is the upper left corner of the screen. That is values on a y axis increase downwards the screen. Accordingly, the coordinate (0, 50) means that we simply receded on 50 pixels from screen top. The most important thing that it is necessary to know at drawing of lines and figures, this distinction between a pen (Pen) and a paintbrush (Brush). All is very simple: the pen (Pen) is used at drawing of lines or frames, and a paintbrush (Brush) for figure filling. Two functions which are used for drawing of lines are more low resulted and both belong TCanvas:
The effect of relocation of a point of the beginning of drawing of a line as is reached by means of setting ??????? PenPos in ???????... For example, "Canvas. PenPos.x: = 20;", "Canvas. PenPos.y: = 50", or "Canvas. PenPos: = Point (20,50);". By default, the point of the beginning of drawing is installed in (0,0), that is, if at once to cause "Canvas. LineTo (100,100);" that the line from a point (0,0) in a point (100, 100) will be drawn. The point of the beginning of drawing will automatically be moved in (100, 100), that is, if to execute a command "Canvas. LineTo (200, 100);", the following line will be drawn from a point (100, 100) in (200, 100). Therefore, if we want to draw lines disconnected with each other it is necessary to use method MoveTo. The line drawn by means of LineTo uses a current pen ??????? (type TPen). The main properties of a pen, it is width - "Canvas. Pen. Width: = 4;" (with which help it is possible to set various width of lines), and color "Canvas. Pen. Color: = clLime;". Let's look at a simple example of chaotic drawing of multi-colored lines:
Procedure DrawLines is caused from the output agent of button OnClick. The amount of lines is set in constant NUM_LINES. By the way, function RGB, makes color of each line of three main components: red, green and dark blue (values from 0 to 255) color in the form of TColor also returns to us. About colors we talk a bit later, and here so the drawn landscape looks:
Drawing of figures For drawing of figures, in TCanvas following functions are provided:
Still there is very necessary function TextOut which allows to draw the text, using a font set in ???????:
By the way, function allows to draw the text, without filling its background. If it is necessary for you to change a font used in TextOut it is necessary to change property Font ??????? (this property has type TFont) - for example "Canvas. Font. Name: = ' Verdana ';", "Canvas. Font. Size: = 24;" or "Canvas. Font. Color: = clRed;". Briefly it would be desirable to pay your attention to useful enough class TRect which is able to store in itself values left, the right, top and a bottom (by the way, in Windows API it RECT). That eats, to specify the left both upper coordinate and width and area height enough, and TRect automatically substitutes in a type (left, top, it is left + width, top + height). Still there is other function Rect () which does too most, but coordinates in it are set directly as left, the right, top and a bottom. Well and at will, it is possible to use API function SetRect. The example which draws in a random way various figures is more low presented:
As you already had time to note, some figures have the color of the frame different from that color by which the figure is filled. It just that moment which I mentioned above. We fill with a paintbrush objects, and with a pen we frame. If color of a paintbrush (brush) changes in a random way color of a pen (pen) remains to constants. Because of it such pattern also turns out.
Window copying Drawing, it that we did above. That is, drew any lines and graphic figures. However, the picture was saved until the window (form) has not been updated. Copying differs from concept "drawing" a little. When it is necessary for window to be drawn again, Windows sends the certain message. This message arrives in the event handler "OnPaint". Any code which will place in the handler OnPaint is caused each time when it is necessary for form to be updated. For an example, place the following code in the project:
If to place on the form the button and to cause DrawSomeText from the output agent of button OnClick the problem with text disappearance at form relocation remains. HOWEVER, if to cause DrawSomeText from the output agent of form OnPaint the text remains on the place final.
Descriptors or how to use similar API functions So, we learned to draw lines, various figures, learned to do so that our creation was not erased at form relocation, and all of us did it by means of standard functions VCL (such as Canvas. TextOut etc.). However, what to do, if you do not want to use graphic functions VCL which only are superstructures over similar functions from Windows API? Please! Anybody to us does not forbid to use API functions directly! But postojte, all of them demand any HDC! What is HDC? Almost all in Windows uses "Descriptor" (Handle). The descriptor, is a method of identification of your object in system. Each window has a descriptor, each button too has a descriptor etc. For this reason all our objects have a descriptor as property - for example, "MyForm. Canvas. Handle". Type HDC is the Descriptor (Handle) the Device Context (Device Context). I already said right at the beginning that TCanvas includes the majority of functions DC. Therefore, we can easy substitute property ??????? Handle everywhere where it is required to us. For the sake of interest it is possible to look at the table in which examples of calls of some functions from VCL and their analogs from Windows API are presented.
As it is possible to use different descriptors to draw in different places. For example, it is possible to use "SomeBmp. Canvas. Handle" for drawing on a picture (???????), or "Form1.Canvas. Handle" to draw on the form. In API it is necessary to transfer versions of function TextOut a line completed in the zero. It means that instead of transferring a line in function directly, it is necessary to transfer it as PChar. As do not forget to transfer in function length of a line. For this purpose it is possible to use function Length. Well, already it wanted to you to place any beautiful picture on the form?
What is Bitmapy (Bitmaps)? ??????, it is a graphic object which contains the title, the necessary information on a picture (such as height, width, colors etc.) and, actually, the image (the big array containing color of each point). In Delphi for this purpose class TBitmap is already provided. ??????? it is possible to draw not only on the form, but also on all screen. It can and can seem a bit to strange, but sometimes it happens it is useful, especially at screensaver creation. However, at first it is necessary for us to understand how to work with ?????????. Here a small example:
This function tries to load and show a picture, (with name Filename, for example ' myBitmap.bmp ') since a point (x, y). At once I will tell that this function is ineffective enough. She creates and destroys ?????? each time when is caused, and as each time checks file existence. It is better to declare object TBitmap as a form part, to create and load a picture in FormCreate, and to release it in FormDestroy. Drawing functions in GDI All these functions are methods TCanvas.
TCanvas. Draw is a wrapper for API functions BitBlt:
The method described above allows to draw ?????? in run-time. Certainly to place on form TImage easier and to install in it a picture. The image will be constant to remain on that place where you placed it, but it is boring ;-). Where it is more interesting to make with the help ???????? animation. On the other hand, understanding principles of operation with ?????????, it will be easier to you to pass to other graphic libraries (for example DirectX). |