| This document should help new developers get started. Like all of Wine, it | 
 | is a work in progress. | 
 |  | 
 |  | 
 | SOURCE TREE STRUCTURE | 
 | ===================== | 
 |  | 
 | The Wine source tree is loosely based on the original Windows modules.  | 
 | Most of the source is concerned with implementing the Wine API, although | 
 | there are also various tools, documentation, sample Winelib code, and | 
 | code specific to the binary loader.  Note that several of the libraries | 
 | listed here are "stubbed out", meaning they still need to be implemented. | 
 |  | 
 | DLLs (under dlls/): | 
 | ------------------- | 
 |  | 
 | 	activeds/		- Active Directory Service Interface | 
 | 	advapi32/		- Crypto, systeminfo, security, eventlogging | 
 | 	advpack/		- Reads and verifies .INF files | 
 | 	amstream/               - MultiMedia Streams | 
 | 	atl/			- Active Template Library | 
 | 	avicap32/		- AVI capture window class | 
 | 	avifil32/		- COM object to play AVI files | 
 | 	cabinet/		- Cabinet file interface | 
 | 	capi2032/		- Wrapper library for CAPI4Linux access | 
 | 	cards/                  - Card graphics | 
 | 	cfgmgr32/		- Config manager | 
 | 	comcat/			- Component category manager | 
 | 	comctl32/		- Common controls | 
 | 	commdlg/		- Common dialog boxes (both 16 & 32 bit) | 
 | 	crtdll/			- Old C runtime library | 
 | 	crypt32/		- Cryptography | 
 | 	cryptdll/		- Cryptography Manager | 
 | 	ctl3d/          	- 3D Effects for Common GUI Components | 
 | 	d3d8/			- Direct3D (3D graphics) | 
 | 	d3d9/			- Direct3D (3D graphics) | 
 | 	d3dim/			- Direct3D Immediate Mode | 
 | 	d3drm/			- Direct3D Retained Mode | 
 | 	d3dx8/			- Direct3D (3D graphics) | 
 | 	d3dxof/			- DirectX Files Functions | 
 | 	dbghelp/                - Engine for symbol and module enumeration | 
 | 	dciman32/		- DCI Manager (graphics) | 
 | 	ddraw/			- DirectDraw (graphics) | 
 | 	devenum/		- Device enumeration (part of DirectShow) | 
 | 	dinput/			- DirectInput (device input) | 
 | 	dinput8/		- DirectInput (device input) | 
 | 	dmband/			- DirectMusic Band | 
 | 	dmcompos/		- DirectMusic Composer | 
 | 	dmime/			- DirectMusic Interactive Engine | 
 | 	dmloader/		- DirectMusic Loader | 
 | 	dmscript/		- DirectMusic Scripting | 
 | 	dmstyle/		- DirectMusic Style Engine | 
 | 	dmsynth/		- DirectMusic Software Synthesizer | 
 | 	dmusic/			- DirectMusic Core Services | 
 | 	dmusic32/		- DirectMusic Legacy Port | 
 | 	dplay/			- DirectPlay (networking) | 
 | 	dplayx/			- DirectPlay (networking) | 
 | 	dpnet/                  - DirectPlay (networking) | 
 | 	dpnhpast/		- DirectPlay NAT Helper PAST | 
 | 	dsound/			- DirectSound (audio) | 
 | 	dswave/			- DirectMusic Wave | 
 | 	dxdiagn/                - DirectX Diagnostic Tool  | 
 | 	gdi/			- GDI (graphics) | 
 | 	glu32/			- OpenGL Utility library (graphics) | 
 | 	glut32/			- OpenGL Utility Toolkit | 
 | 	hhctrl.ocx/             - HHCTRL OCX implementation | 
 | 	iccvid/			- Radius Cinepak Video Decoder | 
 | 	icmp/			- ICMP protocol (networking) | 
 | 	ifsmgr.vxd/		- IFSMGR VxD implementation | 
 | 	imagehlp/		- PE (Portable Executable) Image Helper lib | 
 | 	imm32/			- Input Method Manager | 
 | 	iphlpapi/       	- IP Helper API | 
 | 	itss/			- Infotech Structured Storage (HTML Help) | 
 | 	kernel/			- The Windows kernel | 
 | 	lzexpand/		- Lempel-Ziv compression/decompression | 
 | 	mapi32/			- Mail interface | 
 | 	midimap/		- MIDI mapper | 
 | 	mlang/			- Multi Language Support | 
 | 	mmdevldr.vxd/		- MMDEVLDR VxD implementation | 
 | 	monodebg.vxd/		- MONODEBG VxD implementation | 
 | 	mpr/			- Multi-Protocol Router (networking) | 
 | 	msacm/			- Audio Compression Manager (multimedia) | 
 | 	msacm/imaadp32/		- IMA ADPCM Audio Codec | 
 | 	msacm/msadp32/		- MS ADPCM Audio Codec | 
 | 	msacm/msg711/		- MS G711 Audio Codec (includes A-Law & MU-Law) | 
 | 	msacm/winemp3/		- Mpeg Layer 3 Audio Codec | 
 | 	mscms/			- Color Management System | 
 | 	msdmo/			- DirectX Media Objects | 
 | 	mshtml/			- MS HTML component | 
 | 	msi/			- Microsoft Installer | 
 | 	msimg32/		- Gradient and transparency (graphics) | 
 | 	msisys/			- System information | 
 | 	msnet32/		- Network interface | 
 | 	msrle32/		- Video codecs | 
 | 	msvcrt/			- C runtime library  | 
 | 	msvcrt20/		- C runtime library version 2.0 | 
 | 	msvcrt40/		- C runtime library version 4.0 | 
 | 	msvcrtd/		- C runtime library debugging | 
 | 	msvidc32/		- Microsoft Video-1 Decoder | 
 | 	msvideo/		- 16 bit video manager | 
 | 	mswsock/		- Misc networking | 
 | 	msxml3/			- MSXML Class Factory | 
 | 	netapi32/		- Network interface | 
 | 	newdev/			- New Hardware Device Library | 
 | 	ntdll/			- NT implementation of kernel calls | 
 | 	objsel/			- Object Picker Dialog | 
 | 	odbc32/			- Open DataBase Connectivity driver manager | 
 | 	odbccp32/		- Open DataBase Connectivity driver installer | 
 | 	ole32/			- 32 bit OLE 2.0 libraries | 
 | 	oleacc/			- OLE accessibility support | 
 | 	oleaut32/		- 32 bit OLE 2.0 automation | 
 | 	olecli/			- 16 bit OLE client | 
 | 	oledlg/			- OLE 2.0 user interface support | 
 | 	olepro32/		- 32 bit OLE 2.0 automation | 
 | 	olesvr/			- 16 bit OLE server | 
 | 	opengl32/		- OpenGL implementation (graphics) | 
 | 	powrprof/		- Power Management and Profiling | 
 | 	psapi/			- Process Status interface | 
 | 	qcap/			- DirectShow runtime | 
 | 	quartz/			- DirectShow runtime | 
 | 	rasapi32/		- Remote Access Server interface | 
 | 	riched20/		- Rich text editing control version 2.0 | 
 | 	richedit/		- Rich text editing control | 
 | 	rpcrt4/			- Remote Procedure Call runtime | 
 | 	rsabase/		- RSA encryption | 
 | 	rsaenh/			- Crypto API (DES, 3DES, RSA, etc.) | 
 | 	secur32/                - Contains Windows Security functions | 
 | 	sensapi/		- System Event Notification Service | 
 | 	serialui/		- Serial port property pages | 
 | 	setupapi/		- Setup interface | 
 | 	shdocvw/		- Shell document object and control | 
 | 	shell32/		- COM object implementing shell views | 
 | 	shfolder/		- Shell folder service | 
 | 	shlwapi/		- Shell Light-Weight interface | 
 | 	snmpapi/		- SNMP protocol interface (networking) | 
 | 	stdole2.tlb/		- OLE Automation typelib | 
 | 	stdole32.tlb/		- Standard OLE typelib | 
 | 	sti/			- Still Image service | 
 | 	tapi32/			- Telephone interface | 
 | 	twain/			- TWAIN Imaging device communications | 
 | 	unicows/		- Unicows replacement (Unicode layer for Win9x) | 
 | 	url/			- Internet shortcut shell extension | 
 | 	urlmon/			- URL Moniker allows binding to a URL | 
 | 	user/			- Window management, standard controls, etc. | 
 | 	usp10/			- Uniscribe Script Processor | 
 | 	uxtheme/		- Theme library | 
 | 	vdhcp.vxd/		- VDHCP VxD implementation | 
 | 	vdmdbg/			- Virtual DOS machine debug library | 
 | 	version/		- File installation library | 
 | 	vmm.vxd/		- VMM VxD implementation | 
 | 	vnbt.vxd/               - VNBT VxD implementation | 
 | 	vnetbios.vxd/		- VNETBIOS VxD implementation | 
 | 	vtdapi.vxd/		- VTDAPI VxD implementation | 
 | 	vwin32.vxd/		- VWIN32 VxD implementation | 
 | 	win32s/			- 32-bit function access for 16-bit systems | 
 | 	winaspi/		- 16 bit Advanced SCSI Peripheral Interface | 
 | 	wined3d/		- Wine internal Direct3D helper | 
 | 	winedos/		- DOS features and BIOS calls (Wine specific) | 
 | 	wineps/			- Postscript driver (Wine specific) | 
 | 	wininet/		- Internet extensions | 
 | 	winmm/			- Multimedia (16 & 32 bit) | 
 | 	winmm/joystick/		- Joystick driver | 
 | 	winmm/mcianim/		- MCI animation driver | 
 | 	winmm/mciavi/		- MCI video driver | 
 | 	winmm/mcicda/		- MCI audio CD driver | 
 | 	winmm/mciseq/		- MCI MIDI driver | 
 | 	winmm/mciwave/		- MCI wave driver | 
 | 	winmm/wavemap/		- Audio mapper | 
 | 	winmm/winealsa/		- ALSA audio driver | 
 | 	winmm/winearts/		- aRts audio driver | 
 | 	winmm/wineaudioio/ 	- audioio audio driver | 
 | 	winmm/winejack/		- JACK audio server driver | 
 | 	winmm/winenas/		- NAS audio driver | 
 | 	winmm/wineoss/		- OSS audio driver | 
 | 	winnls/			- National Language Support | 
 | 	winsock/		- Sockets 2.0 (networking) | 
 | 	winspool/		- Printing & Print Spooler | 
 | 	wintab32/		- Tablet device interface | 
 | 	wintrust/		- Trust verification interface | 
 | 	wldap32/		- LDAP support | 
 | 	wow32/			- WOW subsystem | 
 | 	wsock32/		- Sockets 1.1 (networking) | 
 | 	wtsapi32/		- Terminal Services | 
 | 	x11drv/			- X11 display driver (Wine specific) | 
 |  | 
 | Winelib programs (under programs/): | 
 | ----------------------------------- | 
 |  | 
 | 	avitools/		- AVI information viewer and player | 
 | 	clock/			- Graphical clock | 
 | 	cmdlgtst/		- Common dialog tests | 
 | 	control/		- Control panel | 
 | 	expand/			- Decompress Lempel-Ziv compressed archive | 
 | 	msiexec/		- Microsoft Installer frontend | 
 | 	notepad/		- Notepad replacement  | 
 | 	progman/		- Program manager | 
 | 	regedit/		- Registry editor | 
 | 	regsvr32/		- Register COM server | 
 | 	rpcss/			- RPC services | 
 | 	rundll32/		- Execute DLL functions directly | 
 | 	start/			- Replacement for start.exe | 
 | 	taskmgr/		- Manage running Windows/Winelib applications | 
 | 	uninstaller/		- Remove installed programs | 
 | 	view/			- Metafile viewer | 
 | 	wcmd/			- Command line interface | 
 | 	wineboot/		- Wine bootstrap process | 
 | 	winecfg/		- Wine configuration utility | 
 | 	wineconsole/		- Console | 
 | 	winedbg/		- Debugger | 
 | 	winefile/		- File manager | 
 | 	winemenubuilder/	- Helper program for building Unix menu entries | 
 | 	winemine/		- Mine game | 
 | 	winepath/		- Translate between Wine and Unix paths | 
 | 	winetest/		- Wine testing shell | 
 | 	winevdm/		- Wine virtual DOS machine | 
 | 	winhelp/		- Help viewer | 
 | 	winver/			- Windows Version Program | 
 |  | 
 |  | 
 | Support programs, libraries, etc: | 
 | --------------------------------- | 
 |  | 
 | 	dlls/dxerr8/		- DirectX 8 error import lib | 
 | 	dlls/dxerr9/		- DirectX 9 error import lib | 
 | 	dlls/dxguid/		- DirectX UUID import lib | 
 | 	dlls/strmiids/		- Exports class CLSIDs and interface IIDs | 
 | 	dlls/uuid/		- Windows-compatible UUID import lib | 
 | 	documentation/		- some documentation | 
 | 	include/		- Windows standard includes | 
 | 	include/msvcrt/		- MSVC compatible libc headers | 
 | 	include/wine/		- Wine specific headers | 
 | 	libs/			- the Wine libraries | 
 | 	libs/port/		- portability library | 
 | 	libs/unicode/		- Unicode support shared | 
 | 	libs/wine/		- Wine bootstrap library | 
 | 	libs/wpp/		- C preprocessor | 
 | 	loader/			- the main Wine loader | 
 | 	server/			- the Wine server | 
 | 	tools/			- various tools used to build/check Wine | 
 | 	tools/widl/		- the IDL compiler | 
 | 	tools/winapi/	- A Win32 API checker | 
 | 	tools/winebuild/	- Wine build tool | 
 | 	tools/winedump/		- a .DLL dump utility | 
 | 	tools/winegcc/		- a MinGW command line compatible gcc wrapper | 
 | 	tools/wmc/		- the message compiler | 
 | 	tools/wpp/		- the C pre-processor library | 
 | 	tools/wrc/		- the resource compiler | 
 |  | 
 |  | 
 |  | 
 | IMPLEMENTING NEW API CALLS | 
 | ========================== | 
 |  | 
 | This is the simple version, and covers only Win32. Win16 is slightly | 
 | uglier, because of the Pascal heritage and the segmented memory model. | 
 |  | 
 | All of the Win32 APIs known to Wine are listed in the .spec file of | 
 | their corresponding dll. An unimplemented call will look like (from | 
 | gdi32.spec) | 
 |   269 stub PolyBezierTo | 
 | To implement this call, you need to do the following four things. | 
 |  | 
 | 1. Find the appropriate parameters for the call, and add a prototype to | 
 | the correct header file. In this case, that means [include/wingdi.h], | 
 | and it might look like | 
 |   BOOL WINAPI PolyBezierTo(HDC, LPCVOID, DWORD); | 
 | If the function has both an ASCII and a Unicode version, you need to | 
 | define both and add a #define WINELIB_NAME_AW declaration. See below | 
 | for discussion of function naming conventions. | 
 |    | 
 | 2. Modify the .spec file to tell Wine that the function has an | 
 | implementation, what the parameters look like and what Wine function | 
 | to use for the implementation. In Win32, things are simple--everything | 
 | is 32-bits. However, the relay code handles pointers and pointers to | 
 | strings slightly differently, so you should use 'str' and 'wstr' for | 
 | strings, 'ptr' for other pointer types, and 'long' for everything else. | 
 |   269 stdcall PolyBezierTo(long ptr long) PolyBezierTo | 
 | The 'PolyBezierTo' at the end of the line is which Wine function to use | 
 | for the implementation. | 
 |  | 
 | 3. Implement the function as a stub. Once you add the function to the .spec | 
 | file, you must add the function to the Wine source before it will link. | 
 | Add a function called 'PolyBezierTo' somewhere. Good things to put | 
 | into a stub: | 
 |   o a correct prototype, including the WINAPI | 
 |   o header comments, including full documentation for the function and | 
 |     arguments (see documentation/README.documentation) | 
 |   o A FIXME message and an appropriate return value are good things to | 
 |     put in a stub. | 
 |  | 
 |   /************************************************************ | 
 |    *                    PolyBezierTo   (GDI32.269)   | 
 |    *   | 
 |    * Draw many Bezier curves. | 
 |    * | 
 |    * PARAMS | 
 |    *   hdc   [I] Device context to draw to | 
 |    *   p     [I] Array of POINT structs | 
 |    *   count [I] Number of points in p | 
 |    * | 
 |    * RETURNS | 
 |    *   Success: Non-zero. | 
 |    *   Failure: FALSE. Use GetLastError() to find the error cause. | 
 |    * | 
 |    * BUGS | 
 |    *   Unimplemented | 
 |    */ | 
 |    BOOL WINAPI PolyBezierTo(HDC hdc, LPCVOID p, DWORD count)  | 
 |    { | 
 |        /* tell the user they've got a substandard implementation */ | 
 |        FIXME("(%x,%p,%d): stub\n", hdc, p, count); | 
 |  | 
 |        /* some programs may be able to compensate,  | 
 |         * if they know what happened  | 
 |         */ | 
 |        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);   | 
 |        return FALSE;    /* error value */ | 
 |    } | 
 |  | 
 | 4. Implement and test the rest of the function. | 
 |  | 
 |  | 
 | IMPLEMENTING A NEW DLL | 
 | ====================== | 
 |  | 
 | Generic directions | 
 | ------------------ | 
 |  | 
 | Apart from writing the set of needed .c files, you also need to do the  | 
 | following: | 
 |  | 
 | 1.  Create a directory <MyDll> where to store the implementation of | 
 |     the DLL. This directory has to be put under the dlls/ directory. | 
 |     If the DLL exists under Windows as both 16 and 32 bit DLL, you | 
 |     should have a single directory with both implementations. | 
 |  | 
 | 2.  Create the Makefile.in in the ./dlls/<MyDll>/ directory. You can | 
 |     copy an existing Makefile.in from another ./dlls/ subdirectory. | 
 |     You need at least to change the MODULE and C_SRCS macros.  | 
 |  | 
 | 3.  Add the directory in ./configure.ac (in AC_OUTPUT macro at the end | 
 |     of the file to trigger the Makefile generation) | 
 |  | 
 | 4.  Run ./make_dlls in the dlls directory to update Makefile.in in | 
 |     that directory. | 
 |  | 
 | 5.  You can now regenerate ./configure file (with 'autoconf') | 
 |     and the various Makefiles (with 'configure; make depend') (run | 
 |     from the top of Wine's tree). | 
 |     You should now have a Makefile file in ./dlls/<MyDll>/ | 
 |  | 
 | 6.  Create the .spec file for the DLL exported functions in your | 
 |     directory. Refer to 'Implementation of new API calls' earlier in | 
 |     this document for more information on this part. | 
 |  | 
 | 7.  You can now start adding .c files. For the .h files, if they are | 
 |     standard Windows one, put them in include/. If they are linked to | 
 |     *your* implementation of the dll, put them in your newly created | 
 |     directory. | 
 |  | 
 | Debug channels | 
 | -------------- | 
 |  | 
 | If you need to create a new debug channel, just add the | 
 | WINE_DEFAULT_DEBUG_CHANNEL to your .c file(s), and use them.  | 
 | All the housekeeping will happen automatically. | 
 |  | 
 | Resources | 
 | --------- | 
 |  | 
 | If you also need to add resources to your DLL, then create the .rc | 
 | file. Add to your ./dlls/<MyDll>/Makefile.in, in the RC_SRCS macro, | 
 | the list of .rc files to add to the DLL. See dlls/comctl32/ for an | 
 | example of this. | 
 |  | 
 | Thunking | 
 | -------- | 
 |  | 
 | If you're building a 16 & 32 bit DLLs pair, then from the 32 bit code | 
 | you might need to call 16 bit routine. The way to do it to add in the | 
 | code, fragments like: | 
 | /* ### Start build ### */ | 
 | extern WORD CALLBACK <PREFIX>_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG); | 
 | /* ### stop build ### */ | 
 | Where <PREFIX>_ is an internal prefix for your module. The first | 
 | parameter is always of type FARPROC16. Then, you can get the regular | 
 | list of parameters. The _word_wwlll indicates the type of return (long | 
 | or word) and the size of the parameters (here l=>long, w=>word; which | 
 | maps to WORD,WORD,LONG,LONG,LONG. | 
 | You can put several functions between the Start/Stop build pair. | 
 |  | 
 | You can also read the winebuild manpage for more details on this. | 
 |  | 
 | Then, add to ./dlls/<MyDll>/Makefile.in a line like: | 
 |  | 
 | EXTRA_OBJS = $(MODULE).glue.o | 
 |  | 
 | See dlls/winmm/ for an example of this. | 
 |  | 
 | MEMORY AND SEGMENTS | 
 | =================== | 
 |  | 
 | NE (Win16) executables consist of multiple segments.  The Wine loader | 
 | loads each segment into a unique location in the Wine processes memory | 
 | and assigns a selector to that segment.  Because of this, it's not | 
 | possible to exchange addresses freely between 16-bit and 32-bit code. | 
 | Addresses used by 16-bit code are segmented addresses (16:16), formed | 
 | by a 16-bit selector and a 16-bit offset.  Those used by the Wine code | 
 | are regular 32-bit linear addresses. | 
 |  | 
 | There are four ways to obtain a segmented pointer: | 
 |   - Using the MapLS function (recommended). | 
 |   - Allocate a block of memory from the global heap and use | 
 |     WIN16_GlobalLock to get its segmented address. | 
 |   - Declare the argument as 'segptr' instead of 'ptr' in the spec file | 
 |     for a given API function. | 
 |  | 
 | Once you have a segmented pointer, it must be converted to a linear | 
 | pointer before you can use it from 32-bit code.  This can be done with | 
 | the MapSL function.  The linear pointer can then be used freely with | 
 | standard Unix functions like memcpy() etc. without worrying about 64k | 
 | boundaries.  Note: there's no easy way to convert back from a linear | 
 | to a segmented address. | 
 |  | 
 | In most cases, you don't need to worry about segmented address, as the | 
 | conversion is made automatically by the callback code and the API | 
 | functions only see linear addresses. However, in some cases it is | 
 | necessary to manipulate segmented addresses; the most frequent cases | 
 | are: | 
 |   - API functions that return a pointer | 
 |   - lParam of Windows messages that point to a structure | 
 |   - Pointers contained inside structures accessed by 16-bit code. | 
 |  | 
 | It is usually a good practice to used the type 'SEGPTR' for segmented | 
 | pointers, instead of something like 'LPSTR' or 'char *'.  As SEGPTR is | 
 | defined as a DWORD, you'll get a compilation warning if you mistakenly | 
 | use it as a regular 32-bit pointer. | 
 |  | 
 |  | 
 | STRUCTURE PACKING | 
 | ================= | 
 |  | 
 | Under Windows, data structures are tightly packed, i.e. there is no | 
 | padding between structure members. On the other hand, by default gcc | 
 | aligns structure members (e.g. WORDs are on a WORD boundary, etc.). | 
 | This means that a structure like | 
 |  | 
 | struct { BYTE x; WORD y; }; | 
 |  | 
 | will take 3 bytes under Windows, but 4 with gcc, because gcc will add a | 
 | dummy byte between x and y. To have the correct layout for structures | 
 | used by Windows code, you need to embed the struct within two special | 
 | #include's which will take care of the packing for you: | 
 |  | 
 | #include "pshpack1.h" | 
 | struct { BYTE x; WORD y; }; | 
 | #include "poppack1.h" | 
 |  | 
 | For alignment on a 2-byte boundary, there is a "pshpack2.h", etc. | 
 |  | 
 |  | 
 | NAMING CONVENTIONS FOR API FUNCTIONS AND TYPES | 
 | ============================================== | 
 |  | 
 | In order to support both Win16 and Win32 APIs within the same source | 
 | code, the following convention must be used in naming all API | 
 | functions and types. If the Windows API uses the name 'xxx', the Wine | 
 | code must use: | 
 |  | 
 |  - 'xxx16' for the Win16 version, | 
 |  - 'xxx'   for the Win32 version when no strings are involved, | 
 |  - 'xxxA'  for the Win32 version with ASCII strings, | 
 |  - 'xxxW'  for the Win32 version with Unicode strings. | 
 |  | 
 | If the function has both ASCII and Unicode version, you should then | 
 | use the macros WINELIB_NAME_AW(xxx) or DECL_WINELIB_TYPE_AW(xxx) | 
 | (defined in include/windef.h) to define the correct 'xxx' function | 
 | or type for Winelib. When compiling Wine itself, 'xxx' is _not_ | 
 | defined, meaning that code inside of Wine must always specify | 
 | explicitly the ASCII or Unicode version. | 
 |  | 
 | If 'xxx' is the same in Win16 and Win32, you can simply use the same | 
 | name as Windows, i.e. just 'xxx'.  If 'xxx' is Win16 only, you could | 
 | use the name as is, but it's preferable to use 'xxx16' to make it | 
 | clear it is a Win16 function. | 
 |  | 
 | Examples: | 
 |  | 
 | typedef struct { /* Win32 ASCII data structure */ } WNDCLASSA; | 
 | typedef struct { /* Win32 Unicode data structure */ } WNDCLASSW; | 
 | typedef struct { /* Win16 data structure */ } WNDCLASS16; | 
 | DECL_WINELIB_TYPE_AW(WNDCLASS); | 
 |  | 
 | ATOM RegisterClass16( WNDCLASS16 * ); | 
 | ATOM RegisterClassA( WNDCLASSA * ); | 
 | ATOM RegisterClassW( WNDCLASSW * ); | 
 | #define RegisterClass WINELIB_NAME_AW(RegisterClass) | 
 |  | 
 | The Winelib user can then say: | 
 |  | 
 |     WNDCLASS wc = { ... }; | 
 |     RegisterClass( &wc ); | 
 |  | 
 | and this will use the correct declaration depending on the definition | 
 | of the UNICODE symbol. | 
 |  | 
 |  | 
 | DEBUG MESSAGES | 
 | ============== | 
 |  | 
 | To display a message only during debugging, you normally write something | 
 | like this: | 
 |  | 
 |         TRACE("abc...");  or | 
 |         FIXME("abc...");  or | 
 |         WARN("abc...");   or | 
 |         ERR("abc..."); | 
 |  | 
 | depending on the seriousness of the problem. (documentation/debugging.sgml | 
 | explains when it is appropriate to use each of them). You need to declare | 
 | the debug channel name at the top of the file (after the includes) using | 
 | the WINE_DEFAULT_DEBUG_CHANNEL macro, like so: | 
 |  | 
 | 	WINE_DEFAULT_DEBUG_CHANNEL(win); | 
 |  | 
 | If your debugging code is more complex than just printf, you can use  | 
 | the macros: | 
 |  | 
 | 	TRACE_ON(xxx), WARN_ON(xxx), ERR_ON(xxx) and FIXME_ON(xxx)  | 
 |  | 
 | to test if the given channel is enabled. Thus, you can write: | 
 |  | 
 | 	if (TRACE_ON(win)) DumpSomeStructure(&str); | 
 |  | 
 | Don't worry about the inefficiency of the test. If it is permanently  | 
 | disabled (that is TRACE_ON(win) is 0 at compile time), the compiler will  | 
 | eliminate the dead code. | 
 |  | 
 | For more info about debugging messages, read: | 
 |  | 
 | http://www.winehq.org/site/docs/wine-devel/debugging | 
 |  | 
 |  | 
 | MORE INFO | 
 | ========= | 
 |  | 
 | 1. There is a FREE online version of the MSDN library (including | 
 |    documentation for the Win32 API) on http://msdn.microsoft.com/ | 
 |    or http://www.msdn.com/ | 
 |  | 
 | 2. Windows apilist:  http://www.mentalis.org/apilist/apilist.php | 
 |  | 
 | 3. http://www.sonic.net/~undoc/bookstore.html | 
 |  | 
 | 4. In 1993 Dr. Dobbs Journal published a column called "Undocumented Corner". | 
 |  | 
 | 5. www.geocities.com/SiliconValley/4942/ |