Important: The information in this document is obsolete and should not be used for new development.
Drawing Icons in an Icon Family
You can define different versions of an icon for specific sizes and bit depths as part of a single icon family whose members share the same resource ID. If you define all your application's icons in icon families, you can use Icon Utilities routines to draw the icon using the icon family member that is best suited for the destination rectangle and the current bit depth of the display device. When your application uses Icon Utilities routines likePlotIconSuite
orPlotIconID
to plot icons, it doesn't have to determine which icon in the icon family is best suited for a given destination rectangle and bit depth; instead, the routines automatically display the appropriate icon.You can also define individual icons of resource type
'ICON'
,'cicn'
, or'SICN'
that are not part of an icon family and use Icon Utilities routines to draw them when necessary. For information about drawing these types of icons, see the section "Drawing Icons That Are Not Part of an Icon Family" beginning on page 5-13.You can use the Icon Utilities to draw icons using modes or transforms that alter the icon's appearance in standard ways that are analogous to Finder states for icons. For example, the Finder draws a selected icon differently than it draws one that is not selected; to do so, the Finder specifies the transform constant
ttSelected
when it calls Icon Utilities routines to draw a selected icon. If you need to apply a particular transform to an icon, some Icon Utilities routines allow you to apply transforms for both standard Finder states and Finder label colors when you draw the icon.Many of the Icon Utilities routines can also automatically align an icon within its destination rectangle. For example, the generic document icon that appears in the Finder is taller than it is wide. Some Icon Utilities routines allow you to draw such an icon without any special alignment, align it at the left or right of the destination rectangle, or use various other alignments.
Depending on the size of the rectangle, the Icon Utilities routines may stretch or shrink the icon to fit. To draw icons without stretching them, these routines require that the destination rectangle have the exact dimensions of a standard icon: that is, depending on the icon resource type, 32 by 32 pixels, 16 by 16 pixels, or 12 by 16 pixels. If you use destination rectangles of other sizes, these routines stretch or shrink the icons to fit the rectangles.
An icon family is a collection of icons representing a single object. Each icon in the family shares the same resource ID as other icons in the family but has its own resource type identifying the icon data it contains. The simplest way to draw an icon from an icon family is to pass the family's resource ID to the
PlotIconID
function, which draws the appropriate icon from the family for the specified destination rectangle and bit depth. The next section, "Drawing an Icon Directly From a Resource," describes how to usePlotIconID
.Alternatively, you can first use the
GetIconSuite
function to read the resource data for some or all icons in an icon family into memory. Given a resource ID and one or more resource types, theGetIconSuite
function reads in resource data for each icon with the specified resource ID and resource types and collects handles to the resource data in an icon suite. An icon suite typically consists of one or more handles to icon resources from a single icon family that have been read into memory. TheGetIconSuite
function returns a handle for the requested icon suite; you can pass this handle toPlotIconSuite
and other Icon Utilities routines. LikePlotIconID
,PlotIconSuite
draws the appropriate icon from an icon suite for the specified destination rectangle and bit depth. The section "Getting an Icon Suite and Drawing One of Its Icons" on page 5-11 describes how to use theGetIconSuite
andPlotIconSuite
routines.An icon suite can in turn contain handles to each of the six icon resources that an icon family can contain, or it can contain handles to only a subset of the icon resources in an icon family. However, for best results, an icon suite should always include a black-and-white icon and icon mask for any icons you provide; that is, it should include a resource of type
'ICN#'
in addition to any other large icons you provide as well as a resource of type'ics#'
in addition to any other small icons you provide. When you create an icon suite from icon family resources, the associated resource file should remain open while you use Icon Utilities routines.Two types of handles exist in an icon suite: handles to icon data associated with a resource and handles to icon data that isn't associated with a resource. You typically use
GetIconSuite
to fill an icon suite with handles to icon resource data. You typically
useAddIconToSuite
to add to an icon suite handles to icon data. When you useAddIconToSuite
, the handles that you add to the suite do not have to be associated with a resource fork. For example, your application might get icon data from the desktop database rather than reading it from a resource, or your application might read icon data from a resource and then detach it. In either case, you can provide a handle to the icon data and useAddIconToSuite
to add the handle to the icon suite.An icon cache is like an icon suite, except that an icon cache also contains a pointer to an application-defined icon getter function and a pointer to data that is associated with the icon suite. You can pass a handle to an icon cache to any of the Icon Utilities routines that accept a handle to an icon suite. An icon cache typically does not contain handles to the icon resources for all icon family members. Instead, if the icon cache does not contain an entry for a specific type of icon in an icon family, the Icon Utilities routines call your application's icon getter function to retrieve the data for that icon type. The icon getter function should return either a handle to the icon data or
NIL
to indicate that no icon data exists for the specified icon type.Drawing an Icon Directly From a Resource
To draw an icon from an icon family without first creating an icon suite, use thePlotIconID
function. Listing 5-1 shows an application-defined procedure that draws an icon from an icon family. Given a resource ID, thePlotIconID
function determines which member of the icon family to draw and then draws the icon in the given rectangle with the specified transform and alignment.Listing 5-1 Drawing the icon from an icon family that is best suited to the user's display
PROCEDURE MyDrawIconFromFamily (resID: Integer; destRect: Rect); VAR align: IconAlignmentType; transform: IconTransformType; myErr: OSErr; BEGIN align := atAbsoluteCenter; {specify alignment (centered)} transform := ttNone; {specify no special transforms} {draw the icon, using the icon type best suited for the } { destination rect and current bit depth of the display device} myErr := PlotIconID(destRect, align, transform, resID); END;ThePlotIconID
function determines, from the size of the specified destination rectangle and the current bit depth of the display device, which icon of a given size from an icon family to draw. For example, if the coordinates of the destination rectangle are (100,100,116,116) and the display device is set to 4-bit color, thePlotIconID
function draws the icon of type'ics4'
if that icon is available in the icon family.If the width or height of a destination rectangle is greater than or equal to 32,
PlotIconID
uses the 32-by-32 pixel icon with the appropriate bit depth for the display device. If the destination rectangle is less than 32 by 32 pixels and greater than 16 pixels wide or 12 pixels high,PlotIconID
uses the 16-by-16 pixel icon with the appropriate bit depth. If the destination rectangle's height is less than or equal to 12 pixels or its width is less than or equal to 16 pixels,PlotIconID
uses the 12-by-16 pixel icon with the appropriate bit depth. (Typically only the Finder and the Standard File Package use 12-by-16 pixel icons.)Depending on the size of the rectangle, the
PlotIconID
function may stretch or shrink the icon to fit. To draw icons without stretching them,PlotIconID
requires that the destination rectangle have the exact dimensions of a standard icon: that is, depending on the icon resource type, 32 by 32 pixels, 16 by 16 pixels, or 12 by 16 pixels. If you use destination rectangles of other sizes,PlotIconID
stretches or shrinks the icons to fit the rectangles.Getting an Icon Suite and Drawing One of Its Icons
Listing 5-2 shows how you can use theGetIconSuite
andPlotIconSuite
functions to get an icon suite and then draw the icon from the suite that is best suited to the destination rectangle and the current bit depth of the display device.Listing 5-2 Drawing the icon from an icon suite that is best suited to the display device
PROCEDURE MyDrawIconInSuite (resID: Integer; destRect: Rect; VAR iconSuiteHdl: Handle); VAR iconType: IconSelectorValue; align: IconAlignmentType; transform: IconTransformType; myErr: OSErr; BEGIN iconType := svAllAvailable; {get all icons in icon family} myErr := GetIconSuite(iconSuiteHdl, resID, iconType); IF iconSuiteHdl <> NIL THEN BEGIN align := atAbsoluteCenter; {specify alignment (centered)} transform := ttNone; {specify no special transforms} {draw the icon, using the icon type best suited for the } { destination rect & current bit depth of display device} myErr := PlotIconSuite(destRect, align, transform, iconSuiteHdl); END; END;The application-defined procedureMyDrawIconInSuite
shown in Listing 5-2 first uses theGetIconSuite
function, specifying the constantsvAllAvailable
in the third parameter, to get all icons from the icon family with the specified resource ID and to collect the handles to the data for each icon into an icon suite. (You can use other constants in the third parameter ofGetIconSuite
to request only certain members of an icon family for an icon suite.) TheMyDrawIconInSuite
procedure then draws an icon from this suite using thePlotIconSuite
function.Like the
PlotIconID
function described in the previous section, thePlotIconSuite
function determines, from the size of the specified destination rectangle and the current bit depth of the display device, which icon from the icon suite to draw.You can also specify various transforms and alignments to
PlotIconSuite
. For example, the code in Listing 5-2 specifies thatPlotIconSuite
should center the icon within the destination rectangle.Drawing Specific Icons From an Icon Family
In most cases you should usePlotIconID
orPlotIconSuite
to draw an icon from an icon family, because these routines automatically select the best version of an icon to display for a given destination rectangle and bit depth. The preceding sections, "Drawing an Icon Directly From a Resource" and "Getting an Icon Suite and Drawing One of Its Icons," describe how to use these routines.If you need to plot a specific icon from an icon family rather than using the Icon Utilities to select a family member, you must first create an icon suite that contains only the icon from the desired resource type and its corresponding mask. You can then use
PlotIconSuite
to plot the icon. In this casePlotIconSuite
still attempts to use the best icon available for the given destination rectangle and bit depth; however, by limiting the icon resources available in the icon suite, you can forcePlotIconSuite
to plot either the black-and-white icon from the'ICN#'
resource or just one of the other available resources. Listing 5-3 demonstrates how to do this.Listing 5-3 Drawing a specific icon from an icon family or icon suite
PROCEDURE MyDrawThisIcon (destRect: Rect; resID: Integer; VAR iconSuiteHdl: Handle); VAR align: IconAlignmentType; transform: IconTransformType; myErr: OSErr; BEGIN {get only the 'ICN#' and 'icl4' icons and collect them in an } { icon suite} myErr := GetIconSuite(iconSuiteHdl, resID, svLarge1Bit + svLarge4Bit); IF iconSuiteHdl <> NIL THEN BEGIN align := atAbsoluteCenter; {specify alignment (centered)} transform := ttNone; {specify no special transforms} {draw the best icon from the suite referenced by the icon } { suite handle; since the suite contains only 'ICN#' and } { 'icl4' icons, PlotIconSuite draws the best of the two} myErr := PlotIconSuite(destRect, align, transform, iconSuiteHdl); END; END;The application-defined procedureMyDrawThisIcon
passes the constantssvLarge1Bit
andsvLarge4Bit
toGetIconSuite
. In response,GetIconSuite
reads only the'ICN#'
and'icl4'
resources into memory, storing handles to the icon resource data in the icon suite.MyDrawThisIcon
then usesPlotIconSuite
to plot the best available icon from the suite.If the bit depth of the display device is 1, the
PlotIconSuite
function in Listing 5-3 displays the black-and-white version of the icon from the'ICN#'
resource, regardless
of the size of the destination rectangle. If the bit depth of the display device is greater than 1,PlotIconSuite
draws the icon from the'icl4'
resource, regardless of the size of the destination rectangle.Manipulating Icons
You can use theGetIconFromSuite
function to get a handle to the pixel data for a specific icon from an icon suite. You can use the handle returned by the functionGetIconFromSuite
to manipulate the icon data--for example, to alter its color or add three-dimensional shading--but not to draw the icon with other Icon Utilities routines such asPlotIconHandle
.Listing 5-4 provides an example of an application-defined procedure,
MyGetIconData
, that callsGetIconFromSuite
and manipulates the icon data.Listing 5-4 Manipulating icon data in memory
PROCEDURE MyGetIconData (iconType: ResType; iconSuite: Handle; VAR iconHandle: Handle); VAR myErr: OSErr; BEGIN {get the data for the icon with iconType from the suite} myErr := GetIconFromSuite(iconHandle, iconSuite, iconType); {do whatever with the data} myErr := MyManipulateIconData(iconHandle, iconType); END;The Icon Utilities also include routines that allow you to perform an action on one or more icons in an icon suite and to perform hit-testing on icons. For information about these routines, see "Performing Operations on Icons in an Icon Suite" and "Determining Whether a Point or Rectangle Is Within an Icon" beginning on page 5-38 and page 5-46, respectively.