Alexandre Julliard | 902da69 | 1995-11-05 14:39:02 +0000 | [diff] [blame] | 1 | This is a short discussion of resources in WineLib. |
| 2 | |
| 3 | Introduction |
| 4 | Resources are used to store dialogs, menus, bitmaps, icons, |
| 5 | version information, strings, fonts, and accelerators. |
| 6 | In a Win3.1 programming environment, there are three file formats for |
| 7 | resources: |
| 8 | - the RC script, which is human-readable and can be processed by a resource |
| 9 | compiler |
| 10 | - the .RES file, which is the output of the resource compiler |
| 11 | - the .EXE and .DLL files, which store resources as a part of the NE |
| 12 | file format |
| 13 | For WineLib, only a part of this is supported. In particular, there is no |
| 14 | .RES file, the executable is not a NE file (as it is a native Unix executable), |
| 15 | and some resource types are not implemented: icons, version information, |
| 16 | strings, and fonts. |
| 17 | |
| 18 | Building a WineLib application |
| 19 | The build process assumes that the C source files and the resource script |
| 20 | is available. At the moment, a single resource script is recommended. |
| 21 | This script is processed by winerc: |
| 22 | 1) the preprocessor is used to resolve symbolic style name (LBS_STANDARD, ...) |
| 23 | into numbers. This involves processing windows.h |
| 24 | 2) the unused parts of windows.h (type definitions) are removed. This would |
| 25 | not be necessary if Wine's windows.h would use the RC_INVOKED macro. |
| 26 | 3) winerc is invoked to create a binary representation of the resources. |
| 27 | This representation is stored as C source code (arrays). |
| 28 | 4) gcc is used to compile the generated C code. |
| 29 | Now, each resource is available as a C array to the application. As the |
| 30 | executable is not in the NE format, it is not possible to retrieve resource |
| 31 | locations in the executable via name. Instead, the resources have to be |
| 32 | referenced with their generated C array names. The linker then resolves |
| 33 | these names in the compiled resource file. |
| 34 | 5) The program sources are compiled and linked with the output of step 4. |
| 35 | A sample build process is in toolkit/Makefile:hello3. |
| 36 | |
| 37 | Required changes to the program sources |
| 38 | Because loading the resources from an instance handle is not possible, |
| 39 | the *Indirect functions have to be used to load a resource. The C arrays |
| 40 | can be directly passed to the *Indirect functions. So, instead of writing |
| 41 | |
| 42 | hMenu=LoadMenu(hInstance,"MAIN"); |
| 43 | |
| 44 | write |
| 45 | |
| 46 | hMenu=LoadMenuIndirect(hello3_MENU_MAIN.bytes); |
| 47 | |
| 48 | Fortunately, the Windows API has the following functions available: |
| 49 | DialogBoxIndirect |
| 50 | CreateDialogIndirect |
| 51 | DialogBoxIndirectParam |
| 52 | CreateDialogIndirectParam |
| 53 | |
| 54 | LoadMenuIndirect |
| 55 | SetDIBitsToDevice |
| 56 | |
| 57 | Sample code is available in hello3.c. hello3res.c contains the corresponding |
| 58 | resources. |
| 59 | |
| 60 | Keeping a common source |
| 61 | Clearly, changing the sources is not very desirable, and suggestions how |
| 62 | to reduce the amount of work are welcome. In the meantime, two approaches |
| 63 | allow at least to remain a common source between the Win3.1 code and the |
| 64 | WineLib code: |
| 65 | 1) conditional compiles: |
| 66 | When compiling a WineLib application, WINELIB is defined. This can be used |
| 67 | to select Wine-specific code. |
| 68 | 2) usage of winerc for Windows: The *Indirect functions are available on |
| 69 | plain Win3.1, and the resource format is fully compatible. Thus, recompiling |
| 70 | sources modified for WineLib on Win3.1 is possible and known to work. |
| 71 | |
| 72 | Open problems |
| 73 | 1) Icons and cursors: For these resources, there is no *Indirect function |
| 74 | documented. In addition, both are implemented by a set of two resources. |
| 75 | This is the reason why they are not supported by winerc. |
| 76 | 2) Accelerators: Although winerc supports accelerators, there is no |
| 77 | LoadAcceleratorIndirect function. A work-around would be to define one. |
| 78 | 3) Fonts: Font resources are not supported by Wine at all. |
| 79 | 4) String tables: Although string tables are not supported by winerc, there |
| 80 | is no reason not to add such support. Again, some indirect loading would |
| 81 | be necessary. |
| 82 | 5) API requires loading by name: At some places, the name of a resource |
| 83 | is passed instead of a handle. The WNDCLASS structure contains the name |
| 84 | of a menu resource, and the icon in a dialog box is referenced by its name. |
| 85 | (Are there some more places?) |
| 86 | Clearly, loading the resource by name would be highly desirable. The |
| 87 | resource compiler currently creates a structure containing all resources |
| 88 | defined in an RC file. However, it is not clear how WINELIB could find the |
| 89 | location of this structure, especially, when there is more than one RC file. |
| 90 | |
| 91 | |