PMGuide - Drawing in Windows: Difference between revisions
Created page with "==About Window-Drawing Functions== ===Points=== ===Rectangles === ==Using Window-Drawing Functions== ===Working with Points and Rectangles=== ====Determining the Dimensions of..." |
mNo edit summary |
||
(3 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
{{IBM-Reprint}} | |||
{{PMGuide}} | |||
This chapter describes, at a high level, the functions specifically intended for drawing in PM windows. For information on the complete set of drawing functions, see the Graphics Programming Interface Programming Guide. | |||
==About Window-Drawing Functions== | ==About Window-Drawing Functions== | ||
The functionality of the PM window-drawing functions overlaps that of similar Graphic Programming Interface (GPI) drawing functions in OS/2. These window-drawing functions are less general than the GPI functions and are somewhat easier to use, but they also offer fewer capabilities than the complete set of GPI functions. Programmers requiring optimum functionality should use the GPI functions. | |||
===Points=== | ===Points=== | ||
All drawing in a window takes place in the context of the window's coordinate system. Locations of points in the window are described by POINTL structures, which contain an x and a y coordinate for the point. The lower-left corner of a window always has the coordinates (0,0). | |||
The WinMapWindowPoints function converts the coordinates of points from one window-coordinate space to those of another window-coordinate space. If one of the specified windows is HWND_DESKTOP, the function uses screen coordinates. This function is useful for converting window coordinates to screen coordinates or the other way around. | |||
===Rectangles === | ===Rectangles === | ||
Locations of window rectangles are described by RECTL structures, which contain the coordinates of two points that define the lower-left and upper-right corners of the rectangle. An empty rectangle is one that has no area: either its right coordinate is less than or equal to its left coordinate, or its top coordinate is less than or equal to its bottom coordinate. | |||
There are two types of rectangles in OS/2: inclusive-inclusive and inclusive-exclusive. In inclusive-exclusive rectangles, the lower-left coordinate of the rectangle is included within the rectangle area, while the upper-right coordinate is excluded from the rectangle area. In an inclusive-inclusive rectangle, both the lower-left and upper-right coordinates are included in the rectangle. | |||
In general, graphics operations involving device coordinates (such as regions, bit maps and bit blts, and window management) use inclusive-exclusive rectangles. All other graphics operations, such as GPI functions that define paths, use inclusive-inclusive rectangles. | |||
==Using Window-Drawing Functions== | ==Using Window-Drawing Functions== | ||
This section explains how to use drawing functions to fill (paint) a rectangle with color, scroll the contents of a window, draw bit maps and text, and determine the dimensions of a rectangle. | |||
===Working with Points and Rectangles=== | ===Working with Points and Rectangles=== | ||
The operating system includes functions for manipulating rectangles, many of which change the rectangle coordinates. Other functions draw in a presentation space, using a rectangle to position the drawing operation. | |||
The rest of the rectangle functions are mathematical and do not draw. They are used to manipulate and combine rectangles to produce new rectangles that you then can use in drawing operations. | |||
====Determining the Dimensions of a Rectangle==== | ====Determining the Dimensions of a Rectangle==== | ||
You can calculate the dimensions of an inclusive-exclusive rectangle as follows: | |||
cx = rcl.xRight - rcl.xLeft; /* width */ | |||
cy = rcl.yTop - rcl.yBottom; /* height */ | |||
You can calculate the dimensions of an inclusive-inclusive rectangle as follows: | |||
cx = (rcl.xRight - rcl.xLeft) + 1; /* width */ | |||
cy = (rcl.yTop - rcl.yBottom) + 1; /* height */ | |||
====Filling a Rectangle ==== | ====Filling a Rectangle ==== | ||
The WinFillRect function fills (paints) a rectangle with a specified color. For example, to fill an entire window with blue in response to a WM_PAINT message, you could use the following code fragment, which is taken from a window procedure: | |||
<pre> | |||
HPS hps; | |||
RECTL rcl; | |||
case WM_PAINT: | |||
hps = WinBeginPaint(hwnd, (HPS) NULL, (PRECTL) NULL); | |||
WinQueryWindowRect(hwnd, &rcl); | |||
WinFillRect(hps, &rcl, CLR_BLUE); | |||
WinEndPaint(hps); | |||
return 0; | |||
</pre> | |||
A more efficient way of painting a client window is to pass a rectangle to the WinBeginPaint function. The rectangle is set to the coordinates of the rectangle that encloses the update region of the window. Drawing in this rectangle updates the window, which can make drawing faster if only a small portion of the window needs to be painted. This method is shown in the following code fragment. Notice that WinFillRect uses the presentation space and a rectangle defined in window coordinates to guide the paint operation. | |||
<pre> | |||
HPS hps; | |||
RECTL rcl; | |||
case WM_PAINT: | |||
hps = WinBeginPaint(hwnd, (HPS) NULL, &rcl); | |||
WinFillRect(hps, &rcl, CLR_BLUE); | |||
WinEndPaint(hps); | |||
return 0; | |||
</pre> | |||
You could draw the entire window during the WM_PAINT message, but the graphics output would be clipped to the update region. | |||
The default method of indicating that a particular portion of a window has been selected is using the WinInvertRect function to invert the rectangle's bits. | |||
===Scrolling the Contents of a Window=== | ===Scrolling the Contents of a Window=== | ||
An application typically responds to a click in a scroll bar by scrolling the contents of the window. This operation has three parts. First, the application changes its internal data-representation state to show what portion of the image must now be in the window. Next, the application moves the current image in the window. Finally, the application draws in the area that has been uncovered by the scrolling operation. | |||
For example, a simple text editor might display a small portion of several pages of text in a window. When the user clicks the Down arrow of the vertical scroll bar, the application moves all the text up one line and displays the next line at the bottom of the window. | |||
This clicking also causes a message to be sent to the client window of the frame window that owns the scroll bar. The application responds to this message by changing its internal data-representation state to show which line of text is topmost in the window, scrolling the text in the window up one line, and drawing the new line at the bottom of the window. There normally is no need to completely redraw the entire window, because the scrolled portion of the image remains valid. | |||
You can use the WinScrollWindow function to scroll the contents of your application windows. WinScrollWindow scrolls a specified rectangular area of the window by a specified x and y offset (in window coordinates). If you set the SW_INVALIDATERGN flag for this function, the areas you uncover by scrolling are added to the window's update region automatically, causing a WM_PAINT message for the areas to be sent to the window. | |||
For example, as used in the simple text editor described previously, the following call scrolls the text up one line (assuming that the iVScrollInc parameter specifies the height of the current font) and adds the uncovered area at the bottom of the window to the update region. | |||
<pre> | |||
HWND hwnd; | |||
LONG iVScrollInc; | |||
/* Scroll, adding a new area to the update region. */ | |||
WinScrollWindow(hwnd, /* Window handle */ | |||
0, /* x displacement */ | |||
-(iVScrollInc), /* y displacement */ | |||
(PRECTL) NULL, /* Scroll rectangle is entire window */ | |||
(PRECTL) NULL, /* Clip rectangle is entire window */ | |||
(HRGN) NULL, /* Update region */ | |||
(PRECTL) NULL, /* Update rectangle */ | |||
SW_INVALIDATERGN); /* Scroll-window flag */ | |||
</pre> | |||
When the uncovered area is added to the window's update region, a WM_PAINT message is sent to the window. Upon receiving the message, the window draws the line of text at the bottom of the window. If the window has the WS_SYNCPAINT style, the WM_PAINT message is sent to the window before WinScrollWindow returns. | |||
To optimize scrolling speed for repeated scrolling operations, you can omit the SW_INVALIDATERGN flag from the call to WinScrollWindow, which prevents the function from adding the invalid region (uncovered by the scroll) to the window's update region. If you omit the SW_INVALIDATERGN flag, you must pass a region or rectangle to WinScrollWindow. The rectangle or region will contain the area that must be updated after scrolling. | |||
===Drawing a Bit Map=== | ===Drawing a Bit Map=== | ||
The WinDrawBitmap function draws a bit map, identified by a bit map handle, in a specified rectangle. This function enables you to reduce or enlarge the bit map from the source rectangle to the destination rectangle. WinDrawBitmap also can draw in several different copy modes, including using the OR operator to combine source and destination pels. | |||
===Drawing Text === | ===Drawing Text === | ||
There are many ways to draw text in a window in an OS/2 application. The simplest way is to use the WinDrawText function, which draws a single line of text in a specified rectangle, using a variety of alignment methods. | |||
WinDrawText allows you to set a flag so that the function does not draw any text; instead, the function returns the number of characters in the string that will fit in the specified rectangle. For a section of running text, an application can alternate between computation and calls to WinDrawText to draw successive lines of text. When performing this kind of repetitive operation, you can set the DT_WORDBREAK flag in the WinDrawText function to put line breaks on word boundaries rather than between arbitrary characters. |
Latest revision as of 14:48, 29 July 2024
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation
This chapter describes, at a high level, the functions specifically intended for drawing in PM windows. For information on the complete set of drawing functions, see the Graphics Programming Interface Programming Guide.
About Window-Drawing Functions
The functionality of the PM window-drawing functions overlaps that of similar Graphic Programming Interface (GPI) drawing functions in OS/2. These window-drawing functions are less general than the GPI functions and are somewhat easier to use, but they also offer fewer capabilities than the complete set of GPI functions. Programmers requiring optimum functionality should use the GPI functions.
Points
All drawing in a window takes place in the context of the window's coordinate system. Locations of points in the window are described by POINTL structures, which contain an x and a y coordinate for the point. The lower-left corner of a window always has the coordinates (0,0).
The WinMapWindowPoints function converts the coordinates of points from one window-coordinate space to those of another window-coordinate space. If one of the specified windows is HWND_DESKTOP, the function uses screen coordinates. This function is useful for converting window coordinates to screen coordinates or the other way around.
Rectangles
Locations of window rectangles are described by RECTL structures, which contain the coordinates of two points that define the lower-left and upper-right corners of the rectangle. An empty rectangle is one that has no area: either its right coordinate is less than or equal to its left coordinate, or its top coordinate is less than or equal to its bottom coordinate.
There are two types of rectangles in OS/2: inclusive-inclusive and inclusive-exclusive. In inclusive-exclusive rectangles, the lower-left coordinate of the rectangle is included within the rectangle area, while the upper-right coordinate is excluded from the rectangle area. In an inclusive-inclusive rectangle, both the lower-left and upper-right coordinates are included in the rectangle.
In general, graphics operations involving device coordinates (such as regions, bit maps and bit blts, and window management) use inclusive-exclusive rectangles. All other graphics operations, such as GPI functions that define paths, use inclusive-inclusive rectangles.
Using Window-Drawing Functions
This section explains how to use drawing functions to fill (paint) a rectangle with color, scroll the contents of a window, draw bit maps and text, and determine the dimensions of a rectangle.
Working with Points and Rectangles
The operating system includes functions for manipulating rectangles, many of which change the rectangle coordinates. Other functions draw in a presentation space, using a rectangle to position the drawing operation.
The rest of the rectangle functions are mathematical and do not draw. They are used to manipulate and combine rectangles to produce new rectangles that you then can use in drawing operations.
Determining the Dimensions of a Rectangle
You can calculate the dimensions of an inclusive-exclusive rectangle as follows:
cx = rcl.xRight - rcl.xLeft; /* width */ cy = rcl.yTop - rcl.yBottom; /* height */
You can calculate the dimensions of an inclusive-inclusive rectangle as follows:
cx = (rcl.xRight - rcl.xLeft) + 1; /* width */ cy = (rcl.yTop - rcl.yBottom) + 1; /* height */
Filling a Rectangle
The WinFillRect function fills (paints) a rectangle with a specified color. For example, to fill an entire window with blue in response to a WM_PAINT message, you could use the following code fragment, which is taken from a window procedure:
HPS hps; RECTL rcl; case WM_PAINT: hps = WinBeginPaint(hwnd, (HPS) NULL, (PRECTL) NULL); WinQueryWindowRect(hwnd, &rcl); WinFillRect(hps, &rcl, CLR_BLUE); WinEndPaint(hps); return 0;
A more efficient way of painting a client window is to pass a rectangle to the WinBeginPaint function. The rectangle is set to the coordinates of the rectangle that encloses the update region of the window. Drawing in this rectangle updates the window, which can make drawing faster if only a small portion of the window needs to be painted. This method is shown in the following code fragment. Notice that WinFillRect uses the presentation space and a rectangle defined in window coordinates to guide the paint operation.
HPS hps; RECTL rcl; case WM_PAINT: hps = WinBeginPaint(hwnd, (HPS) NULL, &rcl); WinFillRect(hps, &rcl, CLR_BLUE); WinEndPaint(hps); return 0;
You could draw the entire window during the WM_PAINT message, but the graphics output would be clipped to the update region.
The default method of indicating that a particular portion of a window has been selected is using the WinInvertRect function to invert the rectangle's bits.
Scrolling the Contents of a Window
An application typically responds to a click in a scroll bar by scrolling the contents of the window. This operation has three parts. First, the application changes its internal data-representation state to show what portion of the image must now be in the window. Next, the application moves the current image in the window. Finally, the application draws in the area that has been uncovered by the scrolling operation.
For example, a simple text editor might display a small portion of several pages of text in a window. When the user clicks the Down arrow of the vertical scroll bar, the application moves all the text up one line and displays the next line at the bottom of the window.
This clicking also causes a message to be sent to the client window of the frame window that owns the scroll bar. The application responds to this message by changing its internal data-representation state to show which line of text is topmost in the window, scrolling the text in the window up one line, and drawing the new line at the bottom of the window. There normally is no need to completely redraw the entire window, because the scrolled portion of the image remains valid.
You can use the WinScrollWindow function to scroll the contents of your application windows. WinScrollWindow scrolls a specified rectangular area of the window by a specified x and y offset (in window coordinates). If you set the SW_INVALIDATERGN flag for this function, the areas you uncover by scrolling are added to the window's update region automatically, causing a WM_PAINT message for the areas to be sent to the window.
For example, as used in the simple text editor described previously, the following call scrolls the text up one line (assuming that the iVScrollInc parameter specifies the height of the current font) and adds the uncovered area at the bottom of the window to the update region.
HWND hwnd; LONG iVScrollInc; /* Scroll, adding a new area to the update region. */ WinScrollWindow(hwnd, /* Window handle */ 0, /* x displacement */ -(iVScrollInc), /* y displacement */ (PRECTL) NULL, /* Scroll rectangle is entire window */ (PRECTL) NULL, /* Clip rectangle is entire window */ (HRGN) NULL, /* Update region */ (PRECTL) NULL, /* Update rectangle */ SW_INVALIDATERGN); /* Scroll-window flag */
When the uncovered area is added to the window's update region, a WM_PAINT message is sent to the window. Upon receiving the message, the window draws the line of text at the bottom of the window. If the window has the WS_SYNCPAINT style, the WM_PAINT message is sent to the window before WinScrollWindow returns.
To optimize scrolling speed for repeated scrolling operations, you can omit the SW_INVALIDATERGN flag from the call to WinScrollWindow, which prevents the function from adding the invalid region (uncovered by the scroll) to the window's update region. If you omit the SW_INVALIDATERGN flag, you must pass a region or rectangle to WinScrollWindow. The rectangle or region will contain the area that must be updated after scrolling.
Drawing a Bit Map
The WinDrawBitmap function draws a bit map, identified by a bit map handle, in a specified rectangle. This function enables you to reduce or enlarge the bit map from the source rectangle to the destination rectangle. WinDrawBitmap also can draw in several different copy modes, including using the OR operator to combine source and destination pels.
Drawing Text
There are many ways to draw text in a window in an OS/2 application. The simplest way is to use the WinDrawText function, which draws a single line of text in a specified rectangle, using a variety of alignment methods.
WinDrawText allows you to set a flag so that the function does not draw any text; instead, the function returns the number of characters in the string that will fit in the specified rectangle. For a section of running text, an application can alternate between computation and calls to WinDrawText to draw successive lines of text. When performing this kind of repetitive operation, you can set the DT_WORDBREAK flag in the WinDrawText function to put line breaks on word boundaries rather than between arbitrary characters.