Graphics Functions
Most of the Windows 3.x API functions that must be replaced return packed x- and y-coordinates.
In Windows 3.x, the x- and y-coordinates are 16 bits each and are packed into the 32-bit (DWORD) function return value, the largest valid size. In Win32, the coordinates are 32 bits each, totaling 64 bits, and are thus too large to fit into a single return value. Each Windows 3.x function is replaced by a Win32 function with the same name, but with an Ex suffix added. The Ex functions pass the x- and y-coordinates using an additional parameter instead of a return value. Both Win32 and Windows 3.x support these new functions.
The problematic graphics functions fall into two groups. The first group, functions that set coordinates, are shown in the following table with the Win32 versions.
Windows 3.x function | Portable version of function |
MoveTo | MoveToEx |
OffsetViewportOrg | OffsetViewportOrgEx |
OffsetWindowOrg | OffsetWindowOrgEx |
ScaleViewportExt | ScaleViewportExtEx |
ScaleWindowExt | ScaleWindowExtEx |
SetBitmapDimension | SetBitmapDimensionEx |
SetMetaFileBits | SetMetaFileBitsEx |
SetViewportExt | SetViewportExtEx |
SetWindowExt | SetWindowExtEx |
SetWindowOrg | SetWindowOrgEx |
Each of the functions in the first column returns a value, although application code frequently ignores it. However, even if you do not care about the return value, you must replace the old function call with the new form. The old functions are not supported under Win32.
Each Ex function includes an additional parameter that points to a location to receive data. After the function call, this data provides the same information as the corresponding function’s return value. If you do not need this information, you can pass NULL to this parameter.
Under Windows 3.x, a call to the MoveTo function can be written as follows:
MoveTo( hDC, x, y );
In the portable version supported by both versions of Windows, the call to MoveTo is rewritten as follows. Note that the information returned by MoveToEx is ignored:
MoveToEx( hDC, x, y, NULL );
As a general rule, pass NULL as the last parameter unless you need to use the x- and y-coordinates returned by the Windows 3.x version. In the latter case, use the procedure outlined in the next few paragraphs for the Get functions.
The second group consists of functions in which the application code normally does use the return value. They are listed in the following table.
Windows 3.x function | Portable version of function |
GetAspectRatioFilter | GetAspectRatioFilterEx |
GetBitmapDimension | GetBitmapDimensionEx |
GetBrushOrg | GetBrushOrgEx |
GetCurrentPosition | GetCurrentPositionEx |
GetTextExtent | GetTextExtentPoint |
GetTextExtentEx | GetTextExtentExPoint |
GetViewportExt | GetViewportExtEx |
GetViewportOrg | GetViewportOrgEx |
GetWindowExt | GetWindowExtEx |
GetWindowOrg | GetWindowOrgEx |
The 32-bit version of the GetTextExtent function has the Point suffix added because there is already a Windows 3.1 extended function GetTextExtentEx. Therefore, the new functions are GetTextExtentPoint and GetTextExtentExPoint.
As with the first group of functions, each Ex (and Point) version adds an additional parameter: a pointer to a POINT or SIZE structure to receive x- and y-coordinates. Because this structure is always the appropriate size for the environment, you can write portable code by:
Declaring a local variable of type POINT or SIZE, as appropriate.
Passing a pointer to this structure as the last parameter to the function.
Calling the function. The function responds by filling the structure with the appropriate information.
For example, the Windows 3.x version call to GetTextExtent extracts the x- and y-coordinates from a DWORD return value (stored in a temporary variable, dwXY
):
DWORD dwXY;
dwXY = GetTextExtent( hDC, szLabel1, strlen( szLabel1 ) );
rect.left = 0; rect.bottom = 0;
rect.right = LOWORD(dwXY);
rect.top = HIWORD(dwXY);
InvertRect( hDC, &rect );
The portable version passes a pointer to a temporary SIZE structure, and then it extracts data from the structure:
SIZE sizeRect;
GetTextExtentPoint( hDC, szLabel1, strlen( szLabel1 ), &sizeRect );
rect.left = 0; rect.bottom = 0;
rect.right = sizeRect.cx;
rect.top = sizeRect.cy;
InvertRect( hDC, &rect );