Resources

Commands related to Windows file resources

SYNOPSIS

package require twapi_resource
begin_resource_update MODULEPATH ?-deleteall?
delete_resource HMODULE RESTYPE RESNAME LANGID
end_resource_update HMODULE ?-discard?
enumerate_resource_languages HMODULE RESTYPE RESNAME
enumerate_resource_names HMODULE RESTYPE
enumerate_resource_types HMODULE
extract_resources HMODULE ?INCLUDEDATA?
free_bitmap HBITMAP
free_cursor HCURSOR
free_icon HBITMAP
get_file_version_resource PATH ?options? ?STRINGNAME...?
load_bitmap_from_file PATH ?options?
load_bitmap_from_module HMODULE NAME ?options?
load_bitmap_from_system NAME ?options?
load_cursor_from_file PATH ?options?
load_cursor_from_module HMODULE NAME ?options?
load_cursor_from_system NAME ?options?
load_icon_from_file PATH ?options?
load_icon_from_module HMODULE NAME ?options?
load_icon_from_system NAME ?options?
read_resource HMODULE RESTYPE RESNAME LANGID
read_resource_string HMODULE STRINGID LANGID
resource_stringblock_to_strings BINDATA
resource_stringid_to_stringblockid STRINGID
strings_to_resource_stringblock STRINGS
update_resource HMODULE RESTYPE RESNAME LANGID RESDATA

DESCRIPTION

Windows resources are binary data that can be added to executable files. Examples include icons, strings and fonts. This module provides commands related to manipulation of these resources.

Windows Resources

Resources are stored in Portable Executable format files (exe's and dll's). A resource has an associated name, type and a language. The name and type can be either integer values or strings. To retrieve a particular resource, you must know both the associated values, the type and the name, for that resource. When a resource type or name is a string, it must be explicitly enclosed in quotes. For example,

::twapi::read_resource $h 14 {"ICON3"} 0

and not

::twapi::read_resource $h 14 "ICON3" 0

or

::twapi::read_resource $h 14 ICON3 0

To support localization, there can be several resources with the same type and name, but associated with different languages. These languages are identified by a 16 bit language identifier (LANGID) as described in the TWAPI Internationalization documentation.

TWAPI provides commands to retrieve and update resources as binary data. It does not provide any functionality related to constructing the actual binary data itself. Each resource type has a specific structure and it is up to the application to construct it appropriately.

In addition to the commands to load resources as binary data, TWAPI also provides commands to load certain resource types - icons, cursors and bitmaps - as GDI objects accessed through handles by other functions in the Windows API.

The get_file_version_resource command can be used to directly retrieve various information stored within the version resource of a file without using the lower level resource manipulation commands.

Resource Types

Windows defines certain standard resource types shown in the table below along with the corresponding #define values from the SDK.

1 RT_CURSOR - Cursor
2 RT_BITMAP - Bitmap
3 RT_ICON - Icon
4 RT_MENU - Menu
5 RT_DIALOG - Dialog
6 RT_STRING - String (see String Resources)
7 RT_FONTDIR - Font directory
8 RT_FONT - Font
9 RT_ACCELERATOR - Accelerator
10 RT_RCDATA - Application defined raw data
11 RT_MESSAGETABLE - Message table
12 RT_GROUP_CURSOR - Hardware independent cursor
14 RT_GROUP_ICON - Hardware independent icon
16 RT_VERSION - Version
17 RT_DLGINCLUDE - Name of C include file containing corresponding symbolic names of resources
19 RT_PLUGPLAY - Plug and play
20 RT_VXD - Vxd
21 RT_ANICURSOR - Animated cursor
22 RT_ANIICON - Animated icon
23 RT_HTML - HTML
24 RT_MANIFEST - Executable Manifest

Locating and Loading Resources

Manipulating a resource requires a Windows executable module handle for the corresponding executable file. The commands will accept NULL or 0 for this handle corresponding the the main executable for the process. To retrieve resources in other executables or DLL's, the module must be first loaded through the load_library call. Generally, the -datafile option should be passed to the load_library command if the only purpose is to access or update resources.

When the resources in a module are no longer required, it must be released through free_library call.

Once the module is loaded, the content of a particular resource can be retrieved using read_resource and read_resource_string.

You can also enumerate resources present in a module using the enumerate_resource_types enumerate_resource_names enumerate_resource_languages commands. The entire resource tree can be enumerated, optionally retrieving the resource values, through the command extract_resources.

Note that resources themselves do not need to be explicitly freed up. In particular, do not try to close the resource handles through the CloseHandle or close_handles.

Updating Resources

Updating a resource in a file requires that the file not be in use by any application (including the current process). The begin_resource_update command prepares the file for update. One or more update_resource commands can be used to modify the resources in the file and delete_resource commands can be used to delete resources. Finally, the the end_resource_update command is used to commit or discard the modifications.

String Resources

Strings defined through a string table definition in a resource definition file are not directly stored in the resource binary. They are stored in string blocks, each containing 16 strings. It is therefore not possible to directly retrieve or update a string based on its string id.

If you call read_resource with a resource type of 6 (STRING), the resource name or id has to actually be the id of the string block, not the string. The command resource_stringid_to_stringblockid will take a string id and return a pair consisting of the id of the corresponding block and the index of the string within the block. The block id can be passed to read_resource to read the string block. Since this is in binary format, it needs to be converted into a list of strings using resource_stringblock_to_strings. The string index returned from resource_stringid_to_stringblockid can be used to then pick out the appropriate string from the this list.

If you are only interested in a single string, the command read_resource_string encapsulates this entire process.

Updating strings in a resource involves multiple steps for the same reason. First, the string block has to be retrieved and converted to a list of strings as described above. The list must then be modified as desired and converted back to a string block using strings_to_resource_stringblock and then written out using update_resource.

Deleting a string resource is similar. Once the list of strings in the appropriate block is retrieved, set the corresponding element in the list to an empty string before writing it back using update_resource.

A peculiarity in the storage format for resource strings means it is not always possible to distinguish between a resource string that is not defined and a resource string that is defined with an empty value. An attempt to read an undefined resource string may either result in an error being generated, or in the return of an empty string.

Loading Resources as GDI objects

TWAPI also provides commands to load some resource types as GDI objects whose handles are opaque but can be passed to other commands in the Windows API. These include the commands load_icon_from_file, load_cursor_from_file, load_bitmap_from_file, load_icon_from_module, load_cursor_from_module, load_bitmap_from_module, load_icon_from_system, load_cursor_from_system and load_bitmap_from_system.

The handles returned by the above commands may be shared or unshared (as described in the documentation for the specific command). Unshared handles must be freed using free_icon, free_cursor and free_bitmap respectively. Shared handles are automatically freed by the system and must not be passed to the free commands.

The commands to load these GDI objects share a common set of options:

-createdibsection BOOLEAN If true, returns a DIB section bitmap instead of a compatible bitmap. Default is false. This option is only valid for bitmap resources.
-defaultsize BOOLEAN If false (default) and options -height and -width are not specified or specified as 0, Windows will use the actual resource size. If true, Windows will use the system metric settings. This option is only valid for cursors and icons.
-height INTEGER Specifies the desired height of the icon or cursor. Default value is 0 in which case the width is controlled by the -defaultsize option.
-loadtransparent BOOLEAN If specified as true, the color of the first pixel is replaced with the default window color. Should be used only if the color depth is 8 bpp or less. Default is false.
-monochrome BOOLEAN If specified as true, returns a monochrome image. Default is false.
-vgacolor BOOLEAN If true, uses VGA color.
-width INTEGER Specifies the desired width of the icon or cursor. Default value is 0 in which case the width is controlled by the -defaultsize option.

Commands

begin_resource_update MODULEPATH ?-deleteall?
Returns a handle to the file MODULEPATH to be updated. The returned handle must be closed through the end_resource_update command. If the option -deleteall is specified, all existing resources in the file are deleted.
delete_resource HMODULE RESTYPE RESNAME LANGID
Deletes a resource from the specified module HMODULE which must be a handle previously retrieved via begin_resource_update. The resource is not actually deleted from the file until the end_resource_update command is called.
end_resource_update HMODULE ?-discard?
Closes a handle previously returned by the begin_resource_update command. Any modifications made through update_resource are written to the file unless the -discard option is specified in which case they are discarded.
enumerate_resource_languages HMODULE RESTYPE RESNAME
Returns a list of language identifiers for which the specified module contains a resource of type RESTYPE with name RESNAME. HMODULE must be a handle previously retrieved via load_library.
enumerate_resource_names HMODULE RESTYPE
Returns a list of the names of resources of type RESTYPE in the specified module. HMODULE must be a handle previously retrieved via load_library, get_module_handle, or get_module_handle_from_address.
enumerate_resource_types HMODULE
Returns a list of the types of resources in the specified module. HMODULE must be a handle previously retrieved via load_library.
extract_resources HMODULE ?INCLUDEDATA?
Extracts all resources from the specified module. The returned data is a nested dictionary with the first level key being the resource type, second level key the resource name and the third level key the language identifier.

If INCLUDEDATA is true, the actual binary data for the resource is returned as the value for each nested key. If INCLUDEDATA is not specified or is false, an empty string is returned as the value.
free_bitmap HBITMAP
Frees a bitmap handle and associated resources. The handle must not be for be a shared bitmap.
free_cursor HCURSOR
Frees a cursor handle and associated resources. The handle must not be for be a shared cursor.
free_icon HBITMAP
Frees a icon handle and associated resources. The handle must not be for be a shared icon.
get_file_version_resource PATH ?options? ?STRINGNAME...?
Returns the information stored within the version resource of a file. The command will generate a Tcl error if the file specified by PATH does not contain a version resource.

The version resource consists of two parts. The information in the first part is in a fixed format and can be retrieved by specifying appropriate options in options. The second part is a string table, the entries in which can be retrieved by specifying the key as a STRINGNAME argument.

The following options may be used with the command:
-all Returns all information in the fixed part.
-datetime Returns the date and time the file was created (as stored in the version resource) as a 64 bit number. Refer to large_system_time_to_timelist or large_system_time_to_secs_since_1970.
-fileversion Returns the file version as indicated in the version resource. This is returned in the format MAJOR.MINOR.BUILD.PRIVATE. Note this is not necessarily identical to the value specified for the FileVersion entry in the string table.
-fileos Returns a value specifying the platform for which the file was designed. This may be one of dos (MS-DOS), os216 (16-bit OS/2), os232 (16-bit OS/2), nt (Windows NT), wince (Windows CE), windows16 (16-bit Windows), pm16 (16-bit Presentation Manager), pm32 (32-bit Presentation Manager), windows32 (32-bit Windows), dos_windows32 (32-bit Windows on MS-DOS), os216_pm16 (16-bit Presentation Manager on 16-bit OS/2), os232_pm32 (32-bit Presentation Manager on 32-bit OS/2) or nt_windows32 (32-bit Windows on Windows NT).
-filetype Returns the file type which may be one of the following: application, dll, driver.printer, driver.keyboard, driver.language, driver.display, driver.mouse, driver.network, driver.system, driver.installable, driver.sound, driver.comm, driver.inputmethod, driver.versionedprinter, driver.DRIVERSUBTYPENUMBER, font.raster, font.vector, font.truetype, font.FONTSUBTYPENUMBER, vxd.VIRTUALDEVICEID, staticlib or FILETYPENUMBER.FILESUBTYPENUMBER. (Note in cases where the file type or subtype is not recognized, the actual numeric value is returned.)
-flags Returns a list of symbols corresponding to flags set in the version resource. The list may contain symbols from the following: debug, prerelease, patched, privatebuild, infoinferred and specialbuild. In addition, the list may also contain a numeric value corresponding to bits that are set but are not recognized as one of the above.
-foundcodepage Returns the code page of the matched string table (see below).
-foundlangid Returns the language of the matched string table (see below). The returned value is a list of two elements containing the numeric language identifier and a description string for the corresponding language.
-langid LANGID Specifies LANGID as the language identifier to be used for string table lookup (see below). By default, the language identifier returned by get_user_ui_langid is used.
-codepage CODEPAGE Specifies CODEPAGE as the code page to be used for string table lookup (see below).
-productversion Returns the product version as indicated in the version resource. This is returned in the format MAJOR.MINOR.BUILD.PRIVATE. Note this is not necessarily identical to the value specified for the ProductVersion entry in the string table.
-signature Contains a longword that is a signature for the fixed part of the version resource. Not particularly useful for the application.
-structversion Returns the version of the version resource format.
In addition to the options that retrieve fixed portions of the version resource, the caller may also specify string names corresponding to language-specific string tables in the version resource. Each such STRINGNAME is looked up in the string table and returned as a STRINGNAME VALUE pair. If a particular string name does not exist in the string table, an empty string is returned as its value. The following string names are commonly defined in version resources: Comments, InternalName, ProductName, CompanyName, LegalCopyright, ProductVersion, FileDescription, LegalTrademarks, PrivateBuild, FileVersion, OriginalFilename, SpecialBuild.

The version resource may contain multiple string tables for different languages and code pages. The caller can control the string table used through the -langid and -codepage options. The command uses the following algorithm in selecting the string table that is looked up.
  • If a string table exactly matches the language id and code page, it is used.
  • Otherwise, if a string table exactly matches the language id, it is used irrespective of the code page.
  • Otherwise, a string table matching the primary language portion of the language id and the code page is used.
  • Otherwise, a string table matching the primary language portion of the language id is used regardless of the code page.
  • Otherwise, a string table specified as language neutral is used.
  • Otherwise, a string table specified as English is used.
  • Finally, the string table corresponding to the first language and code page specified in the resource is used.
The language identifier and code page corresponding to the actual string table that was looked up may be optionally be retrieved by passing the -foundlangid and -foundcodepage to the command.
load_bitmap_from_file PATH ?options?
Returns a handle to a bitmap loaded from a standalone file. The returned bitmap must be freed when no longer needed by calling free_bitmap.

See Loading Resources as GDI objects for a list of valid options.
load_bitmap_from_module HMODULE NAME ?options?
Returns a handle to a bitmap from a resource in a module that has been loaded into the process. The returned bitmap must be freed when no longer needed by calling free_bitmap.

HMODULE is handle to the module as returned by load_library, get_module_handle, or get_module_handle_from_address. NAME is the resource identifier.

See Loading Resources as GDI objects for a list of valid options.
load_bitmap_from_system NAME ?options?
Returns a handle to a bitmap built into Windows. The returned bitmap is a shared bitmap. Applications must not attempt to free it by calling free_bitmap.

NAME must be one of close, uparrow, dnarrow, rgarrow, lfarrow, reduce, zoom, restore, reduced, zoomd, restored, uparrowd, dnarrowd, rgarrowd, lfarrowd, mnarrow, combo, uparrowi, dnarrowi, rgarrowi, lfarrowi, size, btsize, check, checkboxes, btncorners.

See Loading Resources as GDI objects for a list of valid options.
load_cursor_from_file PATH ?options?
Returns a handle to a cursor loaded from a standalone file. The returned cursor must be freed when no longer needed by calling free_cursor.

See Loading Resources as GDI objects for a list of valid options.
load_cursor_from_module HMODULE NAME ?options?
Returns a handle to a cursor from a resource in a module that has been loaded into the process. The returned cursor must be freed when no longer needed by calling free_cursor.

HMODULE is handle to the module as returned by load_library, get_module_handle, or get_module_handle_from_address. NAME is the resource identifier.

See Loading Resources as GDI objects for a list of valid options.
load_cursor_from_system NAME ?options?
Returns a handle to a cursor built into Windows. The returned cursor is a shared cursor. Applications must not attempt to free it by calling free_cursor.

NAME must be one of normal, ibeam, wait, cross, up, sizenwse, sizenesw, sizewe, sizens, sizeall, no, hand or appstarting.

See Loading Resources as GDI objects for a list of valid options.
load_icon_from_file PATH ?options?
Returns a handle to an icon loaded from a standalone file. The returned icon must be freed when no longer needed by calling free_icon.

See Loading Resources as GDI objects for a list of valid options.
load_icon_from_module HMODULE NAME ?options?
Returns a handle to an icon from a resource in a module that has been loaded into the process. The returned icon must be freed when no longer needed by calling free_icon.

HMODULE is handle to the module as returned by load_library, get_module_handle, or get_module_handle_from_address. NAME is the resource identifier.

See Loading Resources as GDI objects for a list of valid options.
load_icon_from_system NAME ?options?
Returns a handle to an icon built into Windows. The returned icon is a shared icon. Applications must not attempt to free it by calling free_icon.

NAME must be one of sample, hand, ques, bang, note, winlogo, warning, error, information or shield.

See Loading Resources as GDI objects for a list of valid options.
read_resource HMODULE RESTYPE RESNAME LANGID
Returns the content of a resource from the specified module HMODULE which must be a handle previously retrieved via load_library.

Note that If RESTYPE is 6, specifying a STRING resource, RESTYPE is the id for a string block, not an individual string. The returned value is the binary data corresponding to the string block. To retrieve individual strings, use the read_resource_string command.
read_resource_string HMODULE STRINGID LANGID
Returns the string in the resource table for the module specified by HMODULE which must be a handle previously retrieved via load_library.

Because of the storage format used in string resources, it is not always possible to distinguish between a resource string that is not defined and a resource string that is defined with an empty value. An attempt to read an undefined resource string may either result in an error being generated, or in the return of an empty string.
resource_stringblock_to_strings BINDATA
Converts a binary resource string block to a list of strings. As every string block contains 16 strings, the returned list as exactly 16 strings.
resource_stringid_to_stringblockid STRINGID
Maps a string resource id to a list containing the id of the corresponding string block in the resource and the index of the string within the block as described in String Resources.
strings_to_resource_stringblock STRINGS
Converts the list of strings in STRINGS to a binary resource string block that can be passed to update_resource. The number of strings in STRINGS must not be more than 16 which is the number stored in a single resource string block. If fewer than 16 strings are provided, they are stored as empty strings.
update_resource HMODULE RESTYPE RESNAME LANGID RESDATA
Updates a resource from the specified module HMODULE which must be a handle previously retrieved via begin_resource_update. RESDATA should be the raw binary data for the resource in the type-specific format.

The resource is not actually written out to the file until the end_resource_update command is called.

COPYRIGHT

Copyright © 2010 Ashok P. Nadkarni

Tcl Windows API 4.3.5