Programming Windows





ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

                              Programming Windows

         The Microsoft(R) guide to writing applications for Windows 3

                              by Charles Petzold

ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ







Published by
Microsoft Press
A Division of Microsoft Corporation
One Microsoft Way
Redmond, Washington 98052-5399

Copyright(c) 1990 by Charles Petzold

All rights reserved. No part of the contents of this book may be reproduced
or transmitted in any form or by any means without the written permission
of the publisher.

Library of Congress Cataloging-in-Publication Data

Petzold, Charles, 1953-
    Programming Windows : the Microsoft guide to writing applications
  for Windows 3 / Charles Petzold. -- 2nd ed.

       p.     cm.
    ISBN 1-55615-264-7
    1. IBM Personal computer--Programming.  2. Microsoft Windows
  (Computer programs)  I. Title
  QA76.8.I2594P474  1990
  005.4'3--dc20                                          90-35467
                                                            CIP

Printed and bound in the United States of America.

2 3 4 5 6 7 8 9  MLML  4 3 2 1 0

Distributed to the book trade in Canada by General Publishing Company, Ltd.

Distributed to the book trade outside the United States and Canada by
Penguin Books Ltd.

Penguin Books Ltd., Harmondsworth, Middlesex, England
Penguin Books Australia Ltd., Ringwood, Victoria, Australia
Penguin Books N.Z. Ltd., 182-190 Wairau Road, Auckland 10, New Zealand

British Cataloging-in-Publication Data available


Apple(R) and LaserWriter(R) are registered trademarks of Apple Computer,
Inc. IBM(R) is a registered trademark of International Business Machines
Corporation. Microsoft(R), MS-DOS(R), and MultiPlan(R) are registered
trademarks and Windows(TM) is a trademark of Microsoft Corporation.


Project Editor: Jack Litewka
Technical Editor: Wm. Jeff Carey
Acquisitions Editor: Dean Holmes



Table of Contents
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ



     Preface


PART I  GETTING STARTED
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ


Chapter 1  Hello, Windows

     A BRIEF HISTORY OF WINDOWS
     THE USER'S PERSPECTIVE
            The Graphical User Interface (GUI)
            GUI Concepts and Rationale
            The Consistent User Interface
            The Multitasking Advantage
            Memory Management
            The Device-Independent Graphics Interface
            MS-DOS Applications
     THE PROGRAMMER'S PERSPECTIVE
            Windows and MS-DOS
            The Windows Commitment
            The Function Calls
            Dynamic Linking
            Object-Oriented Programming
            Message-Driven Architecture
            The Window Procedure
     YOUR FIRST WINDOWS PROGRAM
            What's Wrong with this Program?
            The HELLOWIN Files
            The Make File
            The C Source Code File
            The Windows Function Calls
            Uppercase Identifiers
            New Data Types
            Getting a Handle on Handles
            Hungarian Notation
            The Program Entry Point
            Registering the Window Class
            Creating the Window
            Displaying the Window
            The Message Loop
            The Window Procedure
            Processing the Messages
            The WM_PAINT Message
            The WM_DESTROY Message
            The Module Definition File
     THE WINDOWS PROGRAMMING HURDLES
            Don't Call Me, I'll Call You
            Queued and Nonqueued Messages
            Nonpreemptive Multitasking
            The Learning Curve

Chapter 2  Painting with Text

     PAINTING AND REPAINTING
            The WM_PAINT Message
            Valid and Invalid Rectangles
     AN INTRODUCTION TO GDI
            The Device Context
            Getting a Device Context Handle: Method One
            The Paint Information Structure
            Getting a Device Context Handle: Method Two
            TextOut: The Details
            The System Font
            The Size of a Character
            Text Metrics: The Details
            Formatting Text
            Putting It All Together
            The SYSMETS1.C Window Procedure
            Not Enough Room!
            The Size of the Client Area
     SCROLL BARS
            Scroll Bar Range and Position
            Scroll Bar Messages
            Scrolling SYSMETS
            Structuring Your Program for Painting
            Building a Better Scroll
            But I Don't Like to Use the Mouse


PART II  READING INPUT
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ


Chapter 3  The Keyboard

     KEYBOARD BASICS
            The Keyboard Driver
            Ignoring the Keyboard
            Focus, Focus, Who's Got the Focus?
            Keystrokes and Characters
     KEYSTROKE MESSAGES
            System and Nonsystem Keystrokes
            The lParam Variable
            Virtual Key Codes
            Shift States
            Using Keystroke Messages
     ENHANCING SYSMETS:
            Adding WM_KEYDOWN Logic
            Sending Messages
     CHARACTER MESSAGES
            WM_CHAR Messages
            Dead-Character Messages
     LOOKING AT KEYBOARD MESSAGES
     THE CARET (NOT THE CURSOR)
            The Caret Functions
            The TYPE Program
     THE WINDOWS CHARACTER SETS
            The OEM Character Set
            The ANSI Character Set
            OEM, ANSI, and Fonts
     INTERNATIONALIZATION CONCERNS
            Working with the Character Set
            Talking with MS-DOS
            Using the Numeric Keypad

Chapter 4  The Mouse

     MOUSE BASICS
            Some Quick Definitions
     CLIENT-AREA MOUSE MESSAGES
            Simple Mouse Processing: An Example
            POINT, RECT, and lParam
            Processing Shift Keys
            Mouse Double-Clicks
     NONCLIENT-AREA MOUSE MESSAGES
            The Hit-Test Message
            Messages Beget Messages
     HIT-TESTING IN YOUR PROGRAMS
            A Hypothetical Example
            A Sample Program
            Emulating the Mouse with the Keyboard
            Adding a Keyboard Interface to CHECKER
            Using Child Windows for Hit-Testing
            Child Windows in CHECKER
     CAPTURING THE MOUSE
            The BLOWUP1 Program
            Changing the Mouse Cursor Shape
            The StretchBlt Call
            Drawing the Capture Block

Chapter 5  The Timer

     TIMER BASICS
            SYSTEM.DRV and the Windows Timer
            Timer Messages Are Not Asynchronous
     USING THE TIMER: THREE METHODS
            Method One
            Method Two
            Method Three
     USING THE TIMER FOR A STATUS REPORT
            Creative Use of Icons
            Forcing the Icon
            Keeping the Icon an Icon
            Calculating Free Memory
            Using Floating-Point Math
     USING THE TIMER FOR A CLOCK
            Positioning and Sizing the Popup
            Getting the Date and Time
            Going International
     WINDOWS STANDARD TIME

Chapter 6  Child Window Controls

     THE BUTTON CLASS
            Creating the Child Windows
            The Child Talks to Its Parent
            The Parent Talks to Its Child
            Push Buttons
            Check Boxes
            Radio Buttons
            Group Boxes
            User-Defined Buttons
            Changing the Button Text
            Visible and Enabled Buttons
            Buttons and Input Focus
     CONTROLS AND COLORS
            System Colors
            The Button Colors
            The WM_CTLCOLOR Messages
     THE STATIC CLASS
     THE SCROLLBAR CLASS
            The COLORS1 Program
            The Automatic Keyboard Interface
            Window Subclassing
            Coloring the Background
            Coloring the Scroll Bars
            Dealing with Multiple Instances
            COLORS1 as an Icon
     THE EDIT CLASS
            The Edit Class Styles
            Edit Control Notification
            Using the Edit Controls
            Messages to an Edit Control
     THE LISTBOX CLASS
            List Box Styles
            Putting Strings in the List Box
            Selecting and Extracting Entries
            Receiving Messages from List Boxes
            A Simple List Box Application
            Listing Files
            A head for Windows
            2 KB of Wasted Space


PART III  USING RESOURCES
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ


Chapter 7  Memory Management

     SEGMENTED MEMORY, INTEL STYLE
     MEMORY ORGANIZATION IN WINDOWS
            Fixed and Moveable Segments
            Discardable Memory
            The Global Memory Layout
            Local Memory
     CODE AND DATA SEGMENTS
            Memory Models: Small, Medium, Compact, Large, and Huge
            Multiple Code Segments
            What About the Compact and Large Models?
            Avoiding Movement Problems
            Program Segment Attributes
     HOW WINDOWS MOVES AND
            Special Treatment of Far Functions
            When Windows Runs the Program
            What MakeProcInstance Does
            The Difference for Dynamic Libraries
            Walking the Stack
            Expanded Memory
            Protected Mode
     ALLOCATING MEMORY WITHIN A PROGRAM
            Lock Your Blocks
            A Quick Example
            Global Memory Functions
            More Global Memory Functions
            Using Discardable Global Memory
            Huge Global Memory Blocks
            Allocating Local Memory
            Other Local Memory Functions
            Locking Your Own Data Segment
            Memory Allocation Shortcuts
            Using C Memory Allocation Functions
            If You Know You're Running in Protected Mode

Chapter 8  Icons, Cursors, Bitmaps, and Strings

     COMPILING RESOURCES
     ICONS AND CURSORS
            The SDKPAINT Tool
            Getting a Handle on Icons
            Using Icons in Your Program
            Using Alternate Cursors
     RESOURCES AND MEMORY
            Bitmaps: Pictures in Pixels
            Using Bitmaps and Brushes
     CHARACTER STRINGS
            Using Character String Resources
            Using Strings with MessageBox
            Character Strings and Memory Space
     USER-DEFINED RESOURCES

Chapter 9  Menus and Accelerators

     MENUS
            Menu Structure
            The Menu Template
            Referencing the Menu in Your Program
            Menus and Messages
            A Sample Program
            Menu Etiquette
            Defining a Menu the Hard Way
            A Third Approach to Defining Menus
            Floating Popup Menus
            Using the System Menu
            Changing the Menu
            Other Menu Commands
            An Unorthodox Approach to Menus
     USING BITMAPS IN MENUS
            Two Methods of Creating Bitmaps for Menus
            The Memory Device Context
            Creating a Bitmap with Text
            Scaling Bitmaps
            Putting the Menu Together
            Adding a Keyboard Interface
     KEYBOARD ACCELERATORS
            Why You Should Use Keyboard Accelerators
            Some Rules on Assigning Accelerators
            The Accelerator Table
            Loading the Accelerator Table
            Translating the Keystrokes
            Receiving the Accelerator Messages
            POPPAD with a Menu and Accelerators
            Enabling Menu Items
            Processing the Menu Options

Chapter 10  Dialog Boxes

     MODAL DIALOG BOXES
            Creating an "About" Dialog Box
            The Dialog Box Template
            The Dialog Box Procedure
            Exporting the Dialog Box Procedure
            Invoking the Dialog Box
            More on the Dialog Box Style
            More on Defining Controls
            A More Complex Dialog Box
            Working with Dialog Box Controls
            The OK and Cancel Buttons
            Tab Stops and Groups
            Painting on the Dialog Box
            Using Other Functions with Dialog Boxes
            Defining Your Own Controls
     THE MESSAGE BOX
            The Assertion Message Box
            Popup Information
     WORKING WITH FILES: POPPAD REVISITED
            The OpenFile Function Call
            Two Methods of File I/O
            Dialog Boxes for Open and Save
            The DlgDirList and DlgDirSelect Functions
            Getting Valid Filenames
            The New Version of POPPAD
     MODELESS DIALOG BOXES
            Differences Between Modal and Modeless Dialog Boxes
            The New COLORS Program
            HEXCALC: Window or Dialog Box?
            Creatively Using Control IDs
     USING THE DIALOG UTILITY


PART IV  THE GRAPHICS DEVICE INTERFACE
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ


Chapter 11  An Introduction to GDI

     THE GDI PHILOSOPHY
     THE DEVICE CONTEXT
            Getting the Handle to the Device Context
            Getting Device Context Information
            The DEVCAPS1 Program
            The Size of the Device
            Finding Out About Color
            The Device Context Attributes
            Saving Device Contexts
     THE MAPPING MODE
            Device Coordinates and Logical Coordinates
            The Device Coordinate Systems
            The Viewport and the Window
            Working with MM_TEXT
            The "Metric" Mapping Modes
            The "Roll Your Own" Mapping Modes
            The WHATSIZE Program

Chapter 12  Drawing Graphics

     DRAWING POINTS
     DRAWING LINES
            Using Stock Pens
            Creating, Selecting, and Deleting Pens
            Avoiding Device Dependencies
            Filling In the Gaps
            Drawing Modes
            The ROP2LOOK Program
            ROP2 and Color
     DRAWING FILLED AREAS
            The Bounding Box
            The ARCS Program
            The Trigonometry of Pie Charts
            The Polygon Function and the Polygon Filling Mode
            Brushing the Interior
            Brushes and Bitmaps
            Creating and Using Bitmap Brushes
            Brush Alignment
     RECTANGLES, REGIONS, AND CLIPPING
            Working with Rectangles
            Creating and Painting Regions
            Clipping with Rectangles and Regions
            The CLOVER Program
     SOME MISCELLANEOUS GDI FUNCTIONS
     PROGRAMS THAT DRAW FOREVER

Chapter 13  Bits, Blts, and Metafiles

     THE OLD BITMAP FORMAT
            Creating Bitmaps in a Program
            The Monochrome Bitmap Format
            The Color Bitmap Format
            The Dimensions of a Bitmap
     THE DEVICE-INDEPENDENT BITMAP (DIB)
            The DIB File
            Creating a DIB
     THE MEMORY DEVICE CONTEXT
     THE MIGHTY BLT
            The PatBlt Function
            Blt Coordinates
            Transferring Bits with BitBlt
            The DrawBitmap Function
            Using Different ROP Codes
            More Fun with Memory Device Contexts
            Color Conversions
            Mapping Mode Conversions
            Stretching Bitmaps with StretchBlt
            Animation
     METAFILES
            Simple Use of Memory Metafiles
            Storing Metafiles on Disk
            Using Preexisting Metafiles
            Using Metafiles as Resources
            Looking at Metafiles
            Metafile Dos and Don'ts

Chapter 14  Text and Fonts

     SIMPLE TEXT OUTPUT
            The Text Drawing Functions
            Device Context Attributes for Text
            Using Stock Fonts
            Graying Character Strings
            The Easy Use of GrayString
            Gray Strings Without GrayString
     BACKGROUND ON FONTS
            The Types of Fonts
            Type Talk I: Families and Faces
            The Font Resource Files
            Type Talk II: Getting the Point
            Why Logical Inches?
            Type Talk III: Leading and Spacing
            The "Logical Twips" Mapping Mode
     CREATING, SELECTING,AND DELETING LOGICAL FONTS
            The PICKFONT Program
            The Logical Font Structure
            The Font-Mapping Algorithm
            Finding Out About the Font
     ENUMERATING THE FONTS
     FORMATTING TEXT
            One-Line Text Alignment
            Working with Paragraphs

Chapter 15  Using the Printer

     PRINTING, SPOOLING, AND ESCAPE
     THE PRINTER DEVICE CONTEXT
            Getting the CreateDC Parameters
            The Revised DEVCAPS Program
            The DeviceMode Call
            Checking for BitBlt Capability
     PRINTING FUNDAMENTALS
            The Escape Function
            The FORMFEED Program
     PRINTING GRAPHICS AND TEXT
            Bare-Bones Printing
            Setting an Abort Procedure
            How Windows Uses AbortProc
            Implementing an Abort Procedure
            Adding a Printing Dialog Box
            Adding Printing to POPPAD
            Handling Error Codes
     THE TECHNIQUE OF BANDING
            Strike Up the Bands
            A Different Use of the Abort Procedure
     THE PRINTER AND FONTS


PART V  DATA EXCHANGE AND LINKS
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ


Chapter 16  The Clipboard

     SIMPLE USE OF THE CLIPBOARD
            The Standard Clipboard Data Formats
            Transferring Text to the Clipboard
            Getting Text from the Clipboard
            What the Clipboard Does
            Opening and Closing the Clipboard
            Using the Clipboard with Bitmaps
            The Revised BLOWUP Program
            The Metafile and the Metafile Picture
     BEYOND SIMPLE CLIPBOARD USE
            Using Multiple Data Items
            Delayed Rendering
            Private Data Formats
     BECOMING A CLIPBOARD VIEWER
            The Clipboard Viewer Chain
            Clipboard Viewer Functions and Messages
            A Simple Clipboard Viewer

Chapter 17  Dynamic Data Exchange (DDE)

     BASIC CONCEPTS
            Application, Topic, and Item
            The Types of Conversations
            Character Strings and Atoms
     A DDE SERVER PROGRAM
            The DDEPOP Program
            The WM_DDE_INITIATE Message
            The ServerProc Window Procedure
            The WM_DDE_REQUEST Message
            DDEPOP's PostDataMessage Function
            The WM_DDE_ADVISE Message
            Updating the Items
            The WM_DDE_UNADVISE Message
            The WM_DDE_TERMINATE Message
     A DDE CLIENT PROGRAM
            Initiating the DDE Conversation
            The WM_DDE_DATA Message
            The WM_DDE_TERMINATE Message
     WHEN THINGS GO WRONG

Chapter 18  The Multiple Document Interface (MDI)

     THE ELEMENTS OF MDI
     WINDOWS 3 AND MDI
     THE SAMPLE PROGRAM
            Three Menus
            Program Initialization
     CREATING THE CHILDREN
     MORE FRAME WINDOW MESSAGE PROCESSING
     THE CHILD DOCUMENT WINDOWS
     THE POWER OF WINDOW PROCEDURES

Chapter 19  Dynamic Link Libraries

     LIBRARY BASICS
            Library: One Word, Many Meanings
            Examining Libraries with EXEHDR
     STRPROG AND STRLIB
            The STRLIB Library
            Make File Differences
            The Library Entry Point
            The STRLIB Functions
            The Library Module Definition File
            The STRPROG Program
            Running STRPROG
            Far Function Prologs
            The Use of Call-Back Functions
     THE DS != SS ISSUE
     OTHER LIBRARY RESTRICTIONS
     DIFFERENT METHODS FOR SPECIFYING LINKS
     USING IMPORT LIBRARIES
     INTERCEPTING WINDOWS FUNCTION CALLS
     DYNAMIC LINKING WITHOUT IMPORTS
     RESOURCE-ONLY LIBRARIES

Preface

When I began writing the first edition of PROGRAMMING WINDOWS in the early
spring of 1987, Microsoft Windows 1.0 had been released for about a year and
a half, a beta-test version of Windows 2.0 was just becoming available, and
Windows 3.0 could only be regarded as a far-fetched dream. At that time, the
eventual success of Windows in the personal computer marketplace was more a
matter of faith than a certain-to-come reality.

With the release of Windows 3, more people than ever are interested in this
operating environment. Windows 3 runs Windows programs in Intel
80286\-compatible protected mode, giving Windows and Windows programs access
to 16 megabytes of memory. This exciting enhancement to Windows--coupled
with the many Windows applications released over the past few years--has
made Windows 3 an important piece of systems software released for
IBM-compatible personal computers. Windows is the graphical interface that
many computer users will first encounter.

Since the publication of the first edition of PROGRAMMING WINDOWS in early
1988, many programmers have told me that the book has been useful in helping
them learn how to write applications for Windows. Nothing could make me
happier.

It was my intention with the first edition of PROGRAMMING WINDOWS to show
the basics of writing programs for Windows using the C programming language.
A book like this cannot delve into the complexities of a full-fledged
application program, of course, but it can show how to handle all the
various components of a Windows program. It is up to the application
programmer to merge these components into a coherent whole.

In this second edition of PROGRAMMING WINDOWS, I have updated the text where
necessary, updated the code listings for a more modern style of C
programming, tightened the early chapters (where I felt I had been more
theoretical than practical), and added two new chapters--None on Dynamic
Data Exchange (DDE) and one on the Multiple Document Interface (MDI).
Interestingly enough, the Windows application program interface has been
fairly stable over the years and very few changes had to be made to the
sample programs.

Windows has a reputation for being easy for users but tough for programmers.
Often, aspiring Windows programmers face a steep learning curve, and they
want to see lots of programming examples. To satisfy that desire, this book
contains more than 50 complete programs. Many of them are short and stripped
down to clearly illustrate various Windows programming techniques. Others
are a bit longer to show how everything fits together. Several of the
programs are useful utilities. Others are tools for exploring Windows.

What I don't do in this book is teach you how to use Windows. If you have no
experience using the environment, now is the time to install it and play
with it for awhile. Windows is very easy to learn.

PROGRAMMING WINDOWS

Nor will I teach you how to program in C. Before you even think about
programming for Windows, you should have a good working knowledge of
programming in C for a more conventional environment such as MS-DOS. If your
C is a little rusty, you may want to spend some time becoming better
acquainted with the topics of structures and pointers.

A good familiarity with the segmented architecture of the Intel 8086 family
of microprocessors will also help. If you know how 80286 addressing works
(in both real mode and protected mode) and the difference between near and
far pointers and functions, you're in good shape. If you don't, I've
included some explanations along the way.

To compile the programs in this book and to write your own programs for
Windows, you need the following software packages:

  þ   Microsoft Windows 3

  þ   Microsoft Windows Software Development Kit 3

  þ   Microsoft C Professional Development System (aka Microsoft C 6)

If you haven't yet installed Microsoft C 6, you should know that the
programs in the book require only the small-model MS-DOS libraries using the
math emulator. You may be able to use a C compiler other than Microsoft's if
the compiler is suitable for compiling Windows programs. Most other C
compilers can't be used for this purpose.

To run Windows and the Windows Software Development Kit, you need the
following hardware:

  þ   An IBM personal computer (or compatible) based on the Intel 80286 or
      80386 microprocessor with a hard disk and 640 KB of memory running
      MS-DOS 3.1 or later. An 80386-based machine with a couple megabytes of
      extended memory is ideal.

  þ   A graphics display and video board, preferably compatible with the IBM
      VGA (Video Graphics Array) or better.

  þ   A mouse. Although a mouse is generally optional for most Windows
      programs, some of the programs in this book require one.

Sometimes readers of computer books are curious about the author's own
system. When I was writing the first edition of PROGRAMMING WINDOWS, I used
an IBM PC/AT Model 339 (8 MHz) with two 30-megabyte (MB) hard disks, 512 KB
of memory on the system board, and a 1.5 MB Intel Above Board PS/AT. The
system included a Microsoft mouse, an IBM 256-KB Enhanced Graphics Adapter
(EGA), and a NEC MultiSync monitor. I wrote the book using WordStar 3.3 and
printed everything on an IBM 5152 Graphics Printer.

For the second edition, I used a 20-MHz IBM PS/2 Model 70 with a 120-MB hard
disk, 6 MB of memory, an IBM 8514/A graphics board (although I generally ran
Windows in VGA mode), a NEC MultiSync 4D monitor, and a Microsoft mouse. I
used Microsoft Word for revising the book chapters, printing on a NEC
SilentWriter LC-890 PostScript printer. (Word for Windows was not available
until I was well into the revision.)

PA book such as this could not have come about without help and
encouragement from some very special people. I offer my heartfelt thanks
with a handshake or hug (as appropriate) to the following people:

  þ   To everyone at Microsoft involved in Windows 3, for creating a system
      with fascinating depth and seemingly endless things to learn.

  þ   To all the Windows 3 developers who reviewed my chapters and offered
      comments and suggestions: Clark Cyr, David D'Souza, and particularly
      David Weise.

  þ   To the MS Online System Support people in the Windows SDK group who
      reviewed galleys of the entire book: Much gratitude to Todd Cole, who
      volunteered his group and coordinated the effort; special thanks to
      John Hagerson, Mike Thurlkill, Dennis Crain, David Long, Ed Mills,
      Steve Molstad, Richard Herrmann, Dan Boone, and Kyle J. Sparks; thanks
      also to Jeff Stone, Dan Quigley, Steve Thompson, Larry Israel, Teresa
      Posakony, Neil Sandlin, Curt Palmer, David Flenniken, Charles E.
      Kindel Jr., and Doug Laundry.

  þ   To everyone at Microsoft Press who has been involved in the first and
      second editions of PROGRAMMING WINDOWS, for behind-the-scenes work
      that makes all the difference in the world.

  þ   To my friends and editors at PC Magazine and Microsoft Systems Journal
      for their help and encouragement over the years.

  þ   To the readers of the first edition of PROGRAMMING WINDOWS who wanted
      to see a second edition. It's here and it's yours!

  þ   To my family, who thought I was crazy when I quit my job to write full
      time: to my Mom, my brother Steve and his wife Bernie and Christopher
      and Michelle, my sister Sue and her husband Rich and Erika and another
      one on the way. You're right. I was crazy.

  þ   To my friend Karen. Words cannot express....

  þ   To my friends at the "DH" (and especially Devon and Leslie) for
      enjoyable company and interesting conversation that has nothing
      whatsoever to do with computers. Completing this book gets me closer
      to writing that novel!

  þ   And most of all, as always, to Jan, who was as happy as I was when I
      called her and said, "I finally finished the chapter on DDE."

Charles Petzold      July 29, 1990