| This is a short discussion of resources in WineLib. |
| |
| Introduction |
| Resources are used to store dialogs, menus, bitmaps, icons, |
| version information, strings, fonts, and accelerators. |
| In a Win3.1 programming environment, there are three file formats for |
| resources: |
| - the RC script, which is human-readable and can be processed by a resource |
| compiler |
| - the .RES file, which is the output of the resource compiler |
| - the .EXE and .DLL files, which store resources as a part of the NE |
| file format |
| For WineLib, only a part of this is supported. In particular, there is no |
| .RES file, the executable is not a NE file (as it is a native Unix executable), |
| and some resource types are not implemented: icons, version information, |
| strings, and fonts. |
| |
| Building a WineLib application |
| The build process assumes that the C source files and the resource script |
| is available. At the moment, a single resource script is recommended. |
| This script is processed by winerc: |
| 1) the preprocessor is used to resolve symbolic style name (LBS_STANDARD, ...) |
| into numbers. This involves processing windows.h |
| 2) the unused parts of windows.h (type definitions) are removed. This would |
| not be necessary if Wine's windows.h would use the RC_INVOKED macro. |
| 3) winerc is invoked to create a binary representation of the resources. |
| This representation is stored as C source code (arrays). |
| 4) gcc is used to compile the generated C code. |
| Now, each resource is available as a C array to the application. As the |
| executable is not in the NE format, it is not possible to retrieve resource |
| locations in the executable via name. Instead, the resources have to be |
| referenced with their generated C array names. The linker then resolves |
| these names in the compiled resource file. |
| 5) The program sources are compiled and linked with the output of step 4. |
| A sample build process is in toolkit/Makefile:hello3. |
| |
| Required changes to the program sources |
| Because loading the resources from an instance handle is not possible, |
| the *Indirect functions have to be used to load a resource. The C arrays |
| can be directly passed to the *Indirect functions. So, instead of writing |
| |
| hMenu=LoadMenu(hInstance,"MAIN"); |
| |
| write |
| |
| hMenu=LoadMenuIndirect(hello3_MENU_MAIN.bytes); |
| |
| Fortunately, the Windows API has the following functions available: |
| DialogBoxIndirect |
| CreateDialogIndirect |
| DialogBoxIndirectParam |
| CreateDialogIndirectParam |
| |
| LoadMenuIndirect |
| SetDIBitsToDevice |
| |
| Sample code is available in hello3.c. hello3res.c contains the corresponding |
| resources. |
| |
| Keeping a common source |
| Clearly, changing the sources is not very desirable, and suggestions how |
| to reduce the amount of work are welcome. In the meantime, two approaches |
| allow at least to remain a common source between the Win3.1 code and the |
| WineLib code: |
| 1) conditional compiles: |
| When compiling a WineLib application, WINELIB is defined. This can be used |
| to select Wine-specific code. |
| 2) usage of winerc for Windows: The *Indirect functions are available on |
| plain Win3.1, and the resource format is fully compatible. Thus, recompiling |
| sources modified for WineLib on Win3.1 is possible and known to work. |
| |
| Open problems |
| 1) Icons and cursors: For these resources, there is no *Indirect function |
| documented. In addition, both are implemented by a set of two resources. |
| This is the reason why they are not supported by winerc. |
| 2) Accelerators: Although winerc supports accelerators, there is no |
| LoadAcceleratorIndirect function. A work-around would be to define one. |
| 3) Fonts: Font resources are not supported by Wine at all. |
| 4) String tables: Although string tables are not supported by winerc, there |
| is no reason not to add such support. Again, some indirect loading would |
| be necessary. |
| 5) API requires loading by name: At some places, the name of a resource |
| is passed instead of a handle. The WNDCLASS structure contains the name |
| of a menu resource, and the icon in a dialog box is referenced by its name. |
| (Are there some more places?) |
| Clearly, loading the resource by name would be highly desirable. The |
| resource compiler currently creates a structure containing all resources |
| defined in an RC file. However, it is not clear how WINELIB could find the |
| location of this structure, especially, when there is more than one RC file. |
| |
| |