Contents of the README.TXT file
Windows Multiple Segment DLL Skeleton Sample
Copyright (c) 1991, 1992 Microsoft Corporation. All rights reserved.
This sample Windows program demonstrates how to create a medium model
dynamic link library. Although this sample demonstrates how to
implicitly load the DLL, it can be easily modified to explicitly load
This sample is composed of two parts: 1) a Windows application and
2) a multiple-segment DLL. The application works like GENERIC that
comes with the Windows SDK, but features two menu items that select
functions exported by the DLL. The DLL functions put up a message box
to tell the user that the function belongs to the DLL. One function
uses the C calling convention and the other uses the Pascal calling
In this sample, the DLL is composed of multiple code segments so that
the functions can be placed in a moveable discardable segment and the
WEP may be placed in a fixed code segment. WEPs must reside in fixed
code segments so that they can always be called even when there is
very little free memory.
WEPs were designed to allow DLLs that hooked interrupts to unhook
them before termination. WEPs were not designed for general purpose
DLL clean-up. As such, in Windows 3.0, they are called off of a small
stack in the Windows kernel that will overflow if they call Windows
APIs. There is enough stack space for unhooking interrupts, however.
In Windows 3.1, WEPs are called off a 4K stack in the Windows kernel,
which allows them to call Windows API functions.
An implictly loaded DLL is loaded into memory before the application
that uses it gets fully loaded and so LibMain(), analogous to
WinMain(), may get called before the application's message queue is
initialized. Thus, do not call APIs that send messages to the
application in LibMain(). Also, an implicitly loaded DLL is
terminated after the application that uses it has been completely
removed from the system. This means that you cannot perform any
actions in a WEP that rely on the application's existence. Example
classes of functions that cannot be called from a WEP include file
manipulation functions, message boxes, and dialog boxes.
To write a DLL that is compatible with both Windows 3.0 and 3.1, follow
1) The DLL's module name in LIBRARY statement of the DLL's module
definition file must be all caps. If this is not done, the DLL
will not be properly unloaded in Windows 3.0. This is a
limitation for Windows 3.0 only.
2) Because Windows 3.0 calls WEPs on a very small stack in the
kernel, WEPs cannot call any Windows API function. DLLs
designed for Windows 3.1 only can call Windows APIs, however.
Please see the discussion above.
3) Use the /30 resource compiler switch to mark the DLL as a
Windows 3.0 DLL.
To convert this sample so that the application explicitly
loads the DLL, you need to call LoadLibrary() to load the DLL; to
unload the DLL, call FreeLibrary(). The makefile needs to be
slightly modifed so that it 1) does not call IMPLIB to make an import
library for the DLL and 2) does not link the import library,
DLLSKEL.LIB to the application. Finally, to access the function exported
by the DLL, you will have to call GetProcAddress() to locate the
function just before calling it.
This sample is divided into the following files:
appskel.c - The main program file for the application.
about.c - The dialog procedure for the About box.
init.c - The initialization code for the application.
mainwnd.c - The main window procedure for the application.
appskel.rc - The resource script file that contains the
resource definitions for the application.
appskel.def - The module definition file for the application.
dllskel.c - The main program file for the DLL.
wepcode.c - The program file that contains the WEP.
dllskel.def - The module definition file for the DLL.
makefile - The NMAKE file that specifies the build commands
for both the DLL and the application.
appskel.exe - Executable application file.
dllskel.dll - Dynamic link library.
Development team: Dan Ruder