OTHER LIBRARY RESTRICTIONS

The start-up code that is added to a Windows program during linking with LINK uses the registers passed to the program on entry, together with some DOS function calls, to set various global variables in the program's data segment. These variables allow programs access to the DOS environment and to other information. This start-up code isn't present in Windows libraries. For this reason, you can't use the getenv or putenv functions in libraries, nor can you use the following global variables defined in Microsoft C:

_dosvermajor _dosverminor
_osmajor _osminor
_psp environ
__argc __argv

I mentioned earlier that a dynamic library module doesn't receive messages. However, a library module can call GetMessage and PeekMessage. The messages the library pulls from the queue with these functions are actually messages for the program that called the library function. In general, the library works on behalf of the program calling it, a rule that holds for most Windows functions that a library calls. The obvious exceptions are local memory allocation functions. As you saw with the STRLIB library, these functions use the library's local heap.

A library can allocate global memory for the program instance calling the library. The global memory blocks are automatically freed when the program instance terminates.

A dynamic library can load resources (such as icons, strings, and bitmaps) either from the library file or from the file of the program that calls the library. The functions that load resources require an instance handle. If the library uses its own instance handle (which is passed to the library during initialization), then the library can obtain resources from its own file. To load resources from the calling program's .EXE file, the library function requires the instance handle of the program calling the function.

Registering window classes and creating windows in a library can be a little tricky. Both the window class structure and the CreateWindow call require an instance handle. Although you can use the library module's instance handle in creating the window class and the window, the window messages still go through the message queue of the program calling the library when the library creates the window. If you must create window classes and windows within a library, then it's probably best to use the calling program's instance handle.

Because messages for modal dialog boxes are retrieved outside a program's message loop, you can create a modal dialog box in a library by calling DialogBox. The instance handle can be that of the library, and the hwndParent parameter to DialogBox can be set to NULL.