ID Number: Q75253
3.00
WINDOWS
Summary:
If an application will be run only under one of Windows' protected
modes (standard mode or enhanced mode), and it is acceptable to allow
only one instance of the application to run at any given time, there
are techniques that can be used to create smaller, faster application
code. This article details the techniques and the factors that must be
considered when they are used.
More Information:
In Windows real mode, when Windows brings a portion of code in from
disk, other objects in memory can be moved about to make room. Every
FAR call (a call to another code segment) and every access to a
resource (menu, dialog box template, string table, and so forth) can
cause memory to move.
Windows allocates a data segment for each instance of each application
run. These data segments are objects that can be moved about as code
and resources are accessed.
Windows provides a data segment identifier to the application. This
value is placed into the DS register. The function prolog code,
generated by the C compiler when the -Gw switch is specified, stores
the value of the DS register on to the stack before any other function
code is executed. If the function changes the value of DS, the
function epilog code will restore the original value when the function
exits.
When Windows moves memory, it "walks" the stack, looking for the
stored DS values. Windows updates the stored information to reflect
the new location for the data segment.
In contrast, under Windows' protected modes, the identifier for the
data segment does not change, even when memory moves. However, because
functions may change the DS register, it is necessary to ensure that
the DS register contains the correct value. The Microsoft C Compiler,
versions 5.1 and later, provides the _loadds keyword, which instructs
the compiler to generate prolog and epilog code for a particular
function. If an application will be run only in protected mode, the
-Gw switch is not necessary. However, the _loadds modifier must be
specified for every exported function.
The restriction to a single instance is important. The code generated
by _loadds sets the DS register to point to the data segment of the
first instance of the program. The second and subsequent instances
would interfere with each other and with the first instance of the
application. The restriction to protected mode is of similar
importance. In the absence of prolog and epilog code, if the data
segment moved, the value of the DS register would not be updated to
reflect the new value; the application would use information in a
random portion of memory.
To prevent an application from running in real mode, use the Resource
Compiler -t option when binding the RES file to the EXE file.
The following code will prevent a second application of the
application from running. When an attempt is made to create a second
instance of the application, the first instance is brought to the top
and activated.
if (!hPrevInstance)
{
/* perform normal RegisterClass processing here */
}
else // This only allows one instance
{
HWND hWnd, hWnd1;
hWnd = FindWindow(szAppName, NULL);
if (IsWindow(hWnd))
{
hWnd1 = GetLastActivePopup(hWnd);
if (IsWindow(hWnd1))
hWnd = hWnd1;
BringWindowToTop(hWnd);
if (IsIconic(hWnd))
ShowWindow(hWnd, SW_RESTORE);
SetFocus(hWnd);
}
return FALSE;
}
Optionally, the -G2 switch can be specified to generate smaller and
faster code for the 80286 or later processors. Because the 8086
processor does not support protected mode, this does not exclude any
other equipment.
To summarize, an application that will run only in Windows protected
mode does not require the Windows prolog and epilog code. Applications
that are compiled without the C compiler -Gw switch must have the
following three attributes:
1. The _loadds modifier is specified for all exported functions.
2. The Resource Compiler -t switch is specified to prevent the
application from running in real mode.
3. Only one instance of the application is allowed. Use the code
provided above to enforce this restriction.