Home of the original IBM PC emulator for browsers.
The following document is from the Microsoft Programmer’s Library 1.3 CD-ROM.
Microsoft Windows Software Development Kit - Tools
────────────────────────────────────────────────────────────────────────────
Microsoft (R) Windows (tm) Software Development Kit - Tools
development tools for building Microsoft (R) Windows applications
VERSION 3.0
────────────────────────────────────────────────────────────────────────────
for the MS-DOS (R) and PC-DOS Operating Systems
Microsoft Corporation
Information in this document is subject to change without notice and does
not represent a commitment on the part of Microsoft Corporation. The
software described in this document is furnished under a license agreement
or nondisclosure agreement. The software may be used or copied only in
accordance with the terms of the agreement. It is against the law to copy
the software on any medium except as specifically allowed in the license or
nondisclosure agreement. No part of this manual may be reproduced or
transmitted in any form or by any means, electronic or mechanical, including
photocopying and recording, for any purpose without the express written
permission of Microsoft.
U.S. Government Restricted Rights
The SOFTWARE and documentation are provided with RESTRICTED RIGHTS. Use,
duplication, or disclosure by the Government is subject to restrictions as
set forth in subparagraph (c) (1) (ii) of the Rights in Technical Data and
Computer Software clause at DFARS 252.227-7013 or subparagraphs (c) (1) and
(2) of the Commercial Computer Software
─ Restricted Rights at 48 CFR 52.227-19, as applicable.
Contractor/manufacturer is Microsoft Corporation/One Microsoft Way/Redmond,
WA 98052-6399.
(C) Copyright Microsoft Corporation, 1990. All rights reserved.
Simultaneously published in the U.S. and Canada.
Printed and bound in the United States of America.
Microsoft, MS, MS-DOS, GW-BASIC, QuickC, CodeView, and
XENIX are registered trademarks and Windows is a trademark of Microsoft
Corporation.
AT&T is a registered trademark of American Telephone
and Telegraph Company.
Aldus is a registered trademark of Aldus Corporation.
COMPAQ is a registered trademark of Compaq Computer Corporation.
IBM is a registered trademark of International Business
Machines Corporation.
Intel is a registered trademark of Intel Corporation.
Lotus and 1-2-3 are registered trademarks of Lotus Development
Corporation.
Mac and Macintosh are registered trademarks of Apple Computer,
Inc.
Olivetti is a registered trademark of Ing. C. Olivetti.
Paintbrush is a registered trademark of Zsoft Corporation.
The Symbol fonts provided with Windows 3.0 are based on the CG Times font,
a product of AGFA Compugraphic Division of Agfa Corporation.
Tandy is a registered trademark of Tandy Corporation.
Document No. SY0314b-300-R00-1089
Table of Contents
────────────────────────────────────────────────────────────────────────────
Introduction
Organization of This Manual
Building a Windows Application
Document Conventions
Summary
PART I Compilers and Linkers
────────────────────────────────────────────────────────────────────────────
Chapter 1 Compiling Applications: The C Compiler
1.1 Compiling C-Language Windows Applications
1.2 Compiler Options
1.2.1 Memory-Model Options
1.2.2 Application Development Options
1.2.3 Dynamic-Link Library Options
1.3 Summary
Chapter 2 Linking Applications: The Linker
2.1 Creating Module-Definition Files
2.1.1 Creating Module Definitions for Applications
2.1.2 Creating Module Definitions for Libraries
2.2 Importing Dynamic-Link Libraries
2.3 Linking an Application
2.3.1 Using the LINK Command
2.3.2 Specifying LINK Command Options
2.3.3 Specifying Libraries on the LINK Command Line
2.4 Examining Executable File Headers
2.5 Summary
Chapter 3 Compiling Resources: The Resource Compiler
3.1 Including Resources in an Application
3.2 Creating a Resource Script File
3.3 Using the Resource Compiler
3.3.1 Compiling Resources Separately
3.3.2 Defining Names for the Preprocessor
3.3.3 Renaming the Compiled Resource File
3.3.4 Controlling the Directories that RC Searches
3.3.5 Displaying Progress Messages
3.4 Summary
PART II Resource Editors
────────────────────────────────────────────────────────────────────────────
Chapter 4 Designing Images: SDKPaint
4.1 How SDKPaint Works with Files
4.1.1 File Types
4.1.2 Icon and Cursor Data: The SDKPAINT.DAT File
4.2 The SDKPaint Window
4.3 Opening Files and Images
4.3.1 Converting Files to 3.0 Format
4.3.2 Opening Bitmaps
4.3.3 Opening Icons and Cursors
4.4 Drawing with SDKPaint Tools
4.5 Using the SDKPaint Palette
4.5.1 Working with Opaque, Screen, and Inverse Colors
4.6 Customizing the Palette
4.6.1 Editing Colors
4.6.2 Saving a Palette
4.6.3 Loading a Customized Palette
4.7 Defining the Cursor Hotspot
4.8 Using the Clipboard
4.9 Using ZoomIn to Examine Images
4.10 Summary
Chapter 5 Designing Dialog Boxes: The Dialog Editor
5.1 How the Dialog Editor Works with Files
5.1.1 The Dialog Script
5.1.2 The Resource File
5.1.3 The Include File
5.2 Installing and Removing Custom Controls
5.2.1 Installing a Custom Control
5.2.2 Removing a Custom Control
5.3 Viewing a Dialog Box: The Dialog Editor Window
5.3.1 The Mode Display
5.3.2 The Toolbox
5.3.3 The Selected Item Status Window
5.4 Opening Files and Dialog Boxes
5.4.1 Opening a Resource File
5.4.2 Opening an Include File
5.4.3 Opening a Dialog Box
5.5 Editing Dialog Box Controls
5.5.1 Adding Controls
5.5.2 Working with Individual Controls
5.6 Working with Groups of Controls
5.6.1 Moving Groups of Controls
5.6.2 Defining Input Focus Sequence
5.7 Working with a Dialog Box
5.7.1 Resizing a Dialog Box
5.7.2 Renaming a Dialog Box
5.7.3 Defining Styles
5.7.4 Setting Memory Flags
5.7.5 Canceling Edits
5.8 Moving a Dialog Box Between Resources
5.9 Working with Include Files
5.9.1 Creating New Include Files
5.9.2 Loading Existing Include Files
5.9.3 Editing Include Files
5.9.4 Saving Include Files
5.10 Summary
Chapter 6 Designing Fonts: The Font Editor
6.1 Opening a Font
6.2 Editing Characters
6.2.1 Turning Pixels On or Off
6.2.2 Changing Rows and Columns of Pixels
6.2.3 Modifying Blocks of Pixels
6.2.4 Changing Character Width
6.2.5 Storing Changes to a Character
6.2.6 Canceling Changes to a Character
6.3 Editing a Font
6.4 Changing Font File Header Information
6.5 Summary
PART III Debugging and Optimization Tools
────────────────────────────────────────────────────────────────────────────
Chapter 7 Debugging in Protected Mode: CodeView for Windows
7.1 Requirements for Use
7.2 Comparing CVW with Other Microsoft Debuggers
7.2.1 Differences between CVW and SYMDEB
7.2.2 Differences between CVW and CodeView for DOS
7.3 Preparing to Run CVW
7.3.1 Setting Up a Secondary Monitor
7.3.2 Setting Up the Debugging Version of Windows
7.3.3 Preparing Windows Applications for Debugging
7.4 Starting a Debugging Session
7.4.1 Starting a Debugging Session for a Single Application
7.4.2 Starting a Debugging Session for Multiple Instances
of an Application
7.4.3 Starting a Debugging Session for Multiple Applications
7.4.4 Starting a Debugging Session for DLLs
7.4.5 Using CVW File Run Options
7.5 Saving Session Information
7.6 Working with the CVW Screen
7.6.1 Using CVW Display Windows
7.6.2 Using the CVW Menu Bar
7.7 Getting On-line Help in CVW
7.8 Displaying Program Data
7.8.1 Displaying Variables
7.8.2 Displaying Expressions
7.8.3 Displaying Arrays and Structures
7.8.4 Using the Quick Watch Command
7.8.5 Tracing Windows Messages
7.8.6 Displaying Memory
7.8.7 Displaying the Contents of Registers
7.8.8 Displaying Windows Modules
7.9 Modifying Program Data
7.10 Controlling Program Execution
7.10.1 Continuous Execution
7.10.2 Single-Step Execution
7.10.3 Jumping to a Particular Location
7.10.4 Interrupting Your Program
7.11 Handling Abnormal Termination of the Application
7.11.1 Handling a Fatal Exit
7.11.2 Handling a GP Fault
7.12 Ending a CVW Session
7.13 Restarting a CVW Debugging Session
7.14 Advanced CVW Techniques
7.14.1 Using Multiple Source Windows
7.14.2 Calling Functions
7.14.3 Checking for Undefined Pointers
7.14.4 Handling Register Variables
7.14.5 Redirecting CVW Input and Output
7.15 Customizing CVW with the TOOLS.INI File
7.16 A Sample Session in CVW
7.17 Summary
Chapter 8 Debugging in Real Mode: Symbolic Debugger
8.1 Preparing Symbol Files
8.1.1 MAPSYM Program
8.1.2 The Incremental Linker
8.1.3 Symbols with C-Language Applications
8.1.4 Symbols with Assembly-Language Applications
8.2 Setting Up the Debugging Terminal
8.2.1 Setting Up a Remote Terminal
8.2.2 Setting Up a Secondary Monitor
8.3 Starting SYMDEB with Windows
8.3.1 Specifying SYMDEB Options
8.3.2 Specifying Symbol Files
8.3.3 Passing the Application to Windows
8.3.4 Using SYMDEB Keys
8.4 Working with Symbol Maps
8.4.1 Listing the Symbol Maps
8.4.2 Opening a Symbol Map
8.4.3 Displaying Symbols
8.5 Starting the Application
8.6 Displaying Allocation Messages
8.6.1 Setting Breakpoints with Symbols
8.6.2 Displaying Variables
8.6.3 Displaying Application Source Statements
8.7 Quitting SYMDEB
8.8 SYMDEB Command Overview and Tables
8.8.1 Command Arguments
8.8.2 Address Arguments
8.8.3 Expressions
8.9 SYMDEB Commands
a ─ Assemble
ba ─ Breakpoint Address
bc ─ Breakpoint Clear
bd ─ Breakpoint Disable
be ─ Breakpoint Enable
bl ─ Breakpoint List
bp ─ Breakpoint Set
c ─ Compare
d ─ Dump
da ─ Dump ASCII
db ─ Dump Bytes
dd ─ Dump Doublewords
df ─ Display Global Free List
dg ─ Display Global Heap
dh ─ Display Local Heap
dl ─ Dump Long Reals
dm ─ Display Global Module List
dq ─ Dump Task Queue
ds ─ Dump Short Reals
dt ─ Dump Ten-Byte Reals
du ─ Display Global LRU List
dw ─ Dump Words
e ─ Enter
ea ─ Enter Address
eb ─ Enter Bytes
ed ─ Enter Doublewords
el ─ Enter Long Reals
es ─ Enter Short Reals
et ─ Enter Ten-Byte Reals
ew ─ Enter Words
f ─ Fill
g ─ Go
h ─ Hex
i ─ Input
k ─ Backtrace Stack
kt ─ Backtrace Task Stack
kv ─ Verbose Backtrace Stack
l ─ Load
m ─ Move
mid─ Macro
n ─ Name
o ─ Output
p ─ Program Step
q ─ Quit
r ─ Register
s ─ Search
Set Source Mode
t ─ Trace
u ─ Unassemble
v ─ View
w ─ Write
x ─ Examine Symbol Map
xo ─ Open Symbol Map
z ─ Set Symbol Value
? ─ Display Help
? ─ Display Expression
. ─ Source-Line Display
Redirect Input
Redirect Output
Redirect Input and Output
! ─ Shell Escape
* ─ Comment
Chapter 9 Advanced Debugging in Protected Mode: 80386 Debugger
9.1 Preparing Symbol Files for the 80386 Debugger
9.2 Starting the Debugger
9.3 When an Application Fails
9.4 Debugger Command Format
9.4.1 Command Keys
9.4.2 Command Parameters
9.4.3 Binary and Unary Operators
9.5 Common Command Directory
? ─ Display Expression
? ─ Display Help Menu
.? ─ Display External Commands
.b ─ Set COM Port Baud Rate
.df ─ Display Global Free List
.dg ─ Display Global Heap
.dh ─ Display Local Heap
.dm ─ Display Global Module List
.dq ─ Dump Task Queue
.du ─ Display Global LRU List
.reboot ─ Reboot Target System
bc ─ Clear Breakpoints
bd ─ Disable Breakpoints
be ─ Enable Breakpoints
bl ─ List Breakpoints
bp ─ Set Breakpoints
c ─ Compare Memory
d ─ Display Memory
db ─ Display Bytes
dd ─ Display Doublewords
dg ─ Display GDT
di ─ Display IDT
dl ─ Display LDT
dt ─ Display TSS
dw ─ Display Words
e ─ Enter Byte
f ─ Fill Memory
g ─ Go
h ─ Hexadecimal Arithmetic
i ─ Input Byte
j ─ Conditional Execute
k ─ Backtrace Stack
ka ─ Set Backtrace Arguments
kt ─ Backtrace Task Stack
kv ─ Verbose Backtrace Stack
la ─ List Absolute Symbols
lg ─ List Groups
lm ─ List Map
ln ─ List Near
ls ─ List Symbols
m ─ Move Memory
o ─ Output to Port
p ─ Program Trace
r ─ Display Registers
s ─ Search Bytes
t ─ Trace Instructions
u ─ Unassemble Bytes
v ─ Set Interrupt Vector Trapping
vl ─ Display Interrupt Trapping Information
w ─ Change Map
y ─ Debugger Option Command
z ─ Zap Embedded INT 1 and INT 3 Instructions
zd ─ Execute Default Command String
zl ─ Display Default Command String
zs ─ Change Default Command String
9.6 386 Enhanced Windows Environment Commands
9.7 Summary
Chapter 10 Monitoring Messages: Spy
10.1 Displaying Messages
10.2 Choosing Options
10.2.1 Choosing Messages
10.2.2 Choosing the Output Device
10.2.3 Choosing Frequency of Output
10.3 Choosing a Window: The Window Menu
10.4 Turning Spy On and Off: The Spy Menu
10.5 Summary
Chapter 11 Viewing the Heap: Heap Walker
11.1 How Heap Walker Views Memory
11.1.1 Viewing the Heap in Protected Mode
11.1.2 Viewing the Heap in Real Mode
11.2 The Heap Walker Window
11.3 Using Heap Walker Commands
11.3.1 Performing File Operations: The File Menu
11.3.2 Walking the Heap: The Walk and EmsWalk Menus
11.3.3 Sorting Memory Objects: The Sort Menu
11.3.4 Displaying Memory Objects: The Object Menu
11.3.5 Allocating Memory: The Alloc Menu
11.3.6 Determining Memory Size: The Add! Menu
11.4 Suggestions for Using Heap Walker
11.5 Summary
Chapter 12 Moving Memory: Shaker
12.1 Using Shaker
12.2 Summary
Chapter 13 Analyzing CPU Time: Profiler
13.1 Overview of Profiler
13.2 Preparing to Run Profiler
13.3 Using Profiler Functions
13.3.1 Starting and Stopping Sampling: The ProfStart and
ProfStop Functions
13.3.2 Checking if Profiler Is Installed: The ProfInsChk
Function
13.3.3 Setting the Sampling Rate: The ProfSampRate Function
13.3.4 Managing Output: The ProfClear, ProfFlush,
and ProfSetup Functions
13.3.5 Stopping Profiler: The ProfFinish Function
13.4 Sampling Code
13.4.1 Sampling Applications in Windows Real Mode
13.4.2 Sampling Applications in Windows 386 Enhanced Mode
13.5 Displaying Samples: SHOWHITS.EXE
13.6 Summary
Chapter 14 Analyzing Swaps: Swap
14.1 Preparing to Run Swap
14.1.1 Files You Need to Run Swap
14.1.2 Using the SwapRecording Function
14.2 Running Swap
14.2.1 Specifying a Symbol-File Path
14.2.2 Specifying a Pathname for the Data Collection File
14.2.3 Specifying a Module and Segment
14.3 Displaying Output
14.4 Summary
PART IV Help Tools
────────────────────────────────────────────────────────────────────────────
Chapter 15 Providing Help: The Help System
15.1 Creating a Help System: The Development Cycle
15.2 How Help Appears to the User
15.3 How Help Appears to the Help Writer
15.4 How Help Appears to the Help Programmer
15.5 Summary
Chapter 16 Planning the Help System
16.1 Developing a Plan
16.1.1 Defining the Audience
16.1.2 Planning the Content of the Help System
16.1.3 Planning the Structure of Help Topics
16.1.4 Displaying Context-Sensitive Help Topics
16.2 Determining the Topic File Structure
16.2.1 Choosing a File Structure for Your Application
16.3 Designing the Appearance of Help Topics
16.3.1 Layout of the Help Text
16.3.2 Type Fonts and Sizes
16.3.3 Graphic Images
16.4 Summary
Chapter 17 Creating the Help Topic Files
17.1 Choosing an Authoring Tool
17.2 Structuring Help Topic Files
17.3 Coding Help Topic Files
17.3.1 Assigning Build Tags
17.3.2 Assigning Context Strings
17.3.3 Assigning Titles
17.3.4 Assigning Key Words
17.3.5 Assigning Browse Sequence Numbers
17.3.6 Creating Cross-References Between Topics
17.3.7 Defining Terms
17.4 Inserting Graphic Images
17.4.1 Creating and Capturing Bitmaps
17.4.2 Placing Bitmaps Using a Graphical Word Processor
17.4.3 Placing Bitmaps by Reference
17.5 Managing Topic Files
17.5.1 Keeping Track of Files and Topics
17.5.2 Creating a Help Tracker
17.6 Summary
Chapter 18 Building the Help File
18.1 Creating the Help Project File
18.2 Specifying Topic Files: The Files Section
18.3 Specifying Build Tags: The BuildTags Section
18.4 Specifying Options: The Options Section
18.4.1 Specifying Error Reporting: The Warning Option
18.4.2 Specifying Build Topics: The Build Option
18.4.3 Specifying the Root Directory: The Root Option
18.4.4 Specifying the Index: The Index Option
18.4.5 Assigning a Title to the Help System: The Title
Option
18.4.6 Converting Fonts: The Forcefont Option
18.4.7 Changing Font Sizes : The Mapfontsize Option
18.4.8 Multiple Key-Word Tables: The Multikey Option
18.4.9 Compressing the File: The Compress Option
18.5 Specifying Alternate Context Strings: The Alias Section
18.6 Mapping Context-Sensitive Topics: The Map Section
18.7 Including Bitmaps by Reference: The Bitmaps Section
18.8 Compiling Help Files
18.8.1 Using the Help Compiler
18.9 Programming the Application to Access Help
18.9.1 Calling WinHelp from an Application
18.9.2 Getting Context-Sensitive Help
18.9.3 Getting Help on an Item Listed on the Help Menu
18.9.4 Accessing Additional Key-Word Tables
18.9.5 Canceling Help
18.10 Summary
Chapter 19 Help Examples and Compiler Error Messages
19.1 Help Topic Examples
19.2 Help Compiler Error Messages
19.2.1 Errors During Processing of Project File
19.2.2 Errors During Processing of RTF Topic Files
Index
Introduction
────────────────────────────────────────────────────────────────────────────
The Microsoft(R) Windows(tm) Software Development Kit Tools manual explains
how to use the programming tools that come with the Microsoft Windows
Software Development Kit (SDK). This manual also explains how to use some
additional tools, such as the C Compiler and linker, that don't come with
the SDK but which you will need in order to create Windows applications.
This introductory chapter describes the following topics:
■ The general organization of Tools
■ An overview of the steps involved in creating a Windows application
■ The notational conventions used throughout the manual
■ Related documentation
Organization of This Manual
This manual is divided into four parts, each of which contains several
chapters.
Part 1, "Compilers and Linkers," explains how to compile and link your
source files. Part 1 consists of the following chapters.
■ Chapter 1, "Compiling Applications: The C Compiler," explains how to
use the C Compiler (CL) to compile C-language source files for Windows
applications.
■ Chapter 2, "Linking Applications: The Linker," explains how to use the
linker (LINK) to link compiled source files into an executable Windows
application.
■ Chapter 3, "Compiling Resources: The Resource Compiler," explains how
to use the Resource Compiler (RC) to compile application resources and
add them to an executable Windows application.
Part 2, "Resource Editors," explains how to create and maintain Windows
program resources, such as icons and bitmaps, using the tools that come with
the SDK. Part 2 consists of the following chapters:
■ Chapter 4, "Designing Images: SDKPaint," explains how to use SDKPaint
(SDKPAINT) to create and edit icons, cursors, and bitmaps for Windows
applications.
■ Chapter 5, "Designing Dialog Boxes: The Dialog Editor," explains how
to use the Dialog Editor (DIALOG) to create and edit dialogs for
Windows applications.
■ Chapter 6, "Designing Fonts: The Font Editor," explains how to use the
Font Editor (FONTEDIT) to create and edit font files for Windows
applications.
Part 3, "Debugging and Optimization Tools," explains how to use the
debugging and testing tools that come with the SDK. Part 3 consists of the
following chapters:
■ Chapter 7, "Debugging in Protected Mode: CodeView for Windows,"
explains how to use CodeView(R) for Windows (CVW) to debug Windows
applications that run in protected mode.
■ Chapter 8, "Debugging in Real Mode: Symbolic Debugger," explains how
to use the Symbolic Debugger (SYMDEB) to debug Windows applications
that run in real mode.
■ Chapter 9, "Advanced Debugging in Protected Mode: 80386 Debugger,"
explains how to use the 80386 Debugger (WDEB386) to debug Windows
applications that run in protected mode.
■ Chapter 10, "Monitoring Messages: Spy," explains how to use Spy (SPY)
to monitor a window receiving system messages.
■ Chapter 11, "Viewing the Heap: Heap Walker," explains how to use Heap
Walker (HEAPWALK) to open and examine the global heap.
■ Chapter 12, "Moving Memory: Shaker," explains how to use Shaker
(SHAKER) to see the effect of memory movement on applications.
■ Chapter 13, "Analyzing CPU Time: Profiler," explains how to use
Profiler (PROFILER) to analyze and optimize the performance of
moveable code.
■ Chapter 14, "Analyzing Swaps: Swap," explains how to use Swap (SWAP)
to analyze and optimize your application's swapping behavior.
Part 4, "Help Tools," explains how to plan, write, and compile a Windows
Help system. Part 4 consists of the following chapters:
■ Chapter 15, "Providing Help: The Help System," gives an overview of
the Help system from the point of view of the user, the Help writer,
and the Help programmer.
■ Chapter 16, "Planning the Help System," explains what considerations
the Help writer should keep in mind when planning a Help system.
■ Chapter 17, "Creating the Help Topic Files," explains how to write and
code Help text files.
■ Chapter 18, "Building the Help File," explains how to build a Help
resource file.
■ Chapter 19, "Help Examples and Compiler Error Messages," shows example
topic files in several word processors, together with their
corresponding Help display. The chapter also includes a listing of
Help compiler error messages.
Building a Windows Application
You can build a Windows application using any ASCII text editor and the
tools described in this manual. This section briefly explains the process
involved in creating a Windows application, and highlights the role that the
development tools play in this process.
To build a Windows application, do the following:
1. Using a text editor, create C-language or assembly-language source
files that contain the WinMain function, window functions, and other
application code.
2. Create any cursor, icon, bitmap, dialog, and font resources the
application will need with the resource editors (SDKPAINT, DIALOG, and
FONTEDIT).
3. Produce a resource script (.RC) file that defines all of the
application's resources. The script file, which you create with a text
editor, lists and names the resources you created in the preceding
step. It also defines menus, dialog boxes, and other resources, such
as string tables and application-defined resources.
4. Use the Resource Compiler with the -r switch to compile the resource
script (.RC) file into a binary resource (.RES) file.
5. Use a text editor to create the module-definition (.DEF) file.
6. Compile all C-language sources with the C Compiler. Use the Microsoft
Macro Assembler (MASM) to assemble all assembly-language sources.
7. Using LINK, link the compiled and/or assembled source files with your
Windows and C run-time libraries. This produces a file with the .EXE
extension; however, you cannot execute such a file, because it does
not yet include the compiled resources.
8. Use RC without the -r switch to add the binary resource (.RES) file to
the .EXE file. This produces an executable Windows application.
9. Track down program errors and other problems with the Windows
debuggers: CodeView for Windows and the Symbolic Debugger. The Spy
program is useful for monitoring the Windows messages your program
receives. The Shaker program lets you simulate memory movements that
occur in the Windows multitasking environment.
10. Fine-tune your program with Windows optimization tools, Profiler and
Swap, so that it runs faster and uses memory more efficiently.
11. Build your program's help system with the Windows Help tools. This
step can take place during, rather than after, the
application-development process.
The following figure shows the steps required to build a Windows
application.
(This figure may be found in the printed book).
The figure "Building a Windows Application" does not include the debugging,
optimization, or Help tools.
Document Conventions
Throughout this manual, the term "DOS" refers to both MS-DOS(R) and PC-DOS,
except when noting features that are unique to one or the other.
The following document conventions are used throughout this manual:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Convention Description of Convention
────────────────────────────────────────────────────────────────────────────
Bold text Bold text indicates a specific term or
punctuation mark intended to be used
literally: language key words or
functions (such as EXETYPE or
CreateWindow), DOS commands, and
command-line options (such as /Zi). You
must type these terms and punctuation
marks exactly as shown. However, the use
of uppercase or lowercase letters is not
always significant. For instance, you
Convention Description of Convention
────────────────────────────────────────────────────────────────────────────
always significant. For instance, you
can invoke the linker by typing either
LINK, link, or Link at the DOS prompt.
( ) In syntax statements, parentheses
enclose one or more parameters that you
pass to a function.
Italic text Italic text indicates a placeholder; you
are expected to provide the actual value.
For example, the following syntax for
the Set-
CursorPos function indicates that you
must substitute values for the X and Y
coordinates, separated by a comma:
SetCursorPos(X, Y)
Monospaced type Code examples are displayed in a
nonproportional typeface.
Convention Description of Convention
────────────────────────────────────────────────────────────────────────────
nonproportional typeface.
BEGIN . . .END A vertical ellipsis in a program example
indicates that a portion of the program
is omitted.
. . . An ellipsis following an item indicates
that more items having the same form may
appear. In the following example, the
horizontal ellipsis indicates that you
can specify more than one breakaddress
value for the g command:
g «=startaddress» «breakaddress»...
« » Double brackets enclose optional fields
or parameters in command lines and
syntax statements. In the following
example, option and executable-file are
Convention Description of Convention
────────────────────────────────────────────────────────────────────────────
example, option and executable-file are
optional parameters of the RC command:
RC «option» filename «executable-file»
| A vertical bar indicates that you may
enter one of the entries shown on either
side of the bar. The following
command-line syntax illustrates the use
of a vertical bar:
DB «address | range»
The bar indicates that following the
Dump Bytes command (DB), you can specify
either an address or a range.
" " Quotation marks set off terms defined in
Convention Description of Convention
────────────────────────────────────────────────────────────────────────────
" " Quotation marks set off terms defined in
the text.
{ } Curly braces indicate that you must
specify one of the enclosed items.
SMALL CAPITAL LETTERS Small capital letters indicate the names
of keys and key sequences, such as: ALT
+ SPACEBAR
Microsoft Windows Software Development Kit Documentation Set
Throughout this documentation set "SDK" refers specifically to the Microsoft
Windows Software Development Kit and its contents. The SDK includes the
following manuals:
Title Contents
────────────────────────────────────────────────────────────────────────────
Installation and Provides an orientation to the SDK,
Update Guide explains how to install the SDK software,
and highlights the changes for version
3.0.
Guide to Programming Explains how to write Windows
applications, and provides sample
applications that you can use as
templates for writing your own programs.
The Guide to Programming also addresses
some advanced Windows programming
topics.
Tools Explains how to use the
software-development tools you'll need
to build Windows applications, such as
debuggers and specialized SDK editors.
Reference Is a comprehensive guide to all the
details of the Microsoft Windows
application program interface (API). The
Reference lists in alphabetical order
all the current functions, messages, and
data structures of the API, and provides
extensive overviews on how to use the
API.
System Application Architecture, Provides guidelines and recommendations
Common User Access: Advanced for writing programs that appear and act
Interface Design Guide consistently like other Microsoft
Windows applications.
Summary
This introductory chapter explained the organization of Tools, and briefly
described the tools and processes you use to build Windows applications.
For more information about building Windows applications, see Guide to
Programming.
PART I Compilers and Linkers
────────────────────────────────────────────────────────────────────────────
Part 1 describes how to use the C Compiler to compile your C-language source
code modules, the linker to link your compiled or assembled source files
with your Microsoft Windows and C run-time libraries, and the Resource
Compiler to produce an executable Windows application.
Chapter 1 Compiling Applications: The C Compiler
────────────────────────────────────────────────────────────────────────────
Many Microsoft Windows applications are written in the C programming
language and are compiled using the Microsoft C Compiler (CL). This chapter
describes the following topics:
■ A brief overview of how to write C-language Windows applications
■ How to use the Microsoft C Compiler to compile C-language Windows
applications
This chapter deals only with the special compilation requirements of
C-language Windows applications. For complete information on using the C
Compiler, see the Microsoft C documentation. For information on writing
Windows applications using the C language, see the Guide to Programming.
1.1 Compiling C-Language Windows Applications
To compile a C-language Windows application, use the Microsoft C Compiler.
The compiler comes with Microsoft C; it is not included in the Microsoft
Windows Software Development Kit (SDK). Microsoft Windows requires version
5.1 or later of Microsoft C, or version 2.0 or later of Microsoft QuickC
(R). To start the Microsoft C Compiler, use the CL command. Table 1.1, "C
Compiler Options for Windows Applications," lists and describes the options
commonly used for compiling Windows applications.
Table 1.1 C Compiler Options for Windows Applications
╓┌───────┌─────────────────────────────────┌─────────────────────────────────╖
Option What It Does When to Use It
────────────────────────────────────────────────────────────────────────────
-AC Compiles the application for the Used when an application has one
compact memory model. code segment but multiple data
segments.
-AL Compiles the application for the Used when an application has
large memory model. multiple segments for both code
and data.
Table 1.1 C Compiler Options for Windows Applications (continued)
╓┌───────┌─────────────────────────────────┌─────────────────────────────────╖
Option What It Does When to Use It
────────────────────────────────────────────────────────────────────────────
-AM Compiles the application for the Used when an application has
medium memory model. multiple code segments but one
data segment. Can also be used
to create applications using the
mixed memory model. See Guide to
Programming for a description of
the mixed memory model.
-AS Compiles the application for the Used when an application has
small memory model. only one code and one data
segment. Can also be used to
create applications using the
mixed memory model.
-Aw Ensures that pointers receive Used when compiling a
Option What It Does When to Use It
────────────────────────────────────────────────────────────────────────────
-Aw Ensures that pointers receive Used when compiling a
their proper segment addresses dynamic-link library (DLL).
when cast to 32-bit addresses.
-c Compiles only. Required if you have more than
one C source module and you want
to separate linking from
compiling.
-Gs Removes stack probes, thereby Recommended for all Windows
improving performance. applications after the
development process is complete.
-Gw Adds the Windows prolog and Required for all Windows source
epilog to all functions. code modules. (May be used for
source code modules that do not
contain exported (callback)
functions; but -GW is
recommended in this case.)
Option What It Does When to Use It
────────────────────────────────────────────────────────────────────────────
recommended in this case.)
-GW Substitutes a reduced Windows Recommended for Windows source
prolog and epilog to functions code modules that do not contain
that are far calls within the exported or callback functions.
application. (Available only
with C version 6.0 and later.)
-Os Optimizes for code size instead Recommended for all Windows
of speed. source code modules.
-Ow Relaxes alias checking within Recommended instead of
certain constraints imposed by non-Windows -Oa relax-alias-
the Windows environment. checking option.
(Available only with C version
6.0 and later.)
-Zd Creates an object file for use Required for debugging the
with the Symbolic Debugger ( source-code module using SYMDEB
Option What It Does When to Use It
────────────────────────────────────────────────────────────────────────────
with the Symbolic Debugger ( source-code module using SYMDEB
SYMDEB) or the 80386 Debugger ( or WDEB386.
WDEB386).
-Zi Creates an object file for use Required for debugging the
with CodeView for Windows (CVW). source-code module using CVW.
-Zp Packs structures on single-byte Required for all Windows source
boundaries. code modules that use structures.
────────────────────────────────────────────────────────────────────────────
In addition to the options in Table 1.1, "C Compiler Options for Windows
Applications," which most Windows applications use, you can supply other
compiler options as necessary. Section 1.2, "Compiler Options," describes
more fully many of the options you may want to use.
In the following example, the source file TEST.C is compiled using the
recommended CL options for a small-model Windows application source file
during application development.
CL -c -Os -Gw -AS -Zdp TEST.C
With these options, the compiler suppresses linking (-c), optimizes for size
(-Os), adds the Windows prolog and epilog to exported functions (-Gw), uses
the small memory model (-AS), provides line-number information (-Zd), and
packs structures (-Zp).
1.2 Compiler Options
This section describes some compiler options you may want to use when
compiling a Windows application. For a complete description of the C
Compiler options, see the Microsoft C Optimizing Compiler User's Guide.
This section describes the following types of compiler options:
■ Memory-model options, which let you compile medium, compact, and
large-model applications. (By default, the compiler uses the small
memory model.)
■ Options you may want to set during application development.
■ Options for compiling dynamic-link libraries.
1.2.1 Memory-Model Options
Windows applications can use the small, medium, compact, or large memory
model. (Windows does not support the huge memory model.)
You specify a programming model by supplying the appropriate compiler option
on the CL command line when you compile the application source files. You
base your choice on the application's need for data and code. The
memory-model compiler options are:
Memory Model Compiler Option
────────────────────────────────────────────────────────────────────────────
Small -AS
Medium -AM
Compact -AC
Large -AL
The compact and large memory models are not recommended for Windows
applications, unless you're creating a Windows application by porting an
existing compact or large-model application from the DOS environment. This
is because Windows requires that all data segments of compact and
large-model applications be fixed, and Windows can run only one instance of
an application with far data segments. The following statement must be in
the module-definition (.DEF) file of any compact or large-model application:
DATA FIXED
When compiling medium, compact, and large-model source files for Windows
applications, you can specify the names of the code and data segments to
which each source belongs. Use the -NT option to specify code segments; use
the -ND option for data segments. If you do not use these options, the C
Compiler assumes that the source belongs to the standard code and data
segments, _TEXT and _DATA.
For more information on memory models, see Guide to Programming and the
appropriate Microsoft C documentation.
1.2.2 Application Development Options
To make application development and debugging easier, the C Compiler
includes options for the following:
■ Provides line-number information so you can display program lines
■ Lets you turn off optimization to make debugging easier
■ Lets you disable stack probes
Preparing for Debugging
Windows applications written in C are easier to debug if the compiler adds
debugging information to the object file. You can then use the Symbolic
Debugger (SYMDEB) utility or CodeView for Windows (CVW) to help you debug
your application.
To add debugging information used by SYMDEB, compile your application with
the -Zd option. This option produces an object file containing line-number
records corresponding to the line numbers of the source file, as well as
global-symbol information which SYMDEB uses. For more information on SYMDEB,
see Chapter 8, "Debugging in Real Mode: Symbolic Debugger."
To add debugging information used by CVW, use the -Zi option when you
compile. The resulting object file contains full symbolic-debugging
information, including local function-variable information, full
symbol-table information, and line numbers. For more information on CVW, see
Chapter 7, "Debugging in Protected Mode: CodeView for Windows."
Turning Off Optimization
While an application is in development, you may want to turn off optimizing
to make debugging easier. (By default, the C Compiler optimizes for speed.)
To turn off program optimization, use the -Od option.
Using Stack Probes
By default, the compiler provides stack probes. Stack probes can be useful
during application development, but they can cause a slight performance
degradation. When the application-development process is complete, it's a
good idea to turn off the stack probes by using the -Gs option.
1.2.3 Dynamic-Link Library Options
When compiling DLLs, you should specify the following compiler options:
■ The -Gw option, to ensure that exported functions receive the Windows
prolog and epilog. (For modules that do not contain exported
functions, you can use the -GW option instead to reduce the size of
the prolog and epilog.)
■ The -Aw option, to ensure that pointers receive their proper segment
addresses when cast to 32-bit addresses. The -Aw option must follow or
be combined with the -AC, -AL, -AM, or -AS option, as appropriate.
Dynamic-link libraries written in C have slightly different requirements
than do Windows applications written in C. Unlike Windows applications,
dynamic-link libraries are not executable programs; although a library is
loaded, it does not execute directly. Instead, the code in a library is made
available to all applications that need to use it, and an application can
execute a portion of the library by calling one of the exported functions in
the library.
Like exported (callback) functions in Windows applications, exported
functions in libraries must have the Windows prolog and epilog. This means
that, for dynamic-link libraries, the -Gw option is required. Exported
functions should be listed in the library's module-definition file. See
Chapter 2, "Linking Applications: The Linker," for information about
module-definition files.
You should compile dynamic-link libraries with the -Aw option; this ensures
that pointers receive their proper segment addresses when cast to 32-bit
addresses. Libraries always use the stack of the calling application for
parameters and local variables. This means that the values of the DS and SS
registers are not equal when the library is executed. Because the C Compiler
generates code that assumes that the DS and SS registers are equal,
dynamic-link libraries may fail unless compiled with the -Aw option. This
option directs the compiler to generate code that does not assume that the
registers are equal.
The following example shows the recommended options for compiling libraries:
CL -c -AMw -Gsw -Os TESTLIB.C
1.3 Summary
The Microsoft C Compiler compiles C-language Windows applications. For more
information about using the compiler, see the Microsoft C documentation.
Chapter 2 Linking Applications: The Linker
────────────────────────────────────────────────────────────────────────────
You create executable Microsoft Windows applications and libraries by
linking your compiled source files using the linker (LINK). LINK takes your
compiled sources, a list of libraries, and a module-definition file, and
creates a file that you can load and run with Windows.
LINK comes with Microsoft C; it is not included in the Microsoft Windows
Software Development Kit (SDK). Windows requires version 5.1 or later of
Microsoft C, or version 2.0 or later of Microsoft QuickC.
────────────────────────────────────────────────────────────────────────────
IMPORTANT
Microsoft C version 5.1 and Microsoft QuickC versions 2.0 and later include
two linkers. If you are developing your application with one of these
versions, use the segmented-executable linker.
────────────────────────────────────────────────────────────────────────────
Microsoft C version 6.0 includes ILINK, the incremental linker. This linker
does not relink files that have already been linked and that have not
changed. ILINK also directly creates .SYM files for use by the Symbolic
Debugger (SYMDEB). ILINK also uses the .SYM files it creates to avoid
unnecessary relinking. For more information on ILINK, see the Microsoft C
6.0 documentation.
This chapter describes the following topics:
■ Module-definition files
■ The difference between applications' and libraries' module-definition
files
■ How to use LINK to link Windows applications
2.1 Creating Module-Definition Files
Every Windows application and library must have a "module-definition file."
A module-definition file is an ordinary text file that defines the
application's contents and system requirements. When you link a Windows
application, the linker uses the information in the application's
module-definition file to determine how to set up the application (for
example, how large to make the application's default stack, or whether to
mark a particular code segment as moveable in memory).
You create a module-definition file using an ordinary ASCII text editor. The
file can have any filename you want, but must have the filename extension
.DEF.
Every module-definition (.DEF) file contains one or more statements. Each
statement defines a specific attribute of the application or library, such
as its module name, the number and type of program segments, or the number
and names of exported and imported functions.
Windows module-definition files can contain the following statements:
Statement Usage
────────────────────────────────────────────────────────────────────────────
CODE Defines code-segment attributes, such as
whether or not a segment is moveable in
memory.
DATA Defines data-segment attributes, such as
whether there are single or multiple
data segments, and whether a segment is
moveable in memory.
DESCRIPTION Briefly describes the module.
EXETYPE Tells LINK what type of .EXE header to
use (Windows or OS/2).
EXPORTS Lists functions in this module that will
be called by Windows or other
applications. For example, an
application's .DEF file always lists the
application's window functions, since
Windows must call these functions in
order for the application to work
properly.
HEAPSIZE Specifies the default size of the local
heap in bytes. The recommended size is
5K.
IMPORTS Lists other applications' functions that
this module calls. For example, if you
wrote a library of utility functions, an
application would have to import those
functions before it could use them. (You
can also import library functions using
the IMPLIB utility. See Section 2.2,
"Importing Dynamic-Link Libraries," for
more information.)
LIBRARY Specifies the module name of a
dynamic-link
library.
NAME Specifies the module name of an
application.
SEGMENTS Specifies the attributes of additional
code or data segments.
STACKSIZE Determines the default size of the local
stack in bytes. The recommended size is
5K.
Statement Usage
────────────────────────────────────────────────────────────────────────────
STUB Specifies the application's old-style
(DOS
environment) executable file.
For details on the module-definition statements, see the Reference, Volume
2.
Because Windows applications and libraries have different needs, the
statements you include in a .DEF file will differ slightly, depending on
whether you are creating the .DEF file for an application or for a library.
The rest of this section describes the specific module-definition needs of
applications and libraries.
2.1.1 Creating Module Definitions for Applications
A module-definition file for an application must include the following
statements:
■ A NAME statement that defines the application's module name. Windows
uses the module name to identify the application. The module name must
match the application's base filename.
■ An EXPORTS statement that lists functions in the module that Windows
or other applications will call, such as window and callback
functions.
■ An EXETYPE WINDOWS statement, which enables the application to run in
the Windows environment. This statement tells LINK to use a Windows
executable-file header instead of an OS/2 header (the default).
Although these are the only required statements in the .DEF file, most .DEF
files contain additional statements, such as the DATA and CODE statements,
to define other aspects of the application.
The following example shows a typical .DEF file for a Windows application:
; Sample Module Definition File
"NAME Sample
DESCRIPTION 'Sample Window Application'
EXETYPE WINDOWS
DATA MULTIPLE MOVEABLE
CODE MOVEABLE DISCARDABLE
HEAPSIZE 5120
STACKSIZE 5120
EXPORTS
MainWndProc @1 SampleDlgProc @2
This is an example of a module-definition file for an application named
"Sample".
"
The NAME statement defines the application's module name as "Sample".
The required statement EXETYPE WINDOWS ensures that LINK gives the
application a Windows-format header.
The DATA MULTIPLE statement tells LINK that this module has multiple data
segments (one for each instance of the application). For most Windows
applications, the data segment should be defined as MULTIPLE, since most
Windows applications can be invoked more than once.
The CODE MOVEABLE DISCARDABLE and previous DATA MULTIPLE MOVEABLE statements
tell LINK that both the data and code segments are moveable and that the
code segment is discardable. It's a good idea to use moveable and
discardable code segments and moveable data segments, since they allow
Windows to take best advantage of memory.
The heap and stack sizes are the recommended 5120 bytes. Heap space is
required if the application uses its local heap. It's a good idea for
applications to have at least 5120 bytes of stack space.
The EXPORTS statement lists the callback functions in the application: the
main window function, named "MainWndProc", and a dialog function,
"SampleDlgProc".
2.1.2 Creating Module Definitions for Libraries
A module-definition file for a dynamic-link library must contain the
following statements:
■ A LIBRARY statement that defines the library's module name. Windows
uses the module name to identify the library.
■ An EXPORTS statement that lists the functions to be exported by the
library; the functions should be exported by ordinals rather than by
name, since using ordinals conserves space. Functions in the library
are accessible to other applications only if they are listed in the
EXPORTS statement.
■ An EXETYPE WINDOWS statement, which enables the library to run in the
Windows environment. This statement tells LINK to use a Windows
executable-file header instead of an OS/2 header (the default).
In addition to these required statements, .DEF files for libraries can
include other statements.
The following example shows a typical .DEF file for a library:
; Example Module Definition File
"LIBRARY MyUtilities
DESCRIPTION 'My Utility Functions'
EXETYPE WINDOWS
DATA SINGLE MOVEABLE
CODE MOVEABLE DISCARDABLE
HEAPSIZE 4096
EXPORTS
UtilityInit @1
UtilityStart @2
UtilityEnd @3
UtilityLoad @4
UtilitySave @5
This is a sample module-definition file for a Windows dynamic-link library.
"
The LIBRARY statement defines the library's module name as MyUtilities.
The required statement EXETYPE WINDOWS ensures that LINK gives the library a
Windows-format header.
The statement DATA SINGLE MOVEABLE tells LINK that this library module has a
single data segment. Unlike an application, of which several copies can be
running at a time, Windows allows only one instance of a library at a time.
The heap size is 4096 bytes. Because libraries never have stacks, the
library's .DEF file contains no STACK statement; libraries use the stack of
the calling application.
The required statement EXPORTS lists the library's exported functions by
name and ordinal number. An application can then call these functions if the
functions' names or ordinals are listed in the IMPORTS statement of the
application's .DEF file.
2.2 Importing Dynamic-Link Libraries
When you link an application that makes function calls to a dynamic-link
library (DLL), you must identify the imported functions using one of the
following methods:
■ Use the IMPORTS statement in the application's module-definition file.
Section 2.1.2, "Creating Module Definitions for Libraries," describes
this method.
■ Use the IMPLIB utility to create a library of imported functions and
specify the library in the LINK command line, as described in this
section.
You can create import libraries by using the IMPLIB utility. IMPLIB reads
the exports for a library, as listed in its definition file, and creates an
import library. You can link the library into an application.
────────────────────────────────────────────────────────────────────────────
NOTE
IMPLIB does not come on the SDK disks. It is shipped with the Microsoft C
Compiler. If you did not request IMPLIB to be copied when you installed the
C Compiler, you may want to copy it from the C Compiler disks.
────────────────────────────────────────────────────────────────────────────
You start IMPLIB by using the IMPLIB command.
Syntax
IMPLIB imp-lib-name mod-def-file
The imp-lib-name parameter specifies the name you want the new import
library to have.
The mod-def-file parameter specifies the name of the module-definition
(.DEF) file for the dynamic-link library. For IMPLIB version 1.1 and later,
distributed with Microsoft C version 6.0 and later, you can provide IMPLIB
the name of the DLL itself instead of the DLL's module-definition file.
The following command creates the import library named MYLIB.LIB from the
module-definition file MYLIB.DEF:
IMPLIB MYLIB.LIB MYLIB.DEF
To link the library, specify it in the LINK command line, as in the
following example:
LINK SAMPLE, SAMPLE.EXE, , /NOD SLIBCEW LIBW MYLIB, SAMPLE.DEF
The example links the import library MYLIB.LIB.
For more information on specifying libraries, see Section 2.3.3, "Specifying
Libraries on the LINK Command Line."
2.3 Linking an Application
You can link object (.OBJ) files from compiled application source files,
libraries, and module-definition files into an executable file using the
linker. The LINK program comes with Microsoft C version 5.1; it is not
included in the SDK.
LINK combines the code and data of all application files with the
appropriate code for any Windows functions that the application calls, and
creates a new executable file or DLL.
2.3.1 Using the LINK Command
To start the linker, you use the LINK command. You can type this command on
the DOS command line, or you can enter it in a batch file or a make file.
Syntax
LINK «options» object-files,«exe-file»,«map-file», «lib-files»,def-file
The options parameter specifies one or more key words (described in Section
2.3.2, "Specifying LINK Command Options") that tell LINK to carry out
special operations.
The object-files parameter specifies the filenames of one or more compiled
application source files. If your application has more than one compiled
source file, you must name all of them on the LINK command line. Separate
the filenames of object files by spaces or the plus sign (+).
The exe-file parameter specifies the name you want LINK to give to the
resulting executable file or dynamic-link library.
The map-file parameter specifies the name you want the map file to have. (A
map file is used for symbolic debugging with SYMDEB or WDEB386.)
The lib-files parameter specifies the names of Windows or standard-language
libraries.
The def-file parameter specifies the filename of the module-definition
(.DEF) file. Each application can have only one .DEF file.
Use commas to separate parameters in the command line.
The following example command line links the application object file
SAMPLE.OBJ with the standard Windows library LIBW.LIB:
LINK SAMPLE.OBJ/al:16, SAMPLE.EXE, SAMPLE.MAP/map/li, /NOD SLIBCEW.LIB
LIBW.LIB, SAMPLE.DEF
The command line creates the file SAMPLE.EXE, which has the module name,
segments, and exported functions defined by the module-definition file
SAMPLE.DEF. It also creates the map file SAMPLE.MAP, used for symbolic
debugging. The command searches the library file LIBW.LIB to resolve any
external function calls made in the application files. It also searches for
the Windows version of the small model emulated math C run-time library.
The LINK program uses default filename extensions if you do not provide
extensions. For example, the preceding example would have the same results
if typed as follows:
LINK SAMPLE/al:16, SAMPLE, SAMPLE/map/li, /NOD SLIBCEW LIBW, SAMPLE
2.3.2 Specifying LINK Command Options
You can use the LINK options parameter to tell the linker to perform special
operations. The LINK options are:
Option Usage
────────────────────────────────────────────────────────────────────────────
/alignment:size Tells the linker to align segment data
in the executable file along the
boundaries specified by size.
The size parameter specifies a boundary
size in bytes; for example, the
following indicates an alignment
boundary of 16 bytes:
/alignment:16
The size parameter must be a power of 2;
therefore, 2, 4, 8, 16, and so on are
appropriate values. The default is 512
bytes.
It is strongly recommended that you link
your application with the alignment set
to 16 or less (or 32 if the application
is larger than 1 megabyte). The default
512-byte alignment wastes a large amount
of disk space, especially for larger
applications using many segments and
resources.
The minimum abbreviation for this option
is /al.
/codeview Tells the linker to prepare for
debugging using CodeView for Windows (
CVW).
The minimum abbreviation for this option
is /co.
Option Usage
────────────────────────────────────────────────────────────────────────────
/help Tells the linker to display a list of
available options.
The minimum abbreviation for this option
is /h.
/linenumbers Tells the linker to copy line-number
information from the object file to the
map file. Use this option to prepare for
source line debugging with the Symbolic
Debugger (SYMDEB).
The minimum abbreviation for this option
is /li.
/map Tells the linker to create a .MAP file,
which the MAPSYM utility uses to create
a .SYM file. The .SYM file is then used
by the Symbolic Debugger.
/nodefaultlibrarysearch Prevents the linker from using the
default C run-time libraries. This
option is recommended if you use the
?LIBC?W.LIB naming of the C runtime
libraries instead of ?LIBC?.LIB.
The minimum abbreviation for this option
is /nod.
/noextendeddictionarysearch Prevents the linker from searching a
library's extended dictionary, which is
a list of symbols stored in the library.
The linker normally consults this list
to speed up library searches. Normally
this option is not needed. The linker
issues an error message if you need to
use this switch.
The minimum abbreviation for this option
is /noe.
Option Usage
────────────────────────────────────────────────────────────────────────────
/nofarcalltrans This option prevents the translation of
far calls within the current segment.
Without this option, far calls are
translated into the assembler
statements:
.
.
.
NOP
PUSH CS
NEAR CALL
.
.
.
The minimum abbreviation for this option
is /nof.
/noignorecase Tells the linker to preserve lowercase
letters when matching symbols during
linking.
The minimum abbreviation for this option
is /noi.
/pause Tells the linker to pause before copying
the executable file to disk.
The minimum abbreviation for this option
is /pau.
/segments:number Sets the maximum number of segments the
linker will process to number. For
example, the following would tell the
linker to process no more than 200
segments:
/segments:200
The default is 128 segments. Windows
limits an application to 254 segments.
The minimum abbreviation for this option
is /se.
Option Usage
────────────────────────────────────────────────────────────────────────────
/warnfixup Causes the linker to display an error
message when an offset fixup occurs
(relative to a logical segment) outside
the physical segment.
The minimum abbreviation for this option
is /w.
The following LINK options are not allowed when linking Windows
applications:
/dsallocate /exepack /high /overlayinterrupt
The following LINK options are not recommended when linking Windows
applications:
/nogroupassociation /packcode /stack
Instead of using the LINK option /stack, set the stack size in the
application's .DEF file.
For more information on LINK command-line options, see the Microsoft C
Optimizing Compiler User's Guide.
2.3.3 Specifying Libraries on the LINK Command Line
When you link an application's object files, you must specify the
appropriate C-language libraries for Windows and C run-time libraries. The
C-language libraries for Windows contain code for the Windows application
start-up routines and references for the Windows functions.
There are corresponding C-language libraries you will use when linking
dynamic-link libraries. Table 2.1 shows which Windows library to use,
depending on the memory model and whether you are linking an application or
a library.
Table 2.1 Linking with a Windows C-Language Library
╓┌────────────────────────┌───────────────────┌──────────────────────────────╖
Memory Model For an Application For a DLL
────────────────────────────────────────────────────────────────────────────
Emulated Math Package
────────────────────────────────────────────────────────────────────────────
Small SLIBCEW.LIB SDLLCEW.LIB
Medium MLIBCEW.LIB MDLLCEW.LIB
Compact CLIBCEW.LIB CDLLCEW.LIB
Large LLIBCEW.LIB LDLLCEW.LIB
────────────────────────────────────────────────────────────────────────────
Alternate Math Package
────────────────────────────────────────────────────────────────────────────
Small SLIBCAW.LIB SDLLCAW.LIB
Medium MLIBCAW.LIB MDLLCAW.LIB
Compact CLIBCAW.LIB CDLLCAW.LIB
Memory Model For an Application For a DLL
────────────────────────────────────────────────────────────────────────────
Compact CLIBCAW.LIB CDLLCAW.LIB
Large LLIBCAW.LIB LDLLCAW.LIB
────────────────────────────────────────────────────────────────────────────
Which C-language libraries you link with depends on your application's
programming model and whether or not the model uses floating-point support.
In addition to these libraries, you must also link with the
model-independent Windows import library, LIBW.LIB.
Use the /nod option to ensure that the linker will not try to find objects
in your non-Windows versions of the C run-time libraries.
For example, a small-model application using the emulator math package must
be linked with the small-model library SLIBCEW.LIB and LIBW.LIB, as shown in
the following example:
LINK SAMPLE,,/NOD SLIBCEW LIBW, SAMPLE.DEF
────────────────────────────────────────────────────────────────────────────
NOTE
You should link your program with the SLIBCEW.LIB or MLIBCEW.LIB library if
you chose the coprocessor/emulator option by specifying -FPi on the compiler
command line. For your Windows application to use the math
coprocessor/emulator, you must include WIN87EM.LIB on your LINK command
line. This library contains import information for the WIN87EM.DLL library
supplied with the retail version of Windows.
You should link your program with the SLIBCAW.LIB or MLIBCAW.LIB library if
you chose the alternative math option by specifying -FPa on the compiler
command line. Ensure that these libraries are available.
────────────────────────────────────────────────────────────────────────────
2.4 Examining Executable File Headers
You can use the EXEHDR utility to determine whether an executable file is a
Windows application or a library. The command also lets you find out which
functions are exported or imported by a module, determine the amount of
space allocated for a module's heap or stack, and determine the size and
number of the segments a module contains.
Syntax
EXEHDR exe-filename
The exe-filename parameter specifies the name of any file with an .EXE
extension.
The following example displays the header for the executable file HELLO.EXE:
EXEHDR HELLO.EXE
The format of this header is closely related to the statements contained in
the application's module-definition file.
For more information about EXEHDR, see the Microsoft C Optimizing Compiler
documentation.
2.5 Summary
LINK is a tool that takes compiled sources, a list of libraries, and a
moduledefinition file, and creates a file that you can load and run with
Windows. For additional information see the following:
Topic Reference
────────────────────────────────────────────────────────────────────────────
Windows versions of C run-time Guide to Programming: Chapter 14, "C
libraries and
Assembly Language"
Module-definition statements Reference, Volume 2: Chapter 10,
"ModuleDefinition Statements"
Chapter 3 Compiling Resources: The Resource Compiler
────────────────────────────────────────────────────────────────────────────
Microsoft Windows Resource Compiler (RC) is a tool that lets you compile
resources, such as icons, cursors, menus, and dialog boxes, that your
application uses. You add the resulting binary resource file to your
application's binary file to produce an executable Windows application.
This chapter describes how to do the following:
■ Include resources in your application
■ Create a resource script file, which describes the resources your
application will use
■ Use the Resource Compiler to compile your application's resources and
add them to the application's executable file
3.1 Including Resources in an Application
To include resources in your Windows application, follow these steps:
1. Create individual resource files for cursors, icons, bitmaps, dialogs,
and fonts, using the appropriate resource editors.
Part 2 of this manual, "Resource Editors," explains how to use these
editors.
2. Create a resource script (.RC) file that defines each application
resource by specifying its name and description.
If the resource is in a separate file, this description includes the
resource's filename.
For example, the .RC file might define a cursor resource by naming it
"SampleCursor," describing it as a resource of type "Cursor," and
defining it as the cursor contained in the file SAMPLE.CUR.
3. Compile the resource script file using the Resource Compiler.
The result will be a compiled resource file with the filename
extension .RES.
4. Add the compiled resources to the application's compiled executable
(.EXE) file using the Resource Compiler.
If you want, you can perform this step and the preceding step with a
single RC command.
3.2 Creating a Resource Script File
After creating individual resource files for your application's icon,
cursor, bitmap, font, and dialog resources, you create a resource script
file. The resource script file always has the .RC extension, and is often
referred to simply as the .RC file.
The .RC file lists every resource in your application, and describes some
types of resources in great detail:
■ For resources that exist in a separate file, such as icons and
cursors, the .RC file simply names the resource and the file that
contains it.
■ For some types of resources, such as menus, the entire definition of
the resource exists within the .RC file.
You create a resource script file using an ordinary ASCII text editor. The
file can contain resource statements and directives.
Resource statements name and describe each resource.
Directives are a special type of statement that defines an action you want
the Resource Compiler to perform on the resource script file before actually
compiling it. You can use directives to assign values to names, include the
contents of files, and control compilation of the script file. The
directives you use in a resource script file are identical to the C-language
directives.
A line in an .RC file cannot exceed 256 characters.
Table 3.1 lists and briefly describes the statements and directives you can
use in a resource script file. (See the Reference, Volume 2, for detailed
descriptions and syntax.)
Table 3.1 Resource Statements
╓┌───────────────────────┌──────────┌────────────────────────────────────────╖
Type of Statement Statement Description
────────────────────────────────────────────────────────────────────────────
Single-line statements BITMAP Defines a bitmap by naming it and
specifying the file that contains it.
(To use a particular bitmap, the
application requests it by name.)
Table 3.1 Resource Statements (continued)
╓┌─────────────────────────────┌──────────────┌──────────────────────────────╖
Type of Statement Statement Description
────────────────────────────────────────────────────────────────────────────
CURSOR Defines a cursor by naming it
and specifying the file that
contains it. (To use a
particular cursor, the
application requests it by
name.)
FONT Specifies a file that
contains a font.
ICON Defines an icon by naming it
and specifying the file that
contains it. (To use a
particular icon, the
application requests it by
Type of Statement Statement Description
────────────────────────────────────────────────────────────────────────────
application requests it by
name.)
Multiple-line statements ACCELERATORS Defines menu accelerator
keys.
DIALOG Defines a template that an
application can use to create
dialog boxes.
MENU Defines the appearance and
function of an application
menu.
RCDATA Defines raw data resources.
Raw data resources let you
include binary data directly
into the executable file.
Type of Statement Statement Description
────────────────────────────────────────────────────────────────────────────
STRINGTABLE Defines string resources.
String resources are null-
terminated ASCII strings that
can be loaded from the
executable file.
Directives #define Defines a specified name by
assigning it a given value.
#elif Marks an optional clause of a
conditional compilation
block.
#else Marks an optional clause of a
conditional compilation
block.
#endif Marks the end of a
Type of Statement Statement Description
────────────────────────────────────────────────────────────────────────────
#endif Marks the end of a
conditional compilation
block.
#if Carries out conditional
compilation if a specified
expression is true.
#ifdef Carries out conditional
compilation if a specified
name has been defined.
#ifndef Carries out conditional
compilation if a specified
name is not defined.
#include Copies the contents of a file
into the resource script
before the Resource Compiler
Type of Statement Statement Description
────────────────────────────────────────────────────────────────────────────
before the Resource Compiler
processes the script.
#undef Removes the current
definition of the specified
name.
User-defined resources User-supplied Any data that needs to be
added to the executable file.
────────────────────────────────────────────────────────────────────────────
For a detailed description of the statements in a resource script file, see
the Reference, Volume 2.
For example, the following script file defines the resources for an
application called "Shapes":
"#include "SHAPES.H"
ShapesCursor CURSOR SHAPES.CUR
ShapesIcon ICON SHAPES.ICO
ShapesMenu MENU
BEGIN
POPUP "&Shape"
BEGIN
MENUITEM "&Clear", ID_CLEAR
MENUITEM "&Rectangle", ID_RECT
MENUITEM "&Triangle", ID_TRIANGLE
MENUITEM "&Star", ID_STAR
MENUITEM "&Ellipse", ID_ELLIPSE
END
END
"
The file uses the #include directive to include the contents of the header
file SHAPES.H.
The CURSOR statement names the application's cursor resource "ShapesCursor"
and specifies the cursor file SHAPES.CUR, which contains the image for that
cursor.
It does the same for the application's icon resource, "ShapesIcon", using
the ICON statement.
The script file uses the MENU statement to define an application menu named
"ShapesMenu", a pop-up menu with five menu items.
The menu definition, enclosed in the BEGIN and END key words, specifies each
menu item and the menu ID code that is returned when the user selects that
item. For example, the first item on the menu, "Clear", returns the menu ID
code "ID_CLEAR" when the user selects it. The ID values are defined in the
application header file, SHAPES.H.
For more information on the resource script file, the syntax of the resource
statements, and how to create user-defined resources, see the Reference,
Volume 2.
3.3 Using the Resource Compiler
The Resource Compiler serves the following functions:
■ It compiles the resource script file and the resource files (such as
icon and cursor files) into a binary resource (.RES) file.
■ It combines the compiled .RES file with the executable (.EXE) file
created by the linker; the result is an executable Windows
application.
■ It marks all Windows applications (even if they have no resources)
with a Windows version stamp.
────────────────────────────────────────────────────────────────────────────
NOTE
All Windows applications and libraries must bear a Windows version stamp.
For this reason, use RC on every Windows application and library you build,
whether or not it uses any resources.
────────────────────────────────────────────────────────────────────────────
To start the Resource Compiler, use the RC command. What you specify on the
command line will depend on whether you are compiling resources, adding
compiled resources to an executable file, or both.
Syntax
RC «options» resource-file «executable-file»
There are several ways you can use the RC command:
■ To compile resources separately, use the RC command in the following
form:
RC -R «options» script-file
When you use this form, the Resource Compiler ignores the executable
file if you specify one.
■ To compile an .RC file and add the resulting .RES file to the
executable file, use the RC command in the following form:
RC «options» script-file «executable-file»
■ To compile a 3.0 version of a dynamic-link library (DLL) that does not
have a .RES file, use the RC command in the following form:
RC «options» dll-file
When you use this form, the DLL filename must explicitly have an .EXE,
.DRV, or .DLL extension.
■ To simply add a compiled resource (.RES) file to an executable file,
use the RC command in the following form:
RC «options» res-file.RES «executable-file»
The rest of this section explains how to specify each of the RC command's
parameters.
Options Parameter
The RC command's options parameter can include one or more of the following:
Option Description
────────────────────────────────────────────────────────────────────────────
-R Creates an .RES file from an .RC file.
Use this option when you do not want to
add the compiled .RES file to the .EXE
file.
-D Defines a symbol for the preprocessor
that you can test with the #ifdef
directive.
-FO Renames the .RES file.
-FE Renames the .EXE file.
-I Searches the specified directory before
searching the directories specified by
the INCLUDE environment variable.
-V Displays messages that report on the
progress of the compiler.
-X Prevents the Resource Compiler from
checking the INCLUDE environment
variable when searching for include
files or resource files.
-L or -LIM32 Tells Windows that the application uses
expanded memory directly, according to
the Lotus(R) Intel(R) Microsoft Expanded
Memory Specification (EMS), version 3.2.
Option Description
────────────────────────────────────────────────────────────────────────────
-M or -MULTINST When Windows is running with the EMS 4.0
memory configuration, this switch
assigns each instance of the application
task to a distinct EMS bank. (By default,
all instances of a task share the same
EMS bank.)
-E For a dynamic-link library, changes the
default location of global memory from
below the EMS bank line to above the EMS
bank line.
-P Creates a private dynamic-link library
(DLL) that is called by only one
application. This allows Windows to use
memory better, since only one
application (or multiple instances of
the same application) will be calling
into the DLL. For example, in the
large-frame EMS memory model, the DLL is
loaded above the EMS bank line, freeing
memory below the bank line.
-K Disables the load-optimization feature
of the Resource Compiler. If this option
is not specified, the compiler arranges
segments and resources in the executable
file so that all preloaded information
is contiguous. This feature allows
Windows to load the application much
more quickly.
If you do not specify the -K option, all
data segments, nondiscardable code
segments, and the entry-point code
segment will be preloaded, unless any
segment and its relocation information
exceed 64K. If the PRELOAD attribute is
not assigned to these segments in the
module-definition (.DEF) file when you
link your application, the compiler will
add the preload attribute and display a
warning. Resources and segments will
have the same segment alignment. This
alignment should be as small as possible
to prevent the final executable file
from growing unnecessarily large. You
can set the alignment using the LINK
/alignment option. See Chapter 2,
"Linking Applications: The Linker," for
more information.
Option Description
────────────────────────────────────────────────────────────────────────────
-T Creates an application that runs only
with Windows in protected (standard or
386 enhanced) mode. If the user attempts
to run the application in real mode,
Windows will display a message box
telling the user that the application
cannot run in real mode.
-? or -H Displays a list of the RC command line
options.
Options are not case-sensitive; for example, -r and -R are equivalent. You
can combine single-letter options if they do not require any additional
parameters. For example, the command:
RC -R -E -V SAMPLE.RC
is equivalent to the command:
RC -REV SAMPLE.RC
Resource-file Parameter
The RC command's resource-file parameter specifies the name of the script
file that contains the names, types, filenames, and descriptions of the
resources you want to add to the .EXE file. It can also specify the name of
a compiled .RES file, in which case the Resource Compiler adds the compiled
resources to the executable file.
Executable-file Parameter
The RC command's executable-file parameter specifies the name of the
executable file that the resources should be added to. If you do not specify
an executable file, the Resource Compiler uses the executable file with the
same name as the script file.
3.3.1 Compiling Resources Separately
By default, the Resource Compiler adds the compiled resources to the
specified executable file. Sometimes you might want to first compile the
resources and then add them to the executable file in separate steps. This
can be useful because resource files don't tend to change much after initial
development. You can save time by compiling your application's resources
separately, then adding the compiled .RES file to your executable file each
time you recompile the .EXE file.
You can use the -R option to compile the resources separately, without
adding them to the executable file. When you use this option, the Resource
Compiler compiles the .RC file and creates a compiled resource .RES file.
For example, the following command reads the resource script file SAMPLE.RC
and creates the compiled resource file SAMPLE.RES.
RC -R SAMPLE.RC
The command does not add SAMPLE.RES to the executable file.
3.3.2 Defining Names for the Preprocessor
You can specify conditional branching in a resource script file, based on
whether or not a term is defined on the RC command line using the -D option.
For example, suppose your application has a pop-up menu, the Debug menu,
which you want to appear only during debugging. When you compile the
application for normal use, the Debug menu is not included. The resource
script file contains the following statements to define the Debug menu:
MainMenu MENU
BEGIN
.
.
.
#ifdef DEBUG
POPUP "&Debug"
BEGIN
MENUITEM "&Memory usage", ID_MEMORY
MENUITEM "&Walk data heap", ID_WALK_HEAP
END
#endif
END
When compiling resources for a debugging version of the application, you
could include the Debug menu by using the following RC command:
RC -R -D DEBUG MYAPP.RC
To compile resources for a normal version of the application─one that does
not include the Debug menu─you could use the following RC command:
RC -R MYAPP.RC
3.3.3 Renaming the Compiled Resource File
Normally, when compiling resources, the Resource Compiler names the compiled
resource file after the .RC file and places it in the same directory as the
script file. For example, when compiling MYAPP.RC, you would normally type:
RC -R MYAPP.RC
The compiler would then create a compiled resource file named MYAPP.RES in
the same directory as MYAPP.RC.
The -FO option lets you give the resulting .RES file a name that differs
from the corresponding .RC script file. For example, to name the resulting
.RES file NEWFILE.RES, you could type:
RC -R -FO NEWFILE.RES MYAPP.RC
The -FO option can also place the .RES file in a different directory. For
example, typing the following command places the compiled resource file
MYAPP.RES in the directory C:\RESOURCE:
RC -R -FO C:\SOURCE\RESOURCE\MYAPP.RES MYAPP.RC
3.3.4 Controlling the Directories that RC Searches
Normally, the Resource Compiler searches for include files and resource
files (such as icon and cursor files) first in the current directory, and
then in the directories specified by the INCLUDE environment variable. (The
PATH environment variable has no effect on the directories that the Resource
Compiler searches.)
Adding a Directory to Search
You can use the -I option to add a directory to the list of directories that
the Resource Compiler searches. The compiler then searches the directories
in the following order:
1. The current directory.
2. The directory or directories you specify by using the -I option, in
the order in which they appear on the command line.
3. The list of directories specified by the INCLUDE environment variable,
in the order in which the variable lists them, unless you specify the
-X option.
The following example compiles the resource script file MYAPP.RC and adds
the compiled resources to MYAPP.EXE:
RC -I C:\SOURCE\STUFF -I D:\RESOURCES MYAPP.RC MYAPP.EXE
When compiling the script file, the Resource Compiler searches for include
files and resource files first in the current directory, then in
C:\SOURCE\STUFF and D:\RESOURCES, and lastly in the directories specified by
the INCLUDE environment variable.
Suppressing the INCLUDE Environment Variable
You can prevent the Resource Compiler from using the INCLUDE environment
variable when determining the directories to search. To do so, use the -X
option. The compiler then searches for files only in the current directory,
and in any directories you specify using the -I option.
The following example compiles the resource script file MYAPP.RC and adds
the compiled resources to MYAPP.EXE:
RC -X -I C:\SOURCE\STUFF MYAPP.RC MYAPP.EXE
When compiling the script file, the Resource Compiler searches for include
files and resource files first in the current directory and then in
C:\SOURCE\STUFF.
3.3.5 Displaying Progress Messages
Normally, the Resource Compiler does not display messages that report on its
progress as it compiles. You can, however, tell the compiler to display
these messages. To do so, use the -V option.
The following example causes the compiler to report on its progress as it
compiles the script file SAMPLE.RC, creates the compiled resource file
SAMPLE.RES, and adds the .RES file to the executable file SAMPLE.EXE:
RC -V SAMPLE.RC
3.4 Summary
The Resource Compiler is a tool that lets you compile resources such as
icons, dialog boxes, and fonts into a binary file. You add the binary
resource file to the binary source files to produce an executable Windows
application.
For information related to the Resource Compiler, see the following:
Topic Reference
────────────────────────────────────────────────────────────────────────────
Creating icons, cursors, and Tools: Chapter 4, "Designing Images:
bitmaps SDKPaint"
Creating and editing dialog Tools: Chapter 5, "Designing Dialog
boxes Boxes: The Dialog Editor"
Creating fonts Tools: Chapter 6, "Designing Fonts: The
Font Editor"
Introduction to application Guide to Programming: Chapter 7, "Menus"
menus
Introduction to controls, such Guide to Programming: Chapter 8,
as "Controls"
buttons and check boxes
Introduction to dialog boxes; Guide to Programming: Chapter 9, "Dialog
also Boxes"
explains how to use controls in
dialog boxes
Syntax and descriptions of each Reference, Volume 2: Chapter 8,
resource statement and directive "Resource Script Statements"
PART II Resource Editors
────────────────────────────────────────────────────────────────────────────
Part 2 describes how to use the Microsoft Windows resource editors:
SDKPaint, the Dialog Editor, and the Font Editor. SDKPaint lets you create
bitmaps, icons, and cursors for your application. The Dialog Editor lets you
create and test dialog boxes on the screen instead of defining dialog
statements in a resource script. The Font Editor lets you create fonts and
update information in the font file header.
Chapter 4 Designing Images: SDKPaint
────────────────────────────────────────────────────────────────────────────
Microsoft Windows SDKPaint (SDKPAINT) lets you create bitmaps, icons, and
cursors for your applications. Using SDKPaint, you can draw bitmaps, icons,
and cursors and examine their appearance on screens of various colors. The
editor also simulates how images appear on different display devices.
This chapter describes the following:
■ How SDKPaint works with bitmap, icon, and cursor files
■ The SDKPaint window, including its menu items and commands
■ Opening files and images within the files
■ Drawing with SDKPaint tools
■ Using the SDKPaint palette, including working with different color
types
■ Customizing the palette, including editing colors, saving changes to
the palette, and loading customized palettes
■ Defining a cursor hotspot
■ Using the clipboard to transfer images between editors, to move images
from one resource to another, and to create multiple images
4.1 How SDKPaint Works with Files
SDKPaint creates or modifies bitmap (.BMP), icon (.ICO), and cursor (.CUR)
files.
You can include these files in the resource script that you use to compile
the resource (.RES) file. The .RES file is a component of the build that
produces an executable file for your application.
Figure 4.1 illustrates the process of incorporating bitmap, icon, and cursor
files into an executable application. For detailed information on this
process, see Chapter 3, "Compiling Resources: The Resource Compiler."
(This figure may be found in the printed book).
4.1.1 File Types
The bitmap (.BMP) files that SDKPaint produces define device-independent
monochrome or color bitmaps. Each .BMP file defines one bitmap. Bitmaps that
you create and save using SDKPaint can range in size from 1-by-1 to 72-by-72
pixels.
Unlike bitmap files, icon (.ICO) and cursor (.CUR) files define a family of
images. Each image in an icon or cursor file is designed for display on a
different kind of device. SDKPaint distinguishes the different kinds of
images by pixel dimensions and color capabilities. For example, when the
application wants to use an icon, it requests the icon by name. Windows then
selects the appropriate icon image in the specified file according to the
pixel dimensions and color capabilities required by the device driver.
4.1.2 Icon and Cursor Data: The SDKPAINT.DAT File
SDKPaint uses the SDKPAINT.DAT file to store display-device information for
individual icon or cursor images within a file. The SDKPAINT.DAT file you
install initially contains information about common display devices, such as
EGA and VGA.
SDKPAINT.DAT is an ASCII, comma-delimited file that you can edit to add
information about display devices. Each string in the file defines a display
device. A string is terminated by a carriage return (no null character) and
contains the following six fields:
name,num-colors,curs-horz-size,curs-vert-size,icon-horz-size,
icon-vert-size
Field definitions are as follows:
Field Description
────────────────────────────────────────────────────────────────────────────
name Name of the display device. The name can
contain up to 10 uppercase and lowercase
letters.
num-colors Number of colors of the icon or cursor
image.
curs-horz-size Horizontal size of a cursor image in
pixels.
curs-vert-size Vertical size of a cursor image in
pixels.
icon-horz-size Horizontal size of an icon image in
pixels.
icon-vert-size Vertical size of an icon image in
pixels.
In addition to information about icon and cursor images, SDKPAINT.DAT can
include comments. Indicate comments by placing a semicolon (;) at the
beginning of the comment line.
For example, the following SDKPAINT.DAT file specifies information for icons
and cursors displayed on two devices:
";This is a sample SDKPAINT.DAT file
4-Plane,16,32,32,32,32
3-Plane,16,32,32,32,32
"
This line is a comment.
This line defines a device with four color planes. The device displays
16-color cursors and icons. Cursors and icons on this device are 32-by-32
pixels.
This line defines a device with three color planes, which also displays
16-color cursors and icons. Cursors and icons on this device are also
32-by-32 pixels.
SDKPaint displays information from the SDKPAINT.DAT file when you load an
icon or cursor image into SDKPaint. For information about loading images,
see "Loading an Image into the Workspace" in Section 4.3.3.
4.2 The SDKPaint Window
The SDKPaint window varies with the kind of resource you are editing. Figure
4.2 illustrates the SDKPaint window after a user has opened an icon file.
(This figure may be found in the printed book).
Regardless of the type of image you edit, the menu bar contains the
following menus:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Menu Commands
────────────────────────────────────────────────────────────────────────────
File This menu contains the following
commands:
New─Initializes the workspace with a
bitmap, icon, or cursor image.
Open─Opens existing .BMP, .ICO, and .CUR
Menu Commands
────────────────────────────────────────────────────────────────────────────
Open─Opens existing .BMP, .ICO, and .CUR
files for editing.
Save and Save As─Save changes to bitmaps,
icons, and cursors.
Exit─Exits the editor.
Edit This menu contains the following
commands:
Undo─Restores the image to its state
before the last edit.
Copy─Moves an image to the clipboard.
Paste─Moves an image from the clipboard.
Image This menu contains the following
Menu Commands
────────────────────────────────────────────────────────────────────────────
Image This menu contains the following
commands:
New─Initializes the workspace with an
icon or cursor image.
Open─Opens images in a bitmap, icon, or
cursor file.
Save─Retains an icon or cursor currently
in the workspace.
Restore─Restores an image to its state
when initially loaded into the editor or
when last retained.
Clear─Sets to white all the pixels in
the work area.
Menu Commands
────────────────────────────────────────────────────────────────────────────
Delete─Deletes an image from the work
area and clears the image from the
SDKPaint window.
Brushsize This menu lets you choose among three
sizes of brushes to draw an image.
Palette This menu contains the following
commands:
Edit Colors─Changes the currently
selected color to the hue you specify or
restores the color to its default value.
Get Colors─Loads a color palette (.PAL)
file into the
editor.
Menu Commands
────────────────────────────────────────────────────────────────────────────
Save Colors─Saves newly-created colors
in a .PAL file.
Hotspot This menu contains commands that let you
define or display the hotspot of a
cursor. For information about the
hotspot, see Section 4.7, "Defining the
Cursor Hotspot."
4.3 Opening Files and Images
Before editing an existing bitmap, icon, or cursor, you must first open a
file to prepare the workspace for the kind of image you are going to edit.
4.3.1 Converting Files to 3.0 Format
When you open a version 2.0 or later bitmap, icon, or cursor file, SDKPaint
automatically converts it to 3.0 format as it is loaded into the editor.
4.3.2 Opening Bitmaps
To open an existing bitmap file, choose the Open command from the File menu.
SDKPaint opens the file and loads its image into the workspace of the
SDKPaint window.
────────────────────────────────────────────────────────────────────────────
NOTE
SDKPaint opens and loads only 2-color and 16-color bitmaps.
────────────────────────────────────────────────────────────────────────────
If you are creating a new bitmap instead of editing one that exists, do the
following:
1. Choose the New command from the File menu.
The editor displays the Resource Type dialog box.
2. Choose the Bitmap option.
SDKPaint displays a dialog box that lets you enter the height and
width of the bitmap image you are creating and placing in the file.
The dialog box also prompts you for the number of bitmap colors.
3. Specify either 2 or 16 colors.
By default, the first time you open a bitmap file, SDKPaint uses
values appropriate to the display on which it is running. If you
subsequently open additional bitmap files, SDKPaint specifies by
default the values of the most recently created bitmap.
SDKPaint prepares the workspace of the SDKPaint window for the bitmap image
that you will create.
4.3.3 Opening Icons and Cursors
Because icon and cursor files contain multiple images, you must first open a
file and then load a specified image into the workspace.
Specifying an Icon or Cursor File
To open an existing icon or cursor file, choose the Open command from the
File menu. SDKPaint offers you a choice of files to open.
If you want to create icons or cursors that you will save in a new file,
choose the New command from the File menu.
When SDKPaint displays the Resource Type dialog box, do the following:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Image Type Procedure
────────────────────────────────────────────────────────────────────────────
Image Type Procedure
────────────────────────────────────────────────────────────────────────────
Icon To specify a new icon file:
1. Choose the Icon option.
SDKPaint displays an Icon Sizes dialog
box. By default, SDKPaint displays icon
image information appropriate for the
display on which SDKPaint is running.
2. Choose the device type from the
combo box.
If you want to create an icon image for
a different type of device, open the
drop-down combo box and choose the kind
of device you want to target.
Cursor To specify a new cursor file, do the
following:
Image Type Procedure
────────────────────────────────────────────────────────────────────────────
following:
1. Choose the Cursor option.
SDKPaint displays a Cursor Sizes dialog
box. By default, SDKPaint displays
cursor image information appropriate for
the display on which SDKPaint is running.
2. Choose the device type from the
combo box.
If you want to create a cursor for a
different type of device, open the
drop-down combo box and choose the kind
of device you want to target.
Loading an Image into the Workspace
After opening a file, you can either load an existing image into the
workspace of the SDKPaint window or specify that you will create a new
image.
To load an icon or cursor image with a specified pixel dimension into the
workspace, choose the Open command from the Image menu. SDKPaint first
prompts you for the image you want and then displays the image you select.
To load a new icon or cursor image with a specified pixel dimension into the
workspace, choose the New command from the Image menu. The editor displays a
dialog box that prompts you first for the characteristics of the image you
want to create and then asks for information about the pixel dimensions of
the image.
4.4 Drawing with SDKPaint Tools
Whether editing an existing image or creating a new image from scratch, use
the tools displayed at the bottom of the SDKPaint window to draw your
bitmap, icon, or cursor.
Table 4.1 illustrates and describes SDKPaint tools.
Table 4.1 SDKPaint Tools
╓┌───────────────┌─────────────────────────────┌─────────────────────────────╖
Tool Illustration Description
────────────────────────────────────────────────────────────────────────────
Oil Can (Please refer to the printed Fills a bordered area with
book) the current drawing color.
Paintbrush (Please refer to the printed Paints the image using the
book) current
drawing width and color.
Rectangle (Please refer to the printed Draws a hollow rectangle
book) using the
current drawing color.
Tool Illustration Description
────────────────────────────────────────────────────────────────────────────
Full Rectangle (Please refer to the printed Draws a rectangle and fills
book) it with the current drawing
color.
Circle (Please refer to the printed Draws a hollow circle or
book) ellipse using the current
drawing color.
Full Circle (Please refer to the printed Draws a circle or ellipse
book) and fills it with the
current drawing color.
Line (Please refer to the printed Draws a straight line
book) between selected star and
end points using the current
drawing color.
Pick Rectangle (Please refer to the printed Selects a rectangular region
Tool Illustration Description
────────────────────────────────────────────────────────────────────────────
Pick Rectangle (Please refer to the printed Selects a rectangular region
book) in the image. Choose the
Copy command from the Edit
menu to transfer the
selected portion of the
image to the clipboard.
Choose the Paste command
from the Edit menu to
transfer the contents of the
clipboard to the selected
region. The selected region
reverts to the entire
workspace following a copy
or paste operation.
────────────────────────────────────────────────────────────────────────────
4.5 Using the SDKPaint Palette
The SDKPaint palette defines available and currently selected colors for
drawing and display. SDKPaint displays two types of colors in the palette:
true colors and dithered colors. When you are creating a bitmap or icon, the
16 colors that SDKPaint displays in the leftmost eight columns of the
palette are true colors. The remaining colors are dithered. When you are
creating a cursor, all colors of the palette are true colors.
The 16 true colors are red, green, and blue (RGB) values guaranteed to be
distinct on a device that displays 16 or more colors.
If you are working with icons or cursors, you can get information about the
RGB values of a color on the palette by first selecting the color and then
choosing the Edit Colors command from the Palette menu. If you are editing a
bitmap image, you can also get the information by double-clicking the color.
The editor lists RGB values of the selected color in the Edit Colors dialog
box.
The palette differs with the type of resource you are editing. Figure 4.3
illustrates the palette that SDKPaint displays when you are editing a
bitmap.
(This figure may be found in the printed book).
The palette displays 16 true and 12 dithered colors that you can use to
define screen background.
Figure 4.4 illustrates the palette that SDKPaint displays when you are
editing an icon.
(This figure may be found in the printed book).
The palette displays 16 true and 12 dithered colors.
Figure 4.5 illustrates the palette that SDKPaint displays when you are
editing a cursor.
(This figure may be found in the printed book).
The palette indicates that you can use only black and white opaque colors to
define a cursor. The palette also displays 16 true colors that you can use
for screen and inverse color.
The following section describes how to use the colors that the palette
displays.
4.5.1 Working with Opaque, Screen, and Inverse Colors
Images comprise one or more of the following types of colors:
Color Description
────────────────────────────────────────────────────────────────────────────
Color (opaque) Colors that retain their hue regardless
of the color of the screen.
Screen The color that defines the screen
background.
Inverse The color that is the inverse of the
screen color. SDKPaint always displays
the inverse color of the currently
specified screen color.
To select an opaque, screen, or inverse color from the palette, do the
following:
1. Select the type of color you want to draw within the color type
window.
2. Click the color displayed in the palette.
SDKPaint displays the selected color in the color type window.
When using the opaque color type, you can associate a color with the left
mouse button by clicking that color with the left mouse button. The color
you select appears in the box labeled "Left."
To associate an opaque color with the right mouse button, click the color
with the right mouse button. The selected color appears in the box labeled
"Right."
The following sections describe how to use opaque, screen, and inverse
colors.
Using Opaque Colors
The following describes the opaque color options for each image:
Image Color Options
────────────────────────────────────────────────────────────────────────────
Bitmap Bitmaps are either monochrome or color.
Icon Icons can use the full spectrum of the
palette.
Cursor Cursors are monochrome.
Using Screen Colors
Screen colors let you see how your icon or cursor looks against various
screens. SDKPaint displays screen colors in the viewing area of the SDKPaint
window. In addition to the selection method described above, you can change
screen colors as follows:
■ Select a color from the palette and then click in the viewing area.
This method changes the screen color, regardless of the color type you
have selected. If you are currently drawing with the opaque color
type, using this procedure changes the color of the screen to the
color you select from the palette.
■ Select the inverse color type and then click a color in the palette.
SDKPaint displays the inverse color you have selected and
automatically displays the corresponding screen color.
Using Inverse Colors
When the opaque colors of an icon or cursor are identical to the color of
the screen on which they are displayed, the icon or cursor is not visible.
Inverse colors are useful for defining the image when this condition occurs.
For example, if you outline an icon in an inverse color, the border of the
icon is visible when the screen and opaque colors are identical.
In addition to the selection method described in the preceding section, you
can change the inverse color by choosing a new screen color. When you change
the screen color, SDKPaint automatically displays the compatible inverse
color.
4.6 Customizing the Palette
SDKPaint lets you customize the palette by editing colors. After editing one
or more colors, you can save them in a special palette that you load into
the editor.
This section describes how to do the following:
■ Edit colors for bitmaps and color icons
■ Save a palette that you have customized
■ Load a customized palette into the editor
4.6.1 Editing Colors
SDKPaint lets you edit the palette used to draw bitmaps and color icons. To
edit a color from the palette that is currently loaded in SDKPaint, do the
following:
1. Select the color you want to edit.
2. Choose the Edit Colors command from the Palette menu.
If you are editing a bitmap, you can also double-click the color on
the palette. In either case, SDKPaint displays the Edit Colors dialog
box.
3. Change the RGB values of the color.
The editor displays the changes to the color in the dialog box.
4. Choose OK if you are satisfied with the new color.
If you want to cancel your edits on the color, choose Cancel.
4.6.2 Saving a Palette
After you customize a palette by editing selected colors on it, you can save
the palette for future use by choosing the Save Colors command from the
Palette menu. SDKPaint prompts you for the filename of the palette you are
saving.
SDKPaint assigns the extension .PAL to custom palettes by default.
4.6.3 Loading a Customized Palette
Choose the Get Colors command from the Palette menu to load a customized
palette into SDKPaint. SDKPaint prompts you for the name and location of the
palette you want to use.
After you load the palette into SDKPaint, you can return to the default
palette by doing the following:
1. Choose the Edit Colors command from the Palette menu.
2. Select Default in the Edit Colors dialog box.
4.7 Defining the Cursor Hotspot
To define the hotspot of a cursor do the following:
1. Choose the Set Hotspot command from the Hotspot menu.
SDKPaint changes the cursor to a bullseye and displays a window that
gives the coordinates of the cursor as you move it around the work
area.
2. Click the left mouse button to define the hotspot.
Clicking the mouse button when the cursor is outside the work area
disables the Set Hotspot command.
To show the current hotspot, choose the Show Hotspot command from the
Hotspot menu. The editor displays the coordinates of the current hotspot in
a window. To delete the window, choose Show Hotspot again.
4.8 Using the Clipboard
SDKPaint lets you transfer images to and from the clipboard using the Copy
and Paste commands from the Edit menu. Transferring images is useful to do
the following:
■ Load an image created using Paintbrush or another paint program.
■ Move an image from one resource type to another, such as when using a
cursor image to create an icon.
■ Create multiple device-specific versions of one image.
The editor uses two data formats when transferring images to and from the
clipboard. To transfer opaque colors, SDKPaint uses the CF_BITMAP format. To
transfer inverse colors, the editor uses a private format. Many drawing
applications, such as Paintbrush, recognize the CF_BITMAP format.
The image you transfer from the clipboard may be smaller or larger than the
selected rectangular region of the image. By default, the selected region is
the entire workspace; you can select a smaller region using the Pick
Rectangle tool.
When the clipboard image is not the same size as the selected region,
SDKPaint displays a dialog box that gives you the following options:
■ Stretch/shrink Clipboard bitmap?
■ Clip Clipboard bitmap?
If you select the Stretch/shrink option, SDKPaint stretches or compresses
the image as necessary. For details about this process, see the description
of the StretchBlt function in the Reference, Volume 1.
If you select the Clip option, SDKPaint pastes the clipboard bitmap to the
screen, justified on the top left corners of the workspace and viewing area.
SDKPaint modifies rows and columns of the image as follows:
Size of Clipboard Bitmap Rows and Columns Modified
────────────────────────────────────────────────────────────────────────────
Smaller than selected region Rows at the bottom and columns at the
far right of the selected region
remain unchanged.
Larger than selected region SDKPaint clips rows at the bottom and
columns at the far right of the
clipboard bitmap.
4.9 Using ZoomIn to Examine Images
The Microsoft Windows ZoomIn utility (ZOOMIN) allows you to examine screen
images in detail. ZoomIn captures images from the screen and expands or
contracts the size of the pixels of that image. For example, you could use
ZoomIn to capture the image of a character displayed with the system font,
expand that image to show the pixel pattern of the character, and then
duplicate the character in the image you are creating with SDKPaint.
When you run ZoomIn, the utility displays a small overlapped window with a
vertical scroll bar. To capture an image, press the left mouse button while
the cursor is inside the client area of the ZoomIn window. A rectangle
appears that shows the size of the area on the screen which ZoomIn will
display. Drag the rectangle to the image on the screen you want to capture,
and then release the mouse button.
To vary the detail of the image, use the vertical scroll bar of the ZoomIn
window. Scrolling up decreases the detail, and scrolling down increases the
detail. To change the size of the image captured by ZoomIn, resize the
ZoomIn window.
4.10 Summary
SDKPaint is a tool that lets you design bitmaps, icons, and cursors.
For more information on subjects related to creating images, see the
following:
Subject Reference
────────────────────────────────────────────────────────────────────────────
Resource files Tools: Chapter 3, "Compiling Resources:
The Resource Compiler"
Icons Guide to Programming: Chapter 5, "Icons"
Cursors Guide to Programming: Chapter 6, "The
Cursor, the Mouse, and the Keyboard"
Bitmaps Guide to Programming: Chapter 11,
"Bitmaps"
Clipboard files Reference, Volume 2: Chapter 9, "File
Formats"
Chapter 5 Designing Dialog Boxes: The Dialog Editor
────────────────────────────────────────────────────────────────────────────
Microsoft Windows Dialog Editor (DIALOG) is a tool that lets you design and
test a dialog box on the display screen instead of defining dialog
statements in a resource script. Using the Dialog Editor, you can add,
modify, and delete controls in a dialog box. The Dialog Editor saves the
changes you make as resource script statements. You then compile these
statements into a binary resource file that is linked to your application's
executable file.
This chapter describes the following topics:
■ How the Dialog Editor works with files
■ Installing custom controls
■ Viewing the Dialog Editor window
■ Opening resource files, include files, and dialog boxes
■ Editing individual controls
■ Working with groups of controls
■ Working with dialog boxes
■ Moving a dialog box between resources
■ Working with include files
────────────────────────────────────────────────────────────────────────────
NOTE
You must use a mouse or similar pointing device with the Dialog Editor.
────────────────────────────────────────────────────────────────────────────
5.1 How the Dialog Editor Works with Files
The Dialog Editor creates or modifies the following types of files:
File Type Description
────────────────────────────────────────────────────────────────────────────
Dialog script (.DLG) Text file containing DIALOG and CONTROL
statements that the Resource Compiler
interprets
Resource file (.RES) Binary file containing multiple dialog
resources, and other resources such as
bitmaps, icons, menus, and string tables
File Type Description
────────────────────────────────────────────────────────────────────────────
Include file (.H) Text file containing #define constants
that are associated with symbol names
for the various controls located in a
dialog box
Figure 5.1 illustrates how the Dialog Editor manages these files.
(This figure may be found in the printed book).
5.1.1 The Dialog Script
The most important output of the Dialog Editor is the dialog script (.DLG)
file. You can define more than one dialog box in a .DLG file. The following
exemplifies a .DLG script that Dialog Editor produces:
FirstBox DIALOG LOADONCALL MOVEABLE DISCARDABLE 12, 20, 130, 113
STYLE WS_DLGFRAME | WS_POPUP
BEGIN
CONTROL "Option 1", 102, "button", BS_RADIOBUTTON |
WS_TABSTOP | WS_CHILD, 33, 19, 28, 12
CONTROL "Option 2", 103, "button", BS_RADIOBUTTON |
WS_TABSTOP | WS_CHILD, 33, 36, 28, 12
CONTROL "Option 3", 104, "button", BS_RADIOBUTTON |
WS_TABSTOP | WS_CHILD, 33, 53, 28, 12
CONTROL "Ok", 1, "button", BS_PUSHBUTTON |
WS_TABSTOP | WS_CHILD, 29, 86, 24, 14
CONTROL "Cancel", 2, "button", BS_PUSHBUTTON |
WS_TABSTOP | WS_CHILD, 70, 86, 24, 14
END
SecondBox DIALOG LOADONCALL MOVEABLE DISCARDABLE 30, 40, 135, 125
STYLE WS_DLGFRAME | WS_POPUP
BEGIN
.
.
.
You include the dialog script within your application's resource script
(.RC) file by using an #include statement that refers to the .DLG file. If
you name the dialog script MYDLGS.DLG, your .RC file might look similar to
the following example:
#include "mydlgs.h"
.
.
.
MainMenu MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&New", MI_FILE_NEW
.
.
.
END
END
#include "mydlgs.dlg"
.
.
.
Using the #include directive, include the .DLG script into the application's
overall .RC script. Then compile the .RC text file to produce an .RES binary
file using the -r switch. Finally, link the .RES file into your
application's .EXE file.
See Section 5.1.3, "The Include File," for more information on how to
include the .H header and the .DLG files.
5.1.2 The Resource File
The Dialog Editor produces an .RES file that is a companion to the .DLG
file. This .RES file is a compiled, binary representation of the dialog
script.
The purpose of the .RES file produced by the Dialog Editor is solely to
reedit the dialog script. The Dialog Editor does not read in .DLG files; it
reads only in .RES files. Note that this .RES file should not be linked to
your application's .EXE file because it does not include the other
resources─such as bitmaps, icons, menus, and string tables─required by your
application.
There are two methods for reediting a dialog resource. The first method is
to read back into the Dialog Editor the .RES file that the editor produced
as a companion to the .DLG file.
The second method is to read into the Dialog Editor the .RES file that the
Resource Compiler produced from the combined .RC and .DLG scripts.
Which method you choose is a matter of personal preference. The advantage of
the first method is that you can group together categories of dialog boxes
into separate .DLG files and their corresponding .RES files, and manage them
separately. Also, it is not necessary for you to use the Resource Compiler
to convert the .DLG text file into the binary .RES format required as input
to the Dialog Editor. The advantage of the second method is that you can
discard .RES files produced by the Dialog Editor and free up disk space.
5.1.3 The Include File
The include (.H) file produced by the Dialog Editor contains #define
statements that identify controls in dialog boxes.
When creating a dialog box, you can assign symbolic names to controls. You
use the symbolic names in your application's C source code to refer to the
controls. As a result of these assignments, the Dialog Editor produces a
header file containing #define statements such as the following:
#define DI_OPTION1 102
#define DI_OPTION2 103
#define DI_OPTION3 104
By including the header file in your C source code with an #include
statement, you can refer to the controls by symbolic names, rather than
numeric values, as the following illustrates:
BOOL FAR PASCAL FirstDlgProc(hDlg, wMessage, wParam, lParam)
.
.
.
switch (wMessage)
{
case DI_OPTION1:
/* Respond to Ok button here */
break; case DI_OPTION2:
/* Respond to Cancel button here */
break;
.
.
.
You must include the header file in your application's resource script file
before including the dialog script. This is necessary because the dialog
script refers to the controls using the symbolic names instead of the
numeric values. For an example of including files, see Section 5.1.1, "The
Dialog Script."
When assigning ID values to controls, you can assign any number you want;
however, there are some special guidelines for ID values 1 and 2.
ID Value of 1
When the user presses ENTER, Windows automatically sends a WM_COMMAND
message to the dialog-input function. If the dialog box has a default button
(for example, the OK button), pressing ENTER sends a WM_COMMAND message with
the ID value. If you have a default OK button, you should assign it an ID
value of 1 so that it is activated when the user presses ENTER. This is
consistent with the recommended guidelines for creating a Windows
application set forth in Guide to Programming.
Windows defines the ID value of 1 as IDOK.
ID Value of 2
When the user presses CANCEL or ESCAPE, Windows automatically sends a
WM_COMMAND message with the ID value of 2. If you have a Cancel button in a
dialog box, it should have an ID value of 2.
Windows defines the ID value of 2 as IDCANCEL.
5.2 Installing and Removing Custom Controls
The Dialog Editor provides a menu and toolbox of standard controls─such as
edit fields and list boxes─that you can select when designing a dialog box.
In addition, you can incorporate nonstandard custom controls into a dialog
box.
You can develop or acquire any number of custom controls and maintain them
in a catalog recognized by the Dialog Editor. A custom control consists of a
dynamic-link library (DLL) that contains the window procedure for the
control. The DLL also contains functions that interact with the Dialog
Editor. For more information on developing custom controls, see Guide to
Programming.
The Dialog Editor maintains the catalog of custom controls in your WIN.INI
file under the heading [User Controls]. Each entry equates the name of a
custom control with the full pathname of the control's DLL file, as shown in
the following example:
[user controls]
rainbow = c:\myctrls\rainbow.dll
The Dialog Editor lets you add and remove custom controls from this catalog.
5.2.1 Installing a Custom Control
To install a custom control in the catalog, do the following:
1. Choose the Add Custom Control command from the File menu.
2. Specify the full pathname of the DLL file that defines your custom
control.
If you want to call up a custom control only during a Dialog Editor session,
without permanently adding it to your custom control catalog, then select
the Create Temporary Control radio button in the Add Control dialog box.
For information on working with custom controls, see Section 5.5, "Editing
Dialog Box Controls."
5.2.2 Removing a Custom Control
To remove a custom control from the catalog, choose the Remove Control
command from the File menu. The editor displays a Remove Control Library
dialog box that lists custom controls you can remove.
5.3 Viewing a Dialog Box: The Dialog Editor Window
Figure 5.2 illustrates the Dialog Editor window after a user has loaded a
dialog box and has chosen the Toolbox and Status commands from the Options
menu.
(This figure may be found in the printed book).
The menu bar contains the following menus:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Menu Commands
────────────────────────────────────────────────────────────────────────────
File This menu contains the following
commands:
New─Creates .DLG and companion .RES
files
Menu Commands
────────────────────────────────────────────────────────────────────────────
files
Open─Opens existing .RES files for
editing
Save and Save As─Save changes to a
dialog boxes
Add Custom Control and Remove Custom
Control─Adds and removes members of your
custom control catalog
Exit─Exits the editor
Include This menu contains the following
commands:
New─Creates a new include file
Menu Commands
────────────────────────────────────────────────────────────────────────────
Open─Opens an existing include file
Save and Save As─Save changes to include
files
View/Edit─Displays and edits include
files
Hex Values─Toggles the display of
hexadecimal and
decimal values in include files
Dialog This menu contains the following
commands:
New─Creates a new dialog box
View─Lists current dialog boxes in the
Menu Commands
────────────────────────────────────────────────────────────────────────────
View─Lists current dialog boxes in the
resource file
Flags─Sets memory flags
Groups─Sets tab stops and group markers
Rename─Renames the current dialog box
Test─Toggles work and test modes to
allow you to test your dialog box
Edit This menu contains the following
commands:
Restore─Reverts to last saved version of
a dialog box
Cut─Moves a dialog box to the clipboard
Menu Commands
────────────────────────────────────────────────────────────────────────────
Cut─Moves a dialog box to the clipboard
Copy─Copies a dialog box to the
clipboard
Paste─Copies a dialog box from the
clipboard
Erase Dialog─Removes a dialog box
Styles─Changes the style of a control or
dialog box
Group Mode─Allows you to move a group of
controls as a unit
Duplicate Mode─Allows you to duplicate
controls by dragging them
Menu Commands
────────────────────────────────────────────────────────────────────────────
Control This menu contains different types of
controls that you can select for the
dialog box.
Options This menu contains the following
commands:
Status─Displays and hides the Selected
Item Status window
Toolbox─Displays and hides the Toolbox
window
Grid─Allows you to specify grid
increments for aligning controls
5.3.1 The Mode Display
Beneath the menu bar, the Dialog Editor displays the mode you are currently
using. The modes are as follows:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Mode Meaning
────────────────────────────────────────────────────────────────────────────
Work Indicates you are creating or modifying
a dialog box
Test Indicates you are testing a box
Work/Group Indicates that you are in the process of
selecting and moving a group of controls
Work/Copy Indicates that you are in the process of
duplicating
controls
Mode Meaning
────────────────────────────────────────────────────────────────────────────
5.3.2 The Toolbox
The Toolbox is a convenient alternative to choosing controls from the
Control menu. Initially, the Dialog Editor does not display the Toolbox. If
you choose the Toolbox command in the Options menu, the editor displays the
toolbox in the upper-right corner of the window.
You can move the Toolbox by dragging its title bar.
5.3.3 The Selected Item Status Window
When you choose the Status command from the Options menu, the Dialog Editor
displays the Selected Item Status window in the lower-right corner of the
Dialog Editor window. You can move the Selected Item Status window or close
it by choosing the Status command from the Options menu a second time. The
window supplies the following information about the currently displayed
dialog box and its controls:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Field Description
────────────────────────────────────────────────────────────────────────────
Dialog The name of the dialog box being edited.
(x, y) Position of the upper-left corner of the
selected dialog box or control.
(cx, cy) Offset of the selected dialog box or
control.
Control Type of control selected (for example,
Radio Button or Check Box). If the
dialog box itself is selected, the
editor displays "Dialog Box" in this
field.
Field Description
────────────────────────────────────────────────────────────────────────────
ID Value Identifier of the selected control. The
identifier is displayed
as either a number or a symbol. If the
dialog box is selected instead of a
control, no ID value is shown.
Size and position values are given in horizontal and vertical dialog units.
The horizontal units are 1/4 of the dialog base width unit; the vertical
units are 1/8 of the dialog base height unit. The current dialog base units
are computed from the height and width of the current system font. The
GetDialogBaseUnits function returns the dialog base units in pixels.
When you change the dialog box or controls, the window reflects the change.
5.4 Opening Files and Dialog Boxes
After invoking DIALOG, you can open the following:
■ An existing or new resource file
■ An existing or new include file
■ An existing or new dialog box
Whenever you open a new resource or include file, the editor offers you the
opportunity of saving your previous work.
5.4.1 Opening a Resource File
Using the File menu, you can either create a new resource file or open an
existing resource file.
If opening an existing resource file, you can specify an .RES file that
either the Dialog Editor or the Resource Compiler created.
5.4.2 Opening an Include File
After you load a resource file, Dialog Editor prompts you for an include
file. The include file associates symbolic names with control identifiers.
If you are already working with an include file, you can choose to continue
working with it or open a new one.
If you loaded an existing resource file, the Dialog Editor displays the Open
File window. To edit an include file, choose one of the files listed.
5.4.3 Opening a Dialog Box
If you are loading an existing resource file, the Dialog Editor offers you
the choice of opening an existing dialog box. The editor displays a list of
dialog boxes available for editing in the View Dialog window. If you want to
create a new dialog box in the existing resource file, choose the Cancel
button from the View Dialog window.
Opening an Existing Dialog Box
To open an existing dialog box, choose it from the list that the View Dialog
window displays. The dialog box appears in the working area of the Dialog
Editor window.
Creating a New Dialog Box
To create a new dialog box, choose the New command from the Dialog menu. The
Dialog Editor prompts you for a dialog box name.
5.5 Editing Dialog Box Controls
The Dialog Editor lets you add, modify, and delete dialog box controls,
which are described in Table 5.1.
Table 5.1 Dialog Box Controls
╓┌──────────────────────┌─────────────────────────┌──────────────────────────╖
Control Illustration Description
────────────────────────────────────────────────────────────────────────────
Push button (Please refer to the Push buttons let the user
printed book) choose an immediate
action, such as canceling
the dialog box.
Radio button (Please refer to the Radio buttons are
printed book) typically used in groups
to give the user a choice
of selections. The user
can select only one radio
button in a group at a
time.
Check box (Please refer to the Check boxes are
printed book) independent of one
Control Illustration Description
────────────────────────────────────────────────────────────────────────────
printed book) independent of one
another, although two or
more often appear next to
each other to give the
user a choice of
selections. The user can
turn any number of check
boxes on or off at a
given moment.
Horizontal scroll bar (Please refer to the Scroll bars let the user
printed book) scroll data. They are
usually associated with
another control or window
that
contains text or graphics.
Vertical scroll bar (Please refer to the
Control Illustration Description
────────────────────────────────────────────────────────────────────────────
Vertical scroll bar (Please refer to the
printed book)
Edit (Please refer to the Edit controls display
printed book) both numbers and text,
and let the user type in
numbers and text.
Static text (Please refer to the Static text controls
printed book) label other
controls, such as edit
controls.
Group box (Please refer to the Group boxes enclose a
printed book) collection or group of
other controls, such as a
group of radio buttons.
Control Illustration Description
────────────────────────────────────────────────────────────────────────────
List box (Please refer to the List boxes display a list
printed book) of strings, such as file
or directory names.
Combo box (Please refer to the Combo boxes combine list
printed book) boxes with edit controls.
Frame (Please refer to the A hollow rectangle you
printed book) can use to frame a
control or group of
controls.
Table 5.1 Dialog Box Controls (continued)
╓┌──────────┌───────────────────────────────┌────────────────────────────────╖
Control Illustration Description
────────────────────────────────────────────────────────────────────────────
Icon (Please refer to the printed A rectangular space in which
book) you can place an icon. Do not
size the icon space; icons
automatically size themselves.
Rectangle (Please refer to the printed A filled rectangle you can use
book) for graphical emphasis.
Custom A control you design and define
in a DLL file. See Section 5.2,
"Installing and Removing Custom
Controls."
────────────────────────────────────────────────────────────────────────────
5.5.1 Adding Controls
The Dialog Editor lets you choose the controls you want to add to a dialog
box from either the Control menu or the Toolbox. The Toolbox displays an
icon for each control.
Enabling the Toolbox
To enable the Toolbox, choose the Toolbox command from the Options menu. The
Dialog Editor displays the Toolbox in the upper-right section of the Dialog
Editor window. You can move the Toolbox by dragging its title bar.
Adding Standard Controls
To add standard controls to a dialog box, do the following:
1. Choose the control you want to add from either the Control menu or the
Toolbox.
Choosing either a control command in the Control menu or a control
icon in the Toolbox changes the cursor to a plus sign (+).
2. Position the cursor where you want to add the control.
3. Click the mouse button.
If the control includes text, add the text using the method described in
Section 5.5.2, "Working with Individual Controls."
Adding Custom Controls
After you have installed a custom control using the procedure described in
Section 5.2.1, "Installing a Custom Control," the control is accessible in
the Control menu and the Toolbox. To add the custom control to a dialog box,
choose either the Custom Control command from the Control menu or the Custom
Control icon from the Toolbox. The Dialog Editor displays the Select Custom
Control dialog box illustrated in Figure 5.3.
(This figure may be found in the printed book).
The window lets you select and view a specified custom control. To complete
the selection, choose the OK button.
You can specify the styles for custom controls as you would standard
controls. For information about editing controls, see the next section.
5.5.2 Working with Individual Controls
The Dialog Editor lets you make changes to individual controls, as follows:
■ Moving a control
■ Resizing a control
■ Changing control identifiers and styles
■ Adding or changing text associated with a control
■ Duplicating a control
■ Deleting a control
Moving a Control
The Dialog Editor lets you move individual controls. Use the mouse to drag a
control to its new position and the DIRECTION keys to make fine adjustments
to the control position.
The DIRECTION keys let you move a control horizontally and vertically by
dialog units. (For a description of dialog units, see Section 5.3.3, "The
Selected Item Status Window.") By default, controls move one dialog unit
each time you press a DIRECTION key. To change the distance moved, choose
the Grid command from the Options menu. The Grid command lets you specify
the number of dialog units moved along the x and y axes. If you choose new
grid coordinates after you have placed a control, the control will align
with the new grid coordinates when you move it.
For information about moving groups of controls, see Section 5.6, "Working
with Groups of Controls."
Resizing a Control
To change the size of a control, do the following:
1. Select the control.
2. Drag one of the eight small rectangles that appear on the boundaries.
Dragging one of the corner rectangles changes the width and height of the
control simultaneously.
The Grid command in the Options menu also affects how a control is resized.
When you resize the control, it will automatically size to the nearest grid
coordinate. However, if you select new grid coordinates and then resize the
control, the size of the control will change in increments of the grid
coordinates, but relative to the control's current position. The control
itself will not move when you resize it, even though it may no longer be
aligned with the grid. To ensure that a control aligns with new grid
coordinates, you must move the control.
Changing Control Identifiers and Styles
To change the identifier or style of a control, do the following:
1. Double-click the control, or select the control and choose the Styles
command from the Edit menu.
The Dialog Editor displays a window that lists the identifier, text,
and style of the control selected. Figure 5.4 illustrates the Button
Control Style dialog box.
(This figure may be found in the printed book).
2. To change the identifier, type the new identifier in the ID Value box.
If you supply a symbolic name instead of a numeric value, the Dialog
Editor checks to determine whether or not you have already defined the
name in the current include file. If you have not, the editor offers
you the option of adding the name.
3. To change the style of a control, select the styles you want in the
Styles box.
Adding or Changing Text
In addition to changing identifiers and styles, the Style window lets you
add or modify text associated with a control.
To add or modify text, type the text in the Text box.
────────────────────────────────────────────────────────────────────────────
NOTE
When you add an icon control to a dialog box, the names of the control and
the identifier in the .RC file should be the same. For example, if the .RC
file defines an icon as "myicon", name the control "myicon" also.
────────────────────────────────────────────────────────────────────────────
Duplicating A Control
You can copy a control from an existing control in your dialog box by using
either of the following methods:
■ Drag the original control while holding down the CONTROL key. The Mode
Display beneath the menu bar indicates "Work/Copy" during this
operation. A copy of the original control follows the cursor until you
release the drag.
■ Choose the Duplicate Controls command from the Edit menu. While
Duplicate Controls is selected, the Mode Display beneath the menu bar
indicates "Work/Copy." In this mode, the effect of dragging a control
is to duplicate it, rather than move it. To cancel this mode, toggle
it by choosing the Duplicate Controls command again.
Deleting A Control
To delete a control, select it and press the DELETE key or choose the Clear
Control command from the Edit menu. The Dialog Editor deletes the selected
control from the dialog box.
5.6 Working with Groups of Controls
The Dialog Editor lets you do the following with groups of controls:
■ Move controls as a group
■ Define the input focus sequence of a group
5.6.1 Moving Groups of Controls
To move a group of controls, do the following:
1. Choose the Group Move command from the Edit menu.
The work mode will indicate "Work/Group."
2. Click each control in the group you want to move.
The editor outlines each control you select, and the group itself,
with a gray line.
3. Click the mouse button while pointing to a location in the group
rectangle not occupied by one of the controls.
4. While holding down the mouse button, drag the group of controls to a
new position.
5. Cancel the "Work/Group" mode by toggling the Group Move command in the
Edit menu.
You must select all the controls you want to move, even if one control
encloses another. For instance, to move several radio buttons and the group
box that encloses them, you must select each radio button and the group box,
and then move them as a unit.
5.6.2 Defining Input Focus Sequence
The Groups command in the Dialog menu lets you specify the input focus
sequence in a group of controls, as follows:
■ Specify the controls forming a group. A group defines a sequence of
controls within which the user can shift input focus by using the
DIRECTION keys.
■ Specify tab stops that define how input shifts from group to group as
the user presses the TAB key.
■ Specify the sequential order in which individual and groups of
controls receive input focus as the user presses DIRECTION and TAB
keys.
When you choose the Groups command, the Dialog Editor displays the Order
Groups window illustrated in Figure 5.5.
(This figure may be found in the printed book).
Defining a Group
To specify a group of controls, place a group marker before the first
control in the group and another after the last control, as follows:
1. Select the first control in the group.
2. Click the Group Marker button.
The Dialog Editor inserts a group marker above the control.
3. Select the control below the last control in the group.
4. Click the Group Marker button.
The Dialog Editor inserts a group marker below the last control in the
group. This marker defines the beginning of the next group.
Placing a group marker before a control instructs the Dialog Editor to
assign the WS_GROUP style to the control.
To delete a group marker, select the group marker and click the Delete Group
button.
Setting and Deleting Tab Stops
Tab stops determine where input focus shifts when the user presses the TAB
key. Set or delete tab stops on individual controls, or on the first control
in a group, as follows:
1. Select the control on which you want to set or remove a tab stop.
2. Click the Tab Stop or Delete Tab button to set or delete a tab,
respectively.
An asterisk appears next to each control on which a tab stop is set.
Placing a tab stop on a control instructs the Dialog Editor to assign the
WS_TABSTOP style to the control.
Changing the Input Focus Sequence of Controls
By default, controls receive input focus in the order in which you place
them in the dialog box, not their position in the dialog box. Repositioning
controls does not affect the order in which they receive input focus.
To change the order in which controls receive user input, reorder the
controls listed in the Order Groups window as follows:
1. Select the control you want to move.
2. Move the cursor to the position where you want the control to appear
in the list box.
The cursor changes from an arrow to a short, horizontal bar. The bar
appears only in places where you can insert the control.
3. Click the mouse button to insert the control.
5.7 Working with a Dialog Box
In addition to adding, changing, and deleting controls in a dialog box, you
can do the following to the box as a whole:
■ Change its size and name
■ Define its styles
■ Set flags that indicate how Windows stores the box in memory
■ Erase the box
5.7.1 Resizing a Dialog Box
To change the size of a dialog box, select it and drag one of its resize
handles.
For information about resizing a control, see Section 5.5.2, "Working with
Individual Controls."
The Grid command in the Options menu affects how a dialog box is resized.
When you resize the dialog box, it will automatically size to the nearest
grid coordinate. However, the presence of the grid does not affect how a
dialog box is moved.
5.7.2 Renaming a Dialog Box
To rename a dialog box, do the following:
1. Choose the Rename command from the Dialog menu.
2. Enter the new name in the Name Dialog window.
5.7.3 Defining Styles
To define the styles of a dialog box, do the following:
1. Select the dialog box.
2. Choose the Styles command from the Edit menu.
3. Select the relevant styles from the Dialog Box Styles window.
5.7.4 Setting Memory Flags
To set memory flags for the currently displayed dialog box, do the
following:
1. Choose the Flags command from the Dialog menu.
2. Select the relevant memory flags from the Memory Flags window.
Memory flags are as follows:
■ Moveable─Dialog resource data segment can be moved in memory if
necessary to compact memory.
■ Preload─Dialog resource data segment is loaded immediately.
■ Discard─Dialog resource data segment can be discarded if no longer
needed.
By default, dialog boxes are moveable, loaded on call rather than preloaded,
and discardable.
For more information about memory flags, see Guide to Programming and the
Reference, Volume 2.
5.7.5 Canceling Edits
To cancel edits on a dialog box, use either the Restore or the Clear command
from the Edit menu. The Restore command cancels edits and reloads the
currently displayed dialog box. The Clear command removes the currently
displayed dialog box from the work area and the resource.
5.8 Moving a Dialog Box Between Resources
To move a dialog box from one resource file to another, use the Cut, Copy,
and Paste commands from the Edit menu, as follows:
1. Cut or copy the currently displayed dialog box to the clipboard.
The Cut command removes the dialog box from the work area and copies
the resource to the clipboard; the Copy command copies the box to the
clipboard.
2. Load a new resource file into the Dialog Editor.
3. Paste the dialog box from the clipboard to the work area.
The Dialog Editor supports the clipboard bitmap format (CF_BITMAP) so that
other clipboard viewers can paste dialog box images. The editor also uses a
private clipboard format, "Dialog," for its own use. The Dialog Editor can
paste from the clipboard only if an instance of the Dialog Editor has
previously copied data to the clipboard in the private "Dialog" format.
5.9 Working with Include Files
Dialog Editor lets you create and modify include files that define symbolic
names for controls.
This section describes the following:
■ How to create new include files when editing a dialog box
■ How to load existing include files into the Dialog Editor
■ How to edit include files
■ How to save include files
Table 5.2 describes the commands used for editing include files.
Table 5.2 Commands for Editing Include Files
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Command Description
────────────────────────────────────────────────────────────────────────────
New Creates a new include file.
Open Opens an existing include file.
Command Description
────────────────────────────────────────────────────────────────────────────
Open Opens an existing include file.
Save Saves a specified include file.
Save As Renames an include file and saves it.
View/Edit Displays the View/Edit Include File
window. This window enables the user to
edit symbolic definitions for controls.
Hex Values Toggles the display of identifier values
between decimal and hexidecimal.
────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────────────────────────────────
NOTE
The Dialog Editor works with include files that have only #define
directives. The Dialog Editor will not work with header files that contain
other directives, such as typedef, or comments preceded by a semicolon ( ;
). When the Dialog Editor saves the include file, it strips out any blank
lines that may have existed previously in the include file.
────────────────────────────────────────────────────────────────────────────
5.9.1 Creating New Include Files
The Dialog Editor lets you create new include files to define symbol names
for controls in your dialog boxes. You can create new include files either
when you create a new resource file or when you are editing a dialog box.
Typically, you create a new include file when creating a new resource file.
After creating a new resource file using the method described in Section
5.4.1, "Opening a Resource File," the Dialog Editor asks whether or not you
want to create a new include file.
When creating a new include file, you can give it a name identical to the
resource filename. Giving the resource and include files identical names
causes the Dialog Editor to open the include file automatically each time
you load the corresponding resource file into the editor. If you give the
resource file and include file different filenames, the Dialog Editor
prompts you for the include file you want to open.
If you want to create a new include file while you are editing a dialog box,
choose the New command from the Include menu.
5.9.2 Loading Existing Include Files
Just as you can create a new include file either when loading a resource
file at the beginning of an editing session or later when editing a dialog
box, you can load existing include files either at the beginning or during
your editing session.
Typically, you load an existing include file into the editor at the
beginning of an editing session. When you open a resource file at the
beginning of a session, the Dialog Editor automatically loads the
corresponding include file, if the file has the same name as the resource
file you open. If the include filename is different than the resource
filename, the editor asks you to select the include file you want to open.
If you want to open an existing include file while you are editing a dialog
box, choose the Open command from the Include menu. The Dialog Editor
displays an Open File window that lists include files you can load.
5.9.3 Editing Include Files
You can edit an include file in the following ways:
■ Select individual controls and define their symbolic names.
■ Open the file and edit its symbolic names and identifiers.
The second method lets you define symbolic names for controls as you work
with them.
Defining Names by Individual Control
Instead of opening an include file and editing it as a whole, you can define
symbolic names for individual controls as you work with them. The Dialog
Editor saves the names in the include file that you loaded into the editor.
To define the symbolic name of an individual control as you are working with
it, do the following:
1. Double-click the control.
The Dialog Editor displays a Style window.
2. Enter the symbolic name of the control in the ID Value field.
If you have not defined the symbolic name before, the Dialog Editor
displays the following warning message: "That symbol does not exist."
3. Click the OK button in the Warning Message window.
The Dialog Editor displays the View/Edit Include File window with the
symbolic name you have defined for the control.
4. Click the Add button to complete adding the symbolic name to the
include file.
Editing the File
To edit an include file, do the following:
1. Choose the View/Edit command from the Include menu. The editor
displays the View/Edit Include File window.
2. Select the symbol you want to edit.
3. Make the change in the Symbol Name or ID Value text box.
4. Choose the Change button.
5. Select the symbol and choose the Delete command.
5.9.4 Saving Include Files
When saving an include file, give the file a name identical to the name of
its corresponding resource file, if possible. If the resource file and
include file have the same name, the Dialog Editor loads the include file
automatically when you open its corresponding resource file.
5.10 Summary
This chapter described the Dialog Editor, a tool that lets you design a
dialog box on the display screen instead of defining dialog statements in a
resource script file. For further information, see the following:
Topic Reference
────────────────────────────────────────────────────────────────────────────
Resource file Tools: Chapter 3, "Compiling Resources:
management The Resource Compiler"
Introduction to dialog boxes Guide to Programming: Chapter 8,
"Controls," and Chapter 9, "Dialog
Boxes"
Memory flags Guide to Programming: Chapter 15,
"Memory
Management" and Reference, Volume 2:
Chapter 8, "Resource Script Statements"
Control and dialog box styles Reference, Volume 2: Chapter 8,
"Resource Script Statements"
System Application Architecture, Common
User Access: Advanced Interface Design
Guide
Chapter 6 Designing Fonts: The Font Editor
────────────────────────────────────────────────────────────────────────────
Microsoft Windows Font Editor (FONTEDIT) lets you modify existing fonts to
create new fonts for your applications. Using the Font Editor, you can
modify each character in a font, or the height, width, and character mapping
of a font itself. In addition, you can use the editor to update information
in the font file header.
This chapter describes the following:
■ Editing letters, numbers, and other characters in the font
■ Modifying the height, width, and character mapping of the font
■ Changing information in the font file header
You can use the Font Editor only to create and edit raster fonts.
After creating a new font with the Font Editor, you must add the new font to
a font resource file.
For information on creating vector fonts and adding fonts to the font
resource file, see the Reference, Volume 2.
────────────────────────────────────────────────────────────────────────────
NOTE
You must use a mouse or similar pointing device with the Font Editor.
────────────────────────────────────────────────────────────────────────────
6.1 Opening a Font
To create a new font, you must open and edit an existing font. You cannot
create a new font from scratch. The font file you open must be in Windows
2.0 or 3.0 format.
If you do not have an existing 2.0 or 3.0 font to edit, the SDK disks
provide two "seed" fonts that are installed in your Windows development
tools directory (named \WINDEV by default). The ATRM1111.FNT is a
fixed-pitch font, while the VGASYS.FNT is a variable-pitch font.
After opening a font, the Font Editor displays the font, a specified
character, and information about the character. Figure 6.1 illustrates the
Font Editor window.
(This figure may be found in the printed book).
The Font Editor window has the following features:
Feature Description
────────────────────────────────────────────────────────────────────────────
Character window Contains a copy of the character you
want to edit. A grid divides the window
into rectangles. Each rectangle
represents a pixel.
Character-viewing window Displays two instances of the character
in its normal size. The
character-viewing window lets you
examine the effect of the changes you
make to the character. It also lets you
see external character leading, the
amount of vertical separation between
lines.
Character information Displays the character ANSI value and
the character width and height in pixels.
Font window Displays normal-size copies of the
characters in the font. This window is
moveable.
The following sections describe how to edit characters displayed in the Font
Editor window.
6.2 Editing Characters
The Font Editor lets you change characters. This section describes how to
change characters in the following ways:
■ By turning on and off individual pixels
■ By adding and deleting columns or rows of pixels
■ By modifying specified blocks of pixels
■ By changing the width of a specified character, if the character
belongs to a variable-pitch font
NOTE When you select a new character for editing, the Font Editor
updates the current workspace with the character you have edited. If
you do not want to save your edits, make sure you cancel changes,
using the Refresh command in the Edit menu, before you make the new
selection. See Section 6.2.6, "Canceling Changes to a Character," for
more information on the Refresh command.
6.2.1 Turning Pixels On or Off
The Font Editor lets you change characters pixel by pixel. To turn a
character pixel on or off, point to the pixel and click the left mouse
button. To turn several pixels on or off, drag the cursor over the pixels
you want to change.
6.2.2 Changing Rows and Columns of Pixels
The Font Editor lets you copy or delete rows and columns of pixels. The Row
and Column menus each contain Add and Delete commands.
Adding a Row or Column
The Font Editor adds rows and columns to a character by copying the row or
column you select. To add a row or column, do the following:
1. Choose the Add command from the appropriate menu.
2. Select the row or column you want to delete by clicking on it.
The Font Editor duplicates the row or column selected.
When adding a new row, the Font Editor inserts it between the selected row
and the row immediately below it. The Font Editor pushes all rows below the
new row down one, and deletes the row at the bottom of the Character window.
Figure 6.2 illustrates selecting a row for addition to the character. Figure
6.3 illustrates the character after the Font Editor has duplicated the row.
(This figure may be found in the printed book).
(This figure may be found in the printed book).
When adding a new column, the Font Editor inserts it between the selected
column and the one to its right. The Font Editor inserts the new column and
pushes all columns to its right one column to the right, and deletes the
column at the far right of the Character window. Figure 6.4 illustrates
selecting a column for addition to the character. Figure 6.5 illustrates the
character after the Font Editor has duplicated the column.
(This figure may be found in the printed book).
(This figure may be found in the printed book).
Deleting a Row or Column
To delete a row or column of pixels, do the following:
1. Choose the Delete command from the appropriate menu.
2. Select the row or column you want to delete by clicking on it.
Deleting a row causes all rows below it to move up one, and causes the last
row in the Character window to be duplicated.
When you delete a whole column, all columns to the right of the deleted
column move left one, and the column at the far right of the Character
window is duplicated.
6.2.3 Modifying Blocks of Pixels
The Fill menu provides commands that let you select and change specified
blocks of pixels. The commands on the Fill menu are useful if you want to
modify a large number of pixels in the same way. For example, you can select
a block of pixels and fill all of them in one operation.
The Fill menu contains the following commands:
Command Description
────────────────────────────────────────────────────────────────────────────
Clear Changes a specified block of pixels to
background pixels.
Solid Fills a specified block with foreground
pixels.
Hatched Creates alternate foreground and
background pixels in a specified block.
Inverted Changes foreground pixels to background
pixels, and vice versa, in a specified
block.
Left=Right Rotates a specified block horizontally
180 degrees.
Top=Bottom Rotates a specified block vertically 180
degrees.
Copy Copies pixels in a specified block to
the clipboard.
Paste Fills a specified block with pixels from
the clipboard.
If you are pasting pixels from the clipboard, be sure the area of the
Character window in which you want to paste is the same size as the block on
the clipboard. If you try to paste your data from the clipboard into an area
that is larger or smaller than the block, the Font Editor tries to stretch
or squeeze the block to fit.
The procedure for carrying out commands in the Fill menu is as follows:
1. Choose the relevant command from the menu.
2. Select the block of pixels you want to change.
The editor executes the relevant operation on all pixels within the
specified block.
6.2.4 Changing Character Width
Use the Width menu to change the width of a character belonging to a
variable-pitch font. Commands in the Width menu change the number of columns
in the character bitmap in the following ways:
Command Description
────────────────────────────────────────────────────────────────────────────
Wider (left) Adds a blank column to the left side of
the character.
Wider (right) Adds a blank column to the right side of
the character.
Wider (both) Adds a blank column to each side of the
character.
Narrower (left) Deletes a column from the left side of
the character.
Narrower (right) Deletes a column from the right side of
the character.
Narrower (both) Deletes a column from each side of the
character.
────────────────────────────────────────────────────────────────────────────
NOTE
The width of a character can be changed only on variable-pitch fonts.
Characters in a variable-pitch font cannot be wider than the maximum
character width. If you try to make a character cell wider than the maximum
character width, a dialog box appears, warning you that the maximum
character width will increase.
────────────────────────────────────────────────────────────────────────────
6.2.5 Storing Changes to a Character
You can store changes to a character by selecting it in the Font-viewing
window.
The Font Editor stores your selection by copying it back to the font buffer.
The Font-viewing window is updated to show the new character.
You can also store changes to a character by making a new selection. The
Font Editor copies the old selection into the font buffer before copying the
new selection to the Character window. This is useful if you want to
continue editing characters in the same font.
6.2.6 Canceling Changes to a Character
To recover from an editing mistake, use either the Undo command or the
Refresh command from the Edit menu.
The Undo command restores the character window to its state before the last
change in the window.
The Undo command cannot cancel changes made to a character that you have
stored in the buffer.
To cancel all changes you have made to a character, use the Refresh command
from the Edit menu. The Refresh command replaces the current character in
the character window with a copy from the Font window.
────────────────────────────────────────────────────────────────────────────
NOTE
You cannot cancel changes to a character by selecting a new character.
Selecting a new character, or reselecting the current character, causes the
Font Editor to store all changes to the character in the font buffer. Only
the Refresh command cancels changes.
────────────────────────────────────────────────────────────────────────────
6.3 Editing a Font
To change the height, width, and character-mapping ANSI value of a font, use
the Size command in the Font menu. The command displays a dialog box that
contains the following options:
Option Description
────────────────────────────────────────────────────────────────────────────
Character Pixel Height Defines the height (in pixels) of the
characters in the font.
Maximum Width (variable-width Defines the width (in pixels) of the
fonts only) widest possible character in a
variable-pitch font.
Character Pixel Width Defines the width (in pixels) of all
(fixed-pitch fonts only) characters in a fixed-pitch font. In
fixed-pitch fonts all characters have
equal width.
First Character Defines the character value (for example,
the ANSI value) of the first character
in the font. The first character is the
character to the far left when you
scroll the contents of the font-viewing
window to the far right.
Option Description
────────────────────────────────────────────────────────────────────────────
Last Character Defines the character value (for example,
the ANSI value) of the last character in
the font. The last character is the
character to the far right when you
scroll the contents of the font-viewing
window to the far left.
Pitch
Defines the font as either Fixed or
Variable. Fixed and Variable are
mutually exclusive.
You can change a font from fixed-pitch
to variable-pitch by selecting Variable
in the Size dialog box. You cannot
change a variable-pitch font to
fixed-pitch.
Weight Lists options that define the font
weight, ranging from thin to heavy. Each
option represents the specific degree of
heaviness (i.e., thickness of stroke) of
the font. The options are mutually
exclusive.
6.4 Changing Font File Header Information
To change the information in the font file header, use the Header command in
the Font menu. The Header command displays a dialog box that contains the
following information about the font:
Item Description
────────────────────────────────────────────────────────────────────────────
Face Name The name used to distinguish the font
from other fonts. It is not necessarily
the same as the font filename. The face
name can be as many as 32 characters.
File Name The name of the font file being edited.
Copyright Either a copyright notice or additional
information about the font. It can be as
many as 60 characters in length.
Nominal Point Size The point size of the characters in the
font. One point is equal to
approximately 1/72 of an inch.
Item Description
────────────────────────────────────────────────────────────────────────────
Height of Ascent The distance (in pixels) from the top of
an ascender to the baseline.
Nominal Vert. The vertical resolution at which the
Resolution characters were digitized.
Nominal Horiz. The horizontal resolution at which the
Resolution characters were digitized.
External Leading The pixel height of the external leading.
External leading is the vertical
distance (in rows) from the bottom of
one character cell to the top of the
character cell below it. The
Character-viewing window shows two
copies of the character, one above the
other, so that you can see the effect of
the leading.
Internal Leading The pixel height of the internal leading.
Internal leading is the vertical
distance (in rows) within a character
cell above the top of the tallest
letter; only marks such as accents,
umlauts, and tildes for capital letters
should appear within the space
designated as internal leading.
Default Character The character value (for example, the
ANSI value) of the default character.
The default character is used whenever
your application tries to use a
character that does not exist in the
font.
Break Character The character value of the break
character. The break character is used
to pad lines that have been justified.
The break character is typically the
space character. (For example, in the
ANSI character set, the value is 32.)
ANSI, OEM, or These options define the character set.
SYMBOL The ANSI character set (value zero) is
the default Windows character set. The
OEM character set (value 255) is
machine-specific. The Symbol character
set (value 2) contains special
characters typically used to represent
mathematical and scientific formulas.
The number to the right of these options
defines the character set. It can be any
value from 0 to 255, but only 0, 2, and
255 have a predefined meaning.
Item Description
────────────────────────────────────────────────────────────────────────────
Font Family The family to which the font belongs.
Font families define the general
characteristics of the font as follows:
Family Description
Name
────────────────────────────────────────────────────────────────────────────
Roman Proportionally-spaced fonts
with serifs.
Modern Fixed-pitch fonts.
Swiss Proportionally-spaced fonts
without serifs.
Decorative Novelty fonts.
Script Cursive or script fonts.
Dontcare Custom font.
Italic This option defines an
italic font.
Underline This option defines an
underlined font.
Strikeout This option defines a font
whose characters have been
struck out.
6.5 Summary
The Font Editor lets you modify existing fonts on the screen to create new
fonts for your application. For an introduction to Windows fonts, see
Chapter 18, "Fonts," in Guide to Programming.
PART III Debugging and Optimization Tools
────────────────────────────────────────────────────────────────────────────
Part 3 describes Microsoft Windows debugging and optimization tools. The
SDK includes three debuggers: Code View for Windows, Symbolic Debugger, and
Windows 80386 Debugger. Use Code View for Windows to debug your application
with protected-mode (standard or 386 enhanced) Windows, and the Symbolic
Debugger to debug your application with real-mode Windows. Use the 80386
Debugger for more advanced debugging in protected mode.
The SDK also includes tools that let you monitor messages and analyze memory
management. Spy lets you monitor messages sent to a specified window or to
all windows. It is useful for verifying that the messages you think a window
is receiving are, in fact, being received. Heap Walker, Profiler, Swap, and
Shaker help you analyze memory management. Heap Walker is useful for
analyzing your application when it allocates objects in the global heap.
Profiler lets you determine the amount of time Windows spends executing
sections of code. Swap ets you analyze the calls, swaps, discards, and
returns that occur when your application runs. It is useful for minimizing
the number of procedure calls that occur across segment boundaries. Shaker
lets you see the effect of memory movement on your applications.
Chapter 7 Debugging in Protected Mode: CodeView for Windows
────────────────────────────────────────────────────────────────────────────
Version 3.0 of the Microsoft CodeView(R) for Windows (CVW) debugger is a
powerful, easy-to-use tool for analyzing the behavior of programs. With CVW,
you have the power to test completely the execution of your program and
examine your data simultaneously. You can isolate problems quickly because
you can display any combination of variables─global or local─while you halt
or trace a program's execution.
The CVW debugger provides a variety of ways to analyze a program. You can
use the debugger to examine source code, disassemble machine code, or
examine a mixed display that shows you precisely what machine instructions
correspond to each of your C-language statements. You can also monitor the
occurrence of specific Windows messages.
CVW is similar to CodeView (CV) for DOS version 3.0. If you are familiar
with CV for DOS, see Section 7.2.2, "Differences between CVW and CodeView
for DOS," for a concise description of CVW's unique features.
This chapter serves as a complement to the CVW on-line Help system. A
significant portion of the CVW documentation is on-line. For information on
using the CVW on-line Help system, see Section 7.7, "Getting On-line Help in
CVW."
This chapter describes the following:
■ Requirements for using CVW
■ Differences between CVW other Microsoft debuggers
■ Preparing to run CVW
■ Starting CVW
■ Working with the CVW screen
■ Displaying program data
■ Controlling program execution
■ Advanced CVW debugging techniques
■ Customizing CVW behavior with the TOOLS.INI file
■ Using CVW to debug a sample application
NOTE CVW supports the Microsoft Mouse, or any fully compatible
pointing device. All operations are first described using the mouse.
The keyboard command follows.
7.1 Requirements for Use
To use version 3.0 of CVW, your system must meet the standard requirements
for running the Microsoft Windows Software Development Kit (SDK). For a list
of the SDK requirements, see the Installation and Update Guide. CVW
specifically requires the following:
■ A secondary monochrome display adapter and monitor. (CVW version 3.0
does not support a serial terminal.) For IBM PS/2 systems, CVW
supports (through the /8 option) a dual-monitor configuration, where
an 8514/a monitor serves as the Windows screen and a VGA monitor
serves as the debugging screen.
■ At least 384K of extended memory. For applications compiled with many
symbols, 1 megabyte or more of extended memory is required.
■ For 80386-based systems, the following entry in the [386enh] section
of your SYSTEM.INI file:
device=windebug.386
The SDK INSTALL program automatically adds this entry to your
SYSTEM.INI file.
■ A PATH environment variable that lists the directory containing
CVW.EXE, WINDEBUG.DLL, WINDEBUG.386, and CVW.HLP. The SDK INSTALL
program will place WINDEBUG.DLL and WINDEBUG.386 in the same directory
as CVW.EXE.
7.2 Comparing CVW with Other Microsoft Debuggers
If you have programmed in the Windows environment, you may have used the
Symbolic Debugger (SYMDEB) or CVW version 2.0 to debug Windows applications.
Or you may have used CodeView (CV) for DOS, which accompanies the Microsoft
C Optimizing Compiler. This section describes the features and functions of
CVW that are different from these other Microsoft debugging tools.
7.2.1 Differences between CVW and SYMDEB
CVW has all the capabilities of SYMDEB and a number of features that SYMDEB
does not provide. The following list summarizes differences between SYMDEB
and CVW.
SYMDEB Feature CVW Feature
────────────────────────────────────────────────────────────────────────────
Debugs applications in real Debugs applications in protected mode.
mode.
Examines only global (static) Examines both global and local
variables. variables.
When examining variables, you Examines memory directly, but also uses
must specify simple memory the C expression evaluators to combine
addresses or symbol names. any program variables with higher
level-language syntax.
Provides only breakpoints to Provides breakpoints, tracepoints, and
halt execution. watchpoints to set Boolean conditions
and then break execution whenever these
conditions become true.
Does not set breakpoints or Sets breakpoints and tracepoints on
tracepoints on Windows messages. Windows messages.
Uses only line-oriented Uses line-oriented or menu-driven
commands. commands.
────────────────────────────────────────────────────────────────────────────
NOTE
CVW version 3.0 supports Windows in protected mode (that is, standard and
386 enhanced modes) only; it does not support Windows in real mode. Use
SYMDEB for real-mode debugging.
────────────────────────────────────────────────────────────────────────────
7.2.2 Differences between CVW and CodeView for DOS
Like CV for DOS, CVW allows you to display and modify any program variable,
section of addressable memory, or processor register. Also like CV for DOS,
CVW lets you monitor the path of execution and precisely control where
execution pauses. However, CV for DOS and CVW differ in the following ways:
CV for DOS Feature CVW Feature
────────────────────────────────────────────────────────────────────────────
Starts from the DOS prompt. Starts from within Windows.
ALT+/ repeats a search. CTRL+R repeats a search.
Exits back to DOS. Under normal termination conditions,
exits back to Windows. Abnormal
terminations of CVW may cause the
Windows session to be terminated also.
In addition to these differences CVW includes the following unique features:
■ The ability to track your application's segments and data as Windows
moves their locations in memory. As items are moved, the debugger
readjusts its symbol table accordingly.
■ The (lh) and (gh) type casts, which you can use to dereference local
and global handles of a memory object into near and far pointer
addresses. For a more detailed description, see "Dereferencing Memory
Handles" in Section 7.8.6.
■ Windows-specific commands. CVW has six new commands:
Command What it does
────────────────────────────────────────────────────────────────────────────
wdl (Windows Display Local Heap) Displays a list of the memory objects in
the local heap.
wdg (Windows Display Global Displays a list of the memory objects in
Heap) the global heap.
wdm (Windows Display Module Displays a list of the application and
List) library modules known by Windows.
wwm (Windows Watch Message) Displays a Windows message or class of
messages in the CVW
Command window.
wbm (Windows Break Message) Sets a breakpoint on a Windows message
or class of messages.
wka (Windows Kill Application) Terminates the currently executing task.
You should use this command with caution.
See Section 7.10.4,
"Interrupting Your Program," for more
information.
7.3 Preparing to Run CVW
Before beginning a CVW debugging session, you must do the following:
■ Set up a secondary monitor on which to display CVW information.
■ Ensure that the Windows application you are going to debug has been
compiled and linked properly.
In addition to these mandatory steps, it is also recommended that you set up
a debugging version of Windows.
The following sections describe how to prepare your system for running CVW.
7.3.1 Setting Up a Secondary Monitor
In addition to the graphics adapter card and graphics display monitor
required for your Windows display, you need a monochrome adapter card and
monochrome display monitor to use CVW.
To set up a secondary monitor for debugging, do the following:
1. Install a secondary monochrome adapter card in a free slot on your
computer and connect the monochrome monitor to the port in the back.
2. Set the secondary-display-adapter switches to the appropriate
settings, according to the display adapter and computer manufacturer
recommendations.
If your system is an IBM PS/2, it must be configured with an 8514/a monitor
as the primary monitor, and a VGA as the secondary monitor. To use this
configuration, specify the /8 (8514/a) option when you choose the Run
command from the CVW File menu. If your VGA monitor is monochrome, you must
also use the /B (black and white) option. The 8514/a serves as the Windows
screen and the VGA as the debugging screen.
────────────────────────────────────────────────────────────────────────────
IMPORTANT
Do not attempt to run non-Windows applications or the DOS shell while
running CVW with the /8 option.
────────────────────────────────────────────────────────────────────────────
By default, the debugging screen operates in 50-line mode in this
configuration. If you specify the /8 option, you can optionally specify the
/25 or /43 option for 25- or 43-line mode, respectively, on the VGA
debugging screen.
With the secondary monitor connected to your system, you can view CVW output
and Windows output simultaneously.
7.3.2 Setting Up the Debugging Version of Windows
You can run CVW with either the debugging or retail version of Windows.
The debugging version performs error checking which is not available in the
retail version. For example, the debugging version of Windows checks whether
a window handle passed to a Windows function is valid. When the debugging
version of Windows detects such an error, it reports a fatal exit. If this
happens while you are running CVW, the fatal exit is reported in the CVW
Command window. Section 7.11, "Handling Abnormal Termination of the
Application," discusses this error handling in greater detail.
Another advantage to using the debugging version of Windows with CVW is the
additional support which the Windows core dynamic-link libraries (DLLs)
(KRNL286.EXE, KRNL386.EXE, GDI.EXE, and USER.EXE) provide for debugging.
These DLLs contain symbol information which makes it easier to determine the
cause of an error. For example, if your application causes a general
protection (GP) fault while running with the debugging version, Windows can
display symbol information for the Windows code that was executing when the
GP fault was detected. If, instead, you were running with the retail version
of Windows, Windows would only be able to display CS:IP address values of
the code that was executing when the fault occurred.
CVW does not automatically use these Windows core DLL symbols. To provide
CVW access to these symbols, you must specify one or more of the core DLLs
either using the /L command-line option or in response to the DLL prompt
within CVW. If you are running CVW with Windows in standard mode, specify
KRNL286.EXE. In 386 enhanced mode, specify KRNL386.EXE. Section 7.4.4,
"Starting a Debugging Session for DLLs," explains how to load symbols from a
DLL.
Installing the debugging version of Windows requires only three simple
steps:
1. Rename or copy the KRNL286.EXE, KRNL386.EXE, GDI.EXE, and USER.EXE
files located in the Windows system directory. If you accepted the
default Windows directory name offered by Windows Setup, the Windows
system directory is named \WINDOWS\SYSTEM.
2. Copy the debugging version of these files from the Windows development
debugging directory (named \WINDEV\DEBUG by default) to the Windows
system directory.
3. Copy the corresponding symbol files from the debugging directory to
the system directory.
7.3.3 Preparing Windows Applications for Debugging
To prepare a Windows application for use with CVW, take the following steps:
1. Compile your C source code with the /Zi option and, optionally, the
/Od options.
The /Zi option directs the compiler to produce object files that
contain CodeView symbolic information. The /Od option disables the
compiler's optimization. If optimization is enabled, the code
generated by the compiler does not match as closely the statements in
the C source code. Using the /Od option makes debugging easier.
For example:
CL -d -c -AS -Gsw -Zpei -Od OUTPUT.C
2. Link your application with the /CO option.
The /CO option directs the linker to produce an executable file that
contains CodeView information. This information is used directly by
CVW.
Note that no other switches, intermediate files, or programs (such as
MAPSYM, used with SYMDEB) are required for CVW. For example:
LINK OUTPUT,,,/NOD /CO SLIBW SLIBCEW, OUTPUT.DEF
After compiling and linking your application with these options, you can
start a CVW debugging session.
7.4 Starting a Debugging Session
Like most Windows applications, you can start CodeView for Windows several
ways. For a complete description of how to start Windows applications, see
the Windows User's Guide. To specify CVW options, you must choose the Run
command from the File menu in Program Manager. See Section 7.4.5, "Using CVW
File Run Options," for more information on CVW options.
You can run CVW to perform the following tasks:
■ Debug a single application
■ Debug multiple instances of an application
■ Debug multiple applications
■ Debug dynamic-link libraries (DLLs)
This section describes the methods you use to perform these tasks, and
summarizes the syntax of the Run command in the File menu of CVW.
7.4.1 Starting a Debugging Session for a Single Application
After you start CVW from Windows, CVW will display the Command Line dialog
box on your secondary monitor. To start debugging a single application:
1. At the Command Line prompt, type the name of the application. If you
do not include an extension, CVW assumes the .EXE extension by
default. You can also include any arguments that the application
recognizes. The following shows the syntax of the command to start
debugging a single application:
appname«.EXE» «application_arguments»
2. Press ENTER or click OK.
CVW displays the following prompt:
Name any other DLL or executable with debug info:
Since you are debugging only one application and no DLLs, press ENTER
or click OK. CVW loads the application and displays the source code
for the application's WinMain routine on the debugging screen.
3. Set breakpoints in the code, if you desire.
4. Use the go command to resume execution of the application.
If you want to avoid the start-up dialog boxes, you can start CVW more
quickly by specifying the application name as an argument in the Run command
line, as follows:
1. Choose the Run command from the Windows File menu.
2. Type the application name and any application arguments in the CVW
command line. The following shows the syntax of the command line to
start debugging a single application:
CVW «cvw_options» appname«.EXE» «application_arguments»
3. Press ENTER or click OK.
7.4.2 Starting a Debugging Session for Multiple Instances of an Application
Windows can run multiple instances of an application simultaneously, which
can be a potential problem for your application. For example, two instances
of an application might interfere with each other, or perhaps one could
corrupt the data of the other.
To help you solve problems associated with running multiple instances of a
program, CVW allows you to debug multiple instances of an application
simultaneously. You can determine which instance of an application you are
looking at by examining the DS register at any breakpoint.
To debug multiple instances of an application, perform the following steps:
1. Start CVW as usual for your application.
2. Run one or more additional instances of your application by choosing
the Run command from the File menu in Windows.
Specifying your application name more than once when starting CVW does not
have the effect of loading multiple instances of the application.
The breakpoints you set in your application will apply to all instances of
the application. To determine which instance of the application has the
current focus in CVW, examine the DS register.
7.4.3 Starting a Debugging Session for Multiple Applications
You can debug two or more applications at the same time, such as a DDE
Client and Server. However, global symbols shared by both applications (such
as the symbol name "WINMAIN") are not distinguished. CVW always resolves
symbol references to the first application named when you started CVW.
Perform the following steps to debug more than one application at the same
time:
1. Start CVW as usual for a single application.
2. Provide the name of the second application when CVW displays this
prompt:
Name any other DLL or executable with debug info:
You must include the .EXE extension of the filename of the second
application.
3. Set breakpoints in either or both applications, using the File Open
Module command to display the source code for the different modules.
4. Use the go command to continue execution of the first application.
5. Choose the Run command from the File menu in Windows to start
execution of the second application.
Alternatively, you can use the /L option on the Run command line in CVW to
load the symbols for a second application, as shown:
cvw /l second.exe first.exe
The /L option and the name of the second application must precede the name
of the first application on the Run command line. You can repeat the /L
option for each application to be included in the debugging session.
Once CVW starts, choose the Run command from the File menu in Windows to
start execution of the second application.
7.4.4 Starting a Debugging Session for DLLs
You can debug one or more DLLs while you are debugging an application. As
with multiple applications, global symbols shared by both applications are
not distinguished.
Perform the following steps to debug a DLL at the same time as an
application:
1. Start CVW as usual for the application.
2. Provide the name of the DLL when CVW displays this prompt:
Name any other DLL or executable with debug info:
CVW assumes the .DLL extension if you do not supply an extension with
the filename. If your DLL has another extension (such as .DRV), you
must specify it explicitly.
3. Set breakpoints in either the application or the DLL, using the File
Open Module command to display the source code for the different
modules.
4. Use the go command to continue execution of the application.
Alternatively, you can use the /L option on the CVW File Run command line to
specify the DLL, as shown:
cvw /l appdll appname.exe
The /L option and the name of the DLL must precede the name of the first
application on the CVW File Run command line. You can repeat the /L option
for each DLL to be included in the debugging session. The .DLL extension is
the default extension for the /L option.
CVW allows you to debug the LibEntry initialization routine of a DLL. If
your application implicitly loads the library, then a special technique is
required to debug the LibEntry routine. An application implicitly loads a
DLL if the library routines are imported in the application's
module-definition (.DEF) file, or if your application imports library
routines through an import library when you link the application. An
application explicitly loads a DLL by calling the LoadLibrary function.
If your application implicitly loads the DLL and you specify the application
at the Command Line prompt, CVW automatically loads the DLL and executes the
DLL's LibEntry routine when CVW loads the application. This gives you no
opportunity to debug the LibEntry routine. To avoid this problem, perform
the following steps:
1. Do not provide the name of your application at the Command Line
prompt. Instead, provide the name of any "dummy" application which
does not implicitly load the library.
2. Enter the name of your DLL, being sure to include the extension if it
is not .DLL, at the following prompt:
Name any other DLL or executable with debug info:
3. Use the File Open Module command to display the source code for the
library module containing the LibEntry routine. Set breakpoints in the
LibEntry routine.
4. Use the File Open Module command to display the source code for other
library or application modules and set desired breakpoints.
5. Use the go command to start execution of the "dummy" application.
6. Execute your application (that is, the application that implicitly
loads the DLL) by choosing the Run command from the File menu in
Windows. CVW will resume control when the breakpoint in the LibEntry
routine is encountered.
Alternatively, you can use the CVW File Run command line to identify the
"dummy" application, your application, and the DLL, as shown:
cvw /l appdll dummyapp
7.4.5 Using CVW File Run Options
Sections 7.4.1 through 7.4.4 illustrated different ways to use the CVW File
Run command line. The following shows the general syntax of this command
line:
CVW «cvw_options» app_name«.EXE» «app_arguments»
None of the parameters are case-sensitive.
The following list describes these parameters.
╓┌──────────────┌─────────────────────────────┌──────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
cvw_options Specifies one or more
options that modify how CVW
runs. Acceptable options
are:
Option Purpose
/L dll_or_exe Specifies the name of an
application or DLL that has
been compiled and linked with
CVW symbols. CVW assumes the
default file extension .DLL
if no extension is supplied.
You can use the /L option
more than once to specify
multiple DLLs or executable
Parameter Description
────────────────────────────────────────────────────────────────────────────
multiple DLLs or executable
files.
/C command Specifies one or more CVW
commands which CVW executes
when it loads the application
specified by the app_name
parameter. The commands must
be enclosed in double
quotation marks ( " ) and
separated with semicolons ( ;
).
/M Disables the use of the mouse
at the debugging screen. You
should use this option when
you set breakpoints in code
that is responsive to mouse
movements on the Windows
Parameter Description
────────────────────────────────────────────────────────────────────────────
movements on the Windows
(application) screen.
/TSF Toggles the save state-file
status. See Section
<NO>7</NO>.5, "Saving Session
Information," for details.
/8 Allows CVW to recognize a
dual-monitor configuration.
See <NO>7</NO>.3.1, "Setting
Up a Secondary Monitor," for
more information.
/B Specifies a monochrome VGA
monitor used as the secondary
display with an 8514/a
display. This option is valid
only in conjunction with the
Parameter Description
────────────────────────────────────────────────────────────────────────────
only in conjunction with the
/8 option.
Option Purpose
/25 Specifies 25-line mode for
the secondary VGA monitor.
This option is valid only in
conjunction with the /8
option.
/43 Specifies 43-line mode for
the secondary VGA monitor.
This option is valid only in
conjunction with the /8
option.
/50 Specifies 50-line mode for
the secondary VGA monitor.
Parameter Description
────────────────────────────────────────────────────────────────────────────
the secondary VGA monitor.
This option is valid only in
conjunction with the /8
option. The /50 option is not
required, since 50-line mode
is the default for the
dual-monitor configuration.
app_name Specifies the pathname of
the application for which
CVW will load symbols and
issue an initial breakpoint.
The .EXE extension is
optional.
app_arguments Specifies one or more
arguments recognized by the
application that CVW loads.
Parameter Description
────────────────────────────────────────────────────────────────────────────
7.5 Saving Session Information
After your session, CVW stores session information in a file called
CURRENT.STS, which is located in the directory pointed to by the INIT
environment variable or in the current directory. If this file does not
already exist, CVW automatically creates it. Session information includes:
■ CodeView display windows that were opened.
■ Breakpoint locations.
CodeView for Windows saves this information, which becomes the default the
next time you run a CVW session for that application.
You can disable this feature by placing the following entry in your
TOOLS.INI file: (The default is "y" ─yes.)
[cvw]
StateFileRead: n
The /TSF option temporarily toggles this setting when you run CVW. That is,
if TOOLS.INI disables this feature, running CVW with the /TSF option saves
session information for that session only.
────────────────────────────────────────────────────────────────────────────
NOTE
If your Windows session abnormally terminates while CVW is running, the
CURRENT.STS file may be corrupted. This may cause CVW to fail when it first
tries to execute the application you are debugging. If this happens, delete
the CURRENT.STS file before attempting to run CVW again.
────────────────────────────────────────────────────────────────────────────
7.6 Working with the CVW Screen
When you start CVW, the CVW menu bar and three display windows─the Local
window, the Source window, and the Command window─will appear on your
secondary monitor. Figure 7.1 illustrates how the screen appears during a
debugging session.
(This figure may be found in the printed book).
7.6.1 Using CVW Display Windows
CVW divides the screen into logically separate sections called display
windows, so that a large amount of information can be displayed in an
organized and easy-to-read fashion. Each CVW display window is a distinct
area on your monitor that operates independently of the other display
windows. The name of each display window appears in the top of the window's
frame. The following list describes the seven types of CVW display windows:
CVW Display Window Purpose
────────────────────────────────────────────────────────────────────────────
Source window Displays the source code. You can open a
second source window to view an include
file, another source file, or the same
source file at a different
location.
Command window Accepts debugging commands.
Watch window Displays the current values of selected
variables.
Local window Lists the values of all variables local
to the current function or block.
Memory window Shows the contents of memory. You can
open a second Memory window to view a
different section of memory.
Register window Displays the contents of the
microprocessor's registers, as well as
the processor flags.
8087 window Displays the registers of the
coprocessor or its software emulator.
Help window Displays the Help options or any Help
information that you request.
Opening Display Windows
There are two ways to open CVW display windows:
■ Choose a window from the View menu. (Note that you can open more than
one Source or Memory window.)
■ Perform an operation that automatically opens a window if it is not
already open. For example, selecting a Watch variable automatically
opens the Watch window.
CodeView continually and automatically updates the contents of all its
display windows.
Selecting Display Windows
To select a window, click anywhere inside of it. You can also press F6 or
SHIFT+F6 to move the focus from one window to the next.
The selected window is called the "current" window and is marked in three
ways:
■ The window's name is displayed in white.
■ The text cursor appears in the window.
■ The vertical and horizontal scroll bars are moved into the window.
Typing commands into the Source window causes CVW to temporarily shift its
focus to the Command window. Whatever you type is appended to the last line
in the Command window. If the Command window is closed, CVW beeps in
response to your entry and ignores the input.
Adjusting Display Windows
CVW display windows often contain more information than they can display on
the screen. Although you cannot change the relative positions of the display
windows, you can manipulate a selected window using the mouse, as follows:
■ To scroll the window vertically or horizontally, use the vertical or
horizontal scroll bar.
■ To maximize a window so that it fills the screen, click the Up arrow
at the right end of the window's top border. To restore the window to
its previous size and position, click the Double arrow at the right
end of the top border.
■ To change the size of a window:
1. Position the cursor anywhere on the border between two windows.
2. Press and hold down the left mouse button.
Two double arrows will appear on the line.
3. Drag the mouse to enlarge or reduce the window.
■ To remove a window, click the small, dotted box at the left end of the
top border.
The adjacent windows automatically expand to recover the empty space.
You can also use the following keyboard commands:
Keyboard Command Description
────────────────────────────────────────────────────────────────────────────
PAGE UP or PAGE DOWN Scrolls through the text vertically.
CTRL+F10 Maximizes a selected display window.
CTRL+F8 Changes the size of a selected display
window.
CTRL+F4 Removes a selected display window.
You can also choose the Maximize, Size, and Close commands from the View
menu to manipulate a selected display window.
The different CVW display windows can help you to conduct a variety of
debugging activities simultaneously. These activities are initiated and
controlled with CVW debugging commands, which can be typed in the CVW
Command window or selected using the CVW menus.
7.6.2 Using the CVW Menu Bar
In addition to display windows, the CVW screen includes a menu bar, which
contains the following menus:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Menu Command
────────────────────────────────────────────────────────────────────────────
File This menu contains the following
commands:
Open Source opens any text file and
reads it into the currently active
source window.
Open Module opens the source file of any
module for which CVW information has
been loaded and reads it into the
currently active source window.
Exit ends your CVW session and returns
you to Windows.
Edit This menu contains the following
commands:
Menu Command
────────────────────────────────────────────────────────────────────────────
commands:
Copy copies selected text to the paste
buffer
Paste inserts text from the paste buffer
into the active window at the present
cursor location, if that location is
valid (for example, text cannot be
pasted into the source window).
View This menu contains the following
commands:
Source opens a new Source window. Memory
opens a new Memory window.
Register acts as a switch to open and
close the Register window.
Menu Command
────────────────────────────────────────────────────────────────────────────
close the Register window.
8087 acts as a switch to open and close
the 8087 window.
Local acts as a switch to open and close
the Local window.
Watch acts as a switch to open and close
the Watch window.
Command acts as a switch to open and
close the Command window.
Help acts as a switch to open and close
the Help window.
Maximize enlarges the current window so
that it fills the screen.
Menu Command
────────────────────────────────────────────────────────────────────────────
that it fills the screen.
Size changes the size of the current
window.
Close closes the current window.
Search This menu contains the following
commands:
Find searches for the next occurrence of
a string or a regular expression that
you supply in the Find dialog box.
Selected Text searches for the next
occurrence of a string of selected text.
Repeat the Last Find searches for the
next occurrence of whatever you
Menu Command
────────────────────────────────────────────────────────────────────────────
next occurrence of whatever you
specified in the previous Find command.
Label/Function searches for a function
or label definition in the active Source
window and, if one is found, changes the
input focus to the active Source window.
Run This menu contains the following
command:
Animate continues the execution of a
program while displaying the execution
path in the Source window. This type of
display is called an "animated trace"
display.
Watch This menu contains the following
commands:
Menu Command
────────────────────────────────────────────────────────────────────────────
commands:
Add Watch adds an expression to the
Watch window.
Delete Watch deletes an expression from
the Watch window.
Set Breakpoint tells the program where
to halt execution; you can set
breakpoints on lines of source code,
variables and expressions, and Windows
messages.
Edit Breakpoint performs editing
functions on breakpoints; they can be
added, removed, modified, enabled or
disabled.
Menu Command
────────────────────────────────────────────────────────────────────────────
Quick Watch selects one expression for
the Quick Watch window.
Options This menu contains the following
commands:
Source Window sets the display
characteristics of the active Source
window.
Memory Window sets the display
characteristics of the active Memory
window.
Trace Speed sets the speed of program
tracing and execution.
Case Sensitivity, when turned on, treats
Menu Command
────────────────────────────────────────────────────────────────────────────
Case Sensitivity, when turned on, treats
uppercase and lowercase letters as
different characters. When turned off,
it does not differentiate between
uppercase and lowercase letters.
386 Instructions, when turned on,
recognizes all 80386 instructions in
32-bit values. When turned off, it reads
all instructions as 16-bit values
Calls The contents and size of this menu
change as your program executes. It
shows the currently executing routine
and the trail of routines from which it
was called. Your application must
execute, at least, the beginning of the
WinMain procedure before CVW will
display the current routine. When you
Menu Command
────────────────────────────────────────────────────────────────────────────
display the current routine. When you
select one of the lines in the Calls
menu, CVW displays the source code
corresponding to the calling location in
the
active source window.
Help This menu contains Help information on
various CodeView topics.
For a more detailed description of the CVW menu and commands, refer to CVW
Help.
7.7 Getting On-line Help in CVW
CVW on-line Help contains detailed information and examples not found in
this chapter. You can get on-line help by choosing a command from the Help
menu described in the previous section, or selecting an item on your screen
and pressing F1. Help is available on items such as commands, menus, dialog
boxes, and error messages.
7.8 Displaying Program Data
CVW offers a variety of ways to display program variables, processor
registers, and memory. You can also modify the values of all these items as
the program executes. This section describes how to display:
■ Variables in the Watch window.
■ Expressions in the Watch window.
■ Arrays and structures in the Watch window.
■ A single expression in the Quick Watch window.
■ Windows messages in the Command window.
■ Memory in the Memory window.
■ The contents of registers in the Register window.
7.8.1 Displaying Variables
You can use the Watch window to monitor the value of a given variable
throughout the execution of your program. For example, do, for, and while
loops can cause problems when they don't terminate correctly. By displaying
loop variables in the Watch window, you can determine if a loop variable
achieves its proper value.
To add a variable to the Watch window:
1. In the Source window, use the mouse or the DIRECTION keys to position
the cursor on the name of the variable you want to watch.
2. Select the Add Watch command from the Watch menu, or press CONTROL+W.
A dialog box will appear with the selected variable's name displayed
in the Expression field.
3. Press ENTER or click the OK button to add the variable to the Watch
window.
If you want to add a different variable than the one shown in the
dialog box, type its name over the one displayed, and then press
ENTER.
The Watch window appears at the top of the screen. Adding a Watch variable
opens the Watch window automatically if it is not already open.
When you add a local variable, you may get the following message:
Watch Expression Not in Context
This message appears when program execution has not yet reached the C
function that defines the local variable. Global variables (those declared
outside C functions) never cause CVW to display this message; you can watch
them from anywhere in the program.
────────────────────────────────────────────────────────────────────────────
NOTE
If you are debugging more than one application or DLL, and if two or more of
these contain global variables with the same name, CVW will display the
variable of only the first application or DLL containing that variable name.
For example, if you are debugging App1 and App2, and both contain a global
variable named hInst, CVW will always display the value of hInst in App1,
even if CVW stopped at a breakpoint in App2.
────────────────────────────────────────────────────────────────────────────
The Watch window will hold as many variables as you like; the quantity is
limited only by available memory. You can scroll through the Watch window to
position it at those variables you want to view. CVW automatically updates
all watched variables as the program runs, including those not currently
visible.
To remove a variable from the Watch window:
1. Choose the Delete Watch command from the Watch menu.
2. Scroll through the dialog box and select the variable you want to
remove.
You can also position the cursor on any line in the Watch window and press
CONTROL+Y to delete the line.
7.8.2 Displaying Expressions
You might have noticed that the Add Watch dialog box prompts for an
expression, not simply a variable name. You can add any valid combination of
variables, constants, or operators as an expression for CVW to evaluate and
display in the Watch window.
The advantage of evaluating expressions is that you can reduce several
variables to a single value, which can be easier to interpret than the
components that make it up. For example, imagine a for loop with two
variables whose ratio is supposed to remain constant. You suspect that one
of these variables sometimes takes the wrong value. With (var1 / var2)
displayed as an expression in the Watch window, you can easily see when the
quotient changes, without having to mentally divide two numbers.
You can also display Boolean expressions. For example, if a variable is
never supposed to be greater than 100 or less than 25, the expression (var >
100) evaluates to 1 (true) when var goes out-of-bounds.
7.8.3 Displaying Arrays and Structures
A program variable is usually a scalar quantity (a single character, integer
or floating-point value). The variable appears in the Watch window with the
variable name to the left, followed by an equal sign (=), and the current
value. The Watch window must provide a different way to display "aggregate"
data items, such as arrays and structures.
Arrays and structures contain multiple values that can be arranged in one or
more layers. You can control how these variables appear in the Watch
window─whether all, part, or none of their internal structure is displayed.
An array initially appears in the Watch window in this form:
+Wordholder[] = [...]
The brackets indicate that this variable contains more than one element. The
plus sign (+) indicates that the variable has more elements than are
displayed on the screen. You can expand the variable to display any or all
of its components; this technique is called "dereferencing."
To dereference (expand) the array, double-click anywhere on the line. You
can also position the cursor on the line and press ENTER. For example, if
Wordholder is a six-character array containing the word "Basic," the Watch
window display changes to:
-Wordholder[]
[0] = 66 'B'
[1] = 97 'a'
[2] = 115 's'
[3] = 105 'i'
[4] = 99 'c'
[5] = 0 ''
Note that both the individual character values and their ASCII decimal
equivalents are listed. The minus sign (-) indicates no further expansion is
possible. To contract the array, double-click its line again or position the
cursor on the line and press ENTER.
Displaying Character Arrays
If viewing a character array in this form is inconvenient, cast the
variable's name to a character pointer by placing the following in front of
the name:
(char *)
The character array is then displayed as a string delimited by apostrophes.
Displaying Multidimensional Arrays
You can display arrays with more than one dimension. For example, imagine a
5-by-5 integer array named Matrix, whose diagonal elements are the numbers 1
through 5 and whose other elements are zero. Unexpanded, the array is
displayed like this:
+Matrix[] = [...]
Double-clicking Matrix (or pressing ENTER) changes the display to:
-Matrix[]
+[0][] = [...]
+[1][] = [...]
+[2][] = [...]
+[3][] = [...]
+[4][] = [...]
The actual values of the elements are not shown yet. You have to descend one
more level to see them. For example, to view the elements of the third row
of the array, position the cursor anywhere on the +[2] line and press ENTER.
The following code shows the third row of the array dereferenced:
-Matrix[]
+[0][] = [...]
+[1][] = [...]
-[2][]
[0] = 0
[1] = 0
[2] = 3
[3] = 0
[4] = 0
+[3][] = [...]
+[4][] = [...]
Dereferencing the fifth row (+[4]) of the array produces this display:
-Matrix[]
+[0][] = [...]
+[1][] = [...]
-[2][]
[0] = 0
[1] = 0
[2] = 3
[3] = 0
[4] = 0
+[3][] = [...]
-[4][]
[0] = 0
[1] = 0
[2] = 0
[3] = 0
[4] = 5
Any element of an array or structure can be independently expanded or
contracted; you need not display every element of the variable. If you only
want to view one or two elements of a large array, specify the particular
array or structure elements in the expression field of the Add Watch dialog
box.
You can dereference a pointer in the same way as an array or structure. The
Watch window will display the pointer address, followed by all the elements
of the variable to which the pointer currently refers. You can display
multiple levels of indirection (that is, pointers referencing other
pointers) simultaneously.
Displaying Dynamic Array Elements
An array may have dynamic elements that change as some other variable
changes. Just as you can display a particular element of an array by
specifying its subscript, you can also display a dynamic array element, by
specifying its variable subscript. For example, suppose that the loop
variable p is a subscript for the array variable Catalogprice. The Watch
window expression Catalogprice[p] displays only the array element currently
specified by the variable p, not the entire array.
You can mix constant and variable subscripts. For example, the expression
BigArray[3][i] displays only the element in the third row of the array to
which the index variable i points.
7.8.4 Using the Quick Watch Command
Using the Quick Watch command is a convenient way to take a quick look at a
variable or expression. Since the Quick Watch window can only display one
variable at a time, you would not use it for most of the variables you want
to view.
Selecting the Quick Watch command from the Watch menu (or pressing SHIFT+F9)
displays the Quick Watch dialog box. If the text cursor is in the Source,
Local, or Watch window, the variable at the current cursor position appears
in the dialog box.
The Quick Watch display automatically expands arrays and structures to their
first level. For example, an array with three dimensions will expand to the
first dimension. You can expand or contract an element just as you would in
the Watch window; position the cursor on the appropriate line and press
ENTER. If the array needs more lines than the Quick Watch window can
display, drag the mouse along the scroll bar, or press DOWN ARROW or PAGE
DOWN to view the rest of the array.
You can add Quick Watch variables to the Watch window. If you decide to add
a Quick Watch item to the Watch window, select the Add Watch button. Arrays
and structures appear in the Watch window expanded as they were displayed in
the Quick Watch box.
7.8.5 Tracing Windows Messages
You can trace the occurrence of a Windows message or an entire class of
Windows messages by using the wwm (Watch Windows Message) command. CVW will
display the messages in the CVW Command window.
To trace a Windows message or message class, type the wwm command in the
Command window. The syntax for the command is:
wwm winproc msgname | msgclasses
The winproc parameter is the symbol name or address of an application's
window function. The msgname parameter is the name of a Windows message,
such as WM_PAINT. The msgclasses parameter is a string of characters that
identify one or more classes of messages to be traced. The classes are
consistent with those defined in the Windows Spy application; they are:
Message Class Type of Windows Message
────────────────────────────────────────────────────────────────────────────
m mouse
w window management
n input
s system
i initialization
c clipboard
d DDE
z nonclient
For example, the following command traces all mouse and input messages sent
to MainWndProc:
wwm MainWndProc mn
The CVW Command window displays Windows messages in the following format:
HWND:lc00 wParm:0000 lParm:000000 msg:000F WM_PAINT
7.8.6 Displaying Memory
Selecting the Memory command from the View menu opens a Memory window. CVW
allows you to have two Memory windows open at one time.
By default, memory is displayed as hexadecimal byte values, with 16 bytes
per line. At the end of each line is a second display of the same memory in
ASCII form. Values that correspond to printable ASCII characters (decimal 32
through 127) are displayed in that form. Values outside this range are shown
as periods ( . ).
Byte values are not always the most convenient way to view memory. If the
area of memory you are examining contains character strings or
floating-point values, you might prefer to view them in a directly readable
form. The Memory Window command of the Options menu displays a dialog box
with a variety of display options:
■ ASCII characters
■ Byte, word, or double-word binary values
■ Signed or unsigned integer decimal values
■ Short (32-bit), long (64-bit), or 10-byte (80-bit) floating-point
values
You can also directly cycle through these display formats by pressing
SHIFT+F3.
If a section of memory cannot be displayed as a valid floating-point number,
the number shown includes the characters NAN (not a number).
Displaying Local and Global Memory Objects
CVW also allows you to display global and local memory objects in their
respective Windows heaps. You can display the heap of global memory objects
with the wdg (Display Global Heap) command, and the heap of local memory
objects with the wdl (Display Local Heap) command. Both of these commands
will display the entire heap of global or local memory objects in the
Command window.
For the wdg command, you can specify the single object parameter to display
a partial list of the global heap. When you use the single object parameter
with the wdg command, the Command window will display the first five memory
objects in the global heap, starting at the handle rather than at the
beginning of the heap. The following illustrates the output format of the
wdg (Display Global Heap) command:
"
047E (0A7D) 00000020b MYAPP PRIV MOVEABLE DISCARDABLE
0A6D 00000134b MYAPP DATA FIXED PGLOCKED=0001
0806 (0805) 00000600b PDB (0465)
FREE 000000A0b
The following describes the indicated fields:
╓┌──┌───────────────────────────────────┌────────────────────────────────────╖
────────────────────────────────────────────────────────────────────────────
" A global memory handle value.
Global memory objects are
displayed in the order in which
Windows manages them, which is
typically not in ascending handle
order.
A memory selector. This value is
not displayed if the selector
────────────────────────────────────────────────────────────────────────────
not displayed if the selector
value is the same as the global
handle, as is the case for DATA
objects.
The length in bytes of the global
memory object.
The name of the application or
library module that allocated the
object. The name "PDB" is for
Process Descriptor Block.
The type of global memory object:
Type Meaning
PRIV Application or DLL global data, or
system object
────────────────────────────────────────────────────────────────────────────
CODE Code segment
DATA Data segment of application or DLL
FREE Free memory block in the global
heap
╓┌─┌────────────────────────────────────┌────────────────────────────────────╖
────────────────────────────────────────────────────────────────────────────
One or more of the following
combinations of memory allocation
attributes:
MOVEABLE
MOVEABLE DISCARDABLE
────────────────────────────────────────────────────────────────────────────
FIXED
The disposition of the object if it
is moveable:
Disposition Meaning
LOCKED=number Number of times the object has been
locked with the GlobalLock or
LockData functions
PGLOCKED=number Number of times Windows has locked
the object in its linear address
space.
The owner handle of the Process
Descriptor Block.
A free memory block, followed by
────────────────────────────────────────────────────────────────────────────
A free memory block, followed by
the size of the free block.
The following shows the output of the wdl (Display Local Heap) command:
"
190A: 000A BUSY (16DA)
The following describes the indicated fields:
╓┌──┌───────────────────────────────────┌────────────────────────────────────╖
────────────────────────────────────────────────────────────────────────────
" The offset of the local memory
object in the local data segment.
The length in bytes of the object.
One of the following dispositions:
────────────────────────────────────────────────────────────────────────────
One of the following dispositions:
Disposition Meaning
BUSY Currently allocated
FREE A free block in the local heap
A local memory handle
Displaying Variables with a Live Expression
Section 7.8.4, "Using the Quick Watch Command," explained how to display a
specific array element by adding the appropriate expression to the Watch
window. It is also possible to watch a particular array element or structure
element in the Memory window. This CVW display feature is called a "live
expression."
"Live" means that the area of memory displayed changes to reflect the value
of a pointer or subscript. For example, if Buffer is an array and pBuf is a
pointer to that array, then *pBuf points to the array element currently
referenced. A live expression displays the section of memory beginning with
this element.
CVW displays live expressions in a Memory window. To create a live
expression:
1. Select the Memory Window command from the Options menu.
2. Select the live expression check box and type the name of the element
you want to view.
For example, if StrgPtr is a pointer to an array of characters, and
you want to see what it currently points to, type:
*StrgPtr
3. Click the OK button or press ENTER.
A new Memory window opens. The first memory location in the window is the
first memory location of the live expression. The section of memory
displayed changes to the section the pointer currently references.
You can use the Memory Window command of the Options menu to display the
value of the live expression in a readable form. This is especially
convenient when the live expression represents strings or floating-point
values, which are difficult to interpret in hexadecimal form.
It is usually more convenient to view an item in the Watch window than as a
live expression. However, you might find some items easier to view as live
expressions. For example, you can examine what is currently at the top of
the stack by specifying SS:SP as the live expression.
Dereferencing Memory Handles
In a Windows application, the LocalLock and GlobalLock functions are used to
dereference memory handles into near or far pointers. In a debugging
session, you may know the handle of the memory object, but might not know
what near or far address it dereferences to, unless you are debugging in an
area where the program has just completed a LocalLock and GlobalLock
function call. To get the near and far pointer addresses for your local and
global handles, use the (lh) and (gh) type casts. For example, you could use
(lh) to dereference the array in the following code:
HANDLE hLocalMem;
int near *pnArray;
hLocalMem = LocalAlloc(LMEM_MOVEABLE,100);
pnArray = LocalLock(hLocalMem);
/* load values into the array */
LocalUnlock(hLocalMem);
To properly display this array in CVW, you would use the following command:
dw (lh)hLocalMem
If you set a breakpoint immediately after the LocalLock function, you could
find out where the local object was allocated in the application's data
segment by looking at the value of the pnArray variable. To display the
value of pnArray, use the following CVW command:
dw pnArray
Note that you cannot rely on the value of pnArray anywhere else in the
program because it may change or the memory object may move.
If the memory object is a string, you can display it using double type
casting, as shown:
HANDLE hGlobalMem;
LPSTR lpstr;
hGlobalMem = GlobalAlloc(GMEM_MOVEABLE, 10L)
lpstr = GlobalLock(hGlobalMem);
lstrcpy(lpstr,"ABCDEF");
GlobalUnlock(hGlobalMem);
You could then display the contents of the string with the following
statement:
? *(char far*) (gh)lpstr,s
The (gh) type cast will return a pointer to the far address of the global
memory object.
7.8.7 Displaying the Contents of Registers
Selecting the Register command from the View menu (or pressing F2) opens a
window on the right side of the screen. The current values of the
microprocessor's registers appear in this window.
At the bottom of the window are a group of mnemonics representing the
processor flags. When you first open the Register window, all values are
shown in normal-intensity video. Any subsequent changes are marked in
high-intensity video. For example, suppose the overflow flag is not set when
the Register window is first opened. The corresponding mnemonic is NV and it
appears in normal-intensity video. If the overflow flag is subsequently set,
the mnemonic changes to OV and appears in high-intensity video.
Selecting the 386 Instructions command from the Options menu displays the
registers as 32-bit values. This command is valid only if your computer uses
an 80386 processor. Selecting this command a second time changes the
registers back to 16-bit values.
You can also display the registers of an 8087/287/387 coprocessor in a
separate window by selecting the 8087 command from the View menu. If your
program uses the coprocessor emulator, the emulated registers are displayed
instead.
7.8.8 Displaying Windows Modules
The wdm (Dump Modules) command displays a list of all the DLL and task
modules that Windows has loaded. For each module, the list shows the module
handle, the type of module (DLL or task), the name of the module, and the
pathname of the module.
7.9 Modifying Program Data
You can easily change the values of variables, memory locations, or
registers displayed in the Watch, Local, Memory, Register, or 8087 window.
Simply position the cursor at the value you want to change and type in the
appropriate value. If you change your mind, press ALT+BACKSPACE to undo the
last change you made.
The Memory window displays the starting address of each line in
segment:offset form. Altering the address automatically shifts the display
to the corresponding section of memory. If that section is not used by your
program, memory locations are displayed as double question marks (??).
You can also change the values of memory locations by modifying the right
side of the memory display, which shows memory values in ASCII form. For
example, to change a byte from decimal 75 to decimal 85, place the cursor
over the letter K, which corresponds to the position where the memory value
is 75 (K is ASCII 75), and type in U (U is ASCII 85).
To change a processor flag, click its mnemonic; or position the cursor on a
mnemonic, and then press any key (except TAB or SPACEBAR). Repeat these
operations to restore the flag to its previous setting.
────────────────────────────────────────────────────────────────────────────
IMPORTANT
You should be especially cautious when altering "machine-level" values. The
effect of changing a register, flag, or memory location may vary from no
effect at all to crashing the operating system. You can alter most items
from the Watch window; although sometimes it is useful to modify a register
or memory directly.
────────────────────────────────────────────────────────────────────────────
One example of altering memory directly would be to replace values in the AX
register. C functions return their values through this register. By altering
the AX register directly, you can change a returned value without having to
execute the function that returns it.
7.10 Controlling Program Execution
This section describes how you can use CVW to control the execution of your
application.
There are two possible forms of program execution in CodeView for Windows:
Program Execution Description
────────────────────────────────────────────────────────────────────────────
Continuous The program executes until either a
previously specified "breakpoint" has
been reached or the program terminates
normally.
Single-step The program pauses after each line of
code has been executed.
Sections 7.10.1, "Continuous Execution," and 7.10.2, "Single-Step
Execution," explain the most effective way to use each form of execution.
Section 7.10.3, "Jumping to a Particular Location," explains how to force
the system to jump to a particular location in your program. Section 7.10.4,
"Interrupting Your Program," tells you how to interrupt your program.
7.10.1 Continuous Execution
Continuous execution lets you quickly execute bug-free sections of code. The
simplest way to initiate continuous execution is to click the right mouse
button on the line of code you want to debug or examine in more detail. The
program executes at full speed up to the start of this line, then pauses.
You can do the same thing by positioning the text cursor on this line, then
pressing F7.
You can also pause execution at a specific line of code with a breakpoint.
CVW provides you with several types of breakpoints to control your program's
execution. The sections that follow describe how to use breakpoints.
Selecting Breakpoint Lines
You can skip over the parts of the program that you don't want to examine by
specifying one or more lines as breakpoints. The program executes at full
speed up to the first breakpoint, then pauses. Pressing F5 continues program
execution up to the next breakpoint, and so on. You can set as many
breakpoints as you want, provided that you have available memory.
There are several ways to set breakpoints:
■ Double-click anywhere on the desired breakpoint line. The selected
line is highlighted to show that it is a breakpoint. To remove the
breakpoint, double-click on the line a second time.
■ Position the cursor anywhere on the line at which you want execution
to pause. Press F9 to select the line as a breakpoint and highlight
it. Press F9 a second time to remove the breakpoint and highlighting.
■ Display the Set Breakpoint dialog box by choosing Set Breakpoint from
the Watch menu. Choose one of the breakpoint options that permits you
to specify a line (location). The line on which the text cursor
currently rests is the default breakpoint line in the Location field.
If this line is not the location you want, replace it with the line
number where you want the breakpoint. When you type in a new line
number, make sure that you precede it with a period.
A breakpoint line must be a program line that represents executable code.
You cannot select a blank line, a comment line, or a declaration line (such
as a variable declaration or a preprocessor statement) as a breakpoint.
────────────────────────────────────────────────────────────────────────────
NOTE
By default, Microsoft compilers optimize your code. In the process of
optimization, some lines of code may be repositioned or reorganized for more
efficient execution. These changes can prevent CodeView from recognizing the
corresponding lines of source code as breakpoints. Therefore, it is a good
idea to disable optimization during development (use the /Od switch). You
can restore optimization once debugging is completed.
────────────────────────────────────────────────────────────────────────────
A breakpoint can also be set at a function or an explicit address. To set a
breakpoint at a function, simply enter its name in the Set Breakpoint dialog
box. To set a breakpoint at an address, enter the address in CS:IP form.
────────────────────────────────────────────────────────────────────────────
NOTE
If you are debugging more than one application or DLL that share names for
certain window procedures (such as MainWndProc), you can only refer by name
to the procedure that is defined in the first application or DLL.
────────────────────────────────────────────────────────────────────────────
You can remove a breakpoint by selecting it in the Source window and
pressing F9 or the using the Edit Breakpoints screen of the Watch menu. When
your program pauses at a breakpoint, you can continue execution by pressing
F5 or clicking the F5 button in the display.
Setting Breakpoint Values
Breakpoints are not limited to specific lines of code. CVW can also break
execution when an expression reaches a particular value, or just changes
value. Use one of the following methods to set a breakpoint value:
■ To pause execution when an expression changes value, type the name of
the expression in the expression field.
■ To pause execution when a expression reaches a particular value, type
an expression that is usually false in the Expression field of the Set
Breakpoint dialog box.
For example, if you want to pause when a variable called looptest
equals 17, type:
looptest == 17.
Execution will halt when this statement becomes true.
You can also use the Set Breakpoint dialog box to combine value breakpoints
with line breakpoints so that execution stops at a specific line only if an
expression has simultaneously reached a particular value, or changed value.
For large variables (such as arrays or character strings), you can specify
the number of bytes you want checked (up to 32K) in the length field.
────────────────────────────────────────────────────────────────────────────
NOTE
When a breakpoint is tied to a variable, CVW must check the variable's value
after each machine instruction is executed. This computational overhead
slows execution greatly. For maximum speed when debugging, either tie value
breakpoints to specific lines, or only set value breakpoints after you have
reached the section of code that needs to be debugged.
────────────────────────────────────────────────────────────────────────────
Setting Breakpoints on Windows Messages
In the Windows environment, you can also set a breakpoint on a Windows
message or an entire class of Windows messages. This feature lets you track
your application's response to user input and window-management messages.
To set a breakpoint on a Windows message or message class, type the wbm
(Windows Breakpoint Message) command in the Watch window. The syntax for the
command is:
wbm winproc msgname | msgclasses
The winproc parameter is the symbol name or address of an application's
window function. The msgname parameter is the name of a Windows message,
such as WM_PAINT. The msgclasses parameter is a string of characters that
identify one or more classes of messages. The classes are consistent with
those defined in the Windows Spy application; they are:
Message Class Type of Windows Message
────────────────────────────────────────────────────────────────────────────
m mouse
w window management
n input
s system
Message Class Types of Windows Message
────────────────────────────────────────────────────────────────────────────
i initialization
c clipboard
d DDE
z nonclient
For example, if your application is failing to refresh the client area of a
window, you might set a breakpoint on the WM_PAINT message so that you can
watch your program's behavior. The following command will halt execution
whenever the application's MainWndProc function receives a WM_PAINT message:
wbm MainWndProc WM_PAINT
Using Breakpoints
Here are several examples that show how breakpoints can help you find the
cause of a problem.
One of the most common bugs is a for loop that executes too many or too few
times. If you set a breakpoint that encloses the loop statements, the
program pauses after each iteration. With the loop variable or critical
program variables in the Watch or Local windows, you can easily see what the
loop is doing wrong.
You do not have to pause a program the first time you reach a breakpoint.
CVW lets you specify the number of times you want to ignore the breakpoint
condition before pausing. To specify how many times a breakpoint line is
executed:
1. Choose the Set Breakpoint command from the Watch menu.
2. Type the decimal number in the Pass Count field of the dialog box.
For example, suppose your program repeatedly calls a function to create a
binary tree. You suspect that something goes wrong with the process about
halfway through. You could mark the line that calls the function as the
breakpoint, then specify how many times this line is to execute before
execution pauses. Running the program creates a representative (but
unfinished) tree structure that can be examined from the Watch window. You
can then continue your analysis using "single-step" execution, which is
described in the next section.
Another programming error is erroneously assigning a value to a variable. If
you enter a variable in the expression field of the Set Breakpoint dialog
box, execution will break every time the variable changes value. By
evaluating a variable expression, you can halt execution when its value
changes unintentionally.
Breakpoints are a convenient way to pause the program so that you can assign
new values to variables. For example, if a limit value is set by a variable,
you can change the value to see if it affects the program's execution.
Similarly, you can pass a variety of values to a switch statement to see if
they are correctly processed. This ability to alter variables is an
especially convenient way to test new functions without having to write a
stand-alone test program.
When your program reaches a breakpoint and you change a variable, you might
want to watch each step execute while you check the value of that variable.
You can do this with a CVW technique called "single-stepping."
7.10.2 Single-Step Execution
When single-stepping, CVW pauses after each line of code is executed. If a
line contains more than one executable statement, CVW executes all the
statements on the line before pausing. The next line to be executed is
highlighted in reverse video.
You can use either the Step function or the Trace function to single-step
through a program. Step does not display each function call as the program
executes. All the code in the function is executed; but the function appears
to execute as a single step. To use Step, press F10. Trace displays each
step of every function for which CVW has symbolic information. Each line of
the function is executed as a separate step. To use Trace, press F8. (CVW
has no symbolic information about run-time functions; therefore, they are
executed as a single step.) You can alternate between Trace and Step as you
like. The method you use depends on whether you want to see what happens
within a particular function.
You can trace through the program continuously, without having to press F8,
by choosing the Animate command from the Run menu. The speed of execution is
controlled by the Trace Speed command from the Options menu. You can halt
animated execution at any time by pressing any key.
────────────────────────────────────────────────────────────────────────────
NOTE
Attempting to step or trace through Windows start-up code while viewing
assembly-language listing will cause unpredictable results. To step through
your program while viewing assembly-language instructions, first set a
breakpoint at the WinMain function and begin stepping through the program
only after the breakpoint has been reached.
────────────────────────────────────────────────────────────────────────────
7.10.3 Jumping to a Particular Location
At times you may wish to force the system to jump to a particular location
in your program during execution. For example, you might want to avoid
executing code that you know has bugs, or you might want to repeatedly
execute a particularly troublesome portion of your program.
To jump to a specific location in your application:
1. Choose the Source command from the Options menu and select the Mix
Source and Assembly and the Show Machine Code options.
2. In the Source window, view the line of source code to which you want
to jump.
3. Examine the code offset of the first machine instruction for the
assembled statement.
4. Use the rip (Register IP) command to change the IP register to this
code offset, supplying the value as a hexadecimal number.
CVW highlights the line to which you have jumped.
────────────────────────────────────────────────────────────────────────────
IMPORTANT
Do not jump from one procedure to another. Jumping from one procedure to
another disrupts the stack.
When jumping to a specific point in your application, remember that
assembled source code for a given statement may rely on memory values and
registers set in previous instructions that you have skipped. This is
particularly true if you have not disabled optimization by compiling the
source module using the -Od option.
────────────────────────────────────────────────────────────────────────────
7.10.4 Interrupting Your Program
There may be times when you want to halt your program immediately. You can
force an immediate interrupt of a CVW session by pressing
CONTROL+ALT+SYSREQ. You then have the opportunity to change debugging
options, such as adding breakpoints and modifying variables. To resume
continuous execution, just press F5; to single-step, press F10.
You should take care when you interrupt the CVW session. For example, if you
interrupted the session while Windows code or other system code was
executing, attempting to use the Step or Trace functions will produce
unpredictable results. When you interrupt the CVW session, it is usually
safest to set breakpoints in your code and then resume continuous execution,
rather than using Step or Trace.
An infinite loop in your code presents a special problem. Again, since you
should avoid using Step or Trace after interrupting your program, you should
try to locate the loop by setting breakpoints in places you suspect are in
the loop.
Whether or not you locate the infinite loop, you will have to terminate your
application. The wka (Windows Kill Application) command terminates the
currently executing task. Since this task is not necessarily your program,
you should use the wka command only when your application is the currently
executing task.
If your application is the currently executing task and is executing a
module containing symbol information, the CVW Source window will highlight
the current instruction. However, if your application contains modules that
were not compiled with the /Zi option, it will be more difficult to
determine whether the assembly-language code displayed in the Source window
belongs to your application or to another task. In this case, use the wdg
(Windows Dump Global Heap) command, supplying the value in the CS register
as the parameter. CVW will display a listing that will indicate whether the
code segment belongs to your application. If it does, you can use the wka
command without affecting other tasks. However, the wka command does not
perform all the cleanup tasks associated with the normal termination of a
Windows application. For example, GDI objects created during the execution
of the program but not destroyed before you terminated the program will
remain allocated in the system-wide global heap. This will reduce the amount
of memory available during your Windows session. Because of this, you should
use the wka command to terminate the application only if you cannot
terminate it normally.
────────────────────────────────────────────────────────────────────────────
NOTE
The wka command simulates a fatal error in your application. Because of
this, when you use the wka command, Windows displays an "Unexpected
Application Error" message box.
After you close this message box, Windows may not release subsequent mouse
input messages from the system queue until you press a key. If this happens,
the cursor will move on the Windows screen, but Windows will not appear to
respond to the mouse. After you press any key, Windows will then respond to
all mouse events that occurred before you pressed the key.
────────────────────────────────────────────────────────────────────────────
7.11 Handling Abnormal Termination of the Application
Your application can terminate abnormally in one of two ways while you are
debugging it with CVW. It can cause a fatal exit, or it can cause a GP
fault. In both cases, CVW regains control, giving you the opportunity to
examine the state of the system when your application terminated. In
particular, you can often determine the location in your application's code
where the error occurred, or which call caused the error. CVW allows you to
view registers, dump the global heap, display memory, and examine the source
code.
Once you have determined where the error occurred, use the q command to
terminate CVW. In most cases, control will return to Windows.
7.11.1 Handling a Fatal Exit
If the abnormal termination was a fatal exit, and the application was
running with the retail version of Windows, the CVW Command window displays
the following:
Trap 13 (0DH) -- General Protection Fault.
The CS:IP register contains an address in the Windows code itself. This
small amount of information provides little to help you locate the last call
that your application made before the error was detected.
If, however, your application was running with the debugging version of
Windows, the CVW Command window displays a stack trace that is much more
useful for finding the error in your source code.
After the stack trace appears in the CVW Command window, Windows displays
this prompt:
Abort, Break, or Ignore?
To locate the cause of the error, press B. This allows CVW to regain control
from Windows.
In most cases, the stack trace will have scrolled off the top of the CVW
Command window, but once CVW regains control, you can scroll it back to
examine the entire stack trace. The following information appears at the top
of the stack trace:
■ A fatal exit number. See the Reference, Volume 2, for a listing of the
possible fatal exit numbers.
■ The CS:IP address or the name of the Windows function where the error
was detected, or the name of the last Windows function called before
the error was detected.
Following this information, additional Windows functions might be listed in
the stack trace. Somewhere near the top of the stack trace a CS:IP address
will be listed without a Windows function name. In most cases, this is the
location in the source code of your application where the call to a Windows
function occurred that triggered the fatal exit.
To examine this location in your source code, open a Source window if
necessary and use the v command followed by the CS:IP address, being sure to
precede both the segment and the offset with the "0x" hexadecimal prefix.
For example, if CVW indicates that the error occurred at 07DA:0543 in your
application, enter the following command:
v 0x07DA:0x0543
If you had compiled the module where the error occurred using the C Compiler
-Zi option, the CVW Source window displays the location in your code where
the errant call to a Windows function occurred.
The first CS:IP address without a name in the stack trace may point to a
location in your code without symbols. For example, the code might be in a
DLL you didn't specify with the /L command-line option or at the CVW prompt.
Or the address might be in a module that you did not compile with the -Zi
option. In such cases, CVW reports that no source code is available. If this
happens, continue down the stack trace, using the v command with each
unnamed CS:IP address. You likely will find a location in a module that was
compiled with the -Zi option, and this location might have made a call into
one of your modules which you did not compile using the -Zi option.
Section 7.16, "A Sample Session in CVW," shows a sample fatal-exit stack
trace and how to use that information to locate an error.
7.11.2 Handling a GP Fault
When a GP fault occurs, CVW displays a message in the Command window to
notify you of the event. If the GP fault occurred at an instruction in one
of your modules, CVW displays the corresponding source code if it had been
compiled using the -Zi option. You can obtain information about the chain of
calls leading up to the GP fault using the CVW Call menu. This displays a
backtrace of calls in the form of a series of segments and offsets, starting
at the most recent call.
If your application was running with the debugging version of Windows, the
backtrace will show window function names next to some of the segment/offset
pairs. By examining the window function names, you might be able to
determine where in your code the error occurred.
7.12 Ending a CVW Session
To terminate a CVW session, use the Exit command in the File menu, or type
the q (Quit) command in the Command window.
7.13 Restarting a CVW Debugging Session
You can terminate your application without terminating CVW. While Windows is
terminating the application, it will notify CVW, and CVW will display the
following message:
Program terminated normally (0)
The value in parentheses is the return value of the WinMain function. This
value is usually the wParam parameter of the WM_QUIT message, which in turn
is the value of the nExitCode parameter passed to the PostQuitMessage
function.
If you were debugging more than one application or DLL, you can then use the
go command to continue the debugging session. You can also restart the
application you just terminated by using the go command and then restarting
your application through Windows File Manager or Program Manager.
7.14 Advanced CVW Techniques
Once you are comfortable displaying and changing variables, and controlling
the program's execution, you might want to experiment with the following
advanced techniques:
■ Using multiple Source windows
■ Calling functions
■ Checking for undefined pointers
■ Handling register variables
■ Redirecting CodeView input and output
7.14.1 Using Multiple Source Windows
You can have two Source windows open at the same time. The windows can
display two different sections of source code for the same program. They can
both track CS:IP addresses; or, one can display a high-level listing and one
can display an assembly-language listing. You can move freely between the
Source windows, executing a single line of source code or a single assembly
instruction at a time.
7.14.2 Calling Functions
You can call any C function in your program from the Command window or the
Watch window. The format for calling C functions is:
?funcname (varlist)
CVW evaluates the function and displays its returned value in the Command
window.
The function does not have to be one that is called by your program. You can
evaluate any function that is included in the .OBJ parameters specified on
the LINK command line.
This feature allows you to run functions from within CVW that you would not
normally include in the final version of your program. For example, you
could call a function that checks the integrity of the data structure.
────────────────────────────────────────────────────────────────────────────
NOTE
Directly calling a Windows application procedure or dialog function might
have unpredictable results.
────────────────────────────────────────────────────────────────────────────
7.14.3 Checking for Undefined Pointers
Until a pointer has been explicitly assigned a value, its value is
undefined. Its value can be completely random, or it can be some consistent
value that does not point to a useful data address (such as -1).
Accessing a value through an uninitialized pointer address can cause
inexplicable or erratic program behavior, because the data is not being read
from or written to the intended location. For example, suppose that var1 is
mistakenly written to the address specified by an uninitialized pointer,
then var2 is also written there. When var1 is read back it does not have its
original value, having been overwritten by var2.
At present, all Microsoft C static or global near pointers have an
uninitialized value of 0. That is, they point to the base address of the
data segment. (There is no guarantee, however, that future versions of the
Microsoft C Compiler will be the same; C language specifications do not
define the value of an uninitialized pointer.)
You can take advantage of this consistency. If you specify DS:0 as a
breakpoint expression, CVW automatically halts execution if your program
attempts to write a nonzero value to a null pointer address. This is an easy
way to see whether or not you have initialized all of your pointers.
7.14.4 Handling Register Variables
A register variable is stored in one of the microprocessor's registers,
rather than in RAM. This speeds up access to the variable.
There are two ways for a conventional variable to become a register
variable. One way is declaring the variable as a register variable. If a
register is free, the compiler will store the variable there. The other way
occurs during optimization, when the compiler stores an often-used variable
(such as a loop variable) in a register to speed up execution.
Register variables can cause problems when debugging. As with local
variables, they are only visible within the function where they are defined.
In addition, a register variable might not always be displayed with its
current value.
In general, it is a good idea to turn off all optimization (using the /Od
option when compiling) and to avoid declaring register variables until the
program has been fully debugged. Any side effects produced by optimization
or register variables can then be easily isolated.
7.14.5 Redirecting CVW Input and Output
You can cause CVW to receive input from an input file and generate output to
an output file. To redirect CVW input and output, use the CVW start-up
command with the /C option as follows:
CVW /c "<infile; t >outfile" myprog
When you redirect input, CVW will execute any commands in infile during
start-up. When CVW exhausts all commands in the input file, focus
automatically shifts to the Command window.
When you redirect output, it is both sent to outfile and echoed to the
Command window. The t parameter must precede the > in the command to send
output to the Command window.
Redirection is a useful way to automate CVW start-up. It also lets you keep
a viewable record of command-line input and output, but no record of mouse
operations. Some applications (particularly interactive ones) may need
modification to allow for redirection of input to the application itself.
7.15 Customizing CVW with the TOOLS.INI File
The TOOLS.INI file customizes the behavior and user interface of several
Microsoft products. The TOOLS.INI file is a plain ASCII text file. You
should place it in a directory pointed to the INIT environment variable. (If
you do not use the INIT environment variable, CodeView for Windows only
looks for TOOLS.INI in its source directory.)
The CodeView for Windows section of TOOLS.INI is preceded by the following
line:
[cvw]
Most of the TOOLS.INI customizations control screen colors, but you can also
specify start-up commands or the name of the file that receives CodeView for
Windows output. The Help system contains full information about all of the
TOOLS.INI switches for CVW.
7.16 A Sample Session in CVW
The following sample session demonstrates how to use the CVW debugger to
examine a Windows application. The session will use the SDK sample
application called Output, which writes text and draws three shapes─a
rectangle, an ellipse, and a dashed semicircle─on the screen.
Before you begin the CVW session, you must prepare the Output application
for debugging. Compile and link the Output make file after you make the
following changes to the CL and LINK commands:
1. Add the -Zi option to CL command by changing -Zpe to -Zpei, and add
the -Od option:
CL -c -Gsw -Oas -Zpei -Od OUTPUT.C
2. Add the -Co option to the LINK command:
LINK OUTPUT,,,/NOD /CO SLIBCEW LIBW, OUTPUT.DEF
After you compile with these options, start Windows and then start a CVW
session for Output. See Section 7.4, "Starting a Debugging Session," for
more information about starting CVW. To start the CVW session:
1. Choose Run from the File menu in Windows and type the following
command in the Run dialog box:
CVW
The debugging monitor displays the CVW Start-up dialog box.
2. Type the application name in the CVW Start-up dialog box:
OUTPUT
Your debugging monitor displays the DLL dialog box.
3. In this session, you will not be debugging additional DLLs, so leave
the command line blank and press ENTER.
The CVW menu, the Source window, the Command window, and the Local window
appear on the debugging monitor. The Source window displays the source code
for Output. Notice its title:
source1 CS:IP output.c (ACTIVE)
The title indicates that the Source window is the active, or selected,
window.
Before you start executing the application, set a breakpoint in your source
code. For example, you could halt Output after it displays text on the
user's screen, but before it draws the rectangle. You know that Output will
draw the rectangle in response to a Windows WM_PAINT message, so use the
Find command to scan the source code for WM_PAINT. To search for this
message:
1. Choose the Find option from the CVW Search menu.
CVW displays the Find dialog box.
2. Type the following on the command line:
WM_PAINT
Select the Match Upper/Lower Case checkbox; press ENTER.
CVW finds the first occurrence of "WM_PAINT" in a comment. This is not
the location you want. To continue the search:
3. Choose the Repeat Last Find option from the Search menu.
This time the Source window displays the case WM_PAINT: statement.
This is the location you were looking for.
Within this case statement, find the Rectangle function. Scroll downward
through the Source window until you see the following code:
Rectangle (
hDC
,nDrawX
,nDrawY
,nDraw + 50
,nDraw + 30
);
Notice that the statement is spread over several lines. To set a breakpoint
on a multiline statement, you must position the cursor on the last line of
the statement. If you try to set a breakpoint on any other line, CVW will
not accept it. To set a breakpoint on this statement:
1. Click the ");" characters─the last line of the statement.
The blinking cursor is now on this line.
2. Choose the Set Breakpoint command on the Options menu, or press F9.
CVW displays the line in bold characters to indicate that it is a
breakpoint. Also, the Command window displays the following message:
Break at: output.c!.297
You have two ways to display a list of the breakpoints:
■ You can use the bl command. In the Command window, type:
bl
The Command window will display a list of the breakpoint messages.
■ You can use the Edit Breakpoints command on the Watch menu. The
Breakpoint dialog box will display a list of breakpoint messages.
The message for the breakpoint you just set is:
0) E output.c!.297
The following table uses this message to illustrate the format for CVW
breakpoint messages:
Message Content What it Means
────────────────────────────────────────────────────────────────────────────
0) Indicates the sequence number of the
breakpoint in the Source Code. This is
the first breakpoint.
E Indicates that the breakpoint is
Enabled.
output.c!.297 Indicates that the breakpoint is set on
line number 297 of the OUTPUT.C source
code file.
When you are ready to execute the Output application, click in the Command
window and type the go command at the prompt:
g
The Output application will start running and displaying the text on the
user's screen (the Windows monitor). While the application is running,
Windows has control of the session. When the application reaches the
breakpoint line, CVW takes control and halts the application before the line
is executed. Notice that the CVW Source window displays the breakpoint line
in reverse video to indicate where the application has stopped.
At this point, CVW has control of the session. You can use the CVW menus and
commands to display values, edit breakpoints, or otherwise modify your
debugging session.
Instead of resuming continuous execution, single-step through the
application as it draws the rectangle on the Windows screen. To execute a
single statement, press F10. The Output application draws a rectangle on the
screen and then stops. The CVW Source window displays the next statement of
code in reverse video:
SelectObject(hDC, hGreenBrush);
Single-step through the next several statements by pressing F10. As you
single-step, the Output application draws each shape on the Windows screen
and then Windows passes control of the session back to CVW. You can resume
continuous execution at any time by pressing F5.
When the application is finished executing, it passes control back to CVW.
To terminate CVW, select the Quit option from the File menu.
If the application is running and you want to interrupt it and terminate
execution:
1. Press CONTROL+ALT+SYSREQ.
2. Select the Quit command from the File menu in CVW.
You will be returned to Windows. Your application will continue to run.
To see how CVW handles a fatal exit, you will need to introduce a severe
error into the code of Output. Replace the hDC parameter of the DrawText
function in the WM_PAINT case statement of MainWndProc with (HDC)0.
Recompile the application and run CVW to debug the application.
When the debugging version of Windows reaches the call to DrawText, it
detects an invalid display-context handle and displays in the CVW Command
window a stack trace similar to the following:
FatalExit code = 0x0000
Stack trace:
GDI!_TEXT:VALIDATEHANDLE+0046
GDI!_TEXT:GSV+0018
USER!_WMG:DRAWTEXT+000D
0A35:03E9
USER!_FFFE:INTRNALUPDATEWINDOW+0033
USER!_FFFE:UPDATEWINDOW+0019
0A35:011E
0A35:0031
0A35:0629
Abort, Break, or Ignore?
The fatal exit code value 0x0000 indicates that an invalid handle was passed
to a GDI function. See the Reference, Volume 2 for a complete list of fatal
exit codes.
To locate the cause of the error in your source code, respond to the prompt
by pressing B. CVW will then display:
Break caused by INT3 in code
Find the first CS:IP address without a label. In this case, it is 0A35:03E9.
Use the v command with this address, remembering to add the 0x hexadecimal
prefix, as shown:
v 0x0A35:0x03E9
CVW will display source code similar to the following:
DrawText (
(HDC)0
, szText
, strlen(szText)
, &rcTextBox
, DT_CENTER |DT_EXTERNALLEADING | DT_NOCLIP
| DT_NOPREFIX | DT_WORDBREAK
);
This is the function call that you changed to cause the fatal exit.
7.17 Summary
CodeView for Windows is a tool that lets you debug Windows applications in
protected mode. With CVW running on your secondary monitor, you can view and
modify program data, and control execution, as you run your Windows
application.
For information related to CodeView for Windows, see the following:
Topic Reference
────────────────────────────────────────────────────────────────────────────
Programming Windows applications Guide to Programming
System requirements Installation and Update Guide
Fatal exit codes Reference, Volume 2: Appendix C,
"Windows
Debugging Messages"
CVW commands CVW on-line Help
Chapter 8 Debugging in Real Mode: Symbolic Debugger
────────────────────────────────────────────────────────────────────────────
Microsoft Windows Symbolic Debugger (SYMDEB) is a debugging program that
helps you test executable files for applications that run in real mode. To
debug applications that run in protected mode, use the Microsoft CodeView
for Windows (CVW) debugger. For information on CVW, see Chapter 7,
"Debugging in Protected Mode: CodeView for Windows."
SYMDEB lets you refer to data and instructions by name rather than by
address. The Symbolic Debugger can access program locations through
addresses, global symbols, or line-number references, making it easy to
locate and debug specific sections of code. You can debug C programs at the
source-file level as well as at the machine level. You can display the
source statements of a program, the disassembled machine code of the
program, or a combination of source statements and disassembled machine
code.
Using SYMDEB, you can display and execute program code, set breakpoints that
stop the execution of your program, examine and change values in memory, and
debug programs that use the floating-point emulation conventions used by
Microsoft languages.
This chapter describes the following topics:
■ Preparing symbol files for an application
■ Setting up the debugging terminal
■ Starting SYMDEB with Windows
■ Working with symbol maps
■ Interpreting SYMDEB's allocation messages
■ Setting breakpoints and interpreting backtraces
■ Displaying the application's code and viewing its source file
The chapter also provides the syntax and description of each SYMDEB command.
────────────────────────────────────────────────────────────────────────────
NOTE
To use the Symbolic Debugger, you must have an extra monochrome card or a
serial terminal, or both.
────────────────────────────────────────────────────────────────────────────
8.1 Preparing Symbol Files
Windows applications are difficult to debug without symbolic information
about Windows and the application. To take advantage of the Symbolic
Debugger's symbolic features, first prepare a symbol file that SYMDEB can
use.
The steps for setting up a symbol file depend on the method used to create
the program. The following sections describe those steps for applications
written in C or assembly language.
8.1.1 MAPSYM Program
The MAPSYM program creates symbol files for symbolic debugging. The program
converts the contents of an application's symbol map (.MAP) file into a form
suitable for loading with SYMDEB, copying the result to a symbol (.SYM)
file.
Syntax
mapsym «{/ | -}l» «{/ | -}n» mapfilename
Parameter Description
────────────────────────────────────────────────────────────────────────────
mapfilename Specifies the filename for a symbol map
file that was created during linking. If
you do not give a filename extension,
.MAP is assumed. If you do not give a
full pathname, the current directory and
drive are assumed. The MAPSYM program
creates a new symbol file having the
same name as the map file but with the
.SYM extension.
/l Directs MAPSYM to display information
about the conversion on the screen. The
information includes the names of groups
defined in the program, the program
start address, the number of segments,
and the number of symbols per segment.
/n Directs MAPSYM to ignore line-number
information in the map file. The
resulting symbol file contains no
line-number information.
In the following example, MAPSYM uses the symbol information in FILE.MAP to
create FILE.SYM on the current drive and directory:
mapsym /l file.map
Information about the conversion is sent to the screen.
────────────────────────────────────────────────────────────────────────────
NOTE
The MAPSYM program always places the new symbol file in the current drive
and directory.
To create a map file for MAPSYM input, you must specify the /map option when
linking. To add line-number information to the map file, specify the
appropriate option when compiling, and specify the /linenumbers option when
linking.
The MAPSYM program can process up to 10,000 symbols for each segment in the
application, and up to 1024 segments.
────────────────────────────────────────────────────────────────────────────
8.1.2 The Incremental Linker
Microsoft C version 6.0 includes , the incremental linker (ILINK). ILINK
directly creates .SYM files for use by the Symbolic Debugger (SYMDEB). If
you use ILINK to link your files and create .SYM files, you do not have to
use MAPSYM.
For more information on ILINK, see the Microsoft C Optimizing Compiler
version 6.0 documentation.
8.1.3 Symbols with C-Language Applications
To prepare a symbol file for an application written in the C language,
follow these steps:
1. Compile your source file using the -Zd option to produce line numbers
in the object file.
Debugging is easier if you disable the compiler's optimization using
the -Od option.
2. Link the object file to produce an executable version of the program
by specifying a map filename in the linker's command line and giving
the /map and /linenumbers options.
Make sure the map filename is the same as the application's module
name given in the module-definition file.
3. Use the MAPSYM program to produce a symbol file. For information about
using MAPSYM, see Section 8.1.1, "MAPSYM Program."
The following example shows how to use symbols with C-language applications:
cl -d -c -AS -Gsw -Od -Zdp test.c
link test,test,test/map/li,/NOD slibcew slibw, test
mapsym test
8.1.4 Symbols with Assembly-Language Applications
To prepare symbol files for Windows applications written in assembly
language, follow these steps:
1. Make sure that all symbols you might want to use with SYMDEB are
declared public.
Segment and group names should not be declared public. They are
automatically available for debugging.
2. Assemble your source file.
3. Link the object file to produce an executable version of the
application by specifying a map filename in the linker's command line
and giving the /map option.
Make sure the map filename is the same as the application's module
name given in the module-definition file.
4. Use the MAPSYM program to create a symbol file. For information about
using MAPSYM, see Section 8.1.1, "MAPSYM Program."
The following is an example of the syntax used when preparing symbol files,
written in assembly language, for debugging:
masm test;
link test,test,test/map,slibw slibc libh,test
mapsym test
8.2 Setting Up the Debugging Terminal
While it is running, Windows takes complete control of the system console,
making debugging through the console impossible. To debug Windows
applications, you can either set up a remote terminal connected through the
computer's serial port, or set up a secondary monochrome display adapter and
monitor.
8.2.1 Setting Up a Remote Terminal
To set up a remote terminal for debugging, follow these steps:
1. Select a serial port on your computer and connect a terminal to it.
2. Use the DOS MODE command to set the baud rate and line protocol of the
serial port to correct values for use with the terminal.
Line protocol includes the number of stop bits, type of parity
checking, and number of transmission bits used by the terminal.
3. When you start the Symbolic Debugger, redirect its input and output to
the remote terminal using the = = command to specify a communication
port.
For example, the following command redirects all subsequent SYMDEB
command input and output to COM2:
== com2
────────────────────────────────────────────────────────────────────────────
NOTE
Debugging through a remote terminal disables the normal function of the
CONTROL+S key combination. Do not use this key combination while debugging
Windows
8.2.2 Setting Up a Secondary Monitor
To set up a secondary monitor for debugging, follow these steps:
1. Install a secondary monochrome display adapter in a free slot of your
computer and connect the monochrome monitor to it.
2. Set the secondary display adapter switches to the appropriate
settings.
Follow the display adapter and computer manufacturer's
recommendations.
3. When you start the Symbolic Debugger, use the /m option to redirect
SYMDEB output to the secondary monitor.
NOTE When the /m option is given, the Symbolic Debugger redirects
output to the secondary monitor, but continues to use the system
keyboard for input until the application being debugged is started.
While the application is running, SYMDEB yields complete control of
the keyboard to the application. As soon as the application reaches a
breakpoint or terminates, SYMDEB reclaims the keyboard and permits
user input again.
8.3 Starting SYMDEB with Windows
To start the Symbolic Debugger with Windows, enter the following SYMDEB
command line at the DOS command prompt:
SYMDEB «options» «symbolfiles» WIN.COM /R «arguments»
The options parameter specifies one or more SYMDEB options. The symbolfiles
parameter specifies the names of symbol files. The arguments parameter
specifies arguments that you want to pass to WIN.COM.
If you want additional symbolic information about Windows, add the full
pathname of the debug, the nondebug, or the kernel version of the symbol
file, as in the following example:
... ,APP.SYM\WM\DEBUG\GDI.SYM
Once started, the Symbolic Debugger displays a start-up message followed by
the SYMDEB command prompt (-). When you see the prompt you can enter SYMDEB
commands. These commands are described in Section 8.9, "SYMDEB Commands."
────────────────────────────────────────────────────────────────────────────
NOTE
To set breakpoints in discardable library code in a large frame EMS
environment, add the following entry to the [kernel] section of WIN.INI:
────────────────────────────────────────────────────────────────────────────
[Kernel]
EnableEMSDebug=1
Adding the entry will slow down debugging.
The following section describes the elements of the SYMDEB command line.
8.3.1 Specifying SYMDEB Options
You can specify one or more SYMDEB options in the command line. These
options control the operation of the Symbolic Debugger. Options must appear
before WIN.COM on the command line so that SYMDEB will not interpret them as
program arguments.
The SYMDEB tool has the following command-line options:
Option Meaning
────────────────────────────────────────────────────────────────────────────
/m Redirects SYMDEB output to a secondary
monochrome monitor and permits debugging
of Windows applications without
redirecting input and output to a remote
terminal. The SYMDEB utility assumes
that the necessary display adapter and
monitor are
installed.
/x Disables the "more" feature. Unless this
option is specified, the Symbolic
Debugger automatically stops lengthy
output and does not continue the display
until the user presses a key. The SYMDEB
utility stops the output after
displaying enough lines to fill the
screen, then prompts the user to
continue by displaying the message
"[more]". If this option
is specified, the Symbolic Debugger
continues to
display output until the command is
completely
executed.
Option Meaning
────────────────────────────────────────────────────────────────────────────
/wnumber Sets the memory-allocation reporting
level. The reporting level defines what
kind of memory allocation and movement
messages the Symbolic Debugger will
display when Windows loads and moves
program segments. The number parameter
specifies the reporting level and can be
0, 1, 2, or 3. Level 0 specifies no
reporting. Level 1, the default level if
the /w option is not given, generates
allocation messages only. Level 2
generates movement messages only. Level
3 generates both allocation and movement
messages. See Section 8.6, "Displaying
Allocation Messages," for more
information about allocation messages.
/@filename Directs the Symbolic Debugger to load
macro definitions from the file
specified by filename. Macro definitions
define the meaning of the debugger's 10
macro commands. The given file must
contain one or more macro definitions in
the following form:
mnumber=command-string
Specifies the macro and one or more
SYMDEB commands. The number parameter
specifies the macro; the command-string
parameter specifies commands.
/n Permits use of nonmaskable interrupts on
non-IBM computers. To use nonmaskable
interrupts, you must have a system that
is equipped with the proper hardware,
such as the following products:
■ IBM Professional Debugging Facility
■ Software Probe (Atron Corporation)
The SYMDEB utility requires only the
hardware provided with these products;
no additional software is needed. If you
are using one of these products with a
non-IBM system, you must use the /n
option to take advantage of the break
capability. Using a
nonmaskable-interrupt break system is
more reliable than using the interactive
break key because you can always stop
program execution regardless of the
state of interrupts and other conditions.
Option Meaning
────────────────────────────────────────────────────────────────────────────
/i«bm» Directs the Symbolic Debugger to use
features available on IBM-compatible
computers. The option is not necessary
if you have an IBM PC, because SYMDEB
automatically checks the hardware on
start-up. If SYMDEB does not find that
the hardware is an IBM PC, it assumes
that the hardware is a generic DOS
machine. Without this option, the
Symbolic Debugger cannot take advantage
of special hardware features such as the
IBM 8259
Interrupt Controller, the IBM-style
video display, and other capabilities of
the IBM basic input and
output system (BIOS).
/ffilename Prevents association of the named symbol
file with the executable file that has
the same name. This option is rarely
used and is not recommended for
debugging Windows applications.
/commands Directs the Symbolic Debugger to execute
commands in the commands list
immediately after starting. Commands in
the list must be separated with
semicolons and the entire list must be
enclosed in double quotation marks. The
slash (/) is required.
────────────────────────────────────────────────────────────────────────────
NOTE
You can specify a hyphen instead of a slash for the option designator. You
can also use both uppercase and lowercase letters to specify the option.
Files containing a hyphen in the filename must be renamed before use with
SYMDEB. Otherwise, SYMDEB will interpret the hyphen as an option designator.
────────────────────────────────────────────────────────────────────────────
8.3.2 Specifying Symbol Files
To debug a Windows application symbolically, you should load symbol files
for the following items:
■ The application
■ Windows kernel, user, and GDI (graphics device interface) libraries
■ Other Windows libraries used by the application
The symbol file for the application is not required. The symbol files for
the Windows libraries are optional, but recommended. They are helpful when
trying to trace calls made to routines that are not in the application or to
trace window messages.
You must give the complete filename and extension when naming a symbol file.
If the symbol file is not in the current directory, you must supply a full
pathname. All symbol files must be specified before the WIN.COM file.
You should always name the application's symbol file before any other symbol
files.
The following example shows how to specify a symbol file:
SYMDEB \APP\TEST.SYM USER.SYM GDI.SYM \APP\TESTLIB.SYM WIN.COM /R
────────────────────────────────────────────────────────────────────────────
NOTE
The Windows symbol files for the kernel, user, and GDI libraries, WIN.COM,
USER.SYM, and GDI.SYM, are provided as part of the Microsoft Windows
Software Development Kit (SDK).
You can create symbol files for other Windows libraries by using the same
methods you used to create application symbol files.
────────────────────────────────────────────────────────────────────────────
8.3.3 Passing the Application to Windows
You can pass the name of your application to Windows by placing the full
pathname on the SYMDEB command line immediately after the WIN.COM filename.
Windows receives the name as an argument when you start WIN.COM from within
SYMDEB. Windows uses the name to load and run the application.
The following example shows how to pass an application to Windows:
SYMDEB \APP\TEST.SYM WIN.COM /R \APP\TEST.EXE
If you do not supply your application's name as an argument, you can load
and start your application by starting WIN.COM and using the Windows shell
to load the application.
8.3.4 Using SYMDEB Keys
The Symbolic Debugger provides a number of special keys for controlling
input and output and program execution. The following is a list of these
keys:
Key Action
────────────────────────────────────────────────────────────────────────────
SCROLL LOCK Suspends and restores SYMDEB output. The
key is typically used to temporarily
stop the output of lengthy displays. To
suspend output, press SCROLL LOCK. To
restore output, press the key again.
CONTROL + SYSREQ Generates an immediate breakpoint that
halts program execution and returns
control to the Symbolic Debugger.
(Available on the IBM PC/AT(R) only.)
Key Action
────────────────────────────────────────────────────────────────────────────
CONTROL + C Cancels the current SYMDEB command. This
key combination does not apply to
commands that pass execution control to
the application being debugged.
8.4 Working with Symbol Maps
Symbol files that the Symbolic Debugger has loaded for debugging are called
symbol maps. The Symbolic Debugger utility lets you examine symbol maps and
use the symbols in the maps to set breakpoints and display variables and
functions.
Although symbol maps are in memory, SYMDEB allows access to only one symbol
map at a time. You can display a list of symbol maps at any time, but to
display or use the symbols in a map, you must first open that map.
────────────────────────────────────────────────────────────────────────────
NOTE
The Symbolic Debugger requires that the filename of the application's .SYM
file be the same as the application's module name (specified in the
application's module-definition file). If these names are not identical, the
Symbolic Debugger will not be able to determine the correct segment
addresses for symbols in the application.
────────────────────────────────────────────────────────────────────────────
8.4.1 Listing the Symbol Maps
You can display a list of the symbol maps by using the x command with the
asterisk (*) argument. The command displays the names of all maps in memory,
the name of each segment belonging to a map, and the 16-bit paragraph
address of each segment. (The x command without an argument displays only
the open map.)
For example, type the following to display a list of the symbol maps:
-x *
The resulting list could look like the following:
[ 0000 TEST ]
[ 0001 IGROUP ]
0002 DGROUP
0000 TESTLIB
0001 _TEXT
0002 DGROUP
The open map name is enclosed in brackets ([ ]). The active segment in the
map is also enclosed in brackets. Segment addresses appear immediately
before the segment names.
────────────────────────────────────────────────────────────────────────────
NOTE
The Symbolic Debugger does not display a segment's actual address until the
code or data corresponding to that segment has been loaded. If you list the
symbol maps before loading an application, SYMDEB displays low-memory
addresses as a warning that the segments are not yet in memory.
────────────────────────────────────────────────────────────────────────────
Once an application is loaded, SYMDEB appends a number to the end of the
data-segment name in the symbol map. This number shows which instance of the
application the data segment belongs to. If you load multiple instances of
an application, SYMDEB adds a new data-segment name to the symbol map for
that application.
In the following example, SYMDEB places parentheses around the active data
segment to show which instance of the application is currently running:
[ 0000 TEST ]
[ 88F0 IGROUP ]
( 87E0 DGROUP )
8944 DGROUP1
8.4.2 Opening a Symbol Map
To access the symbols in a symbol map, you must open the symbol map using
the xo command. For example, to open the symbol map named TEST, you would
type the following:
-xo test!
The Symbolic Debugger opens the symbol map and lets you examine and use
symbols from the map.
You can use the xo command to open a different symbol map at any time.
8.4.3 Displaying Symbols
You can use the x? command to display the symbols in the open symbol map.
The command lists each symbol by name and also gives the symbol's address
offset. For example, to display the symbol TestWndProc, type the following:
-x? testwndproc
The command displays the name and address of the segment to which the symbol
belongs, as in the following example:
[ 88E0 IGROUP ]
005A TESTWNDPROC
The symbol's absolute address can be computed using the segment's address
and the symbol's offset. In the preceding example, the function TestWndProc
is in the segment IGROUP at address 88E0:005A.
If the symbol is an external symbol (for example, a function or variable
defined outside of the application), no group name is given and the offset
is always zero, as shown in the following example:
0000 SHOWWINDOW
You can use the asterisk (*) as a wildcard character with the x command to
display more than one symbol at a time. For example, the following command
displays all symbols in the IGROUP segment:
-x? igroup:*
The following command displays all symbols in the DGROUP segment that begin
with an underscore (_):
-x? dgroup:_*
8.5 Starting the Application
You can start the application by using the g command. The command directs
the Symbolic Debugger to pass execution control to the program at the
current code address. (Immediately after starting SYMDEB with Windows, the
current code address is the start address of the WIN.COM. file.)
If you have supplied your application's filename as a WIN.COM argument on
the SYMDEB command line, WIN.COM starts your application automatically.
Otherwise, it starts the Windows shell, which will load and run your
application.
8.6 Displaying Allocation Messages
The Symbolic Debugger displays memory-allocation messages to show that
Windows has created, freed, or moved memory blocks. The messages are
intended to help you locate your application's program code and data in
memory. The messages can also be used to see the effect of the application
on Windows memory management. The Symbolic Debugger actually displays
messages only if the memory-allocation reporting level is set to an
appropriate value (see the /w option in Section 8.3.1, "Specifying SYMDEB
Options").
When Windows allocates a new block of memory and the reporting level is 1 or
3, the Symbolic Debugger displays a message of the following form:
module-name!segment-name=segment-address
The module-name field specifies the name of the application or library to
receive the allocated memory. The segment-name field specifies the name of
the code or data segment within the application or library that will occupy
the memory block. The segment-address field specifies the 16-bit paragraph
address of the memory block.
When Windows moves a block of memory and the reporting level is 2 or 3, the
Symbolic Debugger displays a message of the following form:
old-address moved to new-address
The old-address and new-address fields specify the old and new 16-bit
paragraph addresses of the memory block.
When Windows frees a block of memory and the reporting level is 1 or 3, the
Symbolic Debugger displays a message of the following form:
segment-address freed
The segment-address field specifies the 16-bit paragraph address of the
block to be freed.
The following is an example of allocation messages that SYMDEB might
display:
TEST!IGROUP=886F
TEST!DGROUP=8799
GDI!Code=1C32
8344 moved to 8230
7C12 freed
8.6.1 Setting Breakpoints with Symbols
You can use the bp command and symbols to set breakpoints in your
application code even before loading the application. The bp command uses
the symbol to compute the instruction address at which to break execution.
If the application has not been loaded, SYMDEB sets a virtual breakpoint. A
virtual breakpoint has no effect on execution until the application is
actually loaded. Once an application is loaded, SYMDEB computes the actual
code addresses of all virtual breakpoints and enables the breakpoints.
For example, to set a breakpoint at the application's WinMain function, you
would type the following:
-bp winmain
After you set the breakpoint, the application breaks and returns control to
SYMDEB when this address is encountered.
────────────────────────────────────────────────────────────────────────────
NOTE
If you do not set breakpoints before starting the application, use an
interrupt key to break execution (see Section 8.3.4, "Using SYMDEB Keys,"
for more information on SYMDEB keys).
────────────────────────────────────────────────────────────────────────────
8.6.2 Displaying Variables
You can use the d command to display the content of the application's global
variables. The command frequently takes the variable's symbol as an argument
and computes the variable's address using the address of the variable's
segment and its offset. The symbol map containing the symbol must be open.
See Section 8.9, "SYMDEB Commands," for details of arguments to the d
command.
When there are multiple instances of the application being debugged, SYMDEB
uses the address of the active data segment to compute a variable's address.
To display a variable in another instance, supply an absolute segment
address. For example, to display the value of hInstance in the first
instance, you must first determine the 16-bit paragraph address of the first
DGROUP segment by typing the following:
-x
SYMDEB displays the name and address of each segment in the open map, as in
the following example:
[ 0000 TEST ]
[ 8A12 IGROUP ]
89A0 DGROUP
( 8882 DGROUP1 )
Specify the address when typing the d command, as follows:
-dw 89A0:hinstance
SYMDEB displays the contents of the specified variable, as follows:
88AO:0010 0235 0000 0000 0000 0000 0000 0000 0000
8.6.3 Displaying Application Source Statements
You can display the source statements of an application by using the v, s+,
and s& commands. The v command displays the source lines of the application
beginning with the source line corresponding to the current code address
(CS:IP). The s+ command directs the Symbolic Debugger to display source
lines whenever you use the u command. The s& command directs the Symbolic
Debugger to display both source lines and unassembled code whenever you use
the u command. For more information on these commands, see Section 8.9,
"SYMDEB Commands."
────────────────────────────────────────────────────────────────────────────
NOTE
If a symbol file does not contain line-number information, the v, s+, and s&
commands have no effect.
If the application source file is not in the current directory, or the file
does not have the same name as the symbol file, SYMDEB prompts for the
file's correct name and/or pathname.
────────────────────────────────────────────────────────────────────────────
8.7 Quitting SYMDEB
You can terminate SYMDEB at any time by using the q command to return to the
DOS prompt. Before quitting SYMDEB, however, you must end the current
Windows session and restore the console display to its normal display modes.
Follow these general rules:
■ Use the q command to quit, if you have not started Windows.
■ Open the Windows shell and choose the Close command from its System
menu, then use the q command, if you have started Windows and it is
still operational. Make sure that all instances of the shell are
closed.
IMPORTANT When Windows terminates as a result of a fatal exit, the
Symbolic Debugger displays a fatal-exit message and returns the
SYMDEB prompt. Do not attempt to restart Windows or quit SYMDEB. You
must reboot the system to continue.
8.8 SYMDEB Command Overview and Tables
This section contains a complete listing of commands that can be used with
the Symbolic Debugger. It also describes the arguments and expressions used
with SYMDEB commands, as well as predefined names used as register and
register-flag names. Table 8.1 is a summary of the syntax and meaning of
SYMDEB commands:
Table 8.1 SYMDEB Commands
╓┌─────────────────────────────────────┌─────────────────────────────────────╖
Syntax Meaning
────────────────────────────────────────────────────────────────────────────
a «address» Assemble instruction mnemonics
ba option size address«value» Set address breakpoint(s) on 80386
«command-string» machines
bc id-list Clear breakpoint(s)
bd id-list Disable breakpoint(s)
be id-list Enable breakpoint(s)
Syntax Meaning
────────────────────────────────────────────────────────────────────────────
be id-list Enable breakpoint(s)
bl List breakpoint(s)
bp«id» address «value» Set breakpoint(s)
«command-string»
c range address Compare
d «range» Dump memory using previous type
da «range» Dump memory ASCII
db «range» Dump memory bytes
Table 8.1 SYMDEB Commands (continued)
╓┌─────────────────────────────────────┌─────────────────────────────────────╖
Syntax Meaning
────────────────────────────────────────────────────────────────────────────
dd «range» Dump memory doublewords
df Display list of global free blocks
dg Display global heap
dh Display local heap for current data
segment register
dl «range» Dump memory, long floating point
dm Display list of loaded modules
dq Dump list of current tasks, their
SS:BP, CS:IP, nEvents, priority,
module name, and queue handle
ds «range» Dump memory, short floating point
Syntax Meaning
────────────────────────────────────────────────────────────────────────────
ds «range» Dump memory, short floating point
dt «range» Dump memory 10-byte reals
du Display LRU list
dw «range» Dump memory words
e address «value» Enter using previous type
ea address «value» Enter ASCII
eb address «value» Enter bytes
ed address «value» Enter doublewords
el address «value» Enter long floating point
es address «value» Enter short floating point
Syntax Meaning
────────────────────────────────────────────────────────────────────────────
es address «value» Enter short floating point
et address «value» Enter 10-byte reals
ew address «value» Enter words
f range list Fill
g «= startaddress » «breakaddress»... Go
h value1 value2 Add hexadecimal command
i value Input from port
k «value» Backtrace stack
kt pdb «value» Backtrace task
kv «value» Annotate each stack frame with the
Syntax Meaning
────────────────────────────────────────────────────────────────────────────
kv «value» Annotate each stack frame with the
associated frame pointer value
l «address «drive record count» » Load
m range address Move
mid«= command-string» Define or execute macro
n «filename»«arguments» Set name
o value byte Output to port
p «= startaddress» «value» Trace program instruction or call
q Quit
r «register» « «= » value» Register
Syntax Meaning
────────────────────────────────────────────────────────────────────────────
s range list Search
s- Set machine debugging only
s& Set machine and source debugging
s+ Set source debugging only
t «= startaddress» «value» Trace program instruction
u «range» Display unassembled instructions
v range View source lines
w «address «drive record count» » Write to disk or file
x «*| ?» symbol Examine symbol(s)
Syntax Meaning
────────────────────────────────────────────────────────────────────────────
xo «symbol!» Open symbol map/segment
z symbol value Set symbol value
? Display list of SYMDEB commands and
operators
? expression Compute and display expression
. Display current source line
< filename Redirect SYMDEB input
> filename Redirect SYMDEB output
= = filename Redirect SYMDEB input and output
{ filename Redirect program input
Syntax Meaning
────────────────────────────────────────────────────────────────────────────
{ filename Redirect program input
} filename Redirect program output
~ filename Redirect program input and output
! «dos-command» Shell escape
* comment Comment
────────────────────────────────────────────────────────────────────────────
Any combination of uppercase and lowercase letters may be used in commands
and arguments. If a command uses two or more parameters, separate them with
a single comma (,) or one or more spaces.
The following provides examples of SYMDEB commands:
ds _avg L 10
U .22
f DS:100,110 ff,fe,01,00
For complete information about command syntax, see Section 8.9, "SYMDEB
Commands."
8.8.1 Command Arguments
Command arguments are numbers, symbols, line numbers, or expressions used to
specify addresses or values to be used by SYMDEB commands. The following is
a list of argument syntax and meaning:
Argument Description
────────────────────────────────────────────────────────────────────────────
address Specifies absolute, relative, or
symbolic address of
a variable or function. The Symbolic
Debugger permits a wide variety of
address types. See Section
8.8.2, "Address Arguments," for a
complete description of address
arguments.
byte Specifies a value argument representing
a byte value. It must be within the
range 0 to 255.
command-string Specifies one or more SYMDEB commands.
If more than one command is given, they
must be separated by semicolons (;).
count Specifies a value argument representing
the number of disk records to read or
write.
dos-command Specifies a DOS command.
drive Specifies a value argument representing
a disk drive. Drives are numbered 0 for
A, 1 for B, 2 for C, and so on.
expression Specifies a combination of arguments and
operators that represents a single value
or address. See Section 8.8.3,
"Expressions," for a list and
explanation of expression operators.
filename Specifies the name of a file or a device.
The filename must follow the DOS
filenaming
conventions.
id Specifies a decimal number representing
a breakpoint or macro identifier. The
number must be within the range 0 to 9.
Argument Description
────────────────────────────────────────────────────────────────────────────
id-list Specifies one or more unique decimal
numbers representing a list of
breakpoint identifiers. The numbers must
be within the range 0 to 9. If more than
one number is given, they must be
separated using spaces or commas. The
wildcard character (*) can be used to
specify all breakpoints.
list Specifies one or more value arguments.
The values must be within the range 0 to
65,535. If more than one value is given,
they must be separated using spaces or
commas.
A list can also be specified as a list
of ASCII values. The list can contain
any combination of characters and must
be enclosed in either single or double
quotation marks. If the enclosing mark
appears within the list, it must be
given twice.
range Specifies an address range. Address
ranges have two forms: a start and end
address pair, and a start address and
object count. The first form consists of
two address arguments, the first
specifying the start address and the
second specifying the end address. The
second form consists of an address
argument, the letter l, and a value
argument. The address specifies the
starting address; the value specifies
the number of objects after the address
to examine or display. The size of an
object depends on the command. If a
command requires a range but only a
start address is given in the command,
the command assumes the range has an
object count of 128. This default count
does not apply to commands that require
a range followed immediately by a value
or an address argument.
record Specifies a value argument representing
the first disk record to be read or
written to.
register Specifies the name of a CPU register. It
can be any one of the following:
╓┌───┌───┌───┌───────────────────────────────────────────────────────────────╖
────────────────────────────────────────────────────────────────────────────
AX CX ES SI
BP DI F SP
BX DS IP SS
CS DX PC
The names IP and PC refer to the same register: the instruction pointer. The
name F is a special name for the flags register. Each flag within the flags
register has a unique name based on its value. These names can be used to
set or clear the flag. Table 8.2 lists the flag names:
Table 8.2 Flag Values
╓┌────────────────┌───────────────┌──────────────────────────────────────────╖
Flag Set Clear
────────────────────────────────────────────────────────────────────────────
Overflow ov nv
Direction dn (decrement) up (increment)
Interrupt ei (enabled) di (disabled)
Sign ng (negative) pl (positive)
Zero zr nz
Auxiliary Carry ac na
Parity pe (even) po (odd)
Carry cy nc
────────────────────────────────────────────────────────────────────────────
Argument Description
────────────────────────────────────────────────────────────────────────────
symbol Identifies the address of a variable,
function, or segment. A symbol consists
of one or more characters, but always
begins with a letter, underscore (_),
question mark (?), at symbol (@), or
dollar sign ($). Symbols are available
only when the .SYM file that defines
their names and values has been loaded.
Any combination of uppercase and
lowercase letters can be used; SYMDEB is
not case-sensitive. For some commands,
the wildcard character (*) may be used
as part of a symbol to represent any
combination of characters.
pdb Specifies a value argument representing
the segment address of a program
descriptor block.
value Specifies an integer number in binary,
octal, decimal, or hexadecimal format. A
value consists of one or more digits
optionally followed by a radix: Y for
binary, O or Q for octal, T for decimal,
or H for hexadecimal. If no radix is
given, hexadecimal is assumed. SYMDEB
truncates leading digits if the number
is greater than 65,535. Leading zeros
are ignored. Hexadecimal numbers have
precedence over symbols, thus FAA is a
number.
8.8.2 Address Arguments
Address arguments specify the location of variables and functions. The
following list explains the syntax and meaning of the various addresses used
in SYMDEB:
Syntax Meaning
────────────────────────────────────────────────────────────────────────────
segment:offset Specifies an absolute address. A full
address has both a segment address and
an offset, separated by a colon (:). A
partial address is just an offset. In
both cases, the segment or offset can be
any number, register name, or symbol. If
no segment is given, the a, g, l, p, t,
u, and w commands use the CS register
for the default segment address. All
other commands use DS.
name{+ | -}offset Specifies a symbol-relative address. The
name can be any symbol. The offset
specifies the offset in bytes. The
address can be specified as a positive
(+) or negative (-) offset.
.{+ | -}number Specifies a relative line number. The
number is an offset (in lines) from the
current source line to the new line. If
+ is given, the new line is closer to
the end of the source file. If - is
given, the new line is closer to the
beginning.
.«filename:»number Specifies an absolute line number. If
filename is given, the specified line is
assumed to be in the source file
corresponding to the symbol file
identified by filename. If no filename
is given, the current instruction
address (the current values of the CS
and IP registers) determines which
source file contains the line.
symbol«{+ | -}number» Specifies a symbolic line number. The
symbol can be any instruction or
procedure label. If number is given, the
number is an offset (in lines) from the
given label or procedure name to the new
line. If + is given, the new line is
closer to the end of the source file. If
- is given, the new line is closer to
the beginning.
────────────────────────────────────────────────────────────────────────────
NOTE
Line numbers can be used only with programs developed with compilers that
copy line-number data to the object file.
────────────────────────────────────────────────────────────────────────────
8.8.3 Expressions
An expression is a combination of arguments and operators that evaluates to
an 8-bit, 16-bit, or 32-bit value. Expressions can be used as values in any
command.
An expression can combine any symbol, number, or address with any of the
unary and binary operators in Tables 8.3 and 8.4.
Table 8.3 Unary Operators
╓┌─────────┌────────────────────────────────────────┌────────────────────────╖
Operator Meaning Precedence
Operator Meaning Precedence
────────────────────────────────────────────────────────────────────────────
++ Unary plus Highest
- Unary minus
not 1's complement
seg Segment address of operand
off Address offset of operand
by Low-order byte from given address
wo Low-order word from given address
dw Doubleword from given address
poi Pointer from given address (same as dw)
port One byte from given port
wport Word from given port Lowest
────────────────────────────────────────────────────────────────────────────
Table 8.4 Binary Operators
╓┌─────────┌─────────────────────────────┌───────────────────────────────────╖
Operator Meaning Precedence
────────────────────────────────────────────────────────────────────────────
Operator Meaning Precedence
────────────────────────────────────────────────────────────────────────────
* Multiplication Highest
/ Integer division
mod Modulus
: Segment override
++ Addition
- Subtraction
and Bitwise Boolean AND
xor Bitwise Boolean exclusive OR
or Bitwise Boolean OR Lowest
────────────────────────────────────────────────────────────────────────────
Unary address operators assume DS as the default segment for addresses.
Expressions are evaluated in order of operator precedence. If adjacent
operators have equal precedence, the expression is evaluated from left to
right. Use parentheses to override this order.
The following exemplifies the use of Unary expressions:
SEG 0001:0002 ; Equals 1
OFF 0001:0002 ; Equals 2
4+2*3 ; Equals 10 (0Ah)
4+(2*3) ; Equals 10 (0Ah)
(4+2)*3 ; Equals 18 (12h)
8.9 SYMDEB Commands
The first part of this chapter described how to use the Symbolic Debugger, a
debugger that helps you test executable files for Windows applications that
run in real mode.
For more information about debugging Windows applications, see Chapter 7,
"Debugging in Protected Mode: CodeView for Windows," and Chapter 9,
"Advanced Debugging in Protected Mode: 80386 Debugger."
This section provides information on SYMDEB commands. Most notably, it
provides the syntax for each command.
a ─ Assemble
────────────────────────────────────────────────────────────────────────────
Syntax
a«address»
This command assembles instruction mnemonics and places the resulting
instruction codes into memory at address. If no address is given, the
asssembly starts at the address given by the current values of the CS and IP
registers. To assemble a new instruction, type the desired mnemonic and
press ENTER. To terminate assembly, press ENTER. There are the following
assembly rules:
■ Use retf for the far return mnemonic.
■ Use movsb or movsw for string-manipulation mnemonics.
■ Use the near or far prefix with labels to override default distance.
The ne abbreviation stands for near.
■ Use the word ptr or byte ptr prefix with destination operands to
specify size. The wo abbreviation stands for word ptr; by for byte
ptr.
■ Use square brackets around constant operands to specify absolute
memory addresses. Constants without brackets are treated as constants.
■ Use the db mnemonics to assemble byte values or ASCII strings directly
into memory.
■ Use 8087, 80287, or 80387 instructions only if your system has these
math coprocessors.
The 80286 protected-mode mnemonics cannot be assembled.
────────────────────────────────────────────────────────────────────────────
NOTE
Assembling over code can destroy checksum and cause a fatal exit.
────────────────────────────────────────────────────────────────────────────
ba ─ Breakpoint Address
────────────────────────────────────────────────────────────────────────────
Syntax
ba option size address «value» «command-string»
This command, available only on 80386 machines, sets an address breakpoint
at a given address. If your program accesses memory at this address, SYMDEB
will stop execution and display the current values of all registers and
flags.
There are three types of breakpoints you can set with the option parameter.
If I is specified, SYMDEB takes a breakpoint when the CPU fetches an
instruction from the given address. If R is specified, SYMDEB takes a
breakpoint when the CPU reads or writes a byte, word, or doubleword to the
given address. If U is specified, SYMDEB takes a breakpoint when the CPU
writes a byte, word, or doubleword to the given address.
The size parameter specifies the size of the data that SYMDEB expects to
find read or written at the given address. If B is specified (8-bit byte),
the command will break only at one address (for example, 0:10). If W is
specified (16-bit word), the command will break at one of two addresses
within that range (for example, 0:10 or 0:11 will cause a break within that
word). If D is specified (32-bit doubleword), the command will break at one
of four addresses within that range (for example, 0:08, 0:09, 0:10, or 0:11
will cause a break within that doubleword).
The address parameter can specify any valid address. The address value is
rounded down if necessary to the nearest byte, word, or doubleword boundary
(for example, if a doubleword address of 0:14 was requested, the command
would access the address of the nearest doubleword boundary below the
address, in this case 0:12).
The optional value parameter specifies the number of times the breakpoint is
to be ignored before being taken. It can be any 16-bit value.
The command-string parameter specifies an optional list of commands to be
executed each time the breakpoint is taken. Each SYMDEB command in the list
can include parameters and is separated from the next command by a
semicolon.
The bc, bd, be, and bl commands can all be used on these breakpoints.
bc ─ Breakpoint Clear
────────────────────────────────────────────────────────────────────────────
Syntax
bc id-list
This command permanently removes one or more previously set breakpoints. If
id-list is given, the command removes the breakpoints named in the list. The
id-list can be any combination of integer values from 0 to 9. If the
wildcard character (*) is given, the command removes all breakpoints.
bd ─ Breakpoint Disable
────────────────────────────────────────────────────────────────────────────
Syntax
bd id-list
This command disables, but does not delete, one or more breakpoints. If
id-list is given, the command disables the breakpoints named in the list.
The id-list can be any combination of integer values from 0 to 9. If the
wildcard character (*) is given, the command disables all breakpoints.
be ─ Breakpoint Enable
────────────────────────────────────────────────────────────────────────────
Syntax
be id-list
This command restores one or more breakpoints that were temporarily disabled
by a bd command. If id-list is given, the command enables the breakpoints
named in the list. The id-list can be any combination of integer values from
0 to 9. If the wildcard character (*) is given, the command enables all
breakpoints.
bl ─ Breakpoint List
────────────────────────────────────────────────────────────────────────────
Syntax
bl
This command lists current information about all breakpoints. The command
displays the breakpoint number, the enabled status, the address of the
breakpoint, the number of passes remaining, and the initial number of passes
(in parentheses). The enabled status can be enabled (e), disabled (d), or
virtual (v). A virtual breakpoint is a breakpoint set at a symbol whose .EXE
file has not yet been loaded.
bp ─ Breakpoint Set
────────────────────────────────────────────────────────────────────────────
Syntax
bp«id» address «value» «command-string»
This command creates a "sticky" breakpoint at the given address. Sticky
breakpoints stop execution and display the current values of all registers
and flags. Sticky breakpoints remain in the program until removed using the
bc command, or temporarily disabled using the bd command. The Symbolic
Debugger allows up to 10 sticky breakpoints (0 through 9). The optional id
parameter specifies which breakpoint is to be created. If no id is given,
the first available breakpoint number is used. The address parameter can be
any valid instruction address (it must be the first byte of an instruction).
The optional value parameter specifies the number of times the breakpoint is
to be ignored before being taken. It can be any 16-bit value. The optional
command-string parameter specifies a list of commands to be executed each
time the breakpoint is taken. Each SYMDEB command in the list can include
parameters and is separated from the next command by a semicolon (;).
c ─ Compare
────────────────────────────────────────────────────────────────────────────
Syntax
c range address
This command compares the bytes in the memory locations specified by range
with the corresponding bytes in the memory locations beginning at address.
If all corresponding bytes match, the command displays its prompt and waits
for the next command. If one or more pairs of corresponding bytes do not
match, the command displays each pair of mismatched bytes.
d ─ Dump
────────────────────────────────────────────────────────────────────────────
Syntax
d «range»
This command displays the contents of memory in the given range. The command
displays data in the same format as the most recent dump command. (Dump
commands include d, da, db, dd, dg, dh, dl, dq, ds, dt, and dw.) If no range
is given and no previous dump command has been used, the command displays
bytes starting from DS:IP.
da ─ Dump ASCII
────────────────────────────────────────────────────────────────────────────
Syntax
da «range»
This command displays the ASCII characters in the given range. Each line
displays up to 48 characters. The display continues until the first null
byte or until all characters in the range have been shown. Nonprintable
characters, such as carriage returns and line feeds, are displayed as
periods (.).
db ─ Dump Bytes
────────────────────────────────────────────────────────────────────────────
Syntax
db «range»
This command displays the hexadecimal and ASCII values of the bytes in the
given range. Each display line shows the address of the first byte in the
line, followed by up to 16 hexadecimal byte values. The byte values are
immediately followed by the corresponding ASCII values. The eighth and ninth
hexadecimal values are separated by a hyphen (-). Nonprintable ASCII values
are displayed as periods (.).
dd ─ Dump Doublewords
────────────────────────────────────────────────────────────────────────────
Syntax
dd «range»
This command displays the hexadecimal values of the doublewords (4-byte
values) in the given range. Each display line shows the address of the first
doubleword in the line and up to four hexadecimal doubleword values.
df ─ Display Global Free List
────────────────────────────────────────────────────────────────────────────
Syntax
df
This command displays a list of the free global memory objects in the global
heap. The list has the following form:
segment-address: size owner
The segment-address field specifies the segment address of the first byte of
the memory object. The size field specifies the size in paragraphs
(multiples of 16 bytes) of the object.
The owner field always specifies that the module is free.
dg ─ Display Global Heap
────────────────────────────────────────────────────────────────────────────
Syntax
dg
This command displays a list of the global memory objects in the global
heap. The list has the following form:
segment-address: size segment-type owner «handle flags chain»
The segment-address field specifies the segment address of the first byte of
the memory object. The size field specifies the size in paragraphs
(multiples of 16 bytes) of the object. The segment-type field specifies the
type of object. The type can be any one of the following:
Segment Type Meaning
────────────────────────────────────────────────────────────────────────────
CODE Segment contains program code.
DATA Segment contains program data and
possible stack and local heap data.
FREE Segment belongs to pool of free memory
objects ready for allocation by an
application.
PRIV Segment contains private data.
SENTINAL Segment marks the beginning or end of
the global heap.
The owner field specifies the module name of the application or library that
allocated the memory object. The name "pdb" is used for memory objects that
represent program descriptor blocks. These blocks contain execution
information about applications.
The handle field specifies the handle of the global memory object. If SYMDEB
displays no handle, the segment is fixed.
The flags field specifies the following:
Flag Meaning
────────────────────────────────────────────────────────────────────────────
D The segment is moveable and discardable.
L The segment is locked. If the segment is
locked, the lock count appears to the
right of the flag.
If SYMDEB displays a handle, but no flag, the segment is moveable but
nondiscardable.
The chain field specifies the previous and next segment addresses in the LRU
list. SYMDEB displays the addresses only if the segment is moveable and
discardable (the D flag).
dh ─ Display Local Heap
────────────────────────────────────────────────────────────────────────────
Syntax
dh
This command displays a list of the local memory objects in the local heap
(if any) belonging to the current data segment. The command uses the current
value of the DS register to locate the data segment and check for a local
heap. The list of memory objects has the following form:
offset: size { BUSY | FREE }
The offset field specifies the address offset from the beginning of the data
segment to the local memory object. The size field specifies the size of the
memory object in bytes. If BUSY is given, the object has been allocated and
is currently in use. If FREE is given, the object is in the pool of free
objects ready to be allocated by the application. A special memory object,
SENTINAL, may also be displayed.
dl ─ Dump Long Reals
────────────────────────────────────────────────────────────────────────────
Syntax
dl «range»
This command displays the hexadecimal and decimal values of the long
(8-byte) floating-point numbers within the given range. Each display line
shows the address of the floating-point number, the hexadecimal values of
the bytes in the number, and the decimal value of the number.
dm ─ Display Global Module List
────────────────────────────────────────────────────────────────────────────
Syntax
dm
This command displays a list of the global modules in the global heap. The
list has the following form:
module-handle module-type module-name file-name
The module-handle field specifies the handle of the module. The module-type
field specifies either a dynamic-link library (DLL) or the name of the
application you are debugging. The module-name field specifies the name of
the module. The file-name field specifies the name of the file from which
you loaded the application.
dq ─ Dump Task Queue
────────────────────────────────────────────────────────────────────────────
Syntax
dq
This command displays a list containing information about the various task
queues supported by the system. The list has the following form:
task-descriptor-block stack-segment:stack-pointer number-of-events
priority internal-messaging-information module
The task-descriptor-block field specifies the selector or segment address.
The task descriptor block is identical to the "pdb."The
stack-segment:stack-pointer field specifies the stack segment and pointer.
The number-of-events field specifies the number of events waiting for the
segment. The priority field specifies the priority of the segment. The
internal-messaging-information field specifies information about internal
messages. The module field specifies the module name.
ds ─ Dump Short Reals
────────────────────────────────────────────────────────────────────────────
Syntax
ds «range»
This command displays the hexadecimal and decimal values of the short
(4-byte) floating-point numbers in the given range. Each display line shows
the address of the floating-point number, the hexadecimal values of the
bytes in the number, and the decimal value of the number.
dt ─ Dump Ten-Byte Reals
────────────────────────────────────────────────────────────────────────────
Syntax
dt «range»
This command displays the hexadecimal and decimal values of the 10-byte
floating-point numbers in the given range. Each display line shows the
address of the floating-point number, the hexadecimal values of the bytes in
the number, and the decimal value of the number.
du ─ Display Global LRU List
────────────────────────────────────────────────────────────────────────────
Syntax
du
This command displays a list of the least-recently-used (LRU) global memory
objects in the global heap. The list has the following form:
segment-address: size segment-type owner «handle flags chain»
The segment-address field specifies the segment address of the first byte of
the memory object. The size field specifies the size in paragraphs
(multiples of 16 bytes) of the object. The segment-type field specifies the
type of object. The type can be any one of the following:
Segment Type Meaning
────────────────────────────────────────────────────────────────────────────
CODE Segment contains program code.
DATA Segment contains program data and
possible stack and local heap data.
FREE Segment belongs to pool of free memory
objects ready for allocation by an
application.
PRIV Segment contains private data.
SENTINAL Segment marks the beginning or end of
the global heap.
The owner field specifies the module name of the application or library that
allocated the memory object. The name "pdb" is used for memory objects that
represent program descriptor blocks. These blocks contain execution
information about applications.
The handle field specifies the handle of the global memory object.
The flags field specifies D, which means the segment is moveable and
discardable.
The chain field specifies the previous and next segment addresses in the LRU
list.
dw ─ Dump Words
────────────────────────────────────────────────────────────────────────────
Syntax
dw «range»
This command displays the hexadecimal values of the words (2-byte values) in
the given range. Each display line shows the address of the first word in
the line and up to eight hexadecimal word values.
e ─ Enter
────────────────────────────────────────────────────────────────────────────
Syntax
e address «list»
This command enters one or more values into memory. The size of the value
entered depends on the most recently used Enter command. (Enter commands are
e, ea, eb, ed, el, es, et, and ew.) The default is eb (bytes). If no list is
given, the command displays the value at address and prompts for a new
value. If list is given, the command replaces the value at address and at
each subsequent address until all values in the list have been used.
ea ─ Enter Address
────────────────────────────────────────────────────────────────────────────
Syntax
ea address «list»
This command enters an ASCII string into memory. If no list is given, the
command displays the byte at address and prompts for a replacement. If list
is given, the command replaces the bytes at address, then displays the next
byte and prompts for a replacement.
eb ─ Enter Bytes
────────────────────────────────────────────────────────────────────────────
Syntax
eb address «list»
This command enters one or more byte values into memory. If list is given,
the command replaces the byte at address and bytes at each subsequent
address until all values in the list have been used. If no list is given,
the command displays the byte at address and prompts for a new value. To
skip to the next byte, enter a new value or press the SPACEBAR. To move back
to the previous byte, type a hyphen (-). To exit from the command, press
ENTER.
ed ─ Enter Doublewords
────────────────────────────────────────────────────────────────────────────
Syntax
ed address «value»
This command enters a doubleword value into memory. If no value is given,
the command displays the doubleword at address and prompts for a
replacement. If value is given, the command replaces the doubleword at
address, then displays the next doubleword and prompts for a replacement.
Doublewords must be typed as two words separated by a colon.
el ─ Enter Long Reals
────────────────────────────────────────────────────────────────────────────
Syntax
el address «value»
This command enters a long-real value into memory. If no value is given, the
command displays the long-real value at address and prompts for a
replacement. If value is given, the command replaces the long-real value at
address, then displays the next long-real value and prompts for a
replacement.
es ─ Enter Short Reals
────────────────────────────────────────────────────────────────────────────
Syntax
es address «value»
This command enters a short-real value into memory. If no value is given,
the command displays the short-real value at address and prompts for a
replacement. If value is given, the command replaces the short-real value at
address, then displays the next short-real value and prompts for a
replacement.
et ─ Enter Ten-Byte Reals
────────────────────────────────────────────────────────────────────────────
Syntax
et address «value»
This command enters a 10-byte real value into memory. If no value is given,
the command displays the 10-byte real value at address and prompts for a
replacement. If value is given, the command replaces the 10-byte real value
at address, then displays the next 10-byte real value and prompts for a
replacement.
ew ─ Enter Words
────────────────────────────────────────────────────────────────────────────
Syntax
ew address «value»
This command enters a word value into memory. If no value is given, the
command displays the word at address and prompts for a replacement. If value
is given, the command replaces the word at address, then displays the next
word and prompts for a replacement.
f ─ Fill
────────────────────────────────────────────────────────────────────────────
Syntax
f range list
This command fills the addresses in the given range with the values in list.
If range specifies more bytes than the number of values in the list, the
list is repeated until all bytes in the range are filled. If list has more
values than the number of bytes in the range, the command ignores any extra
values.
g ─ Go
────────────────────────────────────────────────────────────────────────────
Syntax
g «= startaddress» «breakaddress»...
This command passes execution control to the program at the given
startaddress. Execution continues to the end of the program or until break
address is encountered. The program also stops at any breakpoints set using
the bp command. If no startaddress is given, the command passes execution to
the address specified by the current values of the CS and IP registers. If
breakaddress is given, it must specify an instruction address (that is, the
address must contain the first byte of an instruction). Up to 10 break
addresses, in any order, can be given at one time.
h ─ Hex
────────────────────────────────────────────────────────────────────────────
Syntax
h value1 value2
This command displays the sum and difference of two hexadecimal numbers,
value1 and value2.
i ─ Input
────────────────────────────────────────────────────────────────────────────
Syntax
i value
This command reads and displays one byte from the input port specified by
value. The value parameter can specify any 16-bit port address.
k ─ Backtrace Stack
────────────────────────────────────────────────────────────────────────────
Syntax
k «value»
This command displays the current stack frame. Each line shows the name of a
procedure, its arguments, and the address of the statement that called it.
The command displays two 2-byte arguments by default. If value is given, the
command displays that many 2-byte arguments. Using the k command at the
beginning of a function (before the function prolog has been executed) will
give incorrect results. The command uses the BP register to compute the
current backtrace, and this register is not correctly set for a function
until its prolog has been executed.
kt ─ Backtrace Task Stack
────────────────────────────────────────────────────────────────────────────
Syntax
kt pdb «value»
This command displays the stack frame of the program specified by pdb. Each
line shows the name of a procedure, its arguments, and the address of the
statement that called it. The command displays two 2-byte arguments by
default. If value is given, the command displays that many 2-byte arguments.
The pdb parameter must specify the segment address of the program descriptor
block for the task to be traced.
To obtain the pdb value, use the dq (Dump Task Queue) command.
kv ─ Verbose Backtrace Stack
────────────────────────────────────────────────────────────────────────────
Syntax
kv «value»
This command displays information that the k (Backtrace Stack) command
provides, plus information about stack location and frame pointer values for
each frame.
l ─ Load
────────────────────────────────────────────────────────────────────────────
Syntax
l «address «drive record count» »
This command copies the contents of a named file or the contents of a given
number of logical disk records into memory. The contents are copied to
address or to a default address, and the BX:CX register pair is set to the
number of bytes loaded.
To load a file, set the filename using the n command (otherwise, SYMDEB uses
whatever name is currently at location DS:5C). If address is not given,
SYMDEB copies bytes to CS:100. If the named file has an .EXE extension, the
l command adjusts the load address to the address given in the .EXE file
header. The command strips any header information from an .EXE file before
loading. If the named file has an .HEX extension, the l command adds that
file's start address to address before loading the file.
To load logical records from a disk, set drive to 0 (drive A), 1 (drive B),
or 2 (drive C). Set record to the first logical record to be read (any one-
to four-digit hexadecimal number). Set count to the number of records to
read (any one- to four-digit hexadecimal number).
m ─ Move
────────────────────────────────────────────────────────────────────────────
Syntax
m range address
This command moves the block of memory specified by range to the location
starting at address. All moves are guaranteed to be performed without data
loss.
mid─ Macro
────────────────────────────────────────────────────────────────────────────
Syntax
mid«= command-string»
This command defines or executes a SYMDEB command macro. The id parameter
identifies the macro to be defined or executed. There are 10 macros,
numbered 0 through 9. If command-string is specified, the command assigns
the SYMDEB commands given in the string to the macro. If no string is given,
the command executes the commands currently assigned to the macro. Macros
are initially empty unless the /@ option is used when the Symbolic Debugger
is started. This option reads a set of macro definitions from a specified
file.
n ─ Name
────────────────────────────────────────────────────────────────────────────
Syntax
n «filename» «arguments»
This command sets the filename for subsequent l and w commands, or sets
program arguments for subsequent execution of a loaded program. If filename
is given, all subsequent l and w commands will use this name when accessing
disk files. If arguments is given, the command copies all arguments,
including spaces, to the memory location starting at DS:81 and sets the byte
at DS:80 to a count of the total number of characters copied. If the first
two arguments are also filenames, the command creates file control blocks at
addresses DS:5C and DS:6C and copies the names (in proper format) to these
blocks.
o ─ Output
────────────────────────────────────────────────────────────────────────────
Syntax
o value byte
This command sends the given byte to the output port specified by value. The
value parameter can specify any 16-bit port address.
p ─ Program Step
────────────────────────────────────────────────────────────────────────────
Syntax
p «=startaddress» «value»
This command executes an instruction, then displays the current values of
all registers and flags. If startaddress is given, the command starts
execution at the given address. Otherwise, it starts execution at the
instruction pointed to by the current CS and IP registers. If value is
given, the command executes value number of instructions before stopping.
The command automatically executes and returns from any call instructions or
software interrupts it encounters, leaving execution control at the next
instruction after the call or interrupt.
q ─ Quit
────────────────────────────────────────────────────────────────────────────
Syntax
q
This command terminates SYMDEB execution and returns control to DOS.
r ─ Register
────────────────────────────────────────────────────────────────────────────
Syntax
r «register« «= »value» »
This command displays the contents of CPU registers and allows the contents
to be changed to new values.
If no register is specified, the command displays all registers, all flags,
and the instruction at the address pointed to by the current CS and IP
register values. If register is specified, the command displays the current
value of the register and prompts for a new value. If both register and
value are specified, the command changes the register to the specified
value.
s ─ Search
────────────────────────────────────────────────────────────────────────────
Syntax
s range list
This command searches the given range of memory locations for the byte
values given in list. The command displays the address of each byte found.
Set Source Mode
────────────────────────────────────────────────────────────────────────────
Syntax
s-
s&
s+
These commands set the display mode for commands that display instruction
code.
■ If s- is given, SYMDEB disassembles and displays the instruction code
in memory.
■ If s& is given, SYMDEB displays both the actual program source line
and the disassembled code.
■ If s+ is given, SYMDEB displays the actual program source line
corresponding to the instruction to be displayed.
To access a source file for the first time, SYMDEB might display the
following prompt:
Source file name for mapname(cr for none)?
In such cases, type the name, including extension, of the source file
corresponding to the symbol file mapname.
t ─ Trace
────────────────────────────────────────────────────────────────────────────
Syntax
t «= startaddress» «value»
This command executes an instruction, then displays the current values of
all registers and flags. If startaddress is given, the command starts
execution at the given address. Otherwise, it starts execution at the
instruction pointed to by the current CS and IP registers. If value is
given, the command continues to execute value number of instructions before
stopping. In source-only (s+) mode, t operates directly on source lines. The
t command can be used to trace instructions in ROM.
u ─ Unassemble
────────────────────────────────────────────────────────────────────────────
Syntax
u «range»
This command displays the instructions and/or statements of the program
being debugged. The s command sets the display format. If range is given,
the command displays instructions generated from code within the given
range. Otherwise, the command displays the instructions generated from the
first eight lines of code at the current address. The 80286 protected-mode
mnemonics cannot be displayed.
v ─ View
────────────────────────────────────────────────────────────────────────────
Syntax
v range
This command displays source lines beginning at the specified range. The
symbol file must contain line-number information.
w ─ Write
────────────────────────────────────────────────────────────────────────────
Syntax
w «address «drive record count» »
This command writes the contents of a given memory location to a named file,
or to a given logical record on disk. To write to a file, set the filename
with an n command, and set the BX:CX register pair to the number of bytes to
be written. If no address is given, the command copies bytes starting from
the address CS:100, where CS is the current value of the CS register.
To write to a logical record on disk, set drive to any number in the range
zero (drive A) to 2 (drive C), set record to the first logical record to
receive the data (a one- to four-digit hexadecimal number), and set count to
the number of records to write to the disk (a one- to four-digit hexadecimal
number). Do not write data to an absolute disk sector unless you are sure
the sector is free; otherwise, you may destroy data.
x ─ Examine Symbol Map
────────────────────────────────────────────────────────────────────────────
Syntax
x «* | ? symbol»
This command displays the name and load-segment addresses of the current
symbol map, segments in that map, and symbols within those segments.
If no parameter is given, the command displays the current symbol map name
and the segments within that map. If the asterisk (*) is specified, the
command displays the names and load-segment addresses for all currently
loaded symbol maps. If ? is specified, the command displays all symbols
within the given symbol map that match the symbol specification. A symbol
specification has the following form:
«mapname!» «segmentname:]] «symbolname»
If mapname! is given, the command displays information for that symbol map.
The mapname parameter must specify the filename (without extension) of the
corresponding symbol file.
If segmentname: is given, the command displays the name and load-segment
address for that segment. The segmentname parameter must specify the name of
a segment named within the specified or currently open symbol map.
If symbolname is given, the command displays the segment address and segment
offset for that symbol. The symbolname parameter must specify the name of a
symbol in the given segment.
To display information about more than one segment or symbol, enter a
partial segmentname or symbolname ending with an asterisk (*). The asterisk
acts as a wildcard character.
xo ─ Open Symbol Map
────────────────────────────────────────────────────────────────────────────
Syntax
xo «symbol!»
This command sets the active symbol map and/or segment. If symbol! is given,
the command sets the active symbol map to the given map. The symbol
parameter must specify the filename (without extension) of one of the symbol
files specified in the SYMDEB command line. A map file can be opened only
if it was loaded by providing its name in the SYMDEB command line.
z ─ Set Symbol Value
────────────────────────────────────────────────────────────────────────────
Syntax
z symbol value
This command sets the address of symbol to value.
? ─ Display Help
────────────────────────────────────────────────────────────────────────────
Syntax
?
This command displays a list of all SYMDEB commands and operators.
? ─ Display Expression
────────────────────────────────────────────────────────────────────────────
Syntax
? expression
This command displays the value of expression. The display includes a full
address, a 16-bit hexadecimal value, a full 32-bit hexadecimal value, a
decimal value (enclosed in parentheses), and a string value (enclosed in
double quotation marks). The expression parameter can specify any
combination of numbers, symbols, addresses, and operators.
. ─ Source-Line Display
────────────────────────────────────────────────────────────────────────────
Syntax
.
This command displays the current source line.
Redirect Input
────────────────────────────────────────────────────────────────────────────
Syntax
<filename
{ filename
The command causes SYMDEB to read all subsequent command input from the
specified file. The { command reads all input for the debugged program from
the specified file.
Redirect Output
────────────────────────────────────────────────────────────────────────────
Syntax
>filename
}filename
The > command causes SYMDEB to write all subsequent command output to the
specified file. The } command writes all output from the debugged program to
the specified file.
Redirect Input and Output
────────────────────────────────────────────────────────────────────────────
Syntax
= =filename
~ filename
The = = command causes SYMDEB to both read from and write to the device
specified in the filename. The ~ command causes the debugged program to both
read from and write to the given device.
! ─ Shell Escape
────────────────────────────────────────────────────────────────────────────
Syntax
! «dos-command»
This command passes control to COMMAND.COM, the DOS command processor,
letting the user carry out DOS commands. The DOS EXIT command returns
control to SYMDEB. If dos-command is given, SYMDEB passes the command to
COMMAND.COM for execution, then receives control back as soon as the command
is completed.
* ─ Comment
────────────────────────────────────────────────────────────────────────────
Syntax
*comment
This command echoes comment on the screen (or other output device).
Chapter 9 Advanced Debugging in Protected Mode: 80386 Debugger
────────────────────────────────────────────────────────────────────────────
Microsoft Windows 80386 Debugger (WDEB386) is used to test and debug Windows
applications and dynamic-link libraries (DLLs) running in standard or 386
enhanced mode, but not in real mode. It runs only on systems with an Intel
80386 CPU. The debugger provides commands that allow the operator to inspect
and manipulate test code and environment status, install breakpoints, and
perform other debugging operations.
WDEB386 offers debugging features not available in CodeView for Windows
(CVW), but lacks the the convenient character-oriented window interface of
CVW.
To use the debugger, a serial terminal must be connected to the system
running the debugger and test program. The terminal connection requirements
are described in Section 9.2, "Starting the Debugger."
This chapter describes the following:
■ Preparing symbol files
■ Starting the 80386 Debugger
■ How the 80386 Debugger traps a failed application
■ Debugger command format
■ Common WDEB386 commands
■ WDEB386 commands used with Windows in 386 enhanced mode
9.1 Preparing Symbol Files for the 80386 Debugger
Application symbol files should be prepared for the debugger in the same way
as the files are prepared for the Symbolic Debugger (SYMDEB).
1. Compile your C source files with the -Zd option.
This will prepare the object files for use by the 80386 Debugger.
2. Run LINK to link these object files.
WDEB386 does not use line number information, so you need not use the
/linenumbers option.
3. Run the MAPSYM program to create an application symbol file for the
debugger.
9.2 Starting the Debugger
The command line options are:
WDEB386 «/C: {1 | 2 | 3 | 4}» «/V«P»» «/S: symfilespec»... winfilespec
«parameters»
For example, the following typical commands are valid:
WDEB386 /V /S:\windows\system\krnl286.sym /S:myapp.sym \windows\win.com /s
myapp
WDEB386 /C:1 /S:krnl386.sym /s:user.sym /S:\myapp\myapp.sym
\windows\win.com /3 myapp
Use the /C: option to specify a COM port for debugger output. If no COM port
option is specified, then the debugger checks first for COM2, and if not
found, then checks for COM1. If neither COM1 nor COM2 exists, the debugger
will look for any other COM port in the ROM data area (40:0). A three-wire
null modem cable is all that is needed for terminal connection (no DTR/CTS
handshaking is used).
The /V and /VP options enable Verbose mode, which displays messages
indicating which segments are loading. /V displays the messages for both
Windows in 386 enhanced mode and for Windows applications; /VP displays the
messages for applications only.
Use the /S: option to specify a symbol file to be loaded. These switches are
optional and can be repeated. If the symbol files are not in your current
directory, you must supply a full pathname for the symbol files. WDEB386
does not use the PATH environment variable to locate any of the files
supplied on the command line.
When memory is low, you can use more symbol files by running the 80386
Debugger in the Windows directory and specifying the full pathname of
WIN386.EXE (such as \WINDOWS\SYSTEM\WIN386.EXE) instead of WIN.COM.
A program specification is required, and any characters after the program
specification are passed to the program as parameters.
────────────────────────────────────────────────────────────────────────────
NOTE
The 80386 Debugger does not display your source lines.
────────────────────────────────────────────────────────────────────────────
9.3 When an Application Fails
If a Windows application running in standard or 386 enhanced mode attempts
to read or write memory using a bad selector, beyond a selector limit, or
with a selector set to 0, then a general protection (GP) fault occurs.
Windows in 386 enhanced mode traps this fault and causes the debugger to
display something like the following:
GENERAL PROTECTION VIOLATION
AX=xxxxxxxx BX=xxxxxxxx CX=xxxxxxxx DX=xxxxxxxx SI=xxxxxxxx DI=xxxxxxxx
IP=00000FA0 SP=xxxxxxxx BP=xxxxxxxx CR2=xxxxxxxx CR3=xxxx IOPL=3 F=─
─
CS=00AD SS=xxxx DS=xxxx ES=xxxx FS=xxxx GS=xxxx ─ NV UP EI PL ZR NA PE NC
00AD:00000FA0 MOV BX, WORD PTR ES:[BX]
You can determine the cause of the fault by looking at the value and the
limit of the selector by dumping the LDT entry with the command:
DL selector
The ability to continue execution depends on the cause of the fault. If the
fault was caused by reading or writing beyond the selector limit, then
sometimes it is possible to skip the instruction by incrementing the IP,
using:
R IP
IP=xxxx
:
You might have to disassemble the instruction with code bytes shown to
determine how many bytes it contains. To do this, use the following
commands:
Y CODEBYTES
R
If the fault is caused by a critical logic error, such as trying to use a
selector for a temporary variable, then there probably is no way to continue
execution of the application. Rebooting the machine may be the only option.
9.4 Debugger Command Format
Each debugger command consists of one or two letters, usually followed by
one or more parameters. These commands and parameters are not
case-sensitive.
If a syntax error occurs in a debugger command, the debugger redisplays the
command line and indicates the error with a caret (^) and the word "Error,"
as in the following example:
A100
^ Error
9.4.1 Command Keys
The following is a list of command keys:
╓┌───────────┌───────────────────────────────────────────────────────────────╖
Key Action
────────────────────────────────────────────────────────────────────────────
CONTROL+C Halts debugger output and returns to the debugger prompt.
CONTROL+S Freezes a 80386 Debugger display.
CONTROL+Q Restarts the display.
CONTROL+S and CONTROL+Q are ignored if the target system is executing code.
9.4.2 Command Parameters
You can separate 80386 Debugger command parameters with delimiters (spaces
or commas), but the only required delimiter is between two consecutive
hexadecimal values. The following commands are equivalent:
dCS:100 110
d CS:100 110
d,CS:100,110
────────────────────────────────────────────────────────────────────────────
NOTE
Selector is the term used to indicate the value in a segment register while
in protected mode. Segment is the equivalent in real mode. Although the
following discussion uses selector, the discussion applies to segments as
well.
────────────────────────────────────────────────────────────────────────────
The following describes the parameters you can use with the 80386 Debugger
commands:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
addr Represents an address parameter in one
Parameter Description
────────────────────────────────────────────────────────────────────────────
addr Represents an address parameter in one
of two forms. The first form contains
either an alphabetic selector register
or a four-digit selector address, and an
offset value. The second form is a
physical address using the % operator.
You can omit the selector name or
selector address, in which case the
default selector is DS. This default
selector is used for all commands except
g, p, t, and u. The default selector for
these commands is CS. All numeric values
are hexadecimal. Example addresses
include:
CS:0100
04BA:0100
A colon is required between the selector
Parameter Description
────────────────────────────────────────────────────────────────────────────
A colon is required between the selector
name (whether numeric or alphabetic) and
the offset value. The selector portion
is treated as a selector or segment as
appropriate for the current processor
mode (protected or real) unless
specifically overridden by the # or &
operator.
byte Specifies a 2-digit hexadecimal value.
cmds Specifies an optional set of debugger
commands to be executed with the bp (Set
Breakpoints) or j (Conditional Execute)
commands.
dword Represents an 8-digit (4-byte)
hexadecimal value. A DWORD is most
commonly used as a physical address.
Parameter Description
────────────────────────────────────────────────────────────────────────────
commonly used as a physical address.
expr Represents a combination of parameters
and operators that evaluates to an 8, 16,
or 32-bit value. An expr parameter can
be used as a value in any command. An
expr parameter can combine any symbol,
number, or address with any of the
binary and unary operators.
group-name Specifies the name of a group that
contains the map symbols you want to
display.
list Specifies a series of byte values or a
string. The list parameter must be the
last parameter on the command line.
Following is an example of the f (Fill)
command using a list parameter:
Parameter Description
────────────────────────────────────────────────────────────────────────────
command using a list parameter:
fCS:100 42 45 52 54 41
map-name Specifies the name of a symbol map file.
range Contains two addresses (addr addr) or
one address, an L, and a value (addr L
word, where word is the number of items
on which the command should operate; L
80 is the default). Sample ranges
include:
CS:100 110
CS:100 L 10
CS:100
The limit for range is 10000
(hexadecimal). To specify a word of
Parameter Description
────────────────────────────────────────────────────────────────────────────
(hexadecimal). To specify a word of
10000 using only four digits, use 0000
or 0.
reg Specifies the name of a microprocessor
register.
string Represents any number of characters
enclosed in single (") or double ("")
quotation marks. If the quotation marks
must appear within a string, you must
use two sets of quotation marks. For
example, the following strings are
legal:
'This ''string'' is OK.'
"This ""string"" is OK."
However, the following strings are
Parameter Description
────────────────────────────────────────────────────────────────────────────
However, the following strings are
illegal:
"This "string" is not OK."
"This 'string' is not OK."
The ASCII values of the characters in
the string are used as a list of byte
values.
word Specifies a 4-digit (2-byte) hexadecimal
value.
9.4.3 Binary and Unary Operators
The following list contains, in descending order of precedence, the binary
operators that can be used in 80386 Debugger commands.
╓┌───────────────┌───────────────────────────────────────────────────────────╖
Operator Meaning
────────────────────────────────────────────────────────────────────────────
( ) Parentheses
: Address binder
* Multiplication
/ Integer division
MOD Modulus (remainder)
++ Addition
- Subtraction
> Greater-than relational operator
< Less-than relational operator
>= Greater-than/equal-to relational operator
<= Less-than/equal-to relational operator
== Equal-to relational operator
!= Not-equal-to relational operator
AND Bitwise Boolean AND
XOR Bitwise Boolean exclusive OR
OR Bitwise Boolean OR
Operator Meaning
────────────────────────────────────────────────────────────────────────────
OR Bitwise Boolean OR
&& Logical AND
|- |-|| Logical OR
The following list contains, in descending order of precedence, the unary
operators that can be used in 80386 Debugger commands.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Operator Meaning
────────────────────────────────────────────────────────────────────────────
&(seg) Interpret address using segment value
#(sel) Interpret address using selector value
%%(phy) Interpret address as a physical value
%(lin) Interpret address as a linear value
Operator Meaning
────────────────────────────────────────────────────────────────────────────
- Two's complement
! Logical NOT operator
NOT One's complement
SEG Segment address of operand
OFF Address offset of operand
BY Low-order byte from given address
WO Low-order word from given address
DW Doubleword from given address
POI Pointer (4 bytes) from given
address─this operator only works with
Operator Meaning
────────────────────────────────────────────────────────────────────────────
address─this operator only works with
16:16 addresses
PORT 1 byte from given port
WPORT Word from given port
9.5 Common Command Directory
This section documents the commands available in all environments using the
80386 Debugger. These commands are usually one or two alphabetical
characters, though some are characters preceded by a period (called "dot"
commands).
This section consists of a listing of commands and brief descriptions
followed by detailed descriptions of the commands, including syntax,
purpose, input parameters and examples.
╓┌───────────────┌───────────────────────────────────────────────────────────╖
Command Description
────────────────────────────────────────────────────────────────────────────
? Display expression
? Display help
.? Display external commands
.b Set COM port baud rate
.df Display global free list
.dg Display global heap
.dh Display local heap
.dm Display global module list
.dq Dump task queue
.du Display global LRU list
.reboot Reboot target system
bc Clear breakpoints
bd Disable breakpoints
be Enable breakpoints
bl List breakpoints
bp Set breakpoints
Command Description
────────────────────────────────────────────────────────────────────────────
bp Set breakpoints
c Compare memory
d Display memory
db Display bytes
dd Display doublewords
dg Display GDT
di Display IDT
dl Display LDT
dt Display TSS
dw Display words
e Enter byte
f Fill memory
g Go
h Hexadecimal arithmetic
i Input byte
j Conditional execute
k Backtrace stack
ka Set backtrace arguments
kt Backtrace task stack
Command Description
────────────────────────────────────────────────────────────────────────────
kt Backtrace task stack
kv Verbose backtrace stack
la List absolute symbols
lg List groups
lm List map
ln List near
ls List symbols
m Move memory
o Output to port
p Program trace
r Display registers
s Search bytes
t Trace instructions
u Unassemble bytes
v Set interrupt vector trapping
vl Display interrupt trapping information
w Change map
y Debugger configuration options
z Zap embedded INT 1 and INT 3 instructions
Command Description
────────────────────────────────────────────────────────────────────────────
z Zap embedded INT 1 and INT 3 instructions
zd Execute default command string
zl Display default command string
zs Change default command string
? ─ Display Expression
────────────────────────────────────────────────────────────────────────────
Syntax
? expr | "string"
The ? command displays the value of a specified expression or string. An
expression is first evaluated and then displayed in hexadecimal, decimal,
octal, and binary format. The debugger also displays an ASCII character
representation of the evaluated expression, a physical address
interpretation, and whether the expression is TRUE or FALSE.
Strings enclosed in quotation marks are echoed to the screen.
The expression evaluator provides support for three types of addresses: real
mode (%selector:offset), protected mode (#selector:offset), and physical
address (DWORD). The &, #, and % characters override the current address
type, allowing selectors to be used in real mode, segments to be used in
protected mode, and so on. The % character converts other addresses to
physical addresses.
╓┌──────────┌───────────────────────────────┌────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
expr Specifies any combination of
numbers, addresses, and
operators. If expr is not
specified, this command will
Parameter Description
────────────────────────────────────────────────────────────────────────────
specified, this command will
print help messages. The
following key words can be
used with the expression:
Key Word Description
reg Returns the value of reg, where
reg is one of the following
registers: AX, BX, CX, DX, SI,
DI, BP, DS, ES, SS, CS, SP, or
IP
FLG Returns the value of the flags
GDTB Returns the value of the GDT
base as a physical address
GDTL Returns the value of the GDT
Parameter Description
────────────────────────────────────────────────────────────────────────────
GDTL Returns the value of the GDT
limit
IDTB Returns the value of the IDT
base as a physical address
IDTL Returns the value of the IDT
limit
TR Returns the value of the TR
register
LDTR Returns the value of the LDTR
register
MSW Returns the value of the MSW
register
The @ character can be used
Parameter Description
────────────────────────────────────────────────────────────────────────────
The @ character can be used
with any of the register names
to ensure that the expression
evaluator interprets the name
as a register instead of a
symbol (for example, @AX is
the same as AX).
string Specifies a sequence of
characters enclosed in single
or double quotation marks.
Examples
?%(#001F:0220)
This example looks up selector 1F's physical address in the current LDT and
adds 220 to it.
? ds:si+bx
This example displays the value of the expression DS:SI + BX. The debugger
returns a display similar to the following:
2038:4278 540557944T 40160411700Q 0100001001111000Y 'X' %0245F8 TRUE
? 3*4
This example displays the value of the arithmetic expression 3*4. The
debugger returns the following display:
0CH 12T 14Q 00001100Y '.' %00000C TRUE
bp1 100 "r;d 200;? 'BP 1 REACHED'"
This example is used in a bp (Set Breakpoint) command to announce a
breakpoint number.
? ─ Display Help Menu
────────────────────────────────────────────────────────────────────────────
Syntax
?
The ? command displays a list of commands and syntax recognized by the
debugger.
.? ─ Display External Commands
────────────────────────────────────────────────────────────────────────────
Syntax
.?
The .? command displays a list of external commands. These commands are part
of the debugger, but are specific to the environment in which the debugger
is running.
.b ─ Set COM Port Baud Rate
────────────────────────────────────────────────────────────────────────────
Syntax
.b baud-rate «port-addr»
The .b command sets the baud rate for the debugging port (COM2).
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
baud-rate Specifies one of the following values:
150, 300, 600, 1200, 2400, 4800, 9600,
Parameter Description
────────────────────────────────────────────────────────────────────────────
150, 300, 600, 1200, 2400, 4800, 9600,
or 19200. Since the default radix for
the debugger is 16, you must include a
"t" after the number to indicate decimal
values.
port-addr Can be 1 for COM1, 2 for COM2; anything
else is taken as a base port address.
During initialization, if there is no
COM2, the debugger checks for COM1 and
then any other COM port address in the
ROM data area, and uses it as the
console.
Example
#.b 1200t
This example sets the baud rate to 1200.
.df ─ Display Global Free List
────────────────────────────────────────────────────────────────────────────
Syntax
.df
The .df command displays a list of the free global memory objects in the
global heap. The list has the following form:
address: size owner «chain»
The address field specifies the selector of the memory in standard mode. In
386 enhanced mode, the address field specifies physical and heap addresses.
The size field specifies the size in paragraphs (multiples of 16 bytes) of
the object in standard mode. In 386 enhanced mode, the size field specifies
the size of the object in bytes.
The owner field always specifies that the module is free.
The chain field specifies the previous and next addresses in the LRU list.
WDEB386 displays the addresses only if the segment is moveable and
discardable.
.dg ─ Display Global Heap
────────────────────────────────────────────────────────────────────────────
Syntax
.dg «object»
The .dg command displays a list of the global memory objects in the global
heap.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
object Specifies the first object to be listed.
The object parameter can be a handle,
selector, or (in 386 enhanced mode) a
heap address.
The list has the following form:
address: size segment-type owner «handle flags chain»
The address field specifies the selector of the memory in standard mode. In
386 enhanced mode, the address field specifies physical and heap addresses.
The size field specifies the size in paragraphs (multiples of 16 bytes) of
the object in standard mode. In 386 enhanced mode, the size field specifies
the size of the object in bytes.
The segment-type field specifies the type of object. The type can be any one
of the following:
Segment Type Meaning
────────────────────────────────────────────────────────────────────────────
CODE Segment contains program code.
DATA Segment contains program data and
possible stack and local heap data.
FREE Segment belongs to pool of free memory
objects ready for allocation by an
application.
PRIV Segment contains private data.
SENTINAL Segment marks the beginning or end of
the global heap.
The owner field specifies the module name of the application or library that
allocated the memory object. The name "pdb" is used for memory objects that
represent program descriptor blocks. These blocks contain execution
information about applications.
The handle field specifies the handle of the global memory object. If
WDEB386 displays no handle, the segment is fixed.
The flags field specifies the following:
Flag Meaning
────────────────────────────────────────────────────────────────────────────
D The segment is moveable and discardable.
L The segment is locked. If the segment is
locked, the lock count appears to the
right of the flag.
If WDEB386 displays a handle, but no flag, the segment is moveable but
nondiscardable.
The chain field specifies the previous and next addresses in the LRU list.
WDEB386 displays the addresses only if the segment is moveable and
discardable (the D flag).
.dh ─ Display Local Heap
────────────────────────────────────────────────────────────────────────────
Syntax
.dh
The .dh command displays a list of the local memory objects in the local
heap (if any) belonging to the current data segment. The command uses the
current value of the DS register to locate the data segment and check for a
local heap. The list of memory objects has the following form:
offset: size { BUSY | FREE }
The offset field specifies the address offset from the beginning of the data
segment to the local memory object.
The size field specifies the size of the object in bytes.
If BUSY is given, the object has been allocated and is currently in use. If
FREE is given, the object is in the pool of free objects ready to be
allocated by the application. A special memory object, SENTINAL, may also be
displayed.
.dm ─ Display Global Module List
────────────────────────────────────────────────────────────────────────────
Syntax
.dm
The .dm command displays a list of the global modules in the global heap.
The list has the following form:
module-handle module-type module-name file-name
The module-handle field specifies the handle of the module. The module-type
field specifies either a dynamic-link library (DLL) or the name of the
application you are debugging. The module-name field specifies the name of
the module. The file-name field specifies the name of the file from which
you loaded the application.
.dq ─ Dump Task Queue
────────────────────────────────────────────────────────────────────────────
Syntax
.dq
The .dq command displays a list containing information about the various
task queues supported by the system. The list has the following form:
task-descriptor-block stack-segment:stack-pointer number-of-events
priority internal-messaging-information module
The task-descriptor-block field specifies the selector or segment address.
The task descriptor block is identical to the "pdb."The
stack-segment:stack-pointer field specifies the stack segment and pointer.
The number-of-events field specifies the number of events waiting for the
segment. The priority field specifies the priority of the segment. The
internal-messaging-information field specifies information about internal
messages. The module field specifies the module name.
.du ─ Display Global LRU List
────────────────────────────────────────────────────────────────────────────
Syntax
.du
The .du command displays a list of the least-recently-used (LRU) global
memory objects in the global heap. The list has the following form:
address: size segment-type owner «handle flags chain»
The address field specifies the selector of the memory in standard mode. In
386 enhanced mode, the address field specifies physical and heap addresses.
The size field specifies the size in paragraphs (multiples of 16 bytes) of
the object in standard mode. In 386 enhanced mode, the size field specifies
the size of the object in bytes.
The segment-type field specifies the type of object. The type can be any one
of the following:
Segment Type Meaning
────────────────────────────────────────────────────────────────────────────
CODE Segment contains program code.
DATA Segment contains program data and
possible stack and local heap data.
FREE Segment belongs to pool of free memory
objects ready for allocation by an
application.
PRIV Segment contains private data.
SENTINAL Segment marks the beginning or end of
the global heap.
The owner field specifies the module name of the application or library that
allocated the memory object. The name "pdb" is used for memory objects that
represent program descriptor blocks. These blocks contain execution
information about applications.
The handle field specifies the handle of the global memory object.
The flags field specifies D, which means the segment is moveable and
discardable.
The chain field specifies the previous and next addresses in the LRU list.
.reboot ─ Reboot Target System
────────────────────────────────────────────────────────────────────────────
Syntax
.reboot
The .reboot command causes the target system to reboot.
bc ─ Clear Breakpoints
────────────────────────────────────────────────────────────────────────────
Syntax
bc {list | *}
The bc command removes one or more defined breakpoints.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
list Specifies any combination of integer
values in the range 0-9. If you specify
list, the debugger removes the specified
breakpoints.
* Clears all breakpoints.
Examples
bc 0 4 8
Removes breakpoints 0, 4, and 8.
bc *
Removes all breakpoints.
bd ─ Disable Breakpoints
────────────────────────────────────────────────────────────────────────────
Syntax
bd {list | *}
The bd command temporarily disables one or more breakpoints. To restore
breakpoints disabled by the bd command, use the be (Enable Breakpoints)
command.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
list Specifies any combination of integer
Parameter Description
────────────────────────────────────────────────────────────────────────────
list Specifies any combination of integer
values in the range 0-9. If you specify
list, the debugger disables the
specified breakpoints.
* Disables all breakpoints.
Examples
bd 0 4 8
Disables breakpoints 0, 4, and 8.
bd *
Disables all breakpoints.
be ─ Enable Breakpoints
────────────────────────────────────────────────────────────────────────────
Syntax
be {list | *}
The be command restores (enables) one or more breakpoints that have been
temporarily disabled by a bd (Disable Breakpoints) command.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
list Specifies any combination of integer
values in the range 0-9. If you specify
list, the debugger enables the specified
breakpoints.
Parameter Description
────────────────────────────────────────────────────────────────────────────
* Enables all breakpoints.
Examples
be 0 4 8
Enables breakpoints 0, 4, and 8.
be *
Enables all breakpoints.
bl ─ List Breakpoints
────────────────────────────────────────────────────────────────────────────
Syntax
bl
The bl command lists current information about all breakpoints created by
the bp (Set Breakpoints) command.
Examples
If no breakpoints are currently defined, the debugger displays nothing.
Otherwise, the breakpoint number, enabled status, breakpoint address, number
of passes remaining, initial number of passes (in parentheses), and any
optional debugger commands to be executed when the breakpoint is reached are
displayed on the screen, as in the following example:
0 e 04BA:0100
4 d 04BA:0503 4 (10)
8 e 0D2D:0001 3 (3) "R;DB DS:SI"
9 e xxxx:0012
In this example, breakpoints 0 and 8 are enabled (e), while 4 is disabled
(d). Breakpoint 4 had an initial pass count of 10 and has 4 remaining passes
to be taken before the breakpoint. Breakpoint 8 had an initial pass count of
3 and must make all 3 passes before it halts execution and forces the
debugger to execute the optional debugger commands enclosed in quotation
marks. Breakpoint 0 shows no initial pass count, which means it was set to
1.
Breakpoint 9 shows a virtual breakpoint (a breakpoint set in a segment that
has not been loaded into memory).
bp ─ Set Breakpoints
────────────────────────────────────────────────────────────────────────────
Syntax
bp«n» addr «passcnt» «"cmds"»
The bp command creates a software breakpoint at an address. During program
execution, software breakpoints stop program execution and force the
debugger to execute the default or optional command string. Unlike
breakpoints created by the g (Go) command, software breakpoints remain in
memory until you remove them with the bc (Clear Breakpoints) command or
temporarily disable them with the bd (Disable Breakpoints) command.
The debugger allows up to 10 software breakpoints (0-9). If you specify more
than 10 breakpoints, the debugger returns a "Too Many Breakpoints" message.
The addr parameter is required for all new breakpoints.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
n Specifies which breakpoint is being
created. No space is allowed between the
bp and n. If n is omitted, the first
available breakpoint number is used.
addr Specifies any valid instruction address
Parameter Description
────────────────────────────────────────────────────────────────────────────
addr Specifies any valid instruction address
(the first byte of an instruction
opcode).
passcnt Specifies the number of times the
breakpoint is to be ignored before being
executed. It can be any 16-bit value.
cmds Specifies an optional list of debugger
commands to be executed in place of the
default command when the breakpoint is
reached. You must enclose optional
commands in quotation marks, and
separate optional commands with
semicolons (;).
Examples
bp 123
The first example creates a breakpoint at address CS:123.
bp8 400:23 "db DS:SI"
This example creates breakpoint 8 at address 400:23 and executes a db
(Display Bytes) command.
bp 100 10 "r;c100 L 100 300"
This example creates a breakpoint at address 100 in the current CS selector
and displays the registers before comparing a block of memory. The
breakpoint is ignored 16 (10H) times before being executed.
c ─ Compare Memory
────────────────────────────────────────────────────────────────────────────
Syntax
c range addr
The c command compares one memory location against another memory location.
If the two memory areas are identical, the debugger displays nothing and
returns the debugger prompt. Differences, when they exist, are displayed as
follows:
addr1 byte1 byte2 addr2
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
range Specifies the block of memory that is to
be compared with a block of memory
starting at addr.
Parameter Description
────────────────────────────────────────────────────────────────────────────
addr Specifies the starting address of the
second block of memory.
Examples
The following two commands have the same effect. Each compares the block of
memory from 100H to 1FFH with the block of memory from 300H to 3FFH:
c100 1FF 300
This first example specifies a range with a starting address of 100H and an
ending address of 1FFH. This block of memory is compared with a block of
memory of the same size starting at 300H.
c100 L 100 300
The second example compares the same block of memory, but specifies the
range by using the L (length) option.
d ─ Display Memory
────────────────────────────────────────────────────────────────────────────
Syntax
d «range»
The d command displays the contents of memory at a given address or in a
range of addresses. The d command displays one or more lines, depending on
the range given. Each line displays the address of the first item displayed.
The command always displays at least one value. The memory display is in the
format defined by a previously executed db (Display Bytes), dd (Display
Doublewords), or dw (Display Words) command. Each subsequent d (typed
without parameters) displays the bytes immediately following those last
displayed.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
range Specifies the range of addresses to
display. If you omit range, the d
command displays the next byte of memory
after the last one displayed. The d
command must be separated by at least
one space from any range value.
Examples
d CS:100 L 20
This example displays 20H bytes at CS:100.
d CS:100 115
This example displays all the bytes in the range 100H to 115H in the CS
selector.
db ─ Display Bytes
────────────────────────────────────────────────────────────────────────────
Syntax
db «range»
The db command displays the values of the bytes at a given address or in a
given range.
The display is in two portions: a hexadecimal display (each byte is shown in
hexadecimal value) and an ASCII display (the bytes are shown in ASCII
characters). Nonprinting characters are denoted by a period (.) in the ASCII
portion of the display. Each display line shows 16 bytes, with a hyphen
between the eighth and ninth bytes. Each displayed line begins on a 16-byte
boundary.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
range Specifies the range of addresses to
display. If you omit range, 128 bytes
are displayed beginning at the first
address after the address displayed by
the previous db command.
Example
db CS:100 0A
This example displays the lines in the following format:
04BA:0100 54 4F 4D 20 53 . . . 45 52 TOM SAWYER
Each line of the display begins with an address, incremented by 10H from the
address on the previous line.
dd ─ Display Doublewords
────────────────────────────────────────────────────────────────────────────
Syntax
dd «range»
The dd command displays the hexadecimal values of the doublewords at the
address specified or in the specified range of addresses.
The dd command displays one or more lines, depending on the range given.
Each line displays the address of the first doubleword in the line, followed
by up to four hexadecimal doubleword values. The hexadecimal values are
separated by spaces. The dd command displays values until the end of the
range or until the first 32 doublewords have been displayed.
Typing dd displays 32 doublewords at the current dump address. For example,
if the last byte in the previous dd command was 04BA:0110, the display
starts at 04BA:0111.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
range Specifies the range of addresses to
display. If you omit range, 32 DWORDs
are displayed beginning at the first
address after the address displayed by
the previous dd command.
Example
dd CS:100 110
This example displays the doubleword values from CS:100 to CS:110. The
resulting display is similar to the following:
04BA:0100 7473:2041 676E:6972 5405:0104 0A0D:7865
04BA:0110 0000:002E
No more than four values per line are displayed.
dg ─ Display GDT
────────────────────────────────────────────────────────────────────────────
Syntax
dg«a» «range»
The dg command displays the specified range of entries in the GDT (Global
Descriptor Table).
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
range Specifies the range of entries in the
GDT. If you omit range, the debugger
displays the entire contents of the GDT.
a Causes all entries in the table to be
displayed, not just the valid entries.
The default is to display just the valid
GDT entries. If the command is passed an
LDT selector, it displays LDT and the
appropriate LDT entry.
Example
dg 0 40
This example displays only the valid entries from 0H to 40H in the GDT. The
resulting display is similar to the following:
0008 Data Seg Base=01D700 Limit=3677 DPL=0 Present ReadWrite Accessed
0010 TSS Desc Base=007688 Limit=002B DPL=0 Present Busy
0018 Data Seg Base=020D7A Limit=03FF DPL=0 Present ReadWrite
0020 Data Seg Base=000000 Limit=03FF DPL=0 Present ReadWrite
0028 LDT Desc Base=000000 Limit=0000 DPL=0 Present
0030 Data Seg Base=000000 Limit=0000 DPL=0 Present ReadWrite
0040 Data Seg Base=000400 Limit=03BF DPL=3 Present ReadWrite
di ─ Display IDT
────────────────────────────────────────────────────────────────────────────
Syntax
di«a» «range»
The di command displays the specified range of entries in the IDT (Interrupt
Descriptor Table).
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
a Causes all entries in the table to be
displayed, not just the valid ones. The
default is to display just the valid IDT
entries.
range Specifies the range of entries to be
displayed. If you omit range, the
debugger displays all IDT entries.
Example
di 0 10
This command produces a display of valid entries similar to the following:
0000 Int Gate Sel=1418 Offst=03D8 DPL=3 Present
0001 Int Gate Sel=2D38 Offst=0049 DPL=3 Present
0002 Int Gate Sel=1418 Offst=03E4 DPL=3 Present
0003 Int Gate Sel=2D38 Offst=006F DPL=3 Present
0004 Int Gate Sel=1418 Offst=0417 DPL=3 Present
0005 Int Gate Sel=1418 Offst=041D DPL=3 Present
0006 Int Gate Sel=1418 Offst=0423 DPL=3 Present
0007 Int Gate Sel=2D38 Offst=00A3 DPL=3 Present
0008 Int Gate Sel=1418 Offst=042F DPL=3 Present
0009 Int Gate Sel=2D38 Offst=00CA DPL=3 Present
000A Int Gate Sel=2D38 Offst=00D3 DPL=3 Present
000B Int Gate Sel=2D38 Offst=0156 DPL=3 Present
000C Int Gate Sel=2D38 Offst=01A4 DPL=3 Present
000D Int Gate Sel=2D38 Offst=01C6 DPL=3 Present
dl ─ Display LDT
────────────────────────────────────────────────────────────────────────────
Syntax
dl«a | p | s | h» «range»
The dl command displays the specified range of entries in the LDT (Local
Descriptor Table).
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
a Causes all entries in the table to be
displayed, not just the valid ones. The
default is to display just the valid LDT
entries. If the command is passed a GDT
selector, it displays GDT and the
appropriate GDT entry.
p Causes private segment selectors to be
displayed.
s Causes shared segment selectors to be
Parameter Description
────────────────────────────────────────────────────────────────────────────
s Causes shared segment selectors to be
displayed.
h Causes huge segment selectors to be
displayed. To display the huge segment
selectors, give the shadow selector
followed by the maximum number of
selectors reserved for that segment plus
1.
range Specifies the range of entries to be
displayed. If you omit range, the entire
table is displayed.
Example
dla 4 57
This example displays all of the LDT entries. The command produces a display
similar to the following:
0014 Call Gate Sel=1418 Offst=0417 DPL=0 NotPres WordCount=1D
001C Code Seg Base=051418 Limit=0423 DPL=0 NotPres ExecOnly
0027 Reserved Base=87F000 Limit=FEA5 DPL=3 Present
0034 Code Seg Base=05F000 Limit=1805 DPL=0 NotPres ExecOnly
003C Code Seg Base=05F000 Limit=EF57 DPL=0 NotPres ExecOnly
0047 Code Seg Base=4DC000 Limit=0050 DPL=3 Present ExecOnly
004D Reserved Base=71F000 Limit=F841 DPL=1 NotPres
0057 Code Seg Base=59F000 Limit=E739 DPL=3 Present ExecOnly
dt ─ Display TSS
────────────────────────────────────────────────────────────────────────────
Syntax
dt «addr»
The dt command displays the current TSS (Task State Segment) or the selected
TSS if you specify the optional address.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
addr Specifies the address of the TSS to
display. If no addr is given, dt
displays the current TSS pointed to by
the TR register.
Example
dt
This example displays the current TSS. The resulting display is similar to
the following:
AX=0000 BX=0000 CX=0000 DX=0000 SP=0000 BP=0000 SI=0000
DI=0000
IP=0000 CS=0000 DS=0000 ES=0000 SS=0000 NV UP DI PL NZ NA PO NC
SS0=0038 SP0=08DE SS1=0000 SP1=0000 SS2=0000 SP2=0000
IOPL=0 LDTR=0028 LINK=0000
dw ─ Display Words
────────────────────────────────────────────────────────────────────────────
Syntax
dw «range»
The dw command displays the hexadecimal values of the words at a given
address or in a given range of addresses.
The command displays one or more lines, depending on the range given. Each
line displays the address of the first word in the line, followed by up to
eight hexadecimal word values. The hexadecimal values are separated by
spaces. The command displays values until the end of the range or until the
first 64 words have been displayed.
Typing dw displays 64 words at the current dump address. If the last word in
the previous dw command was displayed at address 04BA:0110, the next display
will start at 04BA:0112.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
range Specifies the range of addresses to
display. If you omit range, 64 words are
displayed beginning at the first address
after the address displayed by the
previous dw command.
Example
dw CS:100 110
This example displays the word values from CS:100 to CS:110, resulting in a
display similar to the following:
04BA:0100 2041 7473 6972 676E 0104 5404 7865 0A0D
04BA:0110 002E
e ─ Enter Byte
────────────────────────────────────────────────────────────────────────────
Syntax
e addr «list»
The e command enters byte values into memory at a specified address. You can
specify the new values on the command line, or let the debugger prompt you
for values. If the debugger uses a prompt, it displays the address and its
contents and then waits for you to perform one of the following actions:
■ Replace a byte value with a value you type. Type the value after the
current value. If the byte you type is an illegal hexadecimal value or
contains more than two digits, the system does not echo the illegal or
extra character.
■ Press the SPACEBAR to advance to the next byte. To change the value,
type the new value after the current value. If, when you press the
SPACEBAR, you move beyond an 8-byte boundary, the 80386 Debugger
starts a new display line with the address displayed at the beginning.
■ Type a hyphen (-) to return to the preceding byte. If you decide to
change a byte before the current position, typing the hyphen returns
the current position to the previous byte. When you type the hyphen, a
new line is started with its address and byte value displayed.
■ Press ENTER to terminate the e command. You can press ENTER at any
byte position.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
addr Specifies the address of the first byte
to be entered.
list Specifies the byte values used for
replacement. These values are inserted
automatically. If an error occurs when
you are using the list form of the
command, no byte values are changed.
Examples
eCS:100
04BA:0100 EB.
This example prompts you to change the value EB at CS:100. To step through
the subsequent bytes without changing values, press the SPACEBAR.
04BA:0100 EB.41 10. 00. BC.
In this example, the SPACEBAR is pressed three times.
To return to a value at a previous address, type a hyphen.
04BA:0100 EB.41 10. 00. BC.-
04BA:0102 00.-
04BA:0101 10.
This example returns to the address CS:101.
f ─ Fill Memory
────────────────────────────────────────────────────────────────────────────
Syntax
f range list
The f command fills the addresses in a specified range with the values in
the specified list.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
range Specifies the range of addresses to be
filled. If range contains more bytes
than the number of values in list, the
debugger uses list repeatedly until all
bytes in range are filled. If any of the
memory in range is not valid (bad or
nonexistent), an error will occur in all
succeeding locations.
Parameter Description
────────────────────────────────────────────────────────────────────────────
list Specifies the list of values to fill the
given range. If list contains more
values than the number of bytes in range,
the debugger ignores the extra values in
list.
Example
f04BA:100 L 100 42 45 52 54 41
This example fills memory locations 04BA:100 through 04BA:1FF with the bytes
specified, repeating the five values until it has filled all 100H bytes.
g ─ Go
────────────────────────────────────────────────────────────────────────────
Syntax
g «=addr «addr...»»
The g command executes the program currently in memory. If you type the g
command by itself, the current program executes as if it had run outside the
debugger. If you specify =addr, execution begins at the specified address.
Specifying an optional breakpoint address causes execution to halt at the
first address encountered, regardless of the position of the address in the
list of addresses that halts execution or program branching. When program
execution reaches a breakpoint, the default command string is executed.
The stack (SS:SP) must be valid and have six bytes available for this
command. The g command uses an IRET instruction to cause a jump to the
program under test. The stack is set, and the user flags, CS register, and
IP register are pushed on the user stack. (If the user stack is not valid or
is too small, the operating environment may crash.) An interrupt code (0CCH)
is placed at the specified breakpoint addresses.
When the debugger encounters an instruction with the breakpoint code, it
restores all breakpoint addresses listed with the g command to their
original instructions. If you do not halt execution at one of the
breakpoints, the interrupt codes are not replaced with the original
instructions.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
=addr Specifies the address where execution is
to begin. The equal sign (=) is needed
to distinguish the starting address from
the breakpoint address.
addr Specifies one or more breakpoint
addresses where execution is to halt.
You can specify up to 10 breakpoints,
but only at addresses containing the
first byte of an opcode. If you attempt
Parameter Description
────────────────────────────────────────────────────────────────────────────
first byte of an opcode. If you attempt
to set more than 10 breakpoints, an
error message will be displayed.
Example
gCS:7550
This example executes the program currently in memory until address 7550 in
the CS selector is executed. The debugger then executes the default command
string, removes the INT 3 trap from this address, and restores the original
instruction. When you resume execution, the original instruction will be
executed.
h ─ Hexadecimal Arithmetic
────────────────────────────────────────────────────────────────────────────
Syntax
h word word
The h command performs hexadecimal arithmetic on the two specified
parameters.
The debugger adds, subtracts, multiplies, and divides the second parameter
and the first parameter, then displays the results on one line. The debugger
does 32-bit multiplication and displays the result as doublewords. The
debugger displays the result of division as a 16-bit quotient and a 16-bit
remainder.
╓┌──────────────────┌────────────────────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
word Specifies two 16-bit word parameters.
Example
h 300 100
This example performs the calculations and displays the following:
+0400 -0200 *0000 0003 /0003 0000
i ─ Input Byte
────────────────────────────────────────────────────────────────────────────
Syntax
i word
The i command inputs and displays one byte from a specified port.
╓┌───────────────────┌───────────────────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
word Specifies the 16-bit port address.
Example
i2F8
This example displays the byte at port address 2F8H.
j ─ Conditional Execute
────────────────────────────────────────────────────────────────────────────
Syntax
j expr «"cmds"»
The j command executes the specified commands when the specified expression
is TRUE. If expr is FALSE, the debugger continues to the next command line
(excluding the commands in cmds).
The j command is useful in breakpoint commands to conditionally break
execution when an expression becomes true.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
expr Evaluates to a Boolean TRUE or FALSE.
cmds Specifies a list of debugger commands to
be executed when expr is TRUE. The list
must be enclosed in single or double
quotation marks. You must separate
optional commands with semicolons (;).
You can use a single or NULL command
without quotation marks.
Parameter Description
────────────────────────────────────────────────────────────────────────────
Examples
bp 167:1454 "J AX == 0;G"
This example causes execution to break if AX does not equal zero when the
breakpoint is reached.
bp 167:1462 "J BY (DS:SI+3) == 40 'R;G';DG DS"
This example displays the registers and continues execution when the byte
pointed to by DS:SI +3 is equal to 40H; otherwise, it displays the
descriptor table.
bp 156:1455 "J (MSW AND 1) == 1 'G'"
This example breaks execution when the breakpoint is reached in real mode.
bp 156:1455 "J (MSW AND 1) 'G'"
This example is a shortcut that produces the same results as the preceding
command.
k ─ Backtrace Stack
────────────────────────────────────────────────────────────────────────────
Syntax
k «ss:bp» «cs:ip»
This command displays the current stack frame. Each line shows the name of a
procedure, its arguments, and the address of the statement that called it.
The command displays four 2-byte arguments by default. The ka command
changes the number of arguments displayed by this command.
Using the k command at the beginning of a function (before the function
prolog has been executed) will give incorrect results. The command uses the
BP register to compute the current backtrace, and this register is not
correctly set for a function until its prolog has been executed.
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
ss:bp Specifies an optional stack-frame address.
cs:ip Specifies an optional code address.
ka ─ Set Backtrace Arguments
────────────────────────────────────────────────────────────────────────────
Syntax
ka value
The ka command sets the number of parameters displayed for all subsequent
stack trace commands. The initial default is four.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
value Specifies the number of parameters to be
displayed. The value parameter must be
in the range 0 to 31.
kt ─ Backtrace Task Stack
────────────────────────────────────────────────────────────────────────────
Syntax
kt «tdb»
This command displays the stack frame of the current task or the task
specified by tdb. Each line shows the name of a procedure, its arguments,
and the address of the statement that called it. The command displays four
2-byte arguments by default. The ka command changes the number of arguments
displayed by this command.
This command can be combined with the kv command; the syntax for the
combined command is kvt «tdb».
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
tdb Specifies the segment address of the
program descriptor block for the task to
be traced. To obtain the tdb value, use
the .dq (Dump Task Queue) command. If
tdb is not supplied, the kt command
displays the stack frame of the current
task.
kv ─ Verbose Backtrace Stack
────────────────────────────────────────────────────────────────────────────
Syntax
kv
The kv command displays information that the k (Backtrace Stack) command
provides, plus information about stack location and frame pointer values for
each frame.
la ─ List Absolute Symbols
────────────────────────────────────────────────────────────────────────────
Syntax
la
The la command lists the absolute symbols in the currently active map.
lg ─ List Groups
────────────────────────────────────────────────────────────────────────────
Syntax
lg
The lg command lists the selector (or segment) and the name of each group in
the active map.
Example
lg
This example produces a display similar to the following:
#0090:0000 DOSCODE
#0828:0000 DOSGROUP
#1290:0000 DBGCODE
#16C0:0000 DBGDATA
#1A38:0000 TASKCODE
#1AD8:0000 DOSRING3CODE
#1AE0:0000 DOSINITCODE
#2018:0000 DOSINITRMCODE
#20A8:0000 DOSINITDATA
#23F8:0000 DOSMTE
#2420:0000 DOSHIGHDATA
#28D0:0000 DOSHIGHCODE
#3628:0000 DOSHIGH2CODE
#0090:0000 DOSCODE
lm ─ List Map
────────────────────────────────────────────────────────────────────────────
Syntax
lm
The lm command lists the symbol files currently loaded and indicates which
one is active.
The last symbol file loaded is made active by default. Use the w (Change
Map) command to change the active file.
Example
lm
This example returns a display similar to the following:
COMSAM2D is active.
DISK01D.
ln ─ List Near
────────────────────────────────────────────────────────────────────────────
Syntax
ln «addr»
The ln command lists the symbol nearest to the specified address. The
command lists the nearest symbol before and after the specified addr
parameter.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
addr Specifies any valid instruction address.
The default is the current disassembly
address.
Example
ln
This example displays the nearest symbols before and after the current
disassembly address. The output looks like this:
6787 VerifyRamSemAddr + 10
67AA PutRamSemID - 13
ls ─ List Symbols
────────────────────────────────────────────────────────────────────────────
Syntax
ls {group-name | name-chars | *}
The ls command lists the symbols in the specified group, or names that match
the search specification in all groups. Only the * wildcard is accepted and
only as the last character (all other characters will be ignored).
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
group-name Names the group that contains the
symbols you want to list.
name-chars Displays a list of symbols that begin
with the specified characters.
Example
ls DOSRING3CODE
ls vkd*
ls vmm_base
The first example displays all of the symbols in the DOSRING3CODE group. The
debugger displays the symbols in a format similar to the following:
0000 Sigdispatch
001A LibInitDisp
The second example displays all of the symbols that start with the first
three characters "vkd." This will show the group names as they are searched,
similar to the following:
GROUP: [0028] CODE
60003A74 VKD_Control_Debug
GROUP: [0030] DATA
6001DFFC VKD_CB_Offset
GROUP: [0030} IDATA
The third example displays the address and group for the symbol "VMM_base."
m ─ Move Memory
────────────────────────────────────────────────────────────────────────────
Syntax
m range addr
The m command moves a block of memory from one memory location to another.
Overlapping moves─those where part of the block overlaps some of the current
addresses─are always performed without loss of data. Addresses that could be
overwritten are moved first. For moves from higher to lower addresses, the
sequence of events is first to move the data at the block's lowest address
and then to work toward the highest. For moves from lower to higher
addresses, the sequence is first to move the data at the block's highest
address and then to work toward the lowest.
Note that if the addresses in the block being moved will not have new data
written to them, the data in the block before the move will remain. The m
command copies the data from one area into another, in the sequence
described, and writes over the new addresses─hence, the importance of the
moving sequence.
To review the results of a memory move, use the d (Display Memory) command,
specifying the same address you used with the m command.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
range Specifies the block of memory to be
moved.
addr Specifies the starting address where the
memory is to be relocated.
Example
mCS:100 110 CS:500
This example first moves address CS:110 to CS:510 and then moves CS:10F to
CS:50F, and so on, until CS:100 is moved to CS:500.
o ─ Output to Port
────────────────────────────────────────────────────────────────────────────
Syntax
o word byte
The o command writes a byte to a 16-bit port address.
╓┌────────────┌──────────────────────────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
word Specifies the 16-bit port address you are writing to.
byte Specifies the 8-bit value to be written to the port.
Example
o 2F8 4F
This example writes the byte value 4F to output port 2F8.
p ─ Program Trace
────────────────────────────────────────────────────────────────────────────
Syntax
p«N» «=addr »«count»
The p command executes the instruction at a specified address and displays
the current values of all the registers and flags (whatever the z command
has been set to). It then executes the default command string, if any.
The p command is identical to the t (Trace Instructions) command, except
that it automatically executes and returns from any calls or software
interrupts it encounters. The t command always stops after executing into
the call or interrupt, leaving execution control inside the called routine.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
N Suppresses the register display so just
the assembly line is displayed. The
suppression will result only if the
default command, z, is set to a normal
setting, r.
addr Specifies the starting address to begin
execution. If you omit the optional addr,
execution begins at the instruction
pointed to by the CS and IP registers.
Use the equal sign (=) only if you
specify an addr.
Parameter Description
────────────────────────────────────────────────────────────────────────────
specify an addr.
count Specifies the number of instructions to
execute before halting and executing the
default command string. If you specify
count, the command continues to execute
count instructions before stopping. The
command executes the default command
string for each instruction before
executing the next.
Examples
p
This example executes the instruction pointed to by the current CS and IP
register values before it executes the default command string.
p=120
This example executes the instruction at address CS:120 before it executes
the default command string.
r ─ Display Registers
────────────────────────────────────────────────────────────────────────────
Syntax
r reg =word
The r command displays the contents of one or more CPU registers and allows
the contents to be changed to new values. If you specify a reg with the r
command, the 16-bit value of that register is displayed in hexadecimal
followed by a colon (:) prompt on the next line. You can then enter a new
word value for the specified register or press ENTER if you do not want to
change the register value.
If you use f for reg, the debugger displays the flags in a row at the
beginning of a new line and displays a hyphen (-) after the last flag.
You can type new flag values in any order as alphabetic pairs. You do not
have to leave spaces between these values. To exit the r command, press
ENTER. Any flags for which you did not specify new values remain unchanged.
If you type more than one value for a flag, or if you enter an invalid flag
name, the debugger returns a "Bad Flag" error message. In both cases, the
flags up to the error in the list are changed; those flags at and after the
error are not changed.
╓┌──────────┌───────────────────────────────┌────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
reg Specifies the register to be
displayed. If you omit reg,
the debugger displays the
Parameter Description
────────────────────────────────────────────────────────────────────────────
the debugger displays the
contents of all registers and
flags along with the next
executable instruction.
word Specifies the new value for
the register. For the Flags
register, set or clear a flag
by using one of the following
names:
Flag Name Action
OV Overflow set
NV Overflow clear
DN Direction decrement
Parameter Description
────────────────────────────────────────────────────────────────────────────
UP Direction increment
EI Interrupt enabled
DI Interrupt disabled
NG Sign negative
PL Sign positive
ZR Zero set
NZ Zero clear
Flag Name Action
AC Auxiliary Carry set
Parameter Description
────────────────────────────────────────────────────────────────────────────
NA Auxiliary Carry clear
PE Parity even
PO Parity odd
CY Carry set
NC Carry clear
NT Nested Task toggle on and off
For the MSW register, use the following names to set a flag:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Flag Name Action
Flag Name Action
────────────────────────────────────────────────────────────────────────────
TS Sets the task switch bit.
EM Sets the emulation processor extension bit.
MP Sets the monitor processor extension bit.
PM Sets the protected mode bit.
Comments
Setting the protected-mode bit from within the debugger does not set the
target system to run in protected mode. The debugger simulates the setting.
To configure the target system to run in protected mode, you would have to
set the PM bit in the MSW register and reset the target system to boot in
protected mode.
Examples
r
This example produces the following display:
AX=0698 BX=2008 CX=2C18 DX=18AB SP=1B7A BP=00FF SI=0020 DI=10CD
IP=0450 CS=18B0 DS=1BE8 ES=0DA8 SS=0048 NV UP DI PL NZ NA PO NC
GDTR=01BE80 3687 IDTR=01F508 03FF TR=0010 LDTR=0028 IOPL=3 MSW=PM
18B0:0450 C3 RET
rf
This example displays each flag with a two-character alphabetic code. To
change any flag, type the opposite two-letter code. The flags are either set
or cleared. This example produces a display similar to the following:
NV UP DI NG NZ AC PE NC - _
To change the value of a flag's setting, enter an opposite setting for the
flag you wish to set.
NV UP DI NG NZ AC PE NC - PLEICY
This example changes the sign flag to positive, enables interrupts, and sets
the carry flag.
rmsw
This example modifies the MSW (Machine Status Word) bits. The debugger
displays the status of the MSW register and prints a colon on the next line.
s ─ Search Bytes
────────────────────────────────────────────────────────────────────────────
Syntax
s range { list | "string" }
The s command searches an address range for a specified list of bytes or an
ASCII character string.
You can include one or more bytes in list, but multiple bytes must be
separated by a space or comma. When you search for more than one byte, the
command returns only the first address of the byte string. When your list
contains only one byte, the debugger displays all addresses of the byte in
the range.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
range Specifies the range of addresses to be
searched.
list Specifies one or more byte values to
search for.
string Specifies an ASCII character string to
be searched for. The string must be
enclosed in quotation marks.
Example
sCS:100 110 41
This example searches for byte 41 in the range CS:100 to CS:110. If it finds
the value, the command produces a display similar to the following:
04BA:0104
04BA:010D
t ─ Trace Instructions
────────────────────────────────────────────────────────────────────────────
Syntax
t«N» «=addr» «word»
The t command executes one or more instructions along with the default
command string, then displays the decoded instruction. If you include an
addr parameter, tracing starts at the specified address. Otherwise, the
command steps through the next machine instruction and then executes the
default command string.
The t command uses the hardware trace mode of the Intel microprocessor.
Consequently, you can also trace instructions stored in ROM.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
N Suppresses the register display so just
the assembly line is displayed. This
works only if the default command, z, is
set to r (the normal setting).
addr Specifies the instruction address to
start tracing. The equal sign (=) is
required.
word Specifies the number of instructions to
Parameter Description
────────────────────────────────────────────────────────────────────────────
word Specifies the number of instructions to
execute and trace.
Example
t
AX=0E00 BX=00FF CX=0007 DX=01FF SP=039D BP=0000 SI=005C DI=0000
IP=011A CS=04BA DS=04BA ES=04BA SS=04BA NV UP DI NG NZ AC PE NC
GDTR=01D700 3677 IDTR=020D7A 03FF TR=0010 LDTR=0028 IOPL=3 MSW=PM
04BA:011A CD21 PUSH 21
This example traces the current position (04BA:011A) and uses the default
command string (r command) to display registers.
t=011A 10
This command causes the debugger to execute 16 (10H) instructions beginning
at 011A in the current selector. The debugger executes and displays the
results of the default command string for each instruction. The display
scrolls until the last instruction is executed. Use CONTROL+S to stop the
display from scrolling, and CONTROL+Q to resume.
u ─ Unassemble Bytes
────────────────────────────────────────────────────────────────────────────
Syntax
u range
The u command disassembles bytes and displays the source statements, with
addresses and byte values, that correspond to them.
The display of disassembled code looks similar to a code listing for an
assembled file. If you type the u command by itself, 20H bytes are
disassembled at the first address after the one displayed by the previous u
command.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
range Specifies the range of addresses in
which instructions are to be
disassembled. If no range is given, the
command disassembles the next 20H bytes.
Example
uCS:046C
This example returns a display similar to the following:
1A60:046C C3 RET
1A60:046D 9A6B3E100D CALL 0D10:3E6B
1A60:0472 33C0 XOR AX,AX
1A60:0474 50 PUSH AX
1A60:0475 9D POPF
1A60:0476 9C PUSHF
1A60:0477 58 POP AX
1A60:0478 2500F0 AND AX,F000
1A60:047B 3D00F0 CMP AX,F000
1A60:047E 7508 JNZ 0488
1A60:0480 689C26 PUSH 269C
1A60:0483 9AF105100D CALL 0D10:05F1
If the bytes in some addresses are altered, the disassembler alters the
instruction statements. You can also use the u command for the changed
locations, for the new instructions viewed, and for the disassembled code
used to edit the source file.
v ─ Set Interrupt Vector Trapping
────────────────────────────────────────────────────────────────────────────
Syntax
v«1 | 3»
The v command is used to specify which privilege rings should have
interrupts 1 and 3 trapped. This is useful for allowing the 80386 Debugger
to coexist with other debuggers such as the Symbolic Debugger (SYMDEB) and
CodeView for Windows (CVW). The 80386 Debugger handles interrupts 1 and 3
which occur in any privilege rings where trapping is enabled, but reflects
the interrupts if trapping is disabled, so that the secondary debugger will
see them. To use the command, enter v1 or v3 as the command with no
parameters. WDEB386 then displays the current rings for which trapping is
enabled. For example:
#v1
Rings trapped for int 1 - 0 1 2 3 V
? +
The question mark (?) is displayed to prompt you for changes. The plus sign
(+) indicates that you are in enabling mode, so you can just press 0, 1, 2,
3, or V to enable trapping in the required ring. If you need to disable
trapping in any rings, then press HYPHEN ( - ); this will change the plus
sign to a minus sign, indicating that you are now disabling trapping.
Pressing PLUS SIGN ( + ) will get you back into enabling mode. Any number of
changes can be made at one time. The current mode is displayed after each
change. For example:
#v1
Rings trapped for int 1 - 0 2 V
? +1 +3 -2 -
This command sequence was created by pressing 1, 3, HYPHEN, 2, and ENTER or
the SPACEBAR. It enabled trapping INT 1 instructions in rings 1 and 3 and
disabled trapping in ring 2.
vl ─ Display Interrupt Trapping Information
────────────────────────────────────────────────────────────────────────────
Syntax
vl
This command shows which privilege rings have trapping enabled for
interrupts 1 and 3. The v command can be used to enable or disable trapping
in specific privilege rings.
Example
vl
Rings trapped for int 1 - 0 1 2 3 V
Rings trapped for int 3 - 0 1 2 3 V
w ─ Change Map
────────────────────────────────────────────────────────────────────────────
Syntax
w «map-name»
The w command changes the active map file.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
map-name Specifies the name of the map file you
want to make active. Use the lm (List
Map) command to display a list of
available map files.
If map-name is not specified, then the
loaded maps are displayed and the user
is prompted to select a map by pressing
its corresponding option number.
Examples
lm
COMSAM2D is active.
DISK01D.
w DISK01D
The first example displays the loaded map files using the lm command, then
sets the active map file to DISK01D.
W
1. KERNEL
2. Win386 is active
activate which map?
The second example shows selecting the desired map from the list of
available maps. At the prompt, pressing 1 will activate the KERNEL map;
pressing 2 will leave the Win386 map activated; pressing the SPACEBAR will
leave the current map activated; any other key will be ignored and the
debugger will continue to wait for input.
y ─ Debugger Option Command
────────────────────────────────────────────────────────────────────────────
Syntax
y [? | 386env | dislwr | regterse | codebytes | symaddrs]
This command allows the debugger configuration to be changed. The ? option
prints the current options supported. The y command by itself prints the
current state of the options. The y and a flag name sets or toggles an
options flag.
386env - 32 bit environment (toggles)
dislwr - lower case disassembly (toggles)
regterse - terse register set (toggles)
codebytes - terse instruction disassembly (toggles)
symaddrs - symbols and addresses (toggles)
All these flags toggle their state when set and are printed only when the
option is on.
The 386env flag controls the size of addresses and registers, when
displayed. When this option is on, addresses, registers, etc., are printed
in 32-bit formats; otherwise they are printed in 16-bit formats. This flag
has nothing to do with the CPU (286/386) the debugger is running on, only
the display sizes.
The dislwr flag controls the disassembler's lowercase option. When the flag
is on, disassembly is in lowercase.
The regterse flag controls the number of registers that are displayed in the
register dump command. In the 386 environment (386env on), when the regterse
flag is on, only the first three lines are displayed (instead of the normal
six-line-plus disassembly line display). In the 286 environment (386env
off), only the first two lines of the normal three-line display (plus the
disassembly line) are printed.
The codebytes flag controls the display of the actual code bytes when
disassembling.
The symaddrs flag controls showing just a symbol name or symbol name and
address when disassembling.
z ─ Zap Embedded INT 1 and INT 3 Instructions
────────────────────────────────────────────────────────────────────────────
Syntax
z
Zaps the current INT 3 or the previous INT 1 instruction, by replacing the
instruction bytes with NOP instructions. This allows the user to avoid INT 1
or INT 3 instructions that were assembled into the executable file from
breaking into the debugger more than once.
zd ─ Execute Default Command String
────────────────────────────────────────────────────────────────────────────
Syntax
zd
The zd command executes the default command string.
The default command string is initially set to the r (Display Registers)
command by the debugger. The default command string is executed every time a
breakpoint is encountered during program execution or whenever a p (Program
Trace) or t (Trace Instructions) command is executed.
Use the zl command to display the default command string and the zs command
to change the default command string.
zl ─ Display Default Command String
────────────────────────────────────────────────────────────────────────────
Syntax
zl
The zl command displays the default command string.
Example
zl
"R"
This example displays the default command string.
zs ─ Change Default Command String
────────────────────────────────────────────────────────────────────────────
Syntax
zs "string"
The zs command lets you change the default command string.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Parameter Description
────────────────────────────────────────────────────────────────────────────
string Specifies the new default command string.
The string must be enclosed in single or
double quotation marks. You must
separate the debugger commands within
the string with semicolons.
Example
zs "r;c100 L 100 300"
This example changes the current default command string to an r (Display
Register) command followed by a c (Compare Memory) command.
zs "j (by cs:ip) == cc 'g'"
This example begins execution whenever an INT 3 instruction is executed in
your test program. This will execute a g (Go) command every time an INT 3
instruction is executed.
You can use zs to set up a watchpoint as follows:
zs "j (wo 40:1234) == 0eeed;t"
This command traces until the word at 40:1234 is not equal to 0EEED. This
won't work if you are tracing through the mode switching code in DOS or
other sections of code that can't be traced.
9.6 386 Enhanced Windows Environment Commands
These commands are specific to the operating environment of Windows running
in 386 enhanced mode. These commands are always dot commands, and are in
addition to the common commands documented in the previous section.
All of these commands are listed when the .? command is executed.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Command Description
────────────────────────────────────────────────────────────────────────────
.DG Calls Windows to dump its global heap
when Windows is installed.
.DF Calls Windows to dump its free list when
Windows is installed.
.DL Calls Windows to dump the LRU list when
Windows is installed.
.VM Displays the status of the current
virtual machine (VM). Status information
includes reentry count, VM handle,
critical section state, client registers,
Command Description
────────────────────────────────────────────────────────────────────────────
critical section state, client registers,
and top entries from the client's stack.
.VC Displays the standard fields of the
current VM's control block.
.VH Displays the current VM's handle.
.VR Displays the current VM's client
registers, if the debugger is in
protected mode.
.VS Displays the current VM's virtual mode
stack, if the debugger is in protected
mode.
.VL Displays a list of all valid VM handles.
.T Toggles the fault logging flag. When
Command Description
────────────────────────────────────────────────────────────────────────────
.T Toggles the fault logging flag. When
fault logging is turned on, all system
faults (hardware interrupts, general
protection faults, page faults, illegal
instruction faults, and so on) are
logged, with the registers at the time
of the fault, and so on. This list of
logged faults can then be viewed with
the .S, .SS, or .SL commands.
.S [item_num] Displays fault logging information in a
single line-condensed form. If an
item_num parameter is given, then the
list starts with the specified log item;
otherwise it starts with the last (most
recent) log item. The list is displayed
from most recent to less recent order.
It displays item number, fault number,
VM handle at the time of fault, critical
Command Description
────────────────────────────────────────────────────────────────────────────
VM handle at the time of fault, critical
section state, client's CS:IP; and, in
the case of general protection faults,
the executed instruction. The display
will look like the following:
= 00003BB8: 000D 60441000 00 01
02B7:23F5 INT 2A 00008002
The first number (00003BB8) is the log
item number. The second number (000D) is
the fault (interrupt) number (0Dh =
General Protection). The next number
(60441000) is the VM handle of the VM
interrupted.
The next two numbers (00) and (01) are
the critical section claim counts at the
start and end of the fault handling. So,
Command Description
────────────────────────────────────────────────────────────────────────────
start and end of the fault handling. So,
in this example, the critical section
was unclaimed on entry, but the fault
handler claimed it before exiting.
The next number (02B7:23F5) is the
client's CS:IP at the time of the
interrupt. (INT 2A) is the instruction
that the client attempted to execute,
causing the protection fault.
The last number (00008002) is the value
of EAX register. This number is given
since it is commonly used for software
interrupt function number selection, and
since all software interrupts done in
virtual 8086 mode will show in this log.
This allows the programmer to see the
most about each fault in a single line.
Command Description
────────────────────────────────────────────────────────────────────────────
most about each fault in a single line.
When the faulting instruction is an IN
or OUT instruction, DX and EAX will be
displayed as appropriate.
After each screenful of display, the
debugger pauses, waiting for the user to
press a key to continue. Pressing ESCAPE
or CONTROL+C aborts any further listing.
This command clears the fault logging
flag, to disable further logging.
.SL [item_num] Displays complete fault logging
information. If a log item number is
specified, then just the one fault's
information is displayed, starting with
the condensed line, then the register
state at the start of the fault, and
then the register state at the end. If
Command Description
────────────────────────────────────────────────────────────────────────────
then the register state at the end. If
no item number is specified, then all
log items are displayed, starting with
the last log item. This list shows the
log number, fault number, VM handle,
client registers, and instruction (if
the item is the end-of-fault item.)
Screen handling is performed exactly as
in the .S command.
.DS Dumps the protected-mode stack and
displays near code segment labels (if
available) next to each DWORD from the
stack.
The following Mx commands are for debugging the 386-enhanced-mode Windows
environment memory manager. They are probably of little use to other
programmers.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Command Description
────────────────────────────────────────────────────────────────────────────
.MH [handle] Displays the 386-enhanced-mode Windows
heap information about a specific handle,
if specified; otherwise global
information is displayed.
.MM [handle] Displays the 386-enhanced-mode Windows
memory information, such as free and
locked pages, if no handle is specified.
Otherwise, it displays information about
the memory handle such as size and
linear address.
.MV Displays the memory handles that are
allocated to the current VM.
Command Description
────────────────────────────────────────────────────────────────────────────
.MS PFTaddr Displays PFT (paged memory) information.
.MF Displays the current free list.
.MI Displays instanced data regions.
.VMM This command displays a menu of
subcommands. Pressing a single character
selects and executes the listed command.
.device-name This command calls the indicated virtual
device so that it can dump information
relevant for debugging it.
.LQ Displays queue outs from the most
recent.
.ML lin_addr Displays page-table information for the
Command Description
────────────────────────────────────────────────────────────────────────────
.ML lin_addr Displays page-table information for the
given linear address.
.MP phys_addr Displays all linear addresses that map
the given physical address.
.MD Changes the debug MONO paging display.
MO Schedules a page-out event of all
present pages that are not locked.
9.7 Summary
The 80386 Debugger is a tool that lets you debug Windows applications in
protected (standard or 386 enhanced) mode on systems with an 80386 CPU. It
offers more advanced debugging features not available in CodeView for
Windows, but lacks CVW's more convenient user interface.
For more information related to the 80386 Debugger, see the following:
Topic Reference
────────────────────────────────────────────────────────────────────────────
Programming Windows applications Guide to Programming
System requirements Installation and Update Guide
Chapter 10 Monitoring Messages: Spy
────────────────────────────────────────────────────────────────────────────
Microsoft Windows Spy (SPY) monitors system messages sent to a specified
application window. Spy records the messages and displays them on a
specified device.
Spy is useful for verifying that the messages you think a window is
receiving are being received. It is also helpful for examining the values of
message parameters.
────────────────────────────────────────────────────────────────────────────
NOTE
If you are using CodeView for Windows to debug your application, you can use
CodeView instead of Spy to trace messages.
────────────────────────────────────────────────────────────────────────────
This chapter describes the following:
■ Displaying messages
■ Choosing options
■ Choosing a window
■ Turning Spy on and off
10.1 Displaying Messages
To watch messages, do the following:
1. Choose the Options menu to display the Options dialog box and select
the following:
■ The kind of message you want to watch
■ The output device to which you want messages to go
■ Whether you want Spy to display messages synchronously or
asynchronously
2. Select the window whose messages you want to watch by choosing the
Window command from the Window menu.
3. Click the window you want to watch. To stop watching messages, choose
the Spy Off command from the Spy menu.
Figure 10.1 illustrates the Spy window.
(This figure may be found in the printed book).
10.2 Choosing Options
The Options menu displays a dialog box that offers you the following
choices:
■ The kind of message you want to watch
■ The output device to which you want samples to go
■ Whether or not Spy sends samples to the output device synchronously or
asynchronously
The following sections describe how to choose these options.
10.2.1 Choosing Messages
The Options menu displays a dialog box that offers the following choices:
Message Description
────────────────────────────────────────────────────────────────────────────
Mouse Mouse-related messages, such as
WM_MOUSEMOVE and WM_SETCURSOR.
Input Input-related messages, such as WM_CHAR
and WM_COMMAND.
System System-wide messages, such as
WM_ENDSESSION and WM_TIMECHANGE.
Message Description
────────────────────────────────────────────────────────────────────────────
Window Window manager messages, such as WM_SIZE
and WM_SHOWWINDOW.
Init Initialization messages, such as
WM_INITMENU and WM_INITDIALOG.
Clipboard Clipboard messages, such as
WM_RENDERFORMAT.
Other Messages other than the types explicitly
listed.
DDE Dynamic Data Exchange messages, such as
WM_DDE_REQUEST.
Non Client Windows nonclient messages, such as
WM_NCDESTROY and WM_NCHITTEST.
By default, Spy monitors all messages.
10.2.2 Choosing the Output Device
You can specify that Spy send messages to the following output devices:
Device Description
────────────────────────────────────────────────────────────────────────────
Window Spy displays messages in the Spy window.
You can specify how many messages Spy
stores in its buffer. By default, it
stores 100 lines of messages which you
can view by scrolling through the Spy
window.
Com1 Spy sends messages to the COM1 port.
File Spy sends messages to the specified file.
The default output file is SPY.OUT.
10.2.3 Choosing Frequency of Output
The following options specify whether Spy sends messages to the output
device as Spy receives them, or queues messages before sending them:
Option Description
────────────────────────────────────────────────────────────────────────────
Synchronous Spy displays messages as it receives
them.
Asynchronous Spy queues messages for display.
By default, Spy sends messages synchronously.
10.3 Choosing a Window: The Window Menu
After specifying message options, use the Window menu to choose the window
you want Spy to watch. The Window menu contains the following commands:
Command Description
────────────────────────────────────────────────────────────────────────────
Window... Specifies the window that Spy watches.
When you choose the Window... command,
Spy displays a dialog box that contains
information for the window in which the
cursor is located. As you move the
cursor from window to window, the
following information changes:
■ Window─Handle to the window
■ Class─Window class
■ Module─Program that created the window
■ Parent─Handle to the parent window and
the name of the program that created the
parent window
■ Rect─Upper-right and lower-left
coordinates of the window and the window
size in screen coordinates
■ Style─Style bits of the window under
the cursor, the principal style of the
window, and an identifier, if the window
is a child window. The principal style
can be WS_POPUP, WS_ICONIC,
WS_OVERLAPPED, or WS_CHILD.
All Windows Specifies that Spy watches all windows.
Choose the All Windows command again to
direct Spy to stop watching all windows.
Clear Window Clears the Spy window of messages.
10.4 Turning Spy On and Off: The Spy Menu
After selecting a window to monitor, turn Spy on by clicking the window and
choosing OK in the dialog box.
To stop monitoring messages, or to resume monitoring messages, or to exit
Spy, use the Spy menu. The Spy menu contains the following commands:
Command Description
────────────────────────────────────────────────────────────────────────────
Spy On/Off Starts and stops message monitoring.
Exit Exits Spy.
About Spy... Provides information about the version
of Spy you are using.
10.5 Summary
Spy is a tool that lets you monitor messages sent to a specified window. For
more information about topics related to Spy, see the following:
Topic Reference
────────────────────────────────────────────────────────────────────────────
Input messages Guide to Programming: Chapter 4,
"Keyboard and Mouse Input"
Message syntax and content Reference, Volume 1: Chapter 6,
"Messages Directory"
Chapter 11 Viewing the Heap: Heap Walker
────────────────────────────────────────────────────────────────────────────
Microsoft Windows Heap Walker (HEAPWALK) lets you examine the global heap,
the system memory that DOS reserves for Windows use. The utility displays
information about memory segments, or objects. Heap Walker is useful for
analyzing the effects your application has when it allocates objects in the
global heap.
This chapter describes the following topics:
■ How Heap Walker views memory
■ The Heap Walker window
■ Using Heap Walker commands to examine the global heap
11.1 How Heap Walker Views Memory
Heap Walker displays the global heap when Windows is running in either
protected or real mode. The heap differs from one mode to the other. The
following sections describe the differences.
11.1.1 Viewing the Heap in Protected Mode
If Windows is running in protected (standard or 386 enhanced) mode, the heap
is an area of memory that starts above DOS, TSR, and system drivers.
When viewing the heap in protected mode, Heap Walker identifies objects by
selector. The CPU uses selectors to indirectly specify memory addresses.
11.1.2 Viewing the Heap in Real Mode
If Windows is running in real mode, the heap can consist of one of the
following:
■ The heap that starts above DOS, TSR programs, and system drivers, and
ends at the top of DOS memory.
■ The heap that Windows uses in real mode plus expanded memory that
Windows can map into the 1-megabyte address space. Windows accesses
this area of memory using handles to appropriate segments. This access
mechanism, called the Expanded Memory Specification (EMS), is
transparent to an application.
11.2 The Heap Walker Window
Figure 11.1 illustrates the Heap Walker window after the user has executed a
Walk command.
(This figure may be found in the printed book).
By default, Heap Walker displays all global objects in the area of memory
below the EMS line, starting at the bottom of the heap. To display objects
in the heap that includes expanded memory, use the EMS menu described in
Table 11.2, "Walk Commands."
Whether you examine the heap below the line or the EMS heap, Heap Walker
displays the following information about each object:
■ ADDR (real mode only)─Segment of the object arena header; the object
starts one paragraph later.
■ SLCT (protected mode only)─Selector of the object.
■ HANDL─Handle of the memory object.
■ SIZE─Size of the object, in bytes.
■ LOCK─Lock count of the object.
■ FLAG─"D" if the object is discardable; "S" if it is shareable.
■ OWNER-NAME─Owner of the object.
■ OBJ-TYPE─Type of the object.
■ ADD-INFO─Additional information that describes the kind of resource
objects allocated.
11.3 Using Heap Walker Commands
Heap Walker commands let you do the following:
■ Perform file operations
■ Walk the heap
■ Sort memory objects
■ Show objects
■ Allocate part or all of the heap
■ Add the size of selected memory objects
The following sections describe Heap Walker commands.
11.3.1 Performing File Operations: The File Menu
Table 11.1 describes Heap Walker commands that perform basic file
operations.
Table 11.1 File Operation Commands
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Command Action
────────────────────────────────────────────────────────────────────────────
Save Saves the current listing of objects on
the heap to a HWG.TXT file. Heap Walker
writes the first listing you save to
file HWG00.TXT, and numbers subsequent
saves consecutively (HWG00.TXT,
HWG01.TXT).
Exit Exits Heap Walker.
About Heap Walker Displays information about the current
version of Heap Walker.
Command Action
────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────────────────────────────────
When saving a list of current objects to a file, Heap Walker dumps the heap
that is displayed on the screen as well as the following information, from
left to right:
■ The module name
■ The number of discardable segments loaded in memory
■ The number of bytes that the discardable segments occupy
■ The number of bytes that nondiscardable segments occupy in memory
■ The total number of bytes that the module occupies in memory
11.3.2 Walking the Heap: The Walk and EmsWalk Menus
Table 11.2 describes commands for walking the heap.
Table 11.2 Walk Commands
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Command Action
────────────────────────────────────────────────────────────────────────────
Walk Heap Displays objects on the heap below the
EMS line (real mode only if EMS is
present). Each display line identifies
one global object. If the heap does not
have EMS or the heap is in protected
mode, this command displays the entire
heap.
Table 11.2 Walk Commands (continued)
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Command Action
────────────────────────────────────────────────────────────────────────────
Walk LRU List Displays only discardable objects. The
Heap Walker lists objects from the least
recently used to the most recently used.
The object at the top of the list has
been least recently used and, therefore,
is most eligible for discarding.
Walk Free List Displays only free blocks of memory.
GC(0) and Walk Performs a global compact, asking for
zero bytes, then displays the heap.
GC(-1) and Walk Attempts to throw out all discardable
objects and then displays the heap.
Command Action
────────────────────────────────────────────────────────────────────────────
GC(-1) and Hit A: Attempts to throw out all discardable
objects, then accesses drive A. Used to
test critical error handling.
Set Swap Area Resets the code fence. The code fence
defines an area of memory reserved for
discardable code.
Segmentation Test Dumps the heap to a file called
HWG00.TXT and does a global compact (-1).
Heap Walker numbers files consecutively
in subsequent dumps. This command is
available whenever Heap Walker is in the
system and EMS memory is not installed,
even if Heap Walker is not the active
application.
Specified application Walks the heap of a specified
Command Action
────────────────────────────────────────────────────────────────────────────
Specified application Walks the heap of a specified
application using the Expanded Memory
Specification. An EMS walk comprises
relevant objects in memory above the EMS
line and below 1-megabyte.. This command
is available only in real mode for
systems with EMS installed.
────────────────────────────────────────────────────────────────────────────
11.3.3 Sorting Memory Objects: The Sort Menu
Heap Walker lets you sort memory objects in a variety of ways. Table 11.3
describes Heap Walker sort commands.
Table 11.3 Sort Commands
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Command Action
────────────────────────────────────────────────────────────────────────────
Address (real mode only) Sorts by address.
Selector (protected mode only) Sorts by selector.
Module Sorts by module name.
Size Sorts by object size.
Label Segments Substitutes segment names for segment
numbers.
────────────────────────────────────────────────────────────────────────────
11.3.4 Displaying Memory Objects: The Object Menu
Heap Walker lets you view objects selectively. Table 11.4 describes commands
to control and display memory objects.
Table 11.4 Memory Object Commands
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Command Action
────────────────────────────────────────────────────────────────────────────
Show Displays the contents of a selected
object in hexadecimal and ASCII format.
Show Bits Displays the bitmap (if any) of a
selected graphics device interface (GDI)
object such as a font or cursor.
Discard Discards a selected object.
Oldest Marks a selected object as the next
candidate for
discarding.
Command Action
────────────────────────────────────────────────────────────────────────────
discarding.
Newest Marks a selected object as the last
candidate for
discarding.
LocalWalk Displays the local heap of the currently
selected object. The object must be a
data segment. The local walk window
shows the following:
OFFSET─The offset from the DS register
of the object
SIZE─Size in bytes of the object
MOV/FIX─Indicates whether the object is
moveable or fixed
Command Action
────────────────────────────────────────────────────────────────────────────
FLAGS─Indicates whether or not an object
is discardable
OBJ TYPE─Object type
Windows allocates the first object in
the local heap, so there are always at
least two objects in a local heap.
LocalWalk has a File menu with a Save
command that saves to a file named
HWL00.TXT. Heap Walker numbers files
consecutively on subsequent dumps
(HWL00.TXT, HWL01.TXT).
LC(-1) and LocalWalk Compacts the selected local heap, then
displays the heap. LocalWalk has a Save
command that saves to a file named
HWL00.TXT. Heap Walker numbers files
Command Action
────────────────────────────────────────────────────────────────────────────
HWL00.TXT. Heap Walker numbers files
consecutively on subsequent dumps
(HWL00.TXT, HWL01.TXT).
Table 11.4 Memory Object Commands (continued)
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Command Action
────────────────────────────────────────────────────────────────────────────
GDI LocalWalk Displays the GDI local heap and provides
information on the objects in the heap.
LocalWalk has a Save command that saves
to a file named HWL00.TXT. Heap Walker
numbers files consecutively on
subsequent dumps (HWL00.TXT, HWL01.TXT).
────────────────────────────────────────────────────────────────────────────
Command Action
────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────────────────────────────────
11.3.5 Allocating Memory: The Alloc Menu
Heap Walker lets you allocate part or all of memory. Table 11.5 describes
commands that allocate memory.
Table 11.5 Memory Allocation Commands
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Command Action
────────────────────────────────────────────────────────────────────────────
Allocate all of memory Allocates all free memory. This command
is useful for testing out-of-memory
conditions in applications.
Command Action
────────────────────────────────────────────────────────────────────────────
Free allocated memory Frees memory allocated by the Allocate
all of memory command.
Free 1K Frees 1K of memory. Applies only to
memory allocated by the Allocate all of
memory command.
Free 2K Frees 2K of memory. Applies only to
memory allocated by the Allocate all of
memory command.
Free 5K Frees 5K of memory. Applies only to
memory allocated by the Allocate all of
memory command.
Free 10K Frees 10K of memory. Applies only to
memory allocated by the Allocate all of
memory command.
Command Action
────────────────────────────────────────────────────────────────────────────
memory command.
Free 25K Frees 25K of memory. Applies only to
memory allocated by the Allocate all of
memory command.
Free 50K Frees 50K of memory. Applies only to
memory allocated by the Allocate all of
memory command.
Free XK Frees a specified number of kilobytes of
memory. Heap Walker displays a dialog
box that lets you specify the number.
────────────────────────────────────────────────────────────────────────────
11.3.6 Determining Memory Size: The Add! Menu
Heap Walker lets you determine the total size of selected memory objects. To
add the total number of bytes of selected objects, choose the Add! menu. The
menu is a command that displays the number of selected segments and total
segment size in a dialog box.
11.4 Suggestions for Using Heap Walker
One error that frequently occurs in applications is the failure to free
memory objects once they are no longer needed. This can cause Windows to
fail when one of its data segments grows beyond the 64K limit.
You can use Heap Walker to help determine if your application is not freeing
memory objects. Heap Walker lets you view changes in the size of all Windows
data segments, allowing you to observe the effect your application has on
these segments.
To check how your application changes the size of the Windows data segments,
follow these steps:
1. Make sure that your application does not generate fatal exits.
2. Start the debugging version of Windows, making sure that all the
values for settings in the [kernel] section of WIN.INI are correct.
3. Immediately start Heap Walker and note the sizes of the GDI and USER
data segments. This establishes the baseline against which you can
compare the size of the data segments later.
4. Select the Object GDI LocalWalk(DATASEG) menu option to display a
window that lists the different objects in the GDI data segment.
Select the Save! menu option of this window to copy this list to a
file; the file will also contain a summary of GDI objects.
5. Run your application and exercise it fully over a long period of time,
noting the changes in the size of the GDI and USER data segments which
Heap Walker displays as your application runs. While your application
is running, repeat step 4 a number of times to take "snapshots" of the
effect your application has on the GDI data segment.
6. Close your application, take a final "snapshot" of the GDI data
segment, and note the total sizes of the GDI and USER data segments.
As you analyze the data that you've recorded, you should look for GDI
objects that your application creates but does not delete when they are no
longer needed.
You should also check the size of the USER data segment before and after you
run your application. While it is normal for the USER data segment to be a
little larger after your application has run once, it should not grow larger
after you have run your application additional times. If it does, your
application probably is calling the MakeProcInstance function without
calling FreeProcInstance to free the procedure-instance address when it is
no longer needed.
11.5 Summary
Heap Walker is a tool that lets you examine objects on the global heap. For
more information on the heap, see Chapter 15, "Memory Management," and
Chapter 16, "More Memory Management," in Guide to Programming.
Chapter 12 Moving Memory: Shaker
────────────────────────────────────────────────────────────────────────────
The Microsoft Windows Shaker (SHAKER) lets you see the effect of memory
movement on your application. Shaker randomly allocates and frees chunks of
global memory with the intention of forcing the system to relocate moveable
data or code segments in your application.
Shaker is useful for making sure that no problems occur when memory moves.
This chapter describes commands you use to allocate and free global memory.
12.1 Using Shaker
To use Shaker, select the parameters you want and start Shaker. You select
parameters and start or stop Shaker with the following commands on the menu
bar:
Command Function
────────────────────────────────────────────────────────────────────────────
Parameter Displays a dialog box that lets you
specify the following parameters:
■ Allocation Granularity─Sets the
minimum
size of the objects to be allocated.
Each object
is some multiple of this size; for
example, if the granularity is 128,
Shaker allocates objects that have byte
sizes of 128, 256, 384, and so on. The
smaller the granularity, the more likely
it is that the allocated objects will
fit in the spaces between global objects.
■ Time Interval─Sets the time interval,
in system-timer ticks, between
allocations. Shaker allocates a new
object after each interval elapses. If
the maximum number of objects has been
allocated, it reallocates one it had
previously allocated.
■ Max Objects─Sets the maximum number
of
objects to be allocated.
Display Displays or removes the display of
object handles and allocation sizes.
Command Function
────────────────────────────────────────────────────────────────────────────
Start Starts the allocation.
Stop Stops the allocation.
Step Allocates one object and stops. This
command can be used when Shaker is
otherwise stopped.
12.2 Summary
Shaker is a tool that shows you the effect of memory movement on your
application. For more information on memory management, see Chapter 15,
"Memory Management," and Chapter 16, "More Memory Management," in Guide to
Programming.
Chapter 13 Analyzing CPU Time: Profiler
────────────────────────────────────────────────────────────────────────────
Microsoft Windows Profiler (PROFILER) is an analytical tool that helps you
optimize the performance of Windows applications. Profiler lets you sample
the amount of time Windows spends executing sections of code.
This chapter describes the following topics:
■ An overview of Profiler
■ Preparing to run Profiler
■ Using Profiler functions
■ Sampling code
■ Displaying samples
Profiler analyzes applications running with Windows in real mode or in 386
enhanced mode; it cannot analyze applications running with Windows in
standard mode. If you are analyzing Windows applications in real mode, you
use Profiler differently than if you are analyzing applications running with
Windows in 386 enhanced mode. Section 13.4, "Sampling Code," discusses the
differences. Profiler does not support Windows running in standard mode.
13.1 Overview of Profiler
Profiler contains the following:
■ A sampling utility
■ A reporting utility
■ A set of functions that you call from your application
The sampling utility gathers information about the time spent between
adjacent labels, and records memory addresses of code. If the application
you are profiling runs with Windows in real mode, the sampling utility is
PROF.COM. To run the Profiler you invoke PROF.COM, which in turns invokes
Windows.
If the application you are profiling runs with Windows in 386 enhanced mode,
the sampling utility is a special device driver, VPROD.386. To run Profiler,
first install VPROD.386, and then run Windows directly.
Profiler stores the information it gathers in a buffer. It writes the buffer
to disk when Windows terminates, producing a CSIPS.DAT file and a
SEGENTRY.DAT file in the directory that was your current directory when you
started Windows. The CSIPS.DAT file contains statistical samplings of the
code segment (CS), instruction pointer (IP) registers. The SEGENTRY.DAT file
contains information about the movement of code segments. Because code
segments can be located at different physical addresses during the execution
of the program, information in both the CSIPS.DAT and SEGENTRY.DAT files are
required to prepare the profiling report.
After the sampling utility has finished gathering information, the reporting
utility, SHOWHITS.EXE, organizes and displays the results.
Profiler's functions let you start and stop examining code, manage the
output of code samples, and get information about Profiler. All applications
that Profiler examines must include two functions that start and stop the
sampling of code. Other Profiler functions are optional.
13.2 Preparing to Run Profiler
To profile a Windows application in real mode, you need an IBM PC/AT(R) or
PS/2(R) compatible system because Profiler uses the AT CMOS clock chip to
time sampling intervals. The utility will not run on standard PC and
PC/XT(tm) systems.
To profile an application running with Windows in 386 enhanced mode, use any
system capable of running Windows in 386 enhanced mode.
In addition to ensuring that your system is compatible with Profiler, you
must do the following:
1. Ensure that the Windows directory is defined in your PATH environment
variable.
2. Include in your application at least two mandatory Profiler functions,
ProfStart and ProfStop.
ProfStart indicates when you want Profiler to start sampling code;
ProfStop indicates when you want Profiler to stop sampling. Other
functions are optional.
3. Compile your application and link the compiled code with the standard
Windows libraries. Use the LINK /m option to prepare a .MAP file. This
file is required by the MAPSYM utility.
4. Use MAPSYM to produce an application symbol (.SYM) file.
13.3 Using Profiler Functions
In addition to the mandatory ProfStart and ProfStop functions, Profiler
includes functions that determine if Profiler is installed, specify a rate
for sampling, and control the output buffer.
The way you use the Profiler functions depends on whether your application
runs in real mode or in 386 enhanced mode.
If your application runs with Windows in real mode and you want to override
the standard sampling rate or the amount of data that the Profiler writes to
disk, you can use either command line options when invoking the Profiler or
Profiler functions. For information on using command line options, see
Section 13.4, "Sampling Code."
If your application runs with Windows in 386 enhanced mode and you want to
specify nondefault values, you must use Profiler functions. You cannot
change default values when invoking the utility.
The sections that follow describe Profiler functions.
13.3.1 Starting and Stopping Sampling: The ProfStart and ProfStop Functions
Use the ProfStart and ProfStop functions for each section of code that you
want to sample. Deciding where to call ProfStart and ProfStop is important.
You should avoid sampling when your application calls Windows functions that
yield to other applications. For example, sampling a function such as
GetMessage could cause Profiler to collect data on applications other than
your own.
The following example illustrates when to call ProfStart and ProfStop:
#include "windows.h"
#include "hello.h"
.
.
.
void HelloPaint( hDC )
HDC hDC;
{
int i, j;
ProfStart();
for(i = 1; i <= 3; i++)
for(j = 1; j <= 20; j++)
{
TextOut( hDC,
(short)(i * 120),
(short)(j * 12),
(LPSTR)szMessage,
(short)MessageLength );
}
ProfStop();
}
.
.
.
In this example, the Profiler ProfStart and ProfStop functions specify that
Profiler sample the application's HelloPaint function. Profiler samples only
the nested loops that include the call to the TextOut function.
13.3.2 Checking if Profiler Is Installed: The ProfInsChk Function
To determine if Profiler is installed, use the ProfInsChk function.
ProfInsChk has the following syntax:
int FAR PASCAL ProfInsChk(void)
The function returns the following values:
■ 0 if Profiler is not installed
■ 1 if the Windows real-mode Profiler is installed
■ 2 if the Windows 386-enhanced-mode Profiler is installed
If Profiler is not installed, the system ignores other Profiler function
calls.
13.3.3 Setting the Sampling Rate: The ProfSampRate Function
To set the rate of code sampling, use the ProfSampRate function.
ProfSampRate has the following syntax:
void FAR PASCAL ProfSampRate(int,int)
The first parameter specifies the sampling rate of Profiler if the
application is running with Windows in real mode. The value of the first
parameter ranges from 1 to 13, indicating the following sampling rates:
Numeric Value Sampling Rate
────────────────────────────────────────────────────────────────────────────
1 122.070 microseconds
2 244.141 microseconds
3 488.281 microseconds
4 976.562 microseconds
5 1.953125 milliseconds
6 3.90625 milliseconds
7 7.8125 milliseconds
8 15.625 milliseconds
9 31.25 milliseconds
10 62.5 milliseconds
11 125 milliseconds
12 250 milliseconds
13 500 milliseconds
The second parameter defines sampling rates if Profiler is analyzing an
application running with Windows in 386 enhanced mode. The value of the
second parameter can range from 1 to 1000, specifying the sampling rate in
milliseconds.
For Windows in real mode the initial rate is 5 (1.953125 milliseconds) or
what you specify when invoking PROF.COM.
For Windows in 386 enhanced mode, the default rate is 2 milliseconds.
────────────────────────────────────────────────────────────────────────────
NOTE
Profiler selects only the parameter appropriate for the version of Windows
used. If your application runs with Windows in real mode, Profiler reads
only the first parameter; if your application runs with Windows in 386
enhanced mode, Profiler reads only the second.
────────────────────────────────────────────────────────────────────────────
13.3.4 Managing Output: The ProfClear, ProfFlush, and ProfSetup Functions
To manage the output of samples that Profiler gathers, use the ProfClear,
ProfFlush, and ProfSetup functions. ProfClear discards all samples currently
in the sampling buffer. ProfFlush flushes the sampling buffer to disk,
provided that samples do not exceed the limit you define.
────────────────────────────────────────────────────────────────────────────
IMPORTANT
Use ProfFlush sparingly because it can distort the performance of your
application. Additionally, do not call the function when DOS may be
unstable, as in interrupt handling.
────────────────────────────────────────────────────────────────────────────
The ProfSetup function lets you specify the size of the output buffer and
the amount of samples written to disk. ProfSetup is available only to
applications running with Windows in 386 enhanced mode.
If your application runs with Windows in real mode, you must specify the
size of the output buffer and the size of sampling data when you invoke
Profiler.
The syntax of ProfSetup is as follows:
void FAR PASCAL ProfSetup(int, int)
The first parameter specifies the size of the output buffer in kilobytes
(K), from 1 to 1064. The default value is 64.
The second parameter controls how much sampling data Profiler writes to
disk. Default value is the size of the output buffer in kilobytes. A value
of 0 specifies unlimited sampling data.
The following example uses ProfSetup to specify values for the size of the
output buffer and the amount of samples written to disk. It also calls
ProfSampRate to change the default sampling rate.
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
PWNDCLASS pHelloClass;
.
.
.
int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
MSG msg;
HWND hWnd;
HMENU hMenu;
.
.
.
ProfSetup(100,0);
ProfSampRate(4,1);
.
.
.
In this example, the ProfSetup function changes the default sample buffer
size from 64K to 100K and specifies that Profiler write an unlimited amount
of data to disk. The function applies only if the application is running
with Windows in 386 enhanced mode. The ProfSampRate function changes default
sampling rates to 1 millisecond in 386 enhanced mode.
If the application runs with Windows in real mode, Profiler ignores the
ProfSetup call. The ProfSampRate function changes default sampling rates to
976.562 microseconds in real mode.
13.3.5 Stopping Profiler: The ProfFinish Function
To stop Profiler, use the ProfFinish function. ProfFinish stops sampling and
flushes the output buffer to disk. If your application is running with
Windows in 386 enhanced mode, ProfFinish also frees the buffer for system
use.
If you do not call ProfFinish, the output buffer automatically flushes to
disk when you terminate Windows.
If you are profiling more than one instance of the same application, calling
the ProfFinish function will stop Profiler for all instances of the
application.
13.4 Sampling Code
The method you use to sample code depends on the version of Windows your
application runs with. If your application runs with Windows in real mode,
you invoke the PROF.COM program, which loads and runs Windows. If your
application runs with Windows in 386 enhanced mode, you first install
VPROD.386, a virtual device driver, and then run Windows directly.
In real mode, the Profiler output buffer is limited to 64K. In 386 enhanced
mode, your application can call ProfSetup to set the size of the output
buffer up to 1064K.
Both sampling methods use memory that is otherwise available to Windows.
Therefore, using Profiler may decrease the performance of the application
you are analyzing. You can reduce the amount of memory used by specifying a
small output buffer. However, a small output buffer may cause sample loss.
Profiler can write samples to disk only when Windows indicates it is safe to
do so. When the sampling buffer fills, Profiler ignores additional samples
until the buffer is flushed to disk. To minimize sample loss, either
increase the buffer size or periodically call the ProfFlush function.
The following sections describe features specific to Windows in real mode,
and Windows in 386 enhanced mode.
13.4.1 Sampling Applications in Windows Real Mode
To profile applications running with Windows in real mode, use the PROF.COM
utility.
The syntax for invoking PROF.COM is as follows:
PROF «-tn» [[-cn» «-ln» «-d» «program arguments»
The KERNEL.EXE file must be in the current directory or in the current PATH
environment. The following describes the command line options:
Option Description
────────────────────────────────────────────────────────────────────────────
-tn Specifies the intervals at which
Profiler samples code. For values of n,
see the description of real-mode Windows
arguments to the ProfSampRate function
in Section 13.3.3, "Setting the Sampling
Rate: The ProfSampRate Function."
-cn Specifies the size of the output buffer
in kilobytes. The value of n can range
from 1 to 64 (default buffer size is
64K).
-ln Limits the total size of samples written
to disk. If this option is not specified,
the default is the size of the output
buffer.
-d Specifies that the program being
analyzed runs with DOS, not Windows.
Option Description
────────────────────────────────────────────────────────────────────────────
program arguments Names the program and arguments, if any,
that Profiler loads and runs. You would
typically place arguments, such as the
name of the application you are running,
on the Windows command line. If
specified, the name must include an
extension. When profiling Windows
applications, this parameter should be
the name of the Windows program,
typically WIN.COM.
13.4.2 Sampling Applications in Windows 386 Enhanced Mode
The PROF.COM command line options are not available when you profile
applications that run with Windows in 386 enhanced mode. Instead, you add
the Profiler functions to your source code to get equivalent results.
To profile applications that run with Windows in 386 enhanced mode, do the
following:
1. Install the VPROD.386 driver by adding the following to the [386enh]
section of your SYSTEM.INI file:
DEVICE=VPROD.386
2. Run Windows in 386 enhanced mode.
3. Run the application you want to profile.
4. When you have finished profiling your application, remove the
VPROD.386 entry from your SYSTEM.INI file.
13.5 Displaying Samples: SHOWHITS.EXE
Use a DOS application, SHOWHITS.EXE, to display data that the Profiler
gathers. This reporting utility reads CSIPS.DAT, SEGENTRY.DAT, and .SYM
files, and organizes and displays the data. The sampling utility places the
CSIPS.DAT and SEGENTRY.DAT files in the current directory. To ensure that
SHOWHITS can locate these files, either run SHOWHITS from the same
directory, or else specify full pathnames for the CSIPS.DAT and SEGENTRY.DAT
files. If the .SYM files are not in the current directory, then use the -i
option to specify the directory or directories containing the symbols files.
SHOWHITS.EXE reads .SYM files to match instruction pointer samples with
global symbols in the application. When you run SHOWHITS.EXE the utility
searches for .SYM files that contain symbolic names identical to the names
of modules that Profiler sampled. If the sampled program is written in the C
language, the symbolic names are typically function names. If the sampled
program is written in assembly language, the symbolic names can be either
procedure names or PUBLIC symbols within procedures.
SHOWHITS.EXE reports the number of times sampling occurred between adjacent
symbols.
The syntax for invoking SHOWHITS.EXE is as follows:
SHOWHITS «-r|3» «-ipath [-ipath«...»»» «csips_file» «segentry_file»
The following describes SHOWHITS.EXE options:
Option Description
────────────────────────────────────────────────────────────────────────────
-r The Profiler was run in real mode
(PROF.COM). SHOWHITS uses the KERNEL.SYM
Windows
kernel symbol file.
-3 The Profiler was run in 386 enhanced
mode (VPROD.386). SHOWHITS uses the
KRNL386.SYM Windows kernel symbol file.
-ipath The path option specifies one or more
directories to search for .SYM files.
The default is the current directory.
SHOWHITS.EXE loads all .SYM files in the
specified directories, regardless of
their relevance to the application you
are profiling.
csips_file Specifies the full pathname of the
CSIPS.DAT file. If not specified,
SHOWHITS.EXE looks for the file in the
current directory.
segentry file Specifies the full pathname of the
SEGENTRY.DAT file. If not specified,
SHOWHITS.EXE looks for the file in the
current directory.
If you do not supply the -r or -3 option, SHOWHITS.EXE will prompt you for
the mode.
SHOWHITS.EXE displays information about hits, which are instruction pointer
samples, into the following four categories:
Category Description
────────────────────────────────────────────────────────────────────────────
Unrecognized A list of instruction pointers that
segments occur within segments for which there
are no symbols of module names.
Unrecognized segments are typically code
for device drivers, TSR programs, and
other code that Windows does not use.
Category Description
────────────────────────────────────────────────────────────────────────────
Known segments The number of hits that occur within
known modules. Hits on known segments
typically include counts for the
application and counts for Windows
modules such as KERNEL, GDI, and DISPLAY.
Profiler also counts hits in DOS and the
ROM BIOS. In addition to display hits,
SHOWHITS.EXE lists the total number of
hits and the segment's percentage of
total hits.
Breakdown A detailed breakdown of the hits between
labels
of the modules for which SHOWHITS.EXE
finds .SYM files. SHOWHITS.EXE also
displays the
total number of hits and the percentage
of the total number.
Summary A list of the top 10 hits.
The following example illustrates a display:
Here are the Hits for Unrecognized Segments
Here are the Hits for Known Segments
0.3% 3 Hits on SYSTEM-0
0.5% 5 Hits on HELLO-0
76.5% 786 Hits on DISPLAY-0
11.3% 116 Hits on GDI-0
11.5% 118 Hits on KERNEL-0
1028 TOTAL HITS
HELLO!_TEXT
0.4% 4 Hits between labels _HelloPaint and _HelloInit
0.1% 1 Hits between labels __cintDIV and __fptrap
Profiler Summary (Top 10 Hits):
0.4% 4 HELLO! _TEXT! _HelloPaint - _HelloInit
0.1% 1 HELLO! _TEXT! __cintDIV - __fptrap
13.6 Summary
Profiler is a tool that lets you determine the amount of time Windows spends
executing sections of code. For more information about Profiler functions,
see Reference, Volume 1: Chapter 4, "Functions Directory."
Chapter 14 Analyzing Swaps: Swap
────────────────────────────────────────────────────────────────────────────
Microsoft Windows Swap (SWAP) is a tool that lets you analyze the calls,
swaps, discards, and returns that occur when your Windows application runs.
Swap includes a utility that records swapping information and another
utility that displays the information to a standard output device.
Swap is useful for determining the number of procedure calls that occur
across segment boundaries. You can optimize the performance of your
application by reducing the number of calls across boundaries.
This chapter describes the following topics:
■ Preparing to run Swap
■ Running Swap
■ Displaying swapping information
14.1 Preparing to Run Swap
Before running Swap, do the following:
■ Ensure that you have the necessary Swap files.
■ Place the SwapRecording function in your application.
14.1.1 Files You Need to Run Swap
To run Swap, you need the following files:
■ SKERNEL.EXE─Windows uses this file instead of KERNEL.EXE as part of
the debugging version of Windows. The SKERNEL.EXE file produces a data
file named SWAPPRO.DAT, which contains information about the swapping
behavior of your application. SKERNEL.EXE runs only when Windows is in
real mode.
■ Application .SYM files─Swap requires symbol files for the modules of
your application that you want to analyze. To create symbol files,
first link the program using the /map option, and then run the MAPSYM
utility.
■ SWAP.EXE─This file uses the SWAPPRO.DAT file to produce a report of
swapping behavior.
Swap also includes the optional SKERNEL.SYM file, which provides a listing
of symbols in SKERNEL.EXE.
14.1.2 Using the SwapRecording Function
Place the SwapRecording function in your application to indicate when to
start and stop recording swapping behavior. The syntax of the function is as
follows:
SwapRecording(value)
The value parameter specifies whether Swap begins or stops analyzing
swapping behavior, as follows:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Value Description
────────────────────────────────────────────────────────────────────────────
0 Specifies that Swap stop analyzing.
1 Specifies that Swap record calls,
discards, and swap returns.
2 Specifies that Swap record calls,
discards, swap returns, and all calls
through thunks.
14.2 Running Swap
To run Swap, do the following:
1. Make a backup copy of the KERNEL.EXE file in your Windows system
directory by copying or renaming it.
2. Copy SKERNEL.EXE in the Windows development tools directory (named
\WINDEV by default at installation) to the Windows system directory.
3. Start Windows in real mode (WIN /R) and run the application you want
to analyze.
4. Exit from Windows.
5. Run SWAP.EXE.
6. When you are finished, be sure to restore the original KERNEL.EXE in
your Windows system directory.
The following command invokes SWAP.EXE:
SWAP [-Ipath[;path...» [-Fswapfile]
[-Mmodule[:segment][;module[:segment]...»
Command line options are as follows:
Option Description
────────────────────────────────────────────────────────────────────────────
-I Specifies one or more directory
pathnames containing the symbol files of
the modules to be analyzed.
-F Specifies the pathname of the data
collection file.
-Mmodule Specifies the application module that
Swap analyzes.
segment Specifies the segment that Swap
analyzes.
14.2.1 Specifying a Symbol-File Path
By default, Swap searches for all required symbol files in the current
directory. To evaluate data in symbol files located in other directories,
specify the pathnames with the -I option. The pathnames must be separated by
semicolons.
For example, the following command line specifies that symbol files reside
in the \PRE\SYSTEM and \TEST\SWAP directories:
SWAP -I\pre\system;\test\swap
14.2.2 Specifying a Pathname for the Data Collection File
By default, Swap searches for the SWAPPRO.DAT file in the current directory.
If you rename the data collection file or place it somewhere other than the
current directory, use the -F option.
For example, the following command line specifies that the data collection
file, named SWAPREC, resides in directory TMP:
SWAP -F\TMP\SWAPREC
14.2.3 Specifying a Module and Segment
If the data collection file contains a large amount of data, Swap takes a
long time processing the module and symbol names. To reduce the time, use
the -M option to limit the number of modules and segments for which Swap
prepares output.
The following example specifies that Swap display only records that contain
the _FONTRES segment of the GDI:
SWAP -MGDI:_FONTRES
You can list multiple segments or module/segment pairs by separating them on
the command line with semicolons. The following example specifies that Swap
display records that contain the _FONTRES segment of the GDI and any segment
of USER:
SWAP -MGDI:_FONTRES;USER
14.3 Displaying Output
Swap displays records of swapping behavior on standard output devices. Use
DOS commands to direct output to either a file or a screen.
Swap records information in columns of ASCII text separated by tabs. The
format is suitable for reading into spreadsheet programs such as Microsoft
Excel.
Swap displays information from left to right as follows:
Column Description
────────────────────────────────────────────────────────────────────────────
Type The kind of event that occurred. The
event can be one of the following:
■ CALL─A normal call through a thunk.
■ SWAP─A call through a thunk that
caused a swap.
■ DISCARD─Discard of a segment. If the
discard was the result of a swap, then
the discard records occur after the swap
record.
■ RETURN─Return that caused a swap in
the
caller.
Time The relative time that the event
occurred, in milliseconds. Resolution is
1/18.2 seconds. The first event is
always 0.
Segment (1st) One of the following:
■ If CALL or SWAP, the segment being
called.
■ If DISCARD, the segment being
discarded.
■ If RETURN, the segment being returned
to.
If the module name appears in
parentheses, Swap could not find the
.SYM file for the module.
Offset (1st) One of the following:
■ If CALL or SWAP, the offset into the
segment being called.
■ If RETURN, the offset into the segment
being
returned to.
■ If DISCARD, this field is blank.
Segment (2nd) One of the following:
■ If CALL or SWAP, the segment that did
the
calling.
Column Description
────────────────────────────────────────────────────────────────────────────
■ If DISCARD, this field is blank.
■ If RETURN, this field is blank.
If the module name appears in
parentheses, Swap could not find the
.SYM file for the module.
Offset (2nd) One of the following:
■ If CALL or SWAP, the offset into the
segment that did the calling.
■ If RETURN, this field is blank.
■ If DISCARD, this field is blank.
14.4 Summary
Swap is a tool that lets you analyze the swapping behavior of Windows
applications. For more information about memory management, see Chapter 15,
"Memory Management," and Chapter 16, "More Memory Management," in Guide to
Programming.
PART IV Help Tools
────────────────────────────────────────────────────────────────────────────
Part 4 provides a guideline for authors and developers of Help systems for
Microsoft Windows applications. It also defines some specific rules that
must be adhered to when creating a Help system for any single application.
For that reason, some sections include step-by-step procedures, while other
sections suggest general methods.
To illustrate concepts and procedures, several chapters use sample screens
and text from the on-line Help in Helpex, a Windows application supplied in
your Software Development Kit. If you want to study this material in greater
detail, you can use the Helpex system as a working model.
Chapter 15 Providing Help: The Help System
────────────────────────────────────────────────────────────────────────────
A Help system provides users with online information about an application.
Creating the system requires the efforts of both a Help writer and a Help
programmer. The Help writer plans, writes, codes, builds, and keeps track of
Help topic files, which are text files that describe various aspects of the
application. The Help programmer ensures that the Help system works properly
with the application.
This chapter describes the following topics:
■ Creating the Help system
■ How Help appears to the user
■ How Help appears to the Help writer
■ How Help appears to the Help programmer
This chapter and those that follow assume you are familiar with Microsoft
Windows Help. The chapters use examples from a sample application called
Helpex, provided on the SDK Sample Source Code disk. If you are unfamiliar
with Windows Help, take a moment to run the Helpex sample application and
use Helpex Help.
15.1 Creating a Help System: The Development Cycle
The creation of a Help system for a Windows application comprises the
following major tasks:
1. Gathering information for the Help topics.
2. Planning the Help system.
Chapter 16, "Planning the Help System," describes considerations you
should keep in mind when planning your Help system.
3. Writing the text for the Help topics.
4. Entering all required control codes into the text files.
Control codes determine how the user can move around the Help system.
Section 15.3, "How Help Appears to the Writer," includes an example of
several control codes. Chapter 17, "Creating the Help Topic Files,"
describes the codes in detail.
5. Creating a project file for the build.
The Help project file provides information that the Help Compiler
needs to build a Help resource file. Chapter 18, "Building the Help
File," describes the Help project file.
6. Building the Help resource file.
The Help resource file is a compiled version of the topic files the
writer creates. Chapter 18, "Building the Help File," describes how to
compile a Help resource file.
7. Testing and debugging the Help system.
8. Programming the application so that it can access Windows Help.
The following flow diagram shows the general work flow in the conception and
development of the Help system.
(This figure may be found in the printed book).
15.2 How Help Appears to the User
To the user, the Help system appears to be part of the application, and is
made up of text and graphics displayed in the Help window in front of the
application. Figure 15.2 illustrates the Help window that appears when the
user asks for help with copying text in Helpex.
(This figure may be found in the printed book).
The Help window displays one sample Help topic, a partial description of how
to perform one task. In Figure 15.2 the first sentence includes a definition
of the word "clipboard." By pressing the mouse button when the cursor is on
the word (denoted by dotted underlined text), the user can read the
definition, which appears in an overlapping box as long as the mouse button
is held down.
Cross-references to related topics are called jumps. By clicking on a jump
term for a related topic (denoted by underlined text), the user changes the
content of the Help window to a description of the new topic or command.
Figure 15.2 includes a look-up to the definition of "clipboard."
15.3 How Help Appears to the Help Writer
To the writer, the Help system is a group of topic files, which are text
files that include special codes. Figure 15.3 illustrates the source text
that corresponds to the topic shown in Figure <$R[C#1]>.2.
(This figure may be found in the printed book).
To create this topic, the Help writer describes the task, formats the text,
and inserts codes using strikethrough text, underlined text, and footnotes.
In place of strikethrough, the writer can use double underlining if the word
processor does not support strikethrough formatting. Footnotes in the text
contain linking information required by the Help Compiler. Chapter 16,
"Planning the Help System," discusses formatting considerations. Chapter 17,
"Creating the Help Topic Files," describes how to create topics and enter
the special codes that the Help system uses.
15.4 How Help Appears to the Help Programmer
To the programmer, Windows Help is a stand-alone Windows application which
the user can run like any other application. Your application can call the
WinHelp function to ask Windows to run the Help application and specify
which topic to display in the Help window.
See Chapter 18, "Building the Help File," for details about the Help
application programming interface (API).
15.5 Summary
The Help system is made up of topics linked via hypertext. The topics and
links appear differently on the screen to the user than they do in a topic
file to the writer. To the programmer, Help is a stand-alone application.
For more information about related topics, see the following:
╓┌─────────────────────┌─────────────────────────────────────────────────────╖
Topic Reference
────────────────────────────────────────────────────────────────────────────
Coding Help topics Tools: Chapter 17, "Creating the Help Topic Files"
Compiling Help files Tools: Chapter 18, "Building the Help File"
Chapter 16 Planning the Help System
────────────────────────────────────────────────────────────────────────────
The initial task for the Help writer is to develop a plan for creating the
system. This chapter discusses planning the Help system for a particular
application.
The chapter covers the following topics:
■ Developing a plan
■ Determining the topic file structure
■ Designing the visual appearance of Help topics
16.1 Developing a Plan
Before you begin writing Help topics using the information you have
gathered, you and the other members of the Help team should develop a plan
that addresses the following issues:
■ The audience for your application
■ The content of the Help topics
■ The structure of topics
■ The use of context-sensitive topics
You might want to present your plan in a design document that includes an
outline of Help information, a diagram of the structure of topics, and
samples of the various kinds of topics your system will include. Keep in
mind that contextsensitive Help requires increased development time,
especially for the application programmer.
16.1.1 Defining the Audience
The audience you address determines what kind of information you make
available in your Help system and how you present the information.
Users of Help systems might be classified as follows:
User Background
────────────────────────────────────────────────────────────────────────────
Computer novice Completely new to computing.
Application novice Some knowledge of computing, but new to
your kind of application. For example,
if you are providing Help for a
spreadsheet program, the application
novice might be familiar only with
word-processing packages.
Application Knowledgeable about your kind of
intermediate application.
Application expert Experienced extensively with your type
of application.
Keep in mind that one user may have various levels of knowledge. For
example, the expert in word processors may have no experience using
spreadsheets.
16.1.2 Planning the Content of the Help System
You should create topics that are numerous enough and specific enough to
provide your users with the help they need.
Novice users need help learning tasks and more definitions of terms. More
sophisticated users occasionally seek help with a procedure or term, but
most often refresh their memory of commands and functions. The expert user
tends only to seek help with command or function syntax, keyboard
equivalents and shortcut keys.
There are no rules for determining the overall content of your Help system.
If you are providing Help for all types of users, you will want to document
commands, procedures, definitions, features, functions, and other relevant
aspects of your application. If you are providing help for expert users
only, you might want to omit topics that describe procedures. Let your
audience definition guide you when deciding what topics to include.
Keep in mind that the decision to implement context-sensitive Help is an
important one. Context-sensitive Help demands a close working relationship
between the Help author and the application programmer, and will therefore
increase the development time necessary to create a successful Help system.
16.1.3 Planning the Structure of Help Topics
Many Help systems structure topics hierarchically. At the top of the
hierarchy is an index or a table of contents, or both. The index and table
of contents list individual topics or categories of topics available to the
user.
Topics themselves can be related hierarchically. Each successive step takes
the user one level down in the hierarchy of the Help system until the user
reaches topic information. The hierarchical relationship of Help topics
determines in part how the user navigates through the Help system. Figure
16.1 illustrates a possible hierarchy:
(This figure may be found in the printed book).
Helpex contains an index that lists several categories of topics. Each
category includes a secondary index, which lists topics in the category, and
the topics themselves.
Moving from the index to a topic, the user goes from the general to the
specific.
The hierarchical structure provides the user a point of reference within
Help. Users are not constrained to navigate up and down the hierarchy; they
can jump from one topic to another, moving across categories of topics. The
effect of jumps is to obscure hierarchical relationships. For example, the
Windows Help application contains a search feature that lets the user enter
a key word into a dialog box and search for topics associated with that key
word. The Help application then displays a list of titles to choose from in
order to access information that relates to the key word.
Because users often know which feature they want help with, they can usually
find what they want faster using the search feature than they can by moving
through the hierarchical structure. For more information about the search
feature, see Section 17.3.4, "Assigning Key Words."
In addition to ordering topics hierarchically, you can order them in a
logical sequence that suits your audience. The logical sequence, or "browse
sequence," lets the user choose the Browse button to move from topic to
topic. Browse sequences are especially important for users who like to read
several related topics at once, such as the topics covering the commands on
the File menu. For more information about browse sequences, see Chapter 17,
"Creating the Help Topic Files."
Whichever structure you decide to use, try to minimize the number of lists
that users must traverse in order to obtain information. Also, avoid making
users move through many levels to reach a topic. Most Help systems function
quite well with only two or three levels.
16.1.4 Displaying Context-Sensitive Help Topics
Windows Help supports context-sensitive Help. When written in conjunction
with programming of the application, context-sensitive Help lets the user
press F1 in an open menu to get help with the selected menu item.
Alternatively, the user can press SHIFT+F1 and then click on a screen region
or command to get help on that item.
For example, if the user presses SHIFT+F1, then clicks on the maximize icon
when using the sample application Helpex, the Help system displays the
information illustrated in Figure 16.2:
(This figure may be found in the printed book).
Developing context-sensitive Help requires coordination between the Help
writer and the application programmer so that Help and the application pass
the correct information back and forth.
To plan for context-sensitive Help, the Help author and the application
programmer should agree on a list of context numbers. Context numbers are
arbitrary numbers that correspond to each menu command or screen region in
the application, and are used to create the links to the corresponding Help
topics. You can then enter these numbers, along with their corresponding
context-string identifiers, in the Help project file, which the Help
Compiler uses to build a Help resource file. Section 18.1, "Creating the
Help Project File," provides details on how to create a Help project file.
The context numbers assigned in the Help project file must correspond to the
context numbers that the application sends at run time to invoke a
particular topic. See Section 18.9, "Programming the Application to Access
Help," for more information on assigning context numbers.
If you do not explicitly assign context numbers to topics, the Help Compiler
generates default values by converting topic context strings into context
numbers. See Section 18.6, "Mapping Context-Sensistive Topics: The Map
Section," for more information on context-sensitive Help and context
strings.
To manage context numbers and file information, you might want to create a
Help tracker to list the context numbers for your context-sensitive topics.
See Section 17.5.1, "Creating the Help Tracker," for information about using
a tracker.
16.2 Determining the Topic File Structure
The Help file structure remains essentially the same for all applications
even though the context and number of topic files differ. Topic files are
segmented into the different topics by means of page breaks. When you build
the Help system, the compiler uses these topic files to create the
information displayed for the user in the application's Help window.
Figure 16.3 shows this basic file structure.
(This figure may be found in the printed book).
16.2.1 Choosing a File Structure for Your Application
When choosing a file structure for your Help system, consider the scope and
content of the Help system you are planning. For example, you could place
all Help topics in a single large topic file. Or, you could place each Help
topic in a separate file. Neither of these file structures is generally
acceptable. An enormous single file or too many individual files can present
difficulties during the creation of the Help resource file.
The number of topics relates to the number of features covered by the Help
system. Consequently, you cannot make extensive changes to one without
making changes to the other. For instance, if a number of additional product
features are added to Help, then additional topics must be created to
accommodate the new information.
Figure 16.4 illustrates the file structure of a possible Help system. The
number of topics and topic files is limited to simplify the diagram and more
clearly show the concept of linking the topics together through jumps, shown
in the figure as arrows. The figure is not intended to show the number of
files that can be included in the Help file system. Moreover, the figure
does not show how topic files are ordered using the browse feature.
(This figure may be found in the printed book).
16.3 Designing the Appearance of Help Topics
How the information in the Help window appears to the user is primarily a
function of the layout of the Help topic. The Windows Help application
supports a number of text attributes and graphic images you can use to
design your Help window.
This section provides general guidelines for designing a window and
describes fonts and graphic images that Windows Help supports.
16.3.1 Layout of the Help Text
Help text files are not limited to plain, unformatted text. You can use
different fonts and point sizes, include color and graphics to emphasize
points, present information in tables, indent paragraphs to present complex
information, and use a variety of other visual devices to present your
information.
Research on screen format and Help systems has produced general guidelines
for presenting information to users. Section 16.5, "Summary," lists some
sources of this research. The following list summarizes the findings of
these studies.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Design Issue Guideline
Design Issue Guideline
────────────────────────────────────────────────────────────────────────────
Language Use language appropriate for the
audience you have defined.
Language that is too sophisticated for
your audience can frustrate users by
requiring them
to learn the definition of unfamiliar
terms and
concepts.
Amount of text Use a minimum of text.
Studies indicate that reading speed
decreases by 30 percent when users read
online text rather than printed text.
Minimal, concise text helps users
compensate for the decreased reading
speed.
Design Issue Guideline
────────────────────────────────────────────────────────────────────────────
Paragraph length Use short paragraphs.
Online users become overloaded with text
more easily than do readers of printed
material. Breaking your text into short
paragraphs helps avoid this problem.
White space Use it to help group information
visually.
White space is important to making
online text more readable. Use it
liberally, while also considering the
overall size that a topic will occupy on
the screen. Users tend to think there is
more information on a screen than exists.
For example, if the ratio of white space
to text is 50:50, users perceive the
Design Issue Guideline
────────────────────────────────────────────────────────────────────────────
to text is 50:50, users perceive the
ratio to be 40:60.
Highlighting Use highlighting techniques judiciously.
Windows Help provides a variety of
highlighting devices, such as font sizes,
font types, and color. Using a few
devices can help users find information
quickly. Using many devices will
decrease
the effectiveness of your visual
presentation and frustrate users. As
with print-based documentation, use only
one or two fonts at a time.
Graphics and icons Use graphics to support the explanation
of visual events.
Design Issue Guideline
────────────────────────────────────────────────────────────────────────────
Windows Help supports the use of
bitmapped graphic images. Use
appropriate images to help
explain the function of icons and screen
elements in your application. Remember
that graphics will draw the user's eye
before the accompanying text. Be sure to
crop your images to remove distracting
information. Use color images only if
you are
certain that all your users' systems
have color capability. As with
context-sensitive Help, consider the
additional time necessary to create
accurate and meaningful graphic images.
Design consistency Be rigorously consistent in your design.
Design Issue Guideline
────────────────────────────────────────────────────────────────────────────
Users expect the appearance of Help
topics to be the same, regardless of the
information presented. Consistent
titling, highlighting, fonts, and
positioning of text in the window is
essential to an effective Help system.
Figure 16.5 illustrates a Help window that follows these design principles.
(This figure may be found in the printed book).
16.3.2 Type Fonts and Sizes
The Windows Help application can display text in any font and size available
to the system. When the topic files are passed to the build process, the
Help Compiler attempts to use the fonts and sizes found in the topic files.
If a font or point size cannot be matched exactly when the Help file is
displayed by Windows Help, the closest available font and size on the user's
system will be used.
Windows ships with only certain fonts in specific font sizes. If you write
Help files using these fonts and sizes, the displayed Help file will closely
match the printed word-processed file. Because fonts other than those
shipped with Windows may not be available on users' machines, you might want
to limit your font selection to the shipped Windows fonts.
The fonts included with Windows are:
■ Courier 10,12,15
■ Helv 8,10,12,14,18,24
■ Modern
■ Roman
■ Script
■ Symbol 8,10,12,14,18,24
■ Tms Rmn 8,10,12,14,18,24
Figure 16.6 illustrates a Help window with Helv-font text:
(This figure may be found in the printed book).
Since Windows Help supports any Windows font, special symbols such as arrows
can be included in your topics by using the Symbol font, as shown in Figure
16.7:
(This figure may be found in the printed book).
16.3.3 Graphic Images
The Windows Help application allows you to embed graphics in the Help file.
Graphics can be placed and displayed anywhere on the page. Text can appear
next to the graphic, as shown in Figure 16.8:
(This figure may be found in the printed book).
Color graphic images can be included, provided you use only the available
Windows system colors. If you use graphics tools that support an enhanced
color palette to create or capture images, these images may not always
display with the intended colors. And since you cannot control the color
capabilities on a user's machine, you might want to limit your graphic
images to black and white bitmaps.
Keep in mind that graphics are most effective when they contribute to the
learning process. Graphics not tied to the information are usually
distracting rather than helpful and should be avoided. See Section 17.4,
"Inserting Graphic Images," for more information on placing graphics into
your Help files.
16.4 Summary
This chapter described how to plan a Help system, including defining the
audience, planning the content, implementing context-sensitive Help,
structuring topic files, and designing the layout of Help topics.
For additional information about planning your Help system, see the
following:
Topic Reference
────────────────────────────────────────────────────────────────────────────
Creating topic files Tools: Chapter 17, "Creating the Help
Topic Files"
Screen design Bradford, Annette Norris. "Conceptual
Differences Between the Display Screen
and the Printed Page." Technical
Communication (Third Quarter 1984):
13-16
Galitz, Wilbert O. Handbook of Screen
Format
Design. 3d ed. Wellesley, MA: QED
Information Sciences, Inc., 1989
Houghton, Raymond C., Jr. "Online Help
Systems: A Conspectus." Communications
of the ACM 27(February 1984): 126-133
Queipo, Larry. "User Expectations of
Online
Information." IEEE Transactions on
Professional Communications PC
29(December 1986): 11-15
Chapter 17 Creating the Help Topic Files
────────────────────────────────────────────────────────────────────────────
Probably the most time-consuming task in developing a Help system for your
application is creating the Help topic files from which you compile the Help
system. Help topic files are text files that define what the user sees when
using the Help system. The topic files can define various kinds of
information, such as an index to information on the system, a list of
commands, or a description of how to perform a task.
Creating topic files entails writing the text that the user sees when using
Help, and entering control codes that determine how the user can move from
one topic to another.
This chapter describes the following topics:
■ Choosing an authoring tool
■ Structuring Help topic files
■ Coding Help topic files
■ Managing Help topic files
17.1 Choosing an Authoring Tool
To write your text files, you will need a Rich Text Format (RTF) editor,
which lets you create the footnotes, underlined text, and strikethrough or
double-underlined text that indicate the control codes. These codes are
described in Section 17.3, "Coding Help Topic Files." Your choices include,
but are not limited to:
■ Microsoft Word for Windows, version 1.0.
■ Microsoft Word for the PC, version 5.0.
■ Microsoft Word for the Macintosh, version 3.0 or 4.0.
■ Other word processors that support RTF.
Microsoft Word's RTF capability allows you to insert the coded text required
to define Help terms, such as jumps, key words, and definitions. If you
choose an editor other than one of the Microsoft Word products, make sure it
will create Help files that work as you intend.
17.2 Structuring Help Topic Files
A Help topic file typically contains multiple Help topics. To identify each
topic within a file:
■ Topics are separated by hard page breaks.
■ Each topic accessible via a hypertext link must have a unique
identifier, or context string.
■ Each topic can have a title.
■ Each topic can have a list of key words associated with it.
■ Each topic can have a build-tag indicator.
■ Any topic can have an assigned browse sequence.
Figure 17.1 illustrates part of the topic file that contains descriptions of
how to perform tasks using the sample application Helpex.
(This figure may be found in the printed book).
For information about inserting page breaks between topics, see the
documentation for the editor you are using. For information about assigning
context strings and titles to topics, see the following sections.
17.3 Coding Help Topic Files
The Help system uses control codes for particular purposes:
Control Code Purpose
────────────────────────────────────────────────────────────────────────────
Asterisk (*) footnote Build tag─Defines a tag that specifies
topics the compiler conditionally builds
into the system. Build tags are optional,
but they must appear first in a topic
when they are used.
Pound sign (#) footnote Context string─Defines a context string
that uniquely identifies a topic.
Because hypertext relies on links
provided by context strings, topics
without context strings can only be
accessed using key words or browse
sequences.
Dollar sign ($) footnote Title─Defines the title of a topic.
Titles are optional.
Letter "K" footnote Key word─Defines a key word the user
uses to search for a topic. Key words
are optional.
Plus sign (+) footnote Browse sequence number─Defines a
sequence that determines the order in
which the user can browse through topics.
Browse sequences are optional. However,
if you omit browse sequences, the Help
window will still include the Browse
buttons, but they will be grayed.
Strikethrough or Cross-reference─Indicates the text the
double-underlined text user can choose to jump to another
topic.
Underlined text Definition─Specifies that a temporary or
"look-up" box be displayed when the user
holds down the mouse button or ENTER key.
The box can include such information as
the definition of a word or phrase, or a
hint about a procedure.
Hidden text Cross-reference context string─Specifies
the context string for the topic that
will be displayed when the user chooses
the text that immediately precedes it.
If you are using build tags, footnote them at the very beginning of the
topic. Place other footnotes in any order you want. For information about
assigning specific control codes, see the following sections.
17.3.1 Assigning Build Tags
Build tags are strings that you assign to a topic in order to conditionally
include or exclude that topic from a build. Each topic can have one or more
build tags. Build tags are not a necessary component of your Help system.
However, they do provide a means of supporting different versions of a Help
system without having to create different source files for each version.
Topics without build tags are always included in a build.
You insert build tags as footnotes using the asterisk (*). When you assign a
build tag footnote to a topic, the compiler includes or excludes the topic
according to build information specified in the BUILD option and [BuildTags]
section of the Help project file. For information about the BUILD option,
the [BuildTags] section and the Help project file, see Chaper 18, "Building
the Help File."
To assign a build tag to a topic:
1. Place the cursor at the beginning of the topic heading line, so that
it appears before all other footnotes for that topic.
2. Insert the asterisk (*) as a footnote reference mark.
Note that a superscript asterisk ( * ) appears next to the heading.
3. Type the build tag name as the footnote.
Be sure to allow only a single space between the asterisk (*) and the
build tag.
Build tags can be made up of any alphanumeric characters. The build tag is
not case-sensitive. The tag may not contain spaces. You can specify multiple
build tags by separating them with a semicolon, as in the following example:
* AppVersion1; AppVersion2; Test_Build
Including a build tag footnote with a topic is equivalent to setting the tag
to true when compared to the value set in the project file. The compiler
assumes all other build tags to be false for that topic. After setting the
truth value of the build tag footnotes, the compiler evaluates the build
expression in the Options section of the Help project file. Note that all
build tags must be declared in the project file, regardless of whether a
given conditional compilation declares the tags. If the evaluation results
in a true state, the compiler includes the topic in the build. Otherwise,
the compiler omits the topic.
The compiler includes in all builds topics that do not have a build tag
footnote regardless of the build tag expressions defined in the Help project
file. For this reason, you may want to use build tags primarily to exclude
specific topics from certain builds. If the compiler finds any build tags
not declared in the Help project file, it displays an error message.
By allowing conditional inclusion and exclusion of specific topics, you can
create multiple builds using the same topic files. This saves time and
effort for the Help development team. It also means that you can develop
Help topics that will help you maintain a higher level of consistency across
your product lines.
17.3.2 Assigning Context Strings
Context strings identify each topic in the Help system. Each context string
must be unique. A given context string may be assigned to only one topic
within the Help project; it cannot be used for any other topic.
The context string provides the means for creating jumps between topics or
to display look-up boxes, such as word and phrase definitions. Though not
required, most topics in the Help system will have context-string
identifiers, Topics without context strings may not be accessed through
hypertext jumps. However, topics without context-string identifiers can be
accessed through browse sequences or key-word searches, if desired. It is up
to the Help writer to justify the authoring of topics that can be accessed
only in these manners. For information about assigning jumps, see Section
17.3.6, "Creating Cross-References Between Topics." For information about
assigning browse sequences, see Section 17.3.5, "Assigning Browse Sequence
Numbers." For information about assigning key words, see Section 17.3.4,
"Assigning Key Words."
To assign a context string to a Help topic:
1. Place the cursor to the left of the topic heading.
2. Insert the pound sign (#) as the footnote reference mark.
Note that a superscript pound sign ( # ) appears next to the heading.
3. Type the context string as the footnote.
Be sure to allow only a single space between the pound sign (#) and
the string.
Context strings are not case-sensitive.
Valid context strings may contain the alphabetic characters A-Z, the numeric
characters 0-9, and the period (.) and underscore (_) characters. The
following example shows the context string footnote that identifies a topic
called "Opening an Existing Text File":
#OpeningExistingTextFile
Although a context string has a practical limitation of about 255
characters, there is no good reason for approaching this value. Keep the
strings sensible and short so that they're easier to enter into the text
files.
17.3.3 Assigning Titles
Title footnotes perform the following functions within the Help system:
■ They appear on the Bookmark menu.
■ They appear in the "Topics found " list that results from a key-word
search. (Topics that do not have titles, but are accessible via key
words are listed as >>Untitled Topic<< in the Topics found list.)
Although not required, most topics have a title. You might not assign a
title to topics containing low-level information that Help's search feature,
look-up boxes and system messages do not access.
To assign a title to a topic:
1. Place the cursor to the left of the topic heading.
2. Insert a footnote with a dollar sign ($) as the footnote reference
mark.
Note that a superscript dollar sign ( $ ) appears next to the heading.
3. Type the title as the footnote.
Be sure to allow only a single space between the dollar sign ($) and
the title.
The following is an example of a footnote that defines the title for a
topic:
$ Help Keys
When adding titles, keep in mind the following restrictions:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Item Restrictions
────────────────────────────────────────────────────────────────────────────
Characters Titles can be up to 128 characters in
length.
The Help compiler truncates title
Item Restrictions
────────────────────────────────────────────────────────────────────────────
The Help compiler truncates title
strings longer than 128 characters.
The help system displays titles in a
list box when the user searches for a
key word or enters a bookmark.
Formatting Title footnote entries cannot be
formatted.
17.3.4 Assigning Key Words
Help allows the user to search for topics with the use of key words assigned
to the topics. When the user searches for a topic by key word, Help matches
the user-entered word to key words assigned to specific topics. Help then
lists matching topics by their titles in the Search dialog box. Because a
key-word search is often a fast way for users to access Help topics, you'll
probably want to assign key words to most topics in your Help system.
────────────────────────────────────────────────────────────────────────────
NOTE
You should specify a key-word footnote only if the topic has a title
footnote since the title of the topic will appear in the search dialog when
the user searches for the key word.
────────────────────────────────────────────────────────────────────────────
To assign a key word to a topic:
1. Place the cursor to the left of the topic heading.
2. Insert an uppercase K as the footnote reference mark.
Note that a superscript K ( K ) appears next to the heading.
3. Type the key word, or key words, as the footnote.
Be sure to allow only a single space between the K and the first key
word.
If you add more than one key word, separate each with a semicolon.
The following is an example of key words for a topic:
K open;opening;text file;ASCII;existing;text only;documents;
Whenever the user performs a search on any of these key words, the
corresponding titles appear in a list box. More than one topic may have the
same key word.
When adding key words, keep in mind the following restrictions:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Item Restrictions
────────────────────────────────────────────────────────────────────────────
Characters Key words can include any ANSI character,
Item Restrictions
────────────────────────────────────────────────────────────────────────────
Characters Key words can include any ANSI character,
including accented characters. The
maximum length for key words is 255
characters.
A space imbedded in a key phrase is
considered to be a character, permitting
phrases to be key words.
Phrases Help searches for any word in the
specified phrase.
Formatting Key words are unformatted.
Case sensitivity Key words are not case-sensitive.
Punctuation Except for semicolon delimiters, you can
use punctuation.
Item Restrictions
────────────────────────────────────────────────────────────────────────────
Creating Multiple Key-Word Tables
Multiple key-word tables are useful to allow a program to look up topics
that are defined in alternate key-word tables. You can use an additional
key-word table to allow users familiar with key words in a different
application to discover the matching key words in your application.
Authoring additional key-word tables is a two-part process. First, the
MULTIKEY option must be placed in the [Options] section of the project file.
For information on the MULTIKEY option, see Section 18.4.8, "Multiple
Key-Word Tables: The Multikey Option."
Second, the topics to be associated with the additional key-word table must
be authored and labeled. Footnotes are assigned in the same manner as the
normal key-word footnotes, except that the letter specified with the
MULTIKEY option is used. With this version of the Help Compiler, the
key-word footnote used is case-sensitive. Therefore, care should be taken to
use the same case, usually uppercase, for your key-word footnote. Be sure to
associate only one topic with a key word. Help does not display the normal
search dialog box for a multiple key-word search. Instead it displays the
first topic found with the specified key word. If you want the topics in
your additional key-word table to appear in the normal Help key-word table,
you must also specify a "K" footnote and the given key word.
The application you are developing Help for can then display the Help topic
associated with a given string in a specified key-word table. Key words are
sorted without regard to case for the key-word table. For information on the
parameters passed by the application to call a topic found in alternate
key-word table, see Section 18.9.4, "Accessing Additional Key-Word Tables."
17.3.5 Assigning Browse Sequence Numbers
────────────────────────────────────────────────────────────────────────────
NOTE
In this version of Help, topics defined in browse sequences are accessed
using the Browse buttons at the top of the Help window. Future versions of
Help will not normally display browse buttons for the user. However, if your
Help resource file includes browse sequences authored in the format
described here, these versions will support the feature by automatically
displaying browse buttons for the user.
────────────────────────────────────────────────────────────────────────────
The Browse >> and Browse browse sequence." A browse sequence is determined
by sequence numbers, established by the Help writer.
To build browse sequences into the Help topics, the writer must:
1. Decide which topics should be grouped together and what order they
should follow when viewed as a group.
Help supports multiple, discontiguous sequence lists.
2. Code topics to implement the sequence.
Organizing Browse Sequences
When organizing browse sequences, the writer must arrange the topics in an
order that will make sense to the user. Topics can be arranged in
alphabetical order within a subject, in order of difficulty, or in a
sensible order that seems natural to the application. The following example
illustrates browse sequences for the menu commands used in a given
application. The Help writer has subjectively defined the order that makes
the most sense from a procedural point of view. You may, of course, choose a
different order.
SampleApp Commands
File Menu - commands:005
New Command - file_menu:005
Open Command - file_menu:010
Save Command - file_menu:015
Save As Command - file_menu:020
Print Command - file_menu:025
Printer Setup Command - file_menu:030
Exit Command - file_menu:035
Edit Menu - commands:010
Undo Command - edit_menu:025
Cut Command - edit_menu:015
Copy Command - edit_menu:010
Paste Command - edit_menu:020
Clear Command - edit_menu:005
Select All Command - edit_menu:030
Word Wrap Command - edit_menu:035
Type Face Command - edit_menu:040
Point Size Command - edit_menu:045
Search Menu - commands:015
Find Command - search_menu:005
Find Next Command - search_menu:010
Previous Command - search_menu:015
Window Menu - commands:020
Tile Command - window_menu:005
Cascade Command - window_menu:010
Arrange Icons Command - window_menu:015
Close All Command - window_menu:020
Document Names Command - window_menu:025
Each line consists of a sequence list name followed by a colon and a
sequence number. The sequence list name is optional. If the sequence does
not have a list name, as in the following example, the compiler places the
topic in a "null" list:
Window Menu - 120
Note that the numbers used in the browse sequence example begin at 005 and
advance in increments of 005. Generally, it is good practice to skip one or
more numbers in a sequence so you can add new topics later if necessary.
Skipped numbers are of no conseqence to the Help Compiler; only their order
is significant.
Sequence numbers establish the order of topics within a browse sequence
list. Sequence numbers can consist of any alphanumeric characters. During
the compiling process, strings are sorted using the ASCII sorting technique,
not a numeric sort.
Both the alphabetic and numeric portions of a sequence can be several
characters long; however, their lengths should be consistent throughout all
topic files. If you use only numbers in the strings make sure the strings
are all the same length; otherwise a higher sequence number could appear
before a lower one in certain cases. For example, the number 100 is
numerically higher than 99, but 100 will appear before 99 in the sort used
by Help, because Help is comparing the first two digits in the strings. In
order to keep the topics in their correct numeric order, you would have to
make 99 a three-digit string: 099.
Coding Browse Sequences
After determining how to group and order topics, code the sequence by
assigning the appropriate sequence list name and number to each topic, as
follows:
1. Place the cursor to the left of the topic heading.
2. Insert the plus sign (+) as the footnote reference mark.
Note that a superscript plus sign ( + ) appears next to the heading.
3. Type the sequence number using alphanumeric characters.
For example, the following footnote defines the browse sequence number for
the Edit menu topic in the previous browse sequence example:
+ commands:010
While it may be easier to list topics within the file in the same order that
they appear in a browse sequence, it is not necessary. The compiler orders
the sequence for you.
17.3.6 Creating Cross-References Between Topics
Cross-references, or "jumps," are specially-coded words or phrases that are
linked to other topics. Although you indicate jump terms with strikethrough
or double-underlined text in the topic file, they appear underlined in the
Help window. In addition, jump terms appear in color on color systems. For
example, the strikethrough text (double-underlined in Word for Windows) New
Command appears as New Command in green text to the user.
To code a word or phrase as a jump in the topic file :
1. Place the cursor at the point in the text where you want to enter the
jump term.
2. Select the strikethrough (or double-underline) feature of your editor.
3. Type the jump word or words in strikethrough mode.
4. Turn off strikethrough and select the editor's hidden text feature.
5. Type the context string assigned to the topic that is the target of
the jump.
When coding jumps, keep in mind that:
■ No spaces can occur between the strikethrough (or double-underlined)
text and the hidden text.
■ Coded spaces before or after the jump term are not permitted.
■ Paragraph marks must be entered as plain text.
17.3.7 Defining Terms
Most topic files contain words or phrases that require further definition.
To get the definition of a word or phrase, the user first selects the word
and then holds down the mouse button or ENTER key, causing the definition to
appear in a box within the Help window. The Help writer decides which words
to define, considering the audience that will be using the application and
which terms might already be familiar.
────────────────────────────────────────────────────────────────────────────
NOTE
The look-up feature need not be limited to definitions. With the capability
to temporarily display information in a box, you might want to show a hint
about a procedure, or other suitable information for the user.
────────────────────────────────────────────────────────────────────────────
Defining a term requires that you:
■ Create a topic that defines the term.
The definition topic must include a context string. See Section
17.3.2, "Assigning Context Strings."
■ Provide a cross-reference for the definition topic whenever the term
occurs.
You don't need to define the same word multiple times in the same
topic, just its first occurrence. Also, consider the amount of colored
text you are creating in the Help window.
See the following "Coding Definitions" section.
Creating Definition Topics
You can organize definition topics any way you want. For example, you can
include each definition topic in the topic file that mentions the term. Or
you can organize all definitions in one topic file and provide the user with
direct access to it. Helpex uses the latter method, with all definitions
residing in the TERMS.RTF file. Organizing definition topics into one file
provides you with a glossary and lets you make changes easily.
Coding Definitions
After creating definition topics, code the terms as they occur, as follows:
1. Place the insertion point where you want to place the term that
requires definition.
2. Select the underline feature of your editor.
3. Type the term.
4. Turn off the underline feature, and select the editor's hidden-text
feature.
5. Type the context string assigned to the topic that contains the
definition of the term.
Figure 17.2 includes a definition of the term "Clipboard."
(This figure may be found in the printed book).
17.4 Inserting Graphic Images
Bitmapped graphic images can be placed in Help topics using either of two
methods. If your word processor supports the placement of Windows 2.1 or
Windows 3.0 graphics directly into a document, you can simply paste your
bitmaps into each topic file. Alternatively, you can save each bitmap in a
separate file and specify the file by name where you want it to appear in
the Help topic file. The latter method of placing graphics is referred to as
"bitmaps by reference." The following sections describe the process of
placing bitmaps directly or by reference into your Help topics.
17.4.1 Creating and Capturing Bitmaps
You can create your bitmaps using any graphical tools, as long as the
resulting images can be displayed in the Windows environment. Each graphic
image can then be copied to the Windows clipboard. Once on the clipboard, a
graphic can be pasted into a graphics editor such as Paint, and modified or
cleaned up as needed.
Windows Help 3.0 supports color bitmaps. However, for future compatibility,
you might want to limit graphics to monochrome format. If you are producing
monochrome images, you might have to adjust manually the elements of your
source graphic that were originally different colors to either black, white,
or a pattern of black and white pixels.
When you are satisfied with the appearance of your bitmap, you can either
save it as a file, to be used as a bitmap by reference, or you can copy it
onto the clipboard and paste it into your word processor. If you save the
graphic as a file, be sure to specify its size in your graphics editor
first, so that only the area of interest is saved for display in the Help
window. The tighter you crop your images, the more closely you will be able
to position text next to the image. Always save (or convert and save if
necessary) graphics in Windows' .BMP format.
Bitmap images should be created in the same screen mode that you intend Help
to use when topics are displayed. If your Help files will be displayed in a
different mode, bitmaps might not retain the same aspect ratio or
information as their source images.
17.4.2 Placing Bitmaps Using a Graphical Word Processor
The easiest way to precisely place bitmaps into Help topics is to use a
graphical word processor. Word for Windows supports the direct importation
of bitmaps from the clipboard. Simply paste the graphic image where you want
it to appear in the Help topic. You can format your text so that it is
positioned below or alongside the bitmap. When you save your Help topic file
in RTF, the pasted-in bitmap is converted as well and will automatically be
included in the Help resource file.
17.4.3 Placing Bitmaps by Reference
If your word processor cannot import and display bitmaps directly, you can
specify the location of a bitmap that you have saved as a file. To insert a
bitmap reference in the Help topic file, insert one the following statements
where you want the bitmap to appear in the topic:
{bmc filename.bmp} {bml filename.bmp} {bmr filename.bmp}
────────────────────────────────────────────────────────────────────────────
NOTE
Do not specify a full path for filename. If you need to direct the compiler
to a bitmap in a location other than the root directory for the build,
specify the absolute path for the bitmap in the [Bitmaps] section of the
project file.
────────────────────────────────────────────────────────────────────────────
The argument bmc stands for "bitmap character," indicating that the bitmap
referred to will be treated the same as a character placed in the topic file
at the same location on a line. Text can precede or follow the bitmap on the
same line, and line spacing will be determined based upon the size of the
characters (including the bitmap character) on the line. Do not specify
negative line spacing for a paragraph with a bitmap image, or the image may
inadvertently overwrite text above it when it is displayed in Help. When you
use the argument bmc, there is no automatic text wrapping around the graphic
image. Text will follow the bitmap, positioned at the baseline.
The argument bml specifies that the bitmap appear at the left margin, with
text wrapping automatically along the right edge of the image. The argument
bmr specifies that the bitmap appear at the right margin, with text to its
left. Bitmap filenames must be the same as those listed in the [Bitmaps]
section of the Help project file. The [Bitmaps] section is described in
Chapter 18, "Building the Help File."
────────────────────────────────────────────────────────────────────────────
NOTE
Multiple references to a bitmap of the same name refer to the same bitmap
when the Help file is displayed. This means that bitmap references can be
repeated in your Help system without markedly increasing the size of the
Help resource file.
────────────────────────────────────────────────────────────────────────────
Figure 17.3 shows the placement of three bitmaps with related text in a
topic as displayed in Help.
(This figure may be found in the printed book).
17.5 Managing Topic Files
Help topic files can be saved in the default word-processor format or in
RTF. If you always save your files in RTF, and later need to make a change,
the word processor may take additional time to interpret the format as it
reloads the file. If you anticipate making numerous changes during Help
development, you might want to minimize this delay by saving topic files in
both default and RTF formats, with different file extensions to distinguish
them. The compiler needs only the RTF files, and you will have faster access
to the source files for changes. On a large project, this practice can save
a considerable amount of development time.
17.5.1 Keeping Track of Files and Topics
It is important to keep track of all topic files for the following reasons:
■ To ensure that no topics are left out of the build process
■ To ensure that each topic has been assigned a unique context string
■ To double-check browse sequencing within general and specific lists
■ To show key-word and title matches
■ To allow writers to see where the text for each of the topics is
located
■ To keep track of changes to files and the current status
■ To track any other aspect of the Help development process that you
think essential
At a minimum, writers must keep track of their own topic files, and must
pass the filenames to the person who is responsible for creating the Help
project file.
17.5.2 Creating a Help Tracker
While it is important that you track topic files throughout the development
cycle, the tracking tool can be anything that suits your needs. You can
maintain a current list of topics in an ASCII text file, in a Microsoft
Excel worksheet (if available), or in another format.
When you or another writer creates or revises a topic, you should update the
Help tracking file to reflect the change. The contents of the tracking file
are not rigidly defined, but should contain entries for filename, context
string, title, browse sequence, and key words. If your application makes use
of the context-sensitive feature of Help, you may want to keep track of the
context-sensitive information as well. This entry is necessary only if you
are assigning context numbers to topics in the Help project file. You can
also include optional information, such as date created, date modified,
status, and author, if you want to keep track of all aspects of the Help
development process. How you organize this information is entirely up to
you.
The following sample text file and worksheet illustrate how the tracker
might be organized for the Help system topics. The examples show both Help
menu and context-sensitive Help entries for the topic files. Typically, the
same topics that the user accesses when choosing commands from the Help
menus can be accessed by the context-sensitive Help feature. The topics with
entries in the context ID column are used for context-sensitive help as well
as for the Help menus. Notice that some topics have more than one
context-sensitive help number. This enables the topic to be displayed when
the user clicks on different regions of the screen.
(This figure may be found in the printed book).
(This figure may be found in the printed book).
Of course, you are free to keep track of the topic files you produce in a
manner different from either of these two examples.
17.6 Summary
This chapter described how to write, code, and keep track of Help topic
files. For information about building a Help file, see Chapter 18, "Building
the Help File."
Chapter 18 Building the Help File
────────────────────────────────────────────────────────────────────────────
After the topic files for your Help system have been written, you are ready
to create a Help project file and run a build to test the Help file. The
Help project file contains all information the compiler needs to convert
help topic files into a binary Help resource file.
You use the Help project file to tell the Help Compiler which topic files to
include in the build process. Information in the Help project file also
enables the compiler to map specific topics to context numbers (for the
context-sensitive portion of Help).
After you have compiled your Help file, the development team programs the
application so the user can access it.
The chapter describes the following:
■ Creating a Help project file
■ Compiling the Help file
■ Programming the application to access Help
18.1 Creating the Help Project File
You use the Help project file to control how the Help Compiler builds your
topic files. The Help project file can contain up to six sections that
perform the following functions:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Section Function
────────────────────────────────────────────────────────────────────────────
[Files] Specifies topic files to be included in
the build. This section is mandatory.
[Options] Specifies the level of error reporting,
topics to be included in the build, the
directory in which to find the files,
and the location of your Help index.
Section Function
────────────────────────────────────────────────────────────────────────────
and the location of your Help index.
This section is optional.
[BuildTags] Specifies valid build tags. This section
is optional.
[Alias] Assigns one or more context strings to
the same topic. This section is
optional.
[Map] Associates context strings with context
numbers. This section is optional.
[Bitmaps] Specifies bitmap files to be included in
the build. This section is optional.
You can use any ASCII text editor to create your Help project file. The
extension of a Help project file is .HPJ. If you do not use the extension
.HPJ on the HC command line, the compiler looks for a project file with this
extension before loading the file. The .HLP output file will have the same
name as the .HPJ file.
The order of the various sections within the Help project file is arbitrary,
with one exception: under all circumstances an [Alias] section must precede
the [Map] section (if an [Alias] section is used).
Section names are placed within square brackets using the following syntax:
[section-name]
You can use a semicolon to indicate a comment in the project file. The
compiler ignores all text from the semicolon to the end of the line on which
it occurs.
18.2 Specifying Topic Files: The Files Section
Use the [Files] section of the Help project file to list all topic files
that the Help Compiler should process to produce a Help resource file. A
Help project file must have a [Files] section.
The following sample shows the format of the [Files] section:
[FILES]
HELPEX.RTF ;Main topics for HelpEx application
TERMS.RTF ;Lookup terms for HelpEx appliction
Using the path defined in the ROOT option, the Help Compiler finds and
processes all files listed in this section of the Help project file. If the
file is not on the defined path and cannot be found, the compiler generates
an error. For more information about the ROOT option, see Section 18.4.3,
"Specifying the Root Directory: The Root Option."
You can include files in the build process using the C #include directive
command.
The #include directive uses the following syntax:
#include <filename>
You must include the angle brackets around the filename. The pound sign ( #
) must be the first character in the line. The filename must specify a
complete path, either the path defined by the ROOT option or an absolute
directory path to the file.
You may find it easier to create a text file that lists all files in the
Help project and include that file in the build, as in this example:
[FILES]
#include <hlpfiles.inc>
18.3 Specifying Build Tags: The BuildTags Section
If you code build tags in your topic files, use the [BuildTags] section of
the Help project file to define all the valid build tags for a particular
Help project. The [BuildTags] section is optional.
The following example shows the format of the [BuildTags] section in a
sample Help project file:
[BUILDTAGS]
WINENV ;topics to include in Windows build
DEBUGBUILD ;topics to include in debugging build
TESTBUILD ;topics to include in a mini-build for testing
The [BuildTags] section can include up to 30 build tags. The build tags are
not case-sensitive and may not contain space characters. Only one build tag
is allowed per line in this section. The compiler will generate an error
message if anything other than a comment is listed after a build tag in the
[BuildTags] section.
For information about coding build tags in topic files, see Section 17.3.3,
"Assigning Build Tags."
18.4 Specifying Options: The Options Section
Use the [Options] section of the Help project file to specify the following
options:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Option Meaning
────────────────────────────────────────────────────────────────────────────
BUILD Determines what topics the compiler
includes in the build.
COMPRESS Specifies compression of the Help
resource file.
FORCEFONT Specifies the creation of a Help
resource file using only one font.
INDEX Specifies the context string of the Help
index.
MAPFONTSIZE Determines the mapping of specified font
sizes to different sizes.
MULTIKEY Specifies alternate key-word mapping for
topics.
Option Meaning
────────────────────────────────────────────────────────────────────────────
topics.
ROOT Designates the directory to be used for
the Help build.
TITLE Specifies the title shown for the Help
system.
WARNING Indicates the kind of error message the
compiler reports.
These options can appear in any order within the [Options] section. The
[Options] section is not required.
Detailed explanations of the available options follow.
18.4.1 Specifying Error Reporting: The Warning Option
Use the WARNING option to specify the amount of debugging information that
the compiler reports. The WARNING option has the following syntax:
WARNING = level
You can set the WARNING option to any of the following levels:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Level Information Reported
────────────────────────────────────────────────────────────────────────────
1 Only the most severe warnings.
2 An intermediate level of warnings.
3 All warnings. This is the default level
if no WARNING option is specified.
The following example specifies an intermediate level of error reporting:
[OPTIONS]
WARNING=2
The compiler reports errors to the standard output file, typically the
screen. You may want to redirect the errors to a disk file so that you can
browse it when you are debugging the Help system. The following example
shows the redirection of compiler screen output to a file.
HC HELPEX > errors.out
────────────────────────────────────────────────────────────────────────────
HINT
Use the DOS CONTROL+PRINT SCREEN accelerator key before you begin your
compilation to echo errors which appear on the screen to your printer. Type
CONTROL+PRINT SCREEN again to stop sending information to the printer.
────────────────────────────────────────────────────────────────────────────
18.4.2 Specifying Build Topics: The Build Option
If you have included build tags in your topic files, use the BUILD option to
specify which topics to conditionally include in the build. If your topic
files have no build tags, omit the BUILD option from the [Options] section.
────────────────────────────────────────────────────────────────────────────
NOTE
All build tags must be listed in the [BuildTags] section of the project
file, regardless whether or not a given conditional compilation declares the
tags.
────────────────────────────────────────────────────────────────────────────
See Chapter 17, "Creating the Help Topic Files," for information on
assigning build tags to topics in the Help topic files.
The BUILD option line uses the following syntax:
BUILD = expression
BUILD expressions cannot exceed 255 characters in length, and must be
entered on only one line. BUILD expressions use Boolean logic to specify
which topics within the specified Help topic files the compiler will include
in the build. The tokens of the language are:
╓┌───────────────────────┌───────────────────────────────────────────────────╖
Token Description
────────────────────────────────────────────────────────────────────────────
<tag> Build tag
( ) Parentheses
& AND operator
| OR operator
~ NOT operator
The compiler evaluates all build expressions from left to right. The
operators have the following precedence:
────────────────────────────────────────────────────────────────────────────
1. ( )
2. ~
3. &
4. |
For example, if you coded build tags called WINENV, APP1, and TEST_BUILD in
your topic files, you could include one of the following build expressions
in the [Options] section:
Build Expression Topics Built
────────────────────────────────────────────────────────────────────────────
BUILD = WINENV Only topics that have the WINENV tag
BUILD = WINENV & APP1 Topics that have both the WINENV and
APP1 tags
BUILD = WINENV | APP1 Topics that have either the WINENV tag
or the APP1 tag
BUILD = (WINENV | APP1) & Topics that have either the WINENV or
TESTBUILD the APP1 tags and that also have the
TESTBUILD tag
BUILD =~ APP1 Topics that do not have a APP1 tag
18.4.3 Specifying the Root Directory: The Root Option
Use the ROOT option to designate the root directory of the Help project. The
compiler searches for files in the specified root directory.
The ROOT option uses the following syntax:
ROOT = pathname
For example, the following root option specifies that the root directory is
\BUILD\TEST on drive D:
[OPTIONS]
ROOT=D:\BUILD\TEST
The ROOT option allows you to refer to all relative paths off the root
directory of the Help project. For example, the following entry in the
[Files] section refers to a relative path off the root directory:
TOPICS\FILE.RTF
To refer to a file in a fixed location, independent of the project root, you
must specify a fully qualified or "absolute" path, including a drive letter,
if necessary, as in the following line:
D:\HELPTEST\TESTFILE.RTF
If you do not include the ROOT option in your Help project file, all paths
are relative to the current DOS directory.
18.4.4 Specifying the Index: The Index Option
Use the INDEX option to identify the context string of the Help index.
Because the Index button gives the user access to the index from anywhere in
the Help system, you will probably not want to author terms to jump to the
index. Users access this general index either from the Help menu of the
application or by choosing the Index button from the Help window.
Assigning a context string to the index topic in the [Options] section lets
the compiler know the location of the main index of Help topics for the
application's Help file. If you do not include the INDEX option in the
[Options] section, the compiler assumes that the first topic it encounters
is the index.
The INDEX option uses the following syntax:
INDEX = context-string
The context string specified must match the context string you assigned to
the Help index topic. In the following example, the writer informs the
compiler that the context string of the Help index is "main_index":
[OPTIONS]
INDEX=main_index
For information about assigning context strings, see Section 17.3.2,
"Assigning Context Strings."
18.4.5 Assigning a Title to the Help System: The Title Option
You can assign a title to your Help system with the TITLE option. The title
appears in the title bar of the Help window with the word "Help"
automatically appended, followed by the DOS filename of the Help resource
file.
The TITLE option uses the following syntax:
TITLE = Help-system-title-name
Titles are limited to 32 characters in length. If you do not specify a title
using the TITLE option, only the word Help followed by the Help system
filename will be displayed in the title bar. Because the compiler always
inserts the word Help, you should keep in mind not to duplicate it in your
title.Title option
18.4.6 Converting Fonts: The Forcefont Option
You can use the FORCEFONT option to create a Help resource file that is made
up of only one typeface or font. This is useful if you must compile a Help
system using topic files that include fonts not supported by your users'
systems.
The FORCEFONT option uses the following syntax:
FORCEFONT = fontname
The fontname parameter is any Windows system font. Windows ships with the
following fonts and sizes:
■ Courier 10,12,15
■ Helv 8,10,12,14,18,24
■ Modern
■ Roman
■ Script
■ Symbol 8,10,12,14,18,24
■ Tms Rmn 8,10,12,14,18,24
Font names must be spelled the same as they are in the Fonts dialog box in
Control Panel. Font names do not exceed 20 characters in length. If you
designate a font that is not recognized by the compiler, an error message is
generated and the compilation continues using the default Helv font.
────────────────────────────────────────────────────────────────────────────
NOTE
The fontname used in the FORCEFONT option cannot contain spaces. Therefore,
Tms Rmn font cannot be used with FORCEFONT.
────────────────────────────────────────────────────────────────────────────
18.4.7 Changing Font Sizes : The Mapfontsize Option
The font sizes specified in your topic files can be mapped to different
sizes using the MAPFONTSIZE option. In this manner, you can create and edit
text in a size chosen for easier viewing in the topic files and have them
sized by the compiler for the actual Help display. This may be useful if
there is a large size difference between your authoring monitor and your
intended display monitor.
The MAPFONTSIZE option uses the following syntax:
MAPFONTSIZE = m[-n]:p
The m parameter is the size of the source font, and the p parameter is the
size of the desired font for the Help resource file. All fonts in the topic
files that are size m are changed to size p. The optional parameter n allows
you to specify a font range to be mapped. All fonts in the topic files
falling between m and n, inclusive, are changed to size p. The following
examples illustrate the use of the MAPFONTSIZE option:
MAPFONTSIZE=12-24:16 ;make fonts from 12 to 24 come out 16.
MAPFONTSIZE=8:12 ;make all size 8 fonts come out size 12.
Note that you can map only one font size or range with each MAPFONTSIZE
statement used in the Options section. If you use more than one MAPFONTSIZE
statement, the source font size or range specified in subsequent statements
cannot overlap previous mappings. For instance, the following mappings would
generate an error when the compiler encountered the second statement:
MAPFONTSIZE=12-24:16 MAPFONTSIZE=14:20
Because the second mapping shown in the first example contains a size
already mapped in the preceding statement, the compiler will ignore the
line. There is a maximum of five font ranges that can be specified in the
project file.
18.4.8 Multiple Key-Word Tables: The Multikey Option
The MULTIKEY option specifies a character to be used for an additional
key-word table.
The MULTIKEY option uses the following syntax:
MULTIKEY = footnote-character
The footnote-character parameter is the case-sensitive letter to be used for
the key-word footnote. The following example illustrates the enabling of the
letter L for a key word-table footnote:
MULTIKEY=L
────────────────────────────────────────────────────────────────────────────
NOTE
You must be sure to limit your key word-table footnotes to one case, usually
uppercase. In the previous example, topics with the footnote L would have
their key words incorporated into the additional key word table, whereas
those assigned the letter l would not.
────────────────────────────────────────────────────────────────────────────
You may use any alphanumeric character for a key-word table except "K" and
"k" which are reserved for Help's normal key-word table. There is an
absolute limit of five key-word tables, including the normal table. However,
depending upon system configuration and the structure of your Help system, a
practical limit of only two or three may actually be the case. If the
compiler cannot create an additional table, the excess table is ignored in
the build.
18.4.9 Compressing the File: The Compress Option
You can use the COMPRESS option to reduce the size of the Help resource file
created by the compiler. The amount of file compression realized will vary
according to the number, size and complexity of topics that are compiled. In
general, the larger the Help files, the more they can be compressed.
The COMPRESS option uses the following syntax:
COMPRESS = TRUE | FALSE
Because the Help application can load compressed files quickly, there is a
clear advantage in creating and shipping compressed Help files with your
application. Compiling with compression turned on, however, may increase the
compile time, because of the additional time required to assemble and sort a
key-phrase table. Thus, you may want to compile without compression in the
early stages of a project.
The COMPRESS option causes the compiler to compress the system by combining
repeated phrases found within the source file(s). The compiler creates a
phrase-table file with the .PH extension if it does not find one already in
existence. If the compiler finds a file with the .PH extension, it will use
the file for the current compilation. This is in order to speed compression
when not a lot of text has changed since the last compilation.
Deleting the key-phrase file before each compilation will prevent the
compiler from using the previous file. Maximum compression will result only
by forcing the compiler to create a new phrase table.
18.5 Specifying Alternate Context Strings: The Alias Section
Use the [Alias] section to assign one or more context strings to the same
topic alias. Because context strings must be unique for each topic and
cannot be used for any other topic in the Help project, the [Alias] section
provides a way to delete or combine Help topics without recoding your files.
The [Alias] section is optional.
For example, if you create a topic that replaces the information in three
other topics, and you delete the three, you will have to search through your
files for invalid cross-references to the deleted topics. You can avoid this
problem by using the [Alias] section to assign the name of the new topic to
the deleted topics. The [Alias] section can also be used when your
application program has multiple context identifiers for which you have only
one topic. This can be the case with context-sensitive Help.
Each expression in the [Alias] section has the following format:
context_string=alias
In the alias expression the alias parameter is the alternate string, or
alias name, and the context_string parameter is the context string
identifying a particular topic. An alias string has the same format and
follows the same conventions as the topic context string. That is, it is not
case-sensitive and may contain the alphabetic characters A-Z, numeric
characters 0-9, and the period and underscore characters.
The following example illustrates an [Alias] section:
[ALIAS]
sm_key=key_shrtcuts
cc_key=key_shrtcuts
st_key=key_shrtcuts ;combined into keyboard shortcuts topic
clskey=us_dlog_bxs
maakey=us_dlog_bxs ;covered in using dialog boxes topic
chk_key=dlogprts
drp_key=dlogprts
lst_key=dlogprts
opt_key=dlogprts
tbx_key=dlogprts ;combined into parts of dialog box topic
frmtxt=edittxt
wrptxt=edittxt
seltxt=edittxt ;covered in editing text topic
────────────────────────────────────────────────────────────────────────────
NOTE
You can use alias names in the [Map] section of the Help project file. If
you do, however, the [Alias] section must precede the [Map] section.
────────────────────────────────────────────────────────────────────────────
18.6 Mapping Context-Sensitive Topics: The Map Section
If your Help system supports context-sensitive Help, use the [Map] section
to associate either context strings or aliases to context numbers. The
context number corresponds to a value the parent application passes to the
Help application in order to display a particular topic. This section is
optional.
When writing the [Map] section, you can do the following:
■ Use either decimal or hexadecimal numbers formatted in standard C
notation to specify context numbers.
■ Assign no more than one context number to a context string or alias.
Assigning the same number to more than one context string will
generate a compiler error.
■ Separate context numbers and context strings by an arbitrary amount of
white space using either space characters or tabs.
You can use the C #include directive to include other files in the mapping.
In addition, the Map section supports an extended format that lets you
include C files with the .H extension directly. Entries using this format
must begin with the #define directive and may contain comments in C format,
as in this example:
#define context_string context_number /* comment */
The following example illustrates several formats you can use in the [Map]
section:
[MAP]
"
Edit_Window 0x0001
Control_Menu 0x0002
Maximize_Icon 0x0003
Minimize_Icon 0x0004
Split_Bar 0x0005
Scroll_Bar 0x0006
Title_Bar 0x0007
Window_Border 0x0008
dcmb_scr 30 ; Document Control-menu Icon
dmxi_scr 31 ; Document Maximize Icon
dmni_scr 32 ; Document Minimize Icon
dri_scr 33 ; Document Restore Icon
dtb_scr 34 ; Document Title Bar
#define vscroll 0x010A /* Vertical Scroll Bar */
#define hscroll 0x010E /* Horizontal Scroll Bar */
#define scrollthm 0x0111 /* Scroll Thumb */
#define upscroll 0x0112 /* Up Scroll Arrow */
#define dnscroll 0x0113 /* Down Scroll Arrow */
#include <sample.h>
In the example:
"
The first eight entries give hexadecimal equivalents for the context
numbers.
The next five entries show decimal context numbers.
The next five entries show how you might include topics defined in a C
include file.
This entry shows a C #include directive for some generic topics.
If context numbers use the #define directive, and the file containing the
#define statements is included in both the application code and the Help
file, then updates made to the context numbers by the application
programmers will automatically be reflected in the next Help build.
You can define the context strings listed in the [Map] section either in a
Help topic or in the [Alias] section. The compiler generates a warning
message if a context string appearing in the [Map] section is not defined
in any of the topic files or in the [Alias] section.
────────────────────────────────────────────────────────────────────────────
NOTE
If you use an alias name, the [Alias] section must precede the [Map] section
in the Help project file.
────────────────────────────────────────────────────────────────────────────
For more information about context-sensitive Help, see Section 16.2.5,
"Displaying Context-Sensitive Help Topics."
18.7 Including Bitmaps by Reference: The Bitmaps Section
If your Help system uses bitmaps by reference, the filenames of each of the
bitmaps must be listed in the [Bitmaps] section of the project file. The
following example illustrates the format of the [Bitmaps] section.
[BITMAPS]
DUMP01.BMP
DUMP02.BMP
DUMP03.BMP
c:\PROJECT\HELP\BITMAPS\DUMP04.BMP
────────────────────────────────────────────────────────────────────────────
NOTE
The [Bitmaps] section uses the same rules as the [Files] section for
locating bitmap files.
────────────────────────────────────────────────────────────────────────────
18.8 Compiling Help Files
After you have created a Help project file, you are ready to build a Help
file using the Help Compiler. The compiler generates the binary Help
resource file from the topic files listed in the Help project file. When the
build process is complete, your application can access the Help resource
file that results.
Before initiating a build operation to create the Help file, consider the
locations of the following files:
■ The Help Compiler, HC.EXE. The compiler must be in a directory from
which it can be executed. This could be the current working directory,
on the path set with the PATH environment variable, or a directory
specified by a full pathname, as follows:
C:\BIN\HC HELPEX.HPJ
■ The Help project file, filename.HPJ. The project file can be located
either in the current directory or specified by a path, as follows:
C:\BIN\HC D:\MYPROJ\HELPEX.HPJ
■ The topic files named in the Help project file, saved as RTF. The
topic files may be located in the current working directory, a
subdirectory of the current working directory specified in the [Files]
section, or the location specified in the Root option.
■ Files included with the #include directive in the Help project file.
Since the #include directive can take pathnames, then any number of
places will work for these files.
■ All bitmap files listed by reference in the topic files.
You must also place any files named in an #include directive in the path of
the project root directory or specify their path using the ROOT option. The
compiler searches only the directories specified in the Help project file.
For information about the ROOT option, see Section 18.4.3, "Specifying the
Root Directory: The Root Option."
────────────────────────────────────────────────────────────────────────────
NOTE
If you use a RAM drive for temporary files (set with the DOS environment
variable TMP), it must be large enough to hold the compiled Help resource
file. If your Help file is larger than the size of the available RAM drive,
the compiler will generate an error message and the compilation will be
aborted.
────────────────────────────────────────────────────────────────────────────
18.8.1 Using the Help Compiler
To run the Help Compiler, use the HC command. There are no options for HC.
All options are specified in the Help project file.
The HC command uses the following syntax:
HC filename.HPJ
As the compiler program runs, it displays sequential periods on the screen,
indicating its progress in the process. Error messages are displayed when
each error condition is encountered. When the Help Compiler has finished
compiling, it writes a Help resource file with an .HLP extension in the
current directory and returns to the DOS prompt. The Help resource file that
results from the build has the same name as does the Help project file.
Compiler errors and status messages can be redirected to a file using
standard DOS redirection syntax. This is useful for a lengthy build where
you may not be monitoring the entire process. The redirected file is saved
as a text file that can be viewed with any ASCII editor.
18.9 Programming the Application to Access Help
The application-development team must program the application so that the
user can access the Windows Help application and your Help file. The Help
application is a stand-alone Windows application, and your application can
ask Windows to run the Help application and specify the topic that Help is
to show the user. To the user, Help appears to be part of your application,
but it acts like any other Windows application.
18.9.1 Calling WinHelp from an Application
An application makes a Help system available to the user by calling the
WinHelp function.
The WinHelp function uses the following syntax:
BOOL WinHelp (hWnd, lpHelpFile, wCommand, dwData)
The hWnd parameter identifies the window requesting Help. The Windows Help
application uses this identifier to keep track of which applications have
requested Help.
The lpHelpFile parameter specifies the name (with optional directory path)
of the Help file containing the desired topic.
The wCommand parameter specifies either the type of search that the Windows
Help application is to use to locate the specified topic, or that the
application no longer requires Help. It may be set to any one of the
following values:
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
Value Meaning
────────────────────────────────────────────────────────────────────────────
HELP_CONTEXT Displays Help for a particular topic
identified by a context number.
HELP_HELPONHELP Displays the Using Help index topic.
HELP_INDEX Displays the main Help index topic.
HELP_KEY Displays Help for a topic identified by
a key word.
HELP_MULTIKEY Displays Help for a topic identified by
a key word in an alternate key-word
table.
HELP_QUIT Informs the Help application that Help
Value Meaning
────────────────────────────────────────────────────────────────────────────
HELP_QUIT Informs the Help application that Help
is no longer needed. If no other
applications have asked for Help,
Windows closes the Help application.
HELP_SETINDEX Displays a designated Help index topic.
The dwData parameter specifies the topic for which the application is
requesting Help. The format of dwData depends upon the value of wCommand
passed when your application calls WinHelp. The following list describes the
format of dwData for each value of wCommand.
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
wCommand Value dwData Format
────────────────────────────────────────────────────────────────────────────
HELP_CONTEXT An unsigned long integer containing the
context number for the topic. Instead of
wCommand Value dwData Format
────────────────────────────────────────────────────────────────────────────
context number for the topic. Instead of
using HELP_INDEX, HELP_CONTEXT can use
the value -1.
HELP_HELPONHELP Ignored.
HELP_INDEX Ignored.
HELP_KEY A long pointer to a string which
contains a key word for the desired
topic.
HELP_MULTIKEY A long pointer to the MULTIKEYHELP
structure, as defined in WINDOWS.H. This
structure specifies the table footnote
character and the key word.
HELP_QUIT Ignored.
wCommand Value dwData Format
────────────────────────────────────────────────────────────────────────────
HELP_SETINDEX An unsigned long integer containing the
context number for the topic.
Because it can specify either a context number or a key word, WinHelp
supports both context-sensitive and topical searches of the Help file.
────────────────────────────────────────────────────────────────────────────
NOTE
To ensure that the correct index remains set, the application should call
WinHelp with wCommand set to HELP_SETINDEX (with dwData specifying the
corresponding context identifier) following each call to WinHelp with a
command set to HELP_CONTEXT. HELP_INDEX should never be used with
HELP_SETINDEX.
────────────────────────────────────────────────────────────────────────────
18.9.2 Getting Context-Sensitive Help
Context-sensitive Help should be made available when a user wants to learn
about the purpose of a particular window or control. For example, the user
might pull down the File menu, select the Open command (by using the
DIRECTION keys), and then press F1 to get Help for the command.
Implementing certain types of context-sensitive help requires advanced
programming techniques. The Helpex sample application illustrates the use of
two techniques. These techniques are described in the following sections.
Shift+F1 Support
To implement a SHIFT+F1 mode, such as in Microsoft Excel or Microsoft Word
for Windows, Helpex responds to the SHIFT+F1 accelerator key by calling
SetCursor to change the shape of the cursor to an arrow pointer supplemented
by a question mark.
case WM_KEYDOWN:
if (wParam == VK_F1) {
/* If Shift-F1, turn help mode on and set help cursor */
if (GetKeyState(VK_SHIFT)) {
bHelp = TRUE;
SetCursor(hHelpCursor);
return (DefWindowProc(hWnd, message, wParam, lParam));
}
/* If F1 without shift, then call up help main index topic */
else {
WinHelp(hWnd,szHelpFileName,HELP_INDEX,0L);
}
}
else if (wParam == VK_ESCAPE && bHelp) {
/* Escape during help mode: turn help mode off */
bHelp = FALSE;
SetCursor((HCURSOR)GetClassWord(hWnd,GCW_HCURSOR));
}
break;
As long as the user is in Help mode (that is, until he clicks the mouse or
hits Escape), Helpex responds to WM_SETCURSOR messages by resetting the
cursor to the arrow and question mark combination.
case WM_SETCURSOR:
/* In help mode it is necessary to reset the cursor in response */
/* to every WM_SETCURSOR message.Otherwise, by default, Windows */
/* will reset the cursor to that of the window class. */
if (bHelp) {
SetCursor(hHelpCursor);
break;
}
return (DefWindowProc(hWnd, message, wParam, lParam));
break;
case WM_INITMENU:
if (bHelp) {
SetCursor(hHelpCursor);
}
return (TRUE);
When the user is in SHIFT+F1 Help mode and clicks the mouse button, Helpex
will receive a WM_NCLBUTTONDOWN message if the click is in a nonclient area
of the application window. By examining the wParam value of this message,
the program can determine which context ID to pass to WinHelp.
case WM_NCLBUTTONDOWN:
/* If we are in help mode (Shift+F1) then display context- */
/* sensitive help for nonclient area. */
if (bHelp) {
dwHelpContextId =
(wParam == HTCAPTION)?(DWORD)HELPID_TITLE_BAR:
(wParam == HTSIZE)? (DWORD)HELPID_SIZE_BOX:
(wParam == HTREDUCE)? (DWORD)HELPID_MINIMIZE_ICON:
(wParam == HTZOOM)? (DWORD)HELPID_MAXIMIZE_ICON:
(wParam == HTSYSMENU)?(DWORD)HELPID_SYSTEM_MENU:
(wParam == HTBOTTOM)? (DWORD)HELPID_SIZING_BORDER:
(wParam == HTBOTTOMLEFT)? (DWORD)HELPID_SIZING_BORDER:
(wParam == HTBOTTOMRIGHT)?(DWORD)HELPID_SIZING_BORDER:
(wParam == HTTOP)?(DWORD)HELPID_SIZING_BORDER:
(wParam == HTLEFT)?(DWORD)HELPID_SIZING_BORDER:
(wParam == HTRIGHT)?(DWORD)HELPID_SIZING_BORDER:
(wParam == HTTOPLEFT)?(DWORD)HELPID_SIZING_BORDER:
(wParam == HTTOPRIGHT)? (DWORD)HELPID_SIZING_BORDER:
(DWORD)0L;
if (!((BOOL)dwHelpContextId))
return (DefWindowProc(hWnd, message, wParam, lParam));
bHelp = FALSE;
WinHelp(hWnd,szHelpFileName,HELP_CONTEXT,dwHelpContextId);
break;
}
return (DefWindowProc(hWnd, message, wParam, lParam));
F1 Support
Context-sensitive F1 support for menus is relatively easy to implement in
your application. If a menu is open and the user presses F1 while one of the
menu items is highlighted, Windows sends a WM_ENTERIDLE message to the
application to indicate that the system is going back into an idle state
after having determined that F1 was not a valid key stroke for choosing a
menu item. You can take advantage of this idle state by looking at the
keyboard state at the time of the WM_ENTERIDLE message.
If the F1 key is down, then you can simulate the user's pressing the ENTER
key by posting a WM_KEYDOWN message using VK_RETURN. You don't really want
your application to execute the menu command. What you do is set a flag
(bHelp=TRUE) so that when you get the WM_COMMAND message for the menu item,
you don't execute the command. Instead, the topic for the menu item is
displayed by Windows Help.
The following code samples illustrate F1 sensing for menu items.
case WM_ENTERIDLE:
if ((wParam == MSGF_MENU) && (GetKeyState(VK_F1) & 0x8000)) {
bHelp = TRUE;
PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0L);
}
break;
case WM_COMMAND:
/* Was F1 just pressed in a menu, or are we in help mode */
/* (Shift+F1)? */
if (bHelp) {
dwHelpContextId =
(wParam == IDM_NEW)?(DWORD)HELPID_FILE_NEW:
(wParam == IDM_OPEN)? (DWORD)HELPID_FILE_OPEN:
(wParam == IDM_SAVE)? (DWORD)HELPID_FILE_SAVE:
(wParam == IDM_SAVEAS)? (DWORD)HELPID_FILE_SAVE_AS:
(wParam == IDM_PRINT)?(DWORD)HELPID_FILE_PRINT:
(wParam == IDM_EXIT)? (DWORD)HELPID_FILE_EXIT:
(wParam == IDM_UNDO)? (DWORD)HELPID_EDIT_UNDO:
(wParam == IDM_CUT)?(DWORD)HELPID_EDIT_CUT:
(wParam == IDM_CLEAR)?(DWORD)HELPID_EDIT_CLEAR:
(wParam == IDM_COPY)? (DWORD)HELPID_EDIT_COPY:
(wParam == IDM_PASTE)?(DWORD)HELPID_EDIT_PASTE:
(DWORD)0L;
if (!dwHelpContextId)
{ Messagebox( hWnd, "Help not available for Help
Menu item", "Help Example", MB_OK
return (DefWindowProc(hWnd, message, wParam, lParam));
}
bHelp = FALSE;
WinHelp(hWnd,szHelpFileName,HELP_CONTEXT,dwHelpContextId);
break;
}
Detecting F1 in dialog boxes is somewhat more difficult than in menus. You
must install a message filter, using the WH_MSGFILTER option of the
SetWindowsHook function. Your message filter function responds to WM_KEYDOWN
and WM_KEYUP messages for VK_F1 when they are sent to a dialog box, as
indicated by the MSGF_DIALOGBOX code. By examining the message structure
passed to the filter, you can determine the context of the F1 help─what the
dialog box is, and the specific option or item. You should not call WinHelp
while processing the filtered message, but rather post an
application-defined message to your application to call WinHelp at the first
available opportunity.
18.9.3 Getting Help on an Item Listed on the Help Menu
Sometimes users may want information about a general concept in the
application rather than about a particular control or window. In these
cases, the application should provide Help for a particular topic that is
identified by a key word rather than a context identifier.
For example, if the Help file for your application contains a topic that
describes how the keyboard is used, you could place a "Keyboard" item in
your Help menu. Then, when the user selects that item, your application
would call WinHelp and request that topic:
case IDM_HELP_KEYBOARD:
WinHelp (hWnd, lpHelpFile, HELP_KEY, (LPSTR) "Keyboard");
break;
18.9.4 Accessing Additional Key-Word Tables
Your application may have commands or terms that correspond to terms in a
similar, but different, application. Given a key word, the application can
call WinHelp and look up topics defined in an alternate key-word table. This
Multikey functionality is accessed through the WinHelp hook with the
wCommand parameter set to HELP_MULTIKEY.
You specify the footnote character for the alternate key-word table, and the
key word or phrase, via a MULTIKEYHELP structure which is passed as the
dwData parameter in the call to WinHelp. This structure is defined in
WINDOWS.H as:
typedef struct tag MULTIKEYHELP {
WORD mdSize;
BYTE mkKeyList;
BYTE szKeyPhrase[1];
} MULTIKEYHELP;
The following table lists the format of the fields of the MULTIKEYHELP
structure:
Parameter Format
────────────────────────────────────────────────────────────────────────────
mkSize The size of the structure, including the
key word (or phrase) and the associated
key-table letter.
mkKeyList A single character which defines the
footnote character for the alternate
key-word table to be searched.
szKeyPhrase A null-terminated key word or phrase to
be looked up in the alternate key-word
table.
The following example illustrates a key-word search for the word "frame" in
the alternate key-word table designated with the footnote character "L":
MULTIKEYHELP mk;
char szKeyword[]="frame";
mk.mkSize=sizeof(MULTIKEYHELP)+(WORD)lstrlen(szKeyword);
mk.mkKeylist="L";
mk.szKeyphrase=szKeyword;
WinHelp(hWnd,lpHelpfile,HELP_MULTIKEY,(LPSTR)&mk);
18.9.5 Canceling Help
The Windows Help application is a shared resource that is available to all
Windows applications. In addition, since it is a stand-alone application,
the user can execute it like any other application. As a result, your
application has limited control over the Help application. While your
application cannot directly close the Help application window, your
application can inform the Help application that Help is no longer needed.
Before closing its main window, your application should call WinHelp with
the wCommand parameter set to HELP_QUIT, as shown in the following example,
to inform the Help application that your application will not need it again.
case WM_DESTROY:
WinHelp (hWnd, lpHelpFile, HELP_QUIT, NULL);
An application that has called WinHelp at some point during its execution
must call WinHelp with the wCommand parameter set to HELP_QUIT before the
application exits from WinMain (typically during the WM_DESTROY message
processing).
If an application opens more than one Help file, then it must call WinHelp
to quit help for each file.
If an application or DLL has opened a Help file but no longer wants the
associated instance of the Help engine (WINHELP.EXE) to remain active, then
the application or DLL should call WinHelp with the wCommand parameter set
to HELP_QUIT to destroy the instance of the Help engine.
Under no circumstances should an application or DLL terminate without
calling WinHelp for any of the opened Help files. A Help file is opened if
any other WinHelp call has been previously made using the Help filename.
The Windows Help application does not exit until all windows that have
called WinHelp have called it with wCommand set to HELP_QUIT. If an
application fails to do so, then the Help application will continue running
after all applications that requested Help have terminated.
18.10 Summary
This chapter described how to create a Help project file, build the Help
resource file, and program your application to access Help. For more
information, see the following:
Topic Reference
────────────────────────────────────────────────────────────────────────────
Planning a Help system Tools: Chapter 16, "Planning the Help
System"
Writing Help topics Tools: Chapter 17, "Creating the Help
Topic Files"
Chapter 19 Help Examples and Compiler Error Messages
────────────────────────────────────────────────────────────────────────────
The first part of this chapter contains several examples of Help source
files and their corresponding topics as displayed in Help. Each example
shows a topic (or part of a topic) as it appears to the Help writer in the
RTF-capable word processor and as it appears to the user in the Help window.
You can use these examples as guides when creating your own topic files. The
examples should help you predict how a particular topic file created in a
word processor will appear to the user.
The second part of this chapter contains a list of Help Compiler error
messages. Each message is shown as it appears when the compiler encounters
the specific error. A short explanation accompanies each message to aid you
in solving the problem in your Help system. Preceding the error message
listing is a short description of the error reporting behavior of the Help
Compiler. Understanding how the compiler reports and reacts to errors will
help you to debug your Help files.
19.1 Help Topic Examples
(This figure may be found in the printed book).
(This figure may be found in the printed book).
<$R>
(This figure may be found in the printed book).
(This figure may be found in the printed book).
(This figure may be found in the printed book).
(This figure may be found in the printed book).
(This figure may be found in the printed book).
(This figure may be found in the printed book).
(This figure may be found in the printed book).
(This figure may be found in the printed book).
The following is the Helpex (sample Help) project file:
[OPTIONS]
ROOT=c:\help
INDEX=main_index
TITLE=Help Example
COMPRESS=true
[FILES]
helpex.rtf ; jump topics
terms.rtf ; look-up terms
[MAP]
main_index 0xFFFF
#define HELPID_EDIT_CLEAR 100
#define HELPID_EDIT_COPY 101
#define HELPID_EDIT_CUT 102
#define HELPID_EDIT_PASTE 103
#define HELPID_EDIT_UNDO 104
#define HELPID_FILE_EXIT 200
#define HELPID_FILE_NEW 201
#define HELPID_FILE_OPEN 202
#define HELPID_FILE_PRINT 203
#define HELPID_FILE_SAVE 204
#define HELPID_FILE_SAVE_AS 205
#define HELPID_EDIT_WINDOW 300
#define HELPID_MAXIMIZE_ICON 301
#define HELPID_MINIMIZE_ICON 302
#define HELPID_SPLIT_BAR 303
#define HELPID_SIZE_BOX 304
#define HELPID_SYSTEM_MENU 305
#define HELPID_TITLE_BAR 306
#define HELPID_SIZING_BORDER 307
19.2 Help Compiler Error Messages
The Help Compiler displays messages when it encounters errors in building
the Help resource file. Errors during processing of the project file are
numbered beginning with the letter P and appear as in the following
examples:
Error P1025: line...7 of filename.HPJ : Section heading sectionname
unrecognized.
Warning P1039: line...38 of filename.HPJ : [BUILDTAGS] section missing.
Errors which occur during processing of the RTF topic file(s) are numbered
beginning with the letter R and appear as in the following examples:
Error R2025: File environment error.
Warning R2501: Using old key-phrase table.
Whenever possible, the compiler will display the topic number and/or
filename that contains the error. Though topics are not numbered, the topic
number given with an error message refers to that topic's sequential
position in your RTF file (first, second, etc.). These numbers may be
identical to the page number shown by your word processor, depending on the
number of lines you have assigned to the hypothetical printed page. Remember
that topics are separated by hard page breaks, even though there is no such
thing as a "page" in the Help system.
Messages beginning with the word "Error" are fatal errors. Errors are always
reported, and no usable Help resource file will result from the build.
Messages beginning with the word "Warning" are less serious in nature. A
build with warnings will produce a valid Help resource file which will load
under Windows, but the file may contain operational errors. You can specify
the amount of warning information to be reported by the compiler. See
section 17.4.1, "Specifying Error Reporting: The Warning Option," for more
information on choosing warning levels to be displayed.
The compiler's reaction to an error is described for each error in the
listing that follows. During processing of the project file, the compiler
ignores lines that contain errors and attempts to continue with the build.
This means that errors encountered early in a build may result in many more
errors being reported as the build continues. Similarly, errors during
processing of the RTF topic files will be reported and if not serious, the
compiler will continue with the build. A single error condition in the topic
file may result in more than one error message being reported by the
compiler. For instance, a misidentified topic will cause an error to be
reported every time jump terms refer to the correct topic identifier. Such a
mistake is easily rectified by simply correcting the footnote containing the
wrong context string.
19.2.1 Errors During Processing of Project File
P1001 Unable to read file filename.
The file specified in the project file
is unreadable. This is a DOS file error.
P1003 Invalid path specified in Root option.
The path specified by the Root option
cannot be found. The compiler uses the
current working directory.
P1005 Path and filename exceed limit of 79
characters.
The absolute pathname, or the combined
root and relative pathname, exceed the
DOS limit of 79 characters. The file is
skipped.
P1007 Root path exceeds maximum limit of 66
characters.
The specified root pathname exceeds the
DOS limit of 66 characters. The pathname
is ignored and the compiler uses the
current working directory.
P1009 [FILES] section missing.
The [Files] section is required. The
compilation is aborted.
P1011 Option optionname previously defined.
The specified option was defined
previously. The compiler ignores the
attempted redefinition.
P1013 Project file extension cannot be .HLP.
You cannot specify that the compiler use
a project file with the .HLP extension.
Normally, project files are given the
.HPJ extension.
P1015 Unexpected end-of-file.
The compiler has unexpectedly come to
the end of the project file. There might
be an open comment in the project file
or an included file.
P1017 Parameter exceeds maximum length of 128
characters.
An option, context name or number, build
tag, or other parameter on the specified
line exceeds the limit of 128 characters.
The line is ignored.
P1021 Context number already used in [MAP]
section.
The context number on the specified line
in the project file was previously
mapped to a different context string.
The line is ignored.
P1023 Include statements nested too deeply.
The #include statement on the specified
line has exceeded the maximum of five
include levels.
P1025 Section heading sectionname
unrecognized.
A section heading that is not supported
by the compiler has been used. The line
is skipped.
P1027 Bracket missing from section heading
sectionname.
The right bracket (]) is missing from
the specified section heading. Insert
the bracket and compile again.
P1029 Section heading missing.
The section heading on the specified
line is not complete. This error is also
reported if the first entry in the
project file is not a section heading.
The compiler continues with the next
line.
P1030 Section sectionname previously defined.
A duplicate section has been found in
the project file. The lines under the
duplicated section heading are ignored
and the compiler continues from the next
valid section heading.
P1031 Maximum number of build tags exceeded.
The maximum number of build tags that
can be defined is 30. The excess tags
are ignored.
P1033 Duplicate build tag in [BUILDTAGS]
section.
A build tag in the [BuildTags] section
has been repeated unnecessarily
P1035 Build tag length exceeds maximum.
The build tag on the specified line
exceeds the maximum of 32 characters.
The compiler skips this entry.
P1037 Build tag tagname contains invalid
characters.
Build tags can contain only alphanumeric
characters or the underscore (_)
character. The line is skipped.
P1039 [BUILDTAGS] section missing.
The BUILD option declared a conditional
build, but there is no [BuildTags]
section in the project file. All topics
are included in the build.
P1043 Too many tags in Build expression.
The Build expression on the specified
line has used more than the maximum of
20 build tags. The compiler ignores the
line.
P1045 [ALIAS] section found after [MAP]
section.
When used, the [Alias] section must
precede the [Map] section in the project
file. The [Alias] section is skipped
otherwise.
P1047 Context string contextname already
assigned an alias.
You cannot do: a=b then a=c (A context
string can only have one alias.)
The specified context string has
previously been aliased in the [Alias]
section. The attempted reassignment on
this line is ignored.
P1049 Alias string aliasname already assigned.
You cannot do: a=b then b=c (You can't
alias an alias.)
An alias string cannot, in turn, be
assigned another alias.
P1051 Context string contextname cannot be
used as alias string.
You cannot do: a=b then c=a
A context string that has been assigned
an alias cannot be used later as an
alias for another context string.
P1053 Maximum number of font ranges exceeded.
The maximum number of font ranges that
can be specified is five. The rest are
ignored.
P1055 Current font range overlaps previously
defined range.
A font size range overlaps a previously
defined mapping. Adjust either font
range to remove any overlaps. The second
mapping is ignored.
P1056 Unrecognized font name in Forcefont
option.
A font name not supported by the
compiler has been encountered. The font
name is ignored and the compiler uses
the default Helv font.
P1057 Font name too long.
Font names cannot exceed 20 characters.
The font is ignored.
P1059 Invalid multiple-key syntax.
The syntax used with a MULTIKEY option
is unrecognized. See Chapter 18,
"Building the Help File," for the proper
syntax.
P1061 Character already used.
The specified key word-table identifier
is already in use. Choose another
character.
P1063 Characters 'K' and 'k' cannot be used.
These characters are reserved for Help's
normal key-word table. Choose another
character.
P1065 Maximum number of keyword tables
exceeded.
The limit of five key-word tables has
been exceeded. Reduce the number. The
excess tables are ignored.
P1067 Equal sign missing.
An option is missing its required equal
sign on the specified line. Check the
syntax for the option.
P1069 Context string missing.
The line specified is missing a context
string before an equal sign.
P1071 Incomplete line in sectionname section.
The entry on the specified line is not
complete. The line is skipped.
P1073 Unrecognized option in [OPTIONS]
section.
An option has been used that is not
supported by the compiler. The line is
skipped.
P1075 Invalid build expression.
The syntax used in the build expression
on the specified line contains one or
more logical or syntax errors.
P1077 Warning level must be 1, 2, or 3.
The WARNING reporting level can only be
set to 1, 2, or 3. The compiler will
default to full reporting (level 3).
P1079 Invalid compression option.
The COMPRESS option can only be set to
TRUE or FALSE. The compilation continues
without compression.
P1081 Invalid title string.
The TITLE option defines a string that
is null or contains more than 32
characters. The title is truncated.
P1083 Invalid context identification number.
The context number on the specified line
is null or contains invalid characters.
P1085 Unrecognized text.
The unrecognizable text that follows
valid text in the specified line is
ignored.
P1086 Invalid font-range syntax.
The font-range definition on the
specified line contains invalid syntax.
The compiler ignores the line. Check the
syntax for the MAPFONTSIZE option.
P1089 Unrecognized sort ordering.
You have specified an ordering that is
not supported by the compiler. Contact
Microsoft Product Support Services for
clarification of the error.
19.2.2 Errors During Processing of RTF Topic Files
R2001 Unable to open bitmap file filename.
The specified bitmap file is unreadable.
This is a DOS file error.
R2003 Unable to include bitmap file filename.
The specified bitmap file could not be
found or is unreadable. This is a DOS
file error or an out-of-memory condition.
R2005 Disk full.
The Help resource file could not be
written to disk. Create more space on
the destination drive.
R2009 Cannot use reserved DOS device name for
file filename.
A file has been referred to as COM1,
LPT2, PRN, etc. Rename the file.
R2013 Output file filename already exists as a
directory.
There is a subdirectory in the Help
project root with the same name as the
desired Help resource file. Move or
rename the subdirectory.
R2015 Output file filename already exists as
read-only.
The specified filename cannot be
overwritten by the Help resource file
because the file has a read-only
attribute. Rename the project file or
change the file's attribute.
R2017 Path for file filename exceeds limit of
79 characters.
The absolute pathname, or the combined
root and relative pathname, to the
specified file exceed the DOS limit of
79 characters. The file is ignored.
R2019 Cannot open file filename.
The specified file is unreadable. This
is a DOS file error.
R2021 Cannot find file filename.
The specified file could not be found or
is unreadable. This is a DOS file error
or an out-of-memory condition.
R2023 Not enough memory to build Help file.
To free up memory, unload any unneeded
applications, device drivers, and
memory-resident programs.
R2025 File environment error.
The compiler has insufficient available
file handles to continue. Increase the
values for FILES= and BUFFERS= in your
CONFIG.SYS file and reboot.
R2027 Build tag tagname not defined in
[BUILDTAGS] section of project file.
The specified build tag has been
assigned to a topic, but not declared in
the project file. The tag is ignored for
the topic.
R2033 Context string in Map section not
defined in any topic.
There are one or more context strings
defined in the project file that the
compiler could not find topics for.
R2035 Build expression missing from project
file.
The topics have build tags, but there is
no Build= expression in the project file.
The compiler includes all topics in the
build.
R2037 File filename cannot be created, due to
previous error(s).
The Help resource file could not be
created because the compiler has no
topics remaining to be processed.
Correct the errors that preceded this
error and recompile.
R2039 Unrecognized table formatting in topic
topicnumber of file filename.
The compiler ignores table formatting
that is unsupported in Help. Reformat
the entries as linear text if possible.
R2041 Jump context_string unresolved in topic
topicnumber of file filename.
The specified topic contains a context
string that identifies a nonexistent
topic. Check spelling, and that the
desired topic is included in the build.
R2043 Hotspot text cannot spread over
paragraphs.
A jump term spans two paragraphs. Remove
the formatting from the paragraph mark.
R2045 Maximum number of tab stops reached in
topic topicnumber of file filename.
The limit of 32 tab stops has been
exceeded in the specified topic. The
default stops are used after the 32nd
tab.
R2047 File filename not created.
There are no topics to compile, or the
build expression is false for all topics.
There is no Help resource file created.
R2049 Context string text too long in topic
topicnumber of file filename.
Context string hidden text cannot exceed
64 characters. The string is ignored.
R2051 File filename is not a valid RTF topic
file.
The specified file is not an RTF file.
Check that you have saved the topic as
RTF from your word processor.
R2053 Font fontname in file filename not in
RTF font table.
A font not defined in the RTF header has
been entered into the topic. The
compiler uses the default system font.
R2055 File filename is not a usable RTF topic
file.
The specified file contains a valid RTF
header, but the content is not RTF or is
corrupted.
R2057 Unrecognized graphic format in topic
topicnumber of file filename.
The compiler supports only Windows
bitmaps. Check that metafiles or
Macintosh formats have not been used.
The graphic is ignored.
R2059 Context string identifier already
defined in topic topicnumber of file
filename.
There is more than one context-string
identifier footnote for the specified
topic. The compiler uses the identifier
defined in the first # footnote.
R2061 Context string contextname already used
in file filename.
The specified context string was
previously assigned to another topic.
The compiler ignores the latter string
and the topic has no identifier.
R2063 Invalid context-string identifier for
topic topicnumber of file filename.
The context-string footnote contains
nonalphanumeric characters or is null.
The topic is not assigned an identifier.
R2065 Context string defined for index topic
is unresolved.
The index topic defined in the project
file could not be found. The compiler
uses the first topic in the build as the
index.
R2067 Footnote text too long in topic
topicnumber of file filename.
Footnote text cannot exceed the limit of
1000 characters. The footnote is ignored.
R2069 Build tag footnote not at beginning of
topic topicnumber of file filename.
The specified topic contains a buildtag
footnote that is not the first character
in the topic. The topic is not assigned
a build tag.
R2071 Footnote text missing in topic
topicnumber of file filename.
The specified topic contains a footnote
that has no characters.
R2073 Keyword string is null in topic
topicnumber of file filename.
A key-word footnote exists for the
specified topic, but contains no
characters.
R2075 Keyword string too long in topic
topicnumber of file filename.
The text in the key-word footnote in the
specified topic exceeds the limit of 255
characters. The excess characters are
ignored.
R2077 Keyword(s) defined without title in
topic topicnumber of file filename.
Key word(s) have been defined for the
specified topic, but the topic has no
title assigned. Search Topics Found
displays Untitled Topic< for the topic.
R2079 Browse sequence string is null in topic
topicnumber of file filename.
The browse-sequence footnote for the
specified topic contains no sequence
characters.
R2081 Browse sequence string too long in topic
topicnumber of file filename.
The browse-sequence footnote for the
specified topic exceeds the limit of 128
characters. The sequence is ignored.
R2083 Missing sequence number in topic
topicnumber of file filename.
A browse-sequence number ends in a colon
(:) for the specified topic. Remove the
colon, or enter a "minor" sequence
number.
R2085 Sequence number already defined in topic
topicnumber of file filename.
There is already a browse-sequence
footnote for the specified topic. The
latter sequence is ignored.
R2087 Build tag too long.
A build tag for the specified topic
exceeds the maximum of 32 characters.
The tag is ignored for the topic.
R2089 Title string null in topic topicnumber
of file filename.
The title footnote for the specified
topic contains no characters. The topic
is not assigned a title.
R2091 Title too long in topic topicnumber of
file filename.
The title for the specified topic
exceeds the limit of 128 characters. The
excess characters are ignored.
R2093 Title titlename in topic topicnumber of
file filename used previously.
The specified title has previously been
assigned to another topic.
R2095 Title defined more than once in topic
topicnumber of file filename.
There is more than one title footnote in
the specified topic. The compiler uses
the first title string.
R2501 Using old key-phrase table.
Maximum compression can only result by
deleting the .PH file before each
recompilation of the Help topics.
R2503 Out of memory during text compression.
The compiler encountered a memory
limitation during compression.
Compilation continues with the Help
resource file not compressed. Unload any
unneeded applications, device drivers,
and memory-resident programs.
R2505 File environment error during text
compression.
The compiler has insufficient available
file handles for compression.
Compilation continues with the Help
resource file not compressed. Increase
the values for FILES= and BUFFERS= in
your CONFIG.SYS file and reboot.
R2507 DOS file error during text compression.
The compiler encountered a problem
accessing a disk file during compression.
Compilation continues with the Help
resource file not compressed.
R2509 Error during text compression.
One of the three compression
errors─R2503, R2505, or R2507─has
occurred. Compilation continues with the
Help resource file not compressed.
R2701 Internal error.
Contact Microsoft Product Support
Services for clarification of the error.
R2703 Internal error.
Contact Microsoft Product Support
Services for clarification of the error.
R2705 Internal error.
Contact Microsoft Product Support
Services for clarification of the error.
R2707 Internal error.
Contact Microsoft Product Support
Services for clarification of the error.
R2709 Internal error.
Contact Microsoft Product Support
Services for clarification of the error.
INDEX
──────────────────────────────────────────────────────────────────────────
{ } (brackets), in symbol map display
{ } (curly braces), as document convention
( ) (parentheses), as document convention
" " (quotation marks), as document convention
-? option
* (asterisk)
wildcard character
with commands
@ (at symbol), with commands
: (colon), use of with doubleword values
, (comma), as parameter separator
$ (dollar sign), as symbol with commands
- (hyphen), as SYMDEB option designator
. (period), as ASCII value
+ (plus sign), as filename separator
? (question mark), with commands
; (semicolon), in SYMDEB command list
/ (slash), as SYMDEB option designator
_ (underscore), with commands
| (vertical bar), as document convention
. . . (ellipses), as document convention
{{ }} (double brackets), as document convention
A
Address arguments, SYMDEB
Allocating memory
Allocation granularity
ANSI character set
Applications
and creating import libraries
and linking files
and starting SYMDEB
building
C language
compiling options for
development options for
executable
memory model for
memory movement in
module-definition (.DEF) files for
optimizing performance of
passing to Windows
resource script (.RC) file
startup routines for
Arguments
address
SYMDEB command
ASCII
byte values, displaying
characters, displaying
strings, entering into memory
Assembling instruction mnemonics
Assembly-language symbol files
Asterisk (*)
wildcard character
with commands
At symbol (@), with commands
B
Binary resource file
Bitmap (.BMP) files
see also Bitmaps
and File menu
and Image menu
and SDKPAINT process
creating
described
working with colors
BITMAP resource statement
Bitmaps
see also Bitmap (.BMP) files
creating
described
editing colors for
editing
opaque color options
using colors with
Bold text, as document convention
Braces, curly ({ }), as document convention
Brackets ({ }), in symbol map display
Brackets, double ({{ }}), as document convention
Breakpoints
"sticky", defined
clearing
disabling
immediate
interrupt key
restoring disabled
setting
virtual
Byte values
displaying 4-byte values as hexadecimal
displaying hexadecimal and ASCII values
searching for
C
C Compiler
default option
options (table)
versions supported by Windows
C language
applications
libraries
C run-time libraries
Callback function
CAPITAL LETTERS, SMALL, as document convention
Character information
Character mapping
Character window
clearing
described
Character-viewing window
Characters
adding columns to
adding rows to
canceling changes to
changing character pixels
changing width of
deleting columns from
deleting rows from
displayed in Font Editor window
editing blocks of pixels
editing
first of font
last of font
pasting to and from Clipboard
width restriction of
Check box control
Choosing messages
CL command
CL Compiler
see C Compiler
Clearing breakpoints
CODE statement
Code, instruction
CodeView for Windows (CVW)
application development option for
breakpoints
examples of
on lines, functions, and addresses
on values
on Windows messages
removing
calling functions
commands
Help on CVW commands
new, in CVW
compared with
CodeView for DOS
SYMDEB
compiling source code for use with
continuous execution
controlling program execution
customizing
debugging multiple instances of an application
described
display windows
adjusting
described
opening
selecting
using multiple Source windows
using the mouse with
displaying memory
dereferencing memory handles
in the Memory window
live expressions
local and global memory objects
register contents
displaying variables
arrays and structures
expressions
single values
summarized
using the Quick Watch command
ending
Help in CVW
interrupting a session
menus
preparing Windows applications
recording session information
redirecting input and output
register variables
requirements for use
restarting
secondary monitor, setting up
setting
breakpoints
single-step execution
described
stepping
tracing
starting a CVW session
tracing
program execution. See single-step execution.
Windows messages
undefined pointers
values, changing
for program data
for variables, memory locations and registers
windows-specific features
Colon (:), use of with doubleword values
Colors
and bitmaps
dithered
inverse
opaque
screen
true
Combo box control
Comma (, ), as parameter separator
Command arguments, SYMDEB
Comparing bytes in memory locations
Compiler options
memory-model
recommended for
dynamic-link libraries
Windows applications
CompilersC Compiler
see Resource Compiler
CONTROL+C key
CONTROL+S key
Controls
changing identifiers
changing styles of
changing text
custom
displaying information about
positions of
predefined identifiers
symbolic names of
temporary
Copying
dialog-box controls
file or disk contents into memory
CPU registers, displaying contents of
Creating
cursor (.CUR) files
cursors
icon (.ICO) files
import libraries
map files
module-definition (.DEF) files
resource script (.RC) files
symbol files
Windows applications
Curly braces ({ }), as document convention
Cursor (.CUR) files
and File menu
and Image menu
and SDKPAINT process
creating
described
working with colors
CURSOR resource statement
Cursor
see also Cursor (.CUR) files
creating
cursor images, and creating icons
defining
displaying
editing
hotspot
inverse colors with
opaque color options
screen colors with
with clipboard
with color
Custom control
Custom controls
D
-D option
DATA statement
Debugging toolsCodeView for Windows (CVW) Spy
see Symbolic Debugger (SYMDEB)
Debugging
adding line-number information
entering into memory;ASCII strings
in protected mode. See CodeView for Windows(CVW)
in real mode. See Symbolic Debugger (SYMDEB)
.DEF file
see Module-definition (.DEF) files
Defining macros
Deleting dialog-box controls
DESCRIPTION statement
Dialog boxes
adding group marker to
controls
changing order of
editing
using custom
creating new
defining styles of
deleting group marker from
editing
canceling edits
include files
methods of
modifying
moving between resources
opening existing
renaming
resizing
setting memory flags for
Dialog Editor
controls, groups of
moving
specifying
controls, order of
described
dialog unit
editing include files
group marker
mouse requirement for
opening
dialog boxes
include files
resource files
sizing handle
tab stop for
toolbox
described
enabling
using Clipboard format
window
working with files
dialog script
include
resource
Dialog script (.DLG) files
Dialog unit, described
Dialog-box controls
adding
custom
standard
custom
defining symbolic names for
deleting
duplicating
identifiers for changing
input focus
specifying
using tab stops
moving
groups of
individual
resizing
static text
styles, changing
text, changing
types of
check box
combo box
edit
frame
group box
horizontal scroll bar
icon
list box
push button
radio button
rectangle
vertical scroll bar
Directives, resource
Disabling breakpoints
Displaying
ASCII characters within a given range
CPU registers, contents of
cursor hotspot
expression, value of
hexadecimal values
of bytes in given range
of doublewords
of words
instruction code
instructions, of program being debugged
list of
global free memory objects in global heap
global memory objects in global heap
global modules in global heap
local memory objects in local heap
LRU global memory objects
SYMDEB commands and operators
long floating-point numbers
memory objects
memory, contents of
one byte from the input port
short floating-point numbers
source line
actual program
current
stack frame
current
for a specified task
stack location and frame-pointer values
statements, of program being debugged
sum and difference of two hexadecimal numbers
symbol map information
symbol maps
symbols
task-queue information
ten-byte floating-point numbers
variables
DLLs
see Dynamic-link libraries
Document conventions
Dollar sign ($), with commands
DOS commands
CL
command processor
exit
mode
RC
Double brackets ({{ }}), as document convention
Doubleword values
Dynamic-link Libraries (DLLs)
custom control
Dynamic-link libraries (DLLs)
module-definition (.DEF) files, requirements
options for compiling
written in C language, requirements
E
-E option
Echoing comment on output devices
Edit control
Editing
canceling dialog box edits
dialog box controls
dialog box
include files
Ellipses, as document convention
horizontal
vertical
EMS (Expanded Memory Specification)
defined
walking
Enabling breakpoints
Enabling toolbox
Epilog (Windows)
Executable files
Executing
instructions
macros
Execution control
EXETYPE statement
EXETYPE WINDOWS statement
Expanded Memory Specification
see EMS
Exported function
EXPORTS statement
Expressions
displaying value of
SYMDEB commands
F
Fatal exit message
-Fe option
File headers, executable
Filenames, setting for load and write commands
Files
dialog script (.DLG)
executable file headers
icon (.ICO)
include (.H)
loading
module-definition (.DEF)
resource (.R)
resource script (.RC)
symbol
Filling addresses in a given range
Floating-point numbers
Floating-point values
-Fo option
Font Editor
adding
columns to a character
rows to a character
canceling changes
changing
character pixels
character width
font file header information
character information display
character window
clearing
described
character-viewing window
Clipboard characters, using
deleting
columns from characters
rows from characters
described
editing
blocks of pixels
characters
fixed-pitch font
Font Editor window
font family names
font window
mouse requirement for
opening fonts
resizing fonts
variable-pitch font
window
Font EditorFonts
see also Pixels
Font file header, editing
FONT resource statement
Fonts
break character of
canceling changes to
copyright of
creating
default character of
editing
face name of
filename of
first character of
font character set
font face name vs. filename
font families
font file header
height of
ascent
character pixel
height
last character of
leading of
external
internal
nominal point size of
nominal resolution of
horizontal
vertical
opening, in Font Editor
options
strikeout
underline
pitches of
saving changes to
types of
fixed-pitch
raster
variable-pitch
vector
weights of
width of
fixed-pitch
variable-pitch
Frame control
Functions
callback
exported
imported
WinMain
G
GDI library, symbol files
Global heap
allocating memory to examine
defining displayed objects
displaying lists of
free global memory objects in
global memory objects in
global modules in
LRU global memory objects in
protected mode
real mode
saving lists of objects on
sorting displayed objects
total size of examined objects
viewing
walking EMS
walking
Group box control
Group marker
adding
deleting
H
.H file
see Include (.H) files
-H option
Heap Walker
allocating memory examined by
defining objects displayed by
described
displaying selected objects
file operation commands
information displayed by
memory allocation commands
memory object commands
saving object lists
sorting displayed objects
total size of objects examined by
window
HEAPSIZE statement
Height, font
Help compiler
Help graphics
bitmaps
creating, capturing
placing
Help Project file
accessing from an application
Alias section
Bitmaps section
bitmaps, including by reference
Build option
Build Tags section
compiling
Compress option
context strings, alternate
context-sensitive Help
context-sensitive topics
creating
F1 support
Files section
Forcefont option
Index option
keyword table, accessing
Map section
Mapfontsize option
Multikey option
on Help menu item
Options section
Root option
Title option
Warning option
Help system
see also Help
appearance to programmer
appearance to user
appearance to writer
calling WinHelp
development cycle described
graphics. See Help graphics
hypertext links summarized
topics. See Help topics
Help text
fonts
layout
Help tools
see Help
Help topic files
authoring tool
browse sequence numbers
build tags
context strings
control codes
cross references
definitions
graphics
jumps
key words
managing
title footnotes
tracking
Help topics
content
context-sensitivity
cross-references
definitions
file structure
files. See Help topic files
jumps
structure of
text. See Help text
Help Tracker
Help
audience definition
cancelling
compiler error messages
context-sensitive
control codes
error messages
F1 support
file structure
file. See Help Project file
key words
keyword table, accessing
on Help menu item
planning
overview
topic files
examples
links summarized
Hexadecimal values
of bytes in the given range
of double words
of floating-point numbers in the given range
of words in the given range
Hits, defined
Hotspot, cursor
defining
displaying
Hyphen (-), as SYMDEB option designator
I
-I option
Icon (.ICO) files
and File menu
and Image menu
and SDKPAINT process
creating
described
working with colors
Icon control
ICON resource statement
Icons
see also Icon (.ICO) files
colors with
creating, with cursor images
editing colors for
editing
inverse colors with
opaque color options
screen colors with
Identifiers, dialog-box control
Immediate breakpoint
IMPLIB utility
IMPORTS statement
Include (.H) files
creating
editing
loading
saving
working with
Input focus, dialog-box control
Input port
Input, redirecting input commands
Instruction code, displaying
Interrupt key
Italic text, as document convention
K
-K option
Kernel library, symbol files
Keys
CONTROL+C
CONTROL+S
SCROLL LOCK
SYS REQ
L
-L option
Leading
LIBRARY statement
Library symbol files
-LIM 32 option
Linker
command options
described
not allowed
not recommended
creating import libraries
LINK command, using
linking
applications files
dynamic-link libraries
module-definition (.DEF) files
source files
Windows applications
module-definition (.DEF) files
creating for applications
creating for libraries
importing dynamic-link libraries
module statements
requirements for creating
Linking
see Linker
List box control
Listing breakpoint information
Loading
files
logical records
Local heap
Logical records, loading
M
-M option
Macro
defining
executing
Managing output
Map files
Maps
see Symbol maps
MAPSYM program
creating symbol files
sample symbol file
MASM assembler
Math coprocessor/emulator, with Windows
Memory flags, setting dialog box
Memory models
Memory
comparing bytes in memory locations
copying file or disk contents into
determining size
displaying contents of within a given range
entering
ASCII strings into
byte values into
doubleword values into
long floating-point values into
short floating-point values into
ten-byte real values into
values into
word values into
moving blocks of
testing movable
Menu bar
Messages
choosing
fatal-exit
information Spy monitors
memory-allocation
monitoring
Microsoft QuickC
Mnemonics, instruction
Mode display
Module statements
see Module-definition (.DEF) files
Module-definition ( DEF) files
for applications
described
Module-definition (.DEF) files
creating
described
for applications
described
sample file
for dynamic-link libraries
described
sample file
linking applications
module statements
list
required
Monitor, secondary, for debugging
Monospaced type, as document convention
Moving blocks of memory
MS-DOS
see DOS commands
N
NAME statement
Naming
modules
symbol files
Non-maskable interrupts
Notational conventions
O
OEM character set
Oil can
Optimization toolsHeap Walker Profiler Shaker
see Swap
Options
compiler
application development
dynamic-link library
memory-model
LINK command
described
options not allowed
options not recommended
option designator
RC command line
Resource Compiler (table)
SYMDEB
Output device, choosing (Spy)
Output port
sending bytes to
Output
redirecting output commands
suspending and restoring
P
-P option
Packed structure
Paintbrush
Parentheses ( ), as document convention
PC-DOS
see DOS commands
Period (.), as ASCII value
Pixels
adding rows or columns of
changing character
copying to Clipboard
deleting rows or columns of
pasting from Clipboard
selecting and changing blocks of
Plus sign (+), as filename separator
Preprocessor, defining names for
PROF.COM program
Profiler
checking if installed
described
displaying samples
ensuring compatibility with your system
functions
managing output (example)
sampling
real-mode Windows applications
setting rate of
starting and stopping
Windows 386 enhanced mode applications
starting and stopping
Program descriptor block (pdb)
Program execution
Program input and output, redirecting
Programming tools
see Tools
Programs
CL
RC
setting arguments for program execution
Prolog (Windows)
Protected mode
debugging in. See CodeView for Windows(CVW)
Public symbols
Push button control
Q
Question mark (?), with commands
Quitting SYMDEB
Quotation marks (" "), as document convention
R
-R option
Radio button control
Raster fonts
RC command
RC Compiler
described
RC compiler
options (table)
.RC file
see Resource script (.RC) files
Real mode
debugging in. See Symbolic Debugger (SYMDEB)
Real-mode Windows applications
REC command
Rectangle control
Redirecting program input and output
Registers, CPU, displaying contents of
Reporting utility
.RES file
see Resource (.RES) files
Resource (.RES) files
Resource Compiler
described
RC command line options
Resource directives
Resource editorsDialog Editor Font Editor
see SDKPaint
Resource script (.RC) files
.RC extension
and Dialog Editor
creating
described
for applications
resource statements
Resource statements
see Resource script (.RC) files
Resources
defining
dialog box
S
Sampling
buffer
displaying samples
minimizing loss when sampling buffer fills
real-mode Windows applications
setting rate of code
standard-mode Windows applications
starting and stopping
utilities for
Windows 386 enhanced mode applications
Scroll bar control
SCROLL LOCK key
SDKPaint
.DAT file, described
color palette, described
converting files
cursor hotspot
defining
showing the current
described
loading images into
menu commands (list)
tools, described (table)
transferring images to and from clipboard
window, described
working with colors
customizing the color palette
editing colors
inverse colors
loading a customized palette
opaque colors
saving a palette
screen colors
true colors
types of
Secondary monitor, setting up for debugging
SEGMENTS statement
Selected Item Status window
Semicolon (
), in SYMDEB command list
Serial port
Setting
active symbol maps and/or segments
breakpoint address
breakpoints
display mode
filenames for load and write commands
program arguments for program execution
Shaker
allocation granularity
commands (list)
described
SHOWHITS.EXE utility
described
sample display
SKERNEL.EXE file
SKERNEL.SYM file
Slash (/), as SYMDEB option designator
SMALL CAPTIAL LETTERS, as document convention
Sorting memory objects
Source file, compiling
Source lines, displaying
Spy
choosing a window
choosing options
message type
output device
output frequency
described
starting
turning on and off
Stack frame
Stack probes
STACK statement
STACKSIZE statement
Starting applications with Windows
Statements
CODE
DATA
DESCRIPTION
EXETYPE WINDOWS
EXETYPE
EXPORTS
HEAPSIZE
IMPORTS
LIBRARY
NAME
SEGMENTS
STACK
STACKSIZE
STUB
Static text control
Static variables
STUB statement
Styles
dialog box
dialog-box control
SWAP.EXE file
Swap
command line options
described
output format
reducing processing time
starting and stopping
.SYM files
Symbol files
for assembly-language applications
for C-language applications
library
loading
naming
setting up
Symbol maps
defined
displaying symbols
listing
opening
using symbols from
Symbolic Debugger (SYMDEB)
and IBM-compatible computers
application development option for
arguments
address (list)
command (list)
commands
canceling current
command options
executing at startup
list of
redirect input and output
set source mode
debugging terminal
remote
secondary
described
displaying
application source statements
variables
expressions (list)
for Assembly-language applications
for C-language applications
loading macro definitions
messages
fatal exit
memory-allocation
option designator
option
passing control to command.com
preparing symbol files for
quitting
redirecting output from
returning control to DOS
setting
breakpoints
memory-allocation reporting level
special keys
specifying symbol files
starting applications
starting
suspending and restoring output
symbol maps
opening
using symbols from
working with
terminating
use of, with Windows
Symbolic Debugger(SYMDEB)
debugging terminal
secondary
Symbols
declaring public
displaying
SYS REQ key
T
Tab stop, setting for dialog-box control
Task descriptor block
Task queue, displaying information about
Terminal
remote, for debugging
secondary, for debugging
Terminating SYMDEB
Text editors
creating applications
creating resource script files
Text, changing
Toolbox
described
enabling
Tools
see Help.
compilers. See C Compiler; Resource Compiler
debugging tools. See CodeView for Windows ; Spy; Symbolic Debugger
linkers. See Linker
optimization tools. See Heap Walker; Profiler; Shaker; Swap
resource editors. See Dialog Editor; Font Editor; SDKPaint
Turning off stack probes
U
Underscore (_), with commands
User library, symbol files
User-defined resource statement
Utilities
see Tools
V
-V option
Variable-pitch fonts
Variables
displaying
static
Vector fonts
Vertical bar (|), as document convention
Virtual breakpoint, defined
VPROD.386 device driver
W
Walking the heap
Width, font
Wildcard character (*), with SYMDEB commands
Window, monitoring messages to
Windows 386 enhanced mode applications
using PROFILER with
Using PROFILER with
using PROFILER with
Windows 386 mode applications
using PROFILER with
Windows applications
compiler option, example
creating
Windows enhanced mode applications
using PROFILER with
Windows version stamp
Windows
epilog
fatal exit message
import libraries
prolog
WinMain function
Writing
to logical records on disk
to named files
X
-X option