Programmer's Guide To The OS2 Presentation Manager
Programmer's Guide To The OS2 Presentation Manager
Note.. The following is a list of all OS |2 and Presentation Manager functions and messages discussed
in the book, organized according to the types of services they provide. Following the name of each
function or message is the number of the figure in the book that provides a full explanation.
• CLIPBOARD Menus
MANAGEMENT MM SETITEMTEXT
Winopenclipbrd MM SETITEMATTR
WinQueryclipbrdData WM INITMENU
WinsetclipbrdData
Scroll Bars
WinEmptyclipbrd
SBM SETSCROLLBAR
Wincloseclipbrd
SBM SETPOS
WM HSCROLL
WM VSCROLL
• COMMUNICATION
(AMONG THREADS)
Dossemset 12.6 . CURSOR
Dossemclear 12.7
MANAGEMENT
Dossemwait 12.8
Wincreatecursor
Winshowcursor
WinDestroycursor
CONTROL WINDOW
MANAGEMENT
General • DIALOGBOX
WM COMRAND MANAGEMENT
WM CONTROL WinDlgBox
WinDefDlgproc
Edit Fields
WinsendDlgltemMsg
- EM SETTEXTLIMIT 8.24
WinDismissDlg
List Boxes WM INITDLG
LM INSERTITEM
LM_QUERYSELECTION
LM_QUERYITEMTEXT
LM DELETEALL
• DISPLAYOFDATA WinMessageBox
WinAlarm
Erasing
WinFillRect
GpiErase
• INFORMATION
WM ERASEBACKGROUND
Winquerysysvalue 11.1
Font Management
GpicreateLogFont
GpiLoadFonts
• INITIALIZATION /
GpiQueryFonts
Gpisetcharset TERMINATION
Winlnitialize
Graphics WincreateMsgQueue
GpiMOve WinRegisterclass
GpiLine WinDestroyMsgqueue
WinDrawBitmap WinTerminate
WinDrawpointer WM CREATE
WM INITDLG
Miscellanous
WM CLOSE
Winscrollwindow
WM_QUIT
Winupdatewindow
WM DESTROY
WM PAINT
Presentation Spaces
WinlnvalidateRect • KEYBOARD
WinBeginpaint MANAGEMENT
WinEndpaint WinGetKeystate
WinGetps WinQueryFocus
WinReleaseps
WinsetFocus
Text Strings / Attributes WM CHAR
WM SETFOCUS
Gpisetcolor
GpisetBackcolor
GpisetBackMix
GpicharstringAt • MEMORY
WinDrawText MANAGEMENT
Winupper
Heap
WincreateHeap
WinLockHeap
• ERROR PROCHSSING WinAlocMem
WinGetLastError 3.11 WinFreeMem
WinDestroyHeap
.P rogrammer's Guide
to the OS/2
Presentation Manager
.P rogranmer'S Guide
to the os/rM
Presentation Manager
Michael J. Young
£EN®
Sam Francisco . Paris . Dtisseldorf . London
Cover design by Thomas Ingans + Associates
Cover photography by David Bishop
Book design by Ingrid Owen
Illustrations by Jeffrey James Giese
Every effort has been made to supply complete and accurate information. However, SYBEX assumes
no responsibility for its use, nor for any infringements of patents or other rights of third parties which
would result.
Copyright©1989 SYBEX inc., 2021 Challenger Drive # 100, Alameda, CA 94501. World rights reserved.
No part of this publication may be stored in a retrieval system, transmitted, or reproduced in any way,
including but not limited to photocopy, photograph, magnetic or other record, without prior agree-
ment and written permission of the publisher.
Writing this book for SYBEX was, as always, an enjoyable and reward-
ing experience. Both Rudolph Langer, editor-in{hief, and Dianne King,
acquisitions editor, were receptive to my ideas and supportive of my
needs as I developed the book. Tanya Kucak, editor, deserves special
thanks for editing the entire manuscript and greatly enhancing the con-
sisteney of the style. I also enjoyed working with Robert Campbell,
technical editor, who caught more than one subtle bug in the example
programs. Byron Dazey, of Microsoft Corporation, was of immense
help during the final stages of preparing the manuscript; his technical
review enhanced the accuracy of the text and helped ensure that the ex-
ample programs would run successfully under the final release of the
system. I would also like to thank the other people at SYBEX who con-
tributed to this project: Ingrid Owen, design and layout; Jocelyn
Reynolds and Bob Myren, word processing; Sonja Schenk, screen
reproductions; Charles Cowens, desktop publishing; and Jeffrey James
Giese, illustrations. Finally, the developers at Microsoft and IBM
deserve much credit for creating the impressive system that is the sub-
ject of this book.
ontents At a Glance
.C
Introduction xvii
Bivliograpky 674
Index FJJ17
.T able of Contents
Introduction
hapter one
Orientation
OS/2Features 3
ScreenGroups 3
Multitasking and Interprocess communication 6
Virtual Memory 7
Dynamic Linking 11
Presentation Manager Features 18
The user Interface shell 18
Types of Programs Managed by the Presentation
Manager 21
The presentation Manager API 24 I
Conclusion 25
hapter two
Creating a Window 26
Becoming a presentation Manager Application 27
Step 1: Initialize the presentation Manager 28
Step 2: Create a Message Queue 33
Step 3: Registera window class 34
Step4: Createawindow 38
Step 5: Get and Dispatch Messages 49
Step 6: Release presentation Manager Resources 57
Processing Messages 58
•xii
hapter three
Managing Memory 80
Managing the Heap 83
Handling Errors 101
Displaying Text 113
The wM_SIZE Message 123
The wM_PAINT Message 124
Enhancements 133
Conclusion 135
Chapter four
Using Scroll Bars 146
Creating the scroll Bars 147
The wM_CREATE Message 151
The wM_SIZE Message 155
Processing the scroll Bar Messages 163
The wM_HSCROLL Message 163
The wM_VSCROLL Message 174
Rerouting Keyboard Input 179
Updating the window 180
Enhancements 184
Conclusion 185
Chapter five
Controlling the Cursor 198
Creating the cursor 200
xiii .
hapter six
Adding a Keyboard Interface 226
The wM_CHAR Message 227
Thescancode 231
The charactercode 231
The virtual-Key code 231
TheRepeatcount 232
The Keyboard control Flags 235
The character Keys 236
Normal character Keys 241
TheTabKey 248
TheEnterKey 249
The Backspace Key 252
ThevirfualKeys 259
TheF9Key 260
TheDelKey 262
ThelnsKey 262
Editing aNewFile 264
Enhancements 265
Inline Display code 266
Eliminating Trailing Blanks 267
Converting Tab characters 268
Conclusion 268
•xiv
hapter seven
Using Menus and Accelerators 300
Creating Menus and Accelerators 301
Managing Menus and Accelerators 311
The wM_INITMENU Message 311
The wM_COMMAND Message 318
The wM_HELP Message 320
TheMenu commands 322
TheNewcommand 322
The save command 330
The Exitcommand 333
The Insert/Overwrite Mode command 333
Enhancements 334
Conclusion 335
hapter eight
Designing Dialog Boxes 336
Creating a Dialog Box 337
Using the Dialog Box Editor 338
The program Dialog Boxes 343
Displaying a Dialog Box 354
Managing a Dialog Box 356
Thecommands 359
TheAboutcommand 360
The Find and Find Next commands 362
TheGotoLinecommand 372
ThesaveAscominand 375
The open command 380
Conclusion 396
XV®
hapter nine
Interfacing with the Clipboard 460
hapter ten
Creating Icons, Bitmaps, and Other Resources 490
Strings 526
Programmer-Defined Resource Types 529
hapter eleven
Adding a Mouse Interface 534
Finding the Mouse pointer Location 535
Setting the Mouse pointer shape 547
Reading the Mouse Buttons 562
Creating a Mouse Interface 577
Mousecommands 578
hapter twelve
Exploiting Multitasking and Inteaprocess Communication 582
Using a second Thread 584
Starting the Thread 585
Writing a Function for a New Thread 590
Communicating between Threads 594
Using semaphores and Global variables 594
Using Messages 606
AIPpendi a
Glossary 610
Hppendib
Selected Presentation Manager Functions 630
PIPpenditc
Selected Presentation Manager Messages
Bibliography
Index
xvii .
.I ntroduction
The Presentation Manager is the windowed graphics interface
provided with the OS/2 operating system, beginning with version 1.1.
Although implemented as an extension to the basic operating system,
the Presentation Manager is central to the purpose of OS/2. OS/2 was
designed to run multiple programs, to allow communication among
these programs, and to provide efficient interaction with the user. The
Presentation Manager uses the basic facilities of OS/2 to run multiple
applications within windows on a single screen, to exchange data
among these applications, and to coordinate their input and output
operations. The Presentation Manager thus realizes the fundamental
design goals of OS/2; it fully exploits the basic operating-system
capabilities and makes these features immediately available to the
programmer and to the user. The designers of OS/2 consider the
Presentation Manager to be the OS/2 programming environment of
choice.
Writing an application for the Presentation Manager offers many ad-
vantages. First, the Presentation Manager uses a graphics display
mode, which can display a higher density of information than a stand-
ard text mode. The Presentation Manager is an ideal environment for
graphics programs, or for programs that display a combination of
graphics and text. Even applications that are primarily textual can
benefit from running in a graphics environment. These programs can
display text in a variety of fonts to produce a screen image that closely
resembles the final printed copy; also, a graphics display mode enables
the Presentation Manager to create the detailed icons and window ele-
ments that auow the user to control the program.
Another important advantage of the Presentation Manager is that the
graphics interface is #7i!/or77t from one apphcation to another. The Presen-
tation Manager provides a standard set of menus, dialog boxes, icons, and
other components of the user interface. Applications that use these stand-
ardfachitieshaveafamiliarappearanceandareeasytolean.Theinterface
is uniform not ordy among Presentation Manager applications, but also
among apphcations written for similar environments, such as Microsoft
Windows for MS-DOS. Additionally, by using these high-level fachities in
• xviii
your programs, you can avoid the significant programming effort re-
quired to develop your own user interface.
The Presentation Manager also provides uniform channels for com-
munication and exchange of data among separate programs. Accord-
ingly, applications written for this environment can easily coordinate
their activities and exchange data in order to form integrated software
Systems.
Finally, under the Presentation Manager you can write programs that
are dcz„.cc-z.77dcpc71dc7if (provided you follow the simple rules empha-
sized in this book). For example, you can write a Presentation Manager
application that will continue to run without modification as higher-
resolution video devices are developed in the future (assuming only
that the vendors of such devices supply the required device drivers for
the Presentation Manager).
Note also that the Presentation Manager forms an integral part of
OS/2. Unlike Microsoft Windows, the Presentation Manager is in-
cluded with every copy of the operating system ®eginning with ver-
sion 1.1), and automatically appears when the system is started.
Accordingly, Presentation Manager applications, which integrate
smoothly with this default environment, should be in great demand.
Unfortunately, however, developing an application for the Presenta-
tion Manager is not a trivial task for the programmer accustomed to
traditional programming environments. There are two basic reasons for
the initial difficulty in writing a Presentation Manager program. First,
as you will see in this book, the basic architecture of a Presentation
Manager application is radically different from that of a traditional pro-
gram. Second, the Presentation Manager is designed to provide a
sophisticated interface for a wide variety of graphics and text mode
programs. Accordingly, the number of function calls it provides is vast,
and many of these function calls accept a large and complex set of
parameters and options. As you develop Presentation Manager applica-
tions, you will likely come to appreciate the variety and subtlety of con-
trol afforded by the Presentation Manager application program
interface. Initially, however, the complexity can form an obstacle to
learning and using the system.
This book is written to help you overcome both of these difficulties.
First, Part I of the book gently introduces you to the basic program ar-
chitecture by tracing the development of a typical Presentation
xix.
BACKGROUND
• AND REQUIREDTOOLS
Given the ambitious scope of the book, there is little opportunity
to explain programming basics. To understand the coding techniques
and the example program listings, you should have a basic familiarity
with the C language (the Bibliography recommends several books that
will help you improve your C programming skills). Fortunately, the
book uses no assembly language.
Because all Presentation Manager applications run in the protected
mode of OS/2, it would also help to have an understanding of the basic
architecture of the Intel 80286 processor and the features of the OS/2
operating-system kernel. The first chapter briefly summarizes the un-
derlying facilities of OS/2; for additional information, see the
Progr¢777777cr's G#z.dc fo OS/2 or one of the other books on OS/2 kernel
programming cited in the Bibliography.
Programmers who have written applications for Microsoft Windows
will find many features of the Presentation Manager quite familiar.
•XX
• OVERVIEWOFTHE BOOK
This book is divided into two parts. Part I describes the essential
elements of a Presentation Manager application and provides the step-
by-step techniques for writing a basic program. Part 11 explores a set of
more advanced topics.
Part I consists of Chapters 1, through 8. Chapter 1 summarizes the
underlying facilities of OS/2 and the general features of the Presenta-
tion Manager; the purpose of this chapter is to provide an overview of
the context in which Presentation Manager applications run. The
remaining chapters in Part I describe the specific techniques for
developing a basic Presentation Manager application. These chapters
are based upon a single example program: a Presentation Manager text
editor.
Chapter 2 describes how to write the basic program skeleton, which
displays a window on the screen and writes a single line of text to this
window. Although this program performs only a rudimentary set of
tasks, it contains most of the essential elements of a Presentation
Manager application.
Chapter 3 then shows how to use the Presentation Manager memory-
management functions to provide a buffer for storing the file data man-
aged by the text editor. This chapter also describes how to display
multiple lines of text within the window, how to handle errors that occur
when calling Presentation Manager functions, and how to use the
xxi.
you how to use the clipboard to implement cut, copy, and paste com-
mands within the text editor presented in Part I.
Chapter 10 covers the techniques for defining and using several
types of Presentation Manager resources, including icons, pointers, bit-
maps, strings, and programmer-defined resource types. By using
resources, you can define graphic or textual data, store the data within
special segments in the program file, and then load and use the data
when required at run-time.
Chapter 11 explains how to add a mouse interface to your applica-
tion. Specifically, it shows how to read the position of the mouse
pointer, how to control the shape of the pointer, and how to detect the
state of the mouse buttons. The examples in this chapter also
demonstrate several of the Presentation Manager graphics functions.
Finally, Chapter 12 shows you how to improve the efficiency and
responsiveness of your Presentation Manager applications by using
multiple threads of execution. This chapter also explores the methods
for smoothly synchronizing the activities of separate program threads.
As an example, the chapter shows you how to implement a print
routine as a secondary thread within the text editor presented in Part I.
The appendices provide reference material that will be useful both
while you read the book, and when you begin developing Presentation
Manager applications. Appendix A contains a glossary that defines
many of the terms you will encounter while working with OS/2 and the
Presentation Manager. Appendix 8 briefly summarizes each of the
operating-system services discussed in the text, and Appendix C
provides the same information for the predefined Presentation
Manager messages. The Bibliography lists books that are useful for ob-
taining background information or for exploring specific topics in
greater depth. Finally, the inside covers of the book provide a list of the
system functions and messages discussed in the text, organized accord-
ing to the types of services they perform.
• HOWTOUSETHEBOOK
Although the book contains a large amount of reference material,
it is primarily tutorial. Ideally, you should start by reading all of the
xxiii .
chapters in Part I in order; each of these chapters builds upon the con-
cepts presented in the previous chapter. If desired, you can then read
selected chapters in Part 11. Each of these chapters relies upon the
material of Part I, but does not necessarily depend upon the previous
chapter.
Note that each chapter has a primary topic indicated by its title, but
also presents many subsidiary topics. In general, topics are explored as
they are first encountered in the development of the example programs.
Accordingly, the discussions in this book are presented in approximate-
ly the same order in which you would normally encounter them when
developing a Presentation Manager application.
The book contains basic reference information covering a large set of
the Presentation Manager functions and predefined messages. Once
you have read the book, you will find this reference material useful for
developing your own applications. Each of the functions or messages
discussed in the text is described in an accompanying figure. You can
locate the appropriate figure in one of two ways. First, if you are search-
ing for a suitable function or message, you will find each of them listed
on one of the inside covers of the book according to the type of service
it provides, including a reference to the corresponding figure. Second, if
you already know the name of the desired function or message, you can
find a brief description and a figure reference in Appendix 8 (the func-
tions) or Appendix C (the messages).
The Presentation Manager documentation contains a large number
off newly coined words and expressions, as well as common terms that
have specific, nonconventional meanings. If a term is unfamiliar, or if
you are uncertain of its meaning in a specific context, be sure to look it
up in the glossary (Appendix A).
Although the book does not supply formal programming exercises,
many of the chapters have a section near the end that describes possible
enhancements to the example code presented in that chapter; you can in-
plement selected enhancements as exercises in Presentation Manager
programming. Also, the chapters in Part 11 describe the general procedures
for adding features to the example program given in Part I; you can imple-
ment these procedures as additional programming exercises. Finauy, the
book may inspire you to explore advanced Presentation Manager features
that could not be included, and to add these features to the example
programs or to use them in developing your own apphcations.
• xxiv
BASIC:
FEAT`urREs
ost of this book is devoted to detailed, step-by-step pro-
cedures for developing OS/2 Presentation Manager ap-
• OS/2FEATURES
As mentioned in the Introduction, the Presentation Manager is an
operating-system cxfc77s€.o71. It is implemented through the basic
facilities of the OS/2 kernel that support all types of OS/2 programs.
This section describes these basic features and explains how they relate
to the Presentation Manager and the applications written for it. For an
in-depth treatment of the OS/2 kernel and application program inter-
face, refer to the Progr¢777777cr's G#z.dc fo OS/2 or one of the other books on
OS/2 kernel programming cited in the Bibliography.
Screen Groups
One of the primary features of OS/2 that distinguishes it from
MS-DOS is the existence of multiple sc7'cc71 971o#z7s (also known as scs-
sz.o77s). Each screen group consists of one or more programs that share
the screen, keyboard, and mouse. You can run as many as 14 simul-
taneous screen groups, but you can view and interact with only one of
them at a time (which is known as the /oregro%71d screen group). The
screen groups relegated to the background continue to run concurrently
(except for the real mode screen group, described later in this section).
• 4 Programmer's Guide to the os/2PresentationManager
Protected Mode
Screen Group
(OS/2 Kernel APplication) A|t-Esc
Alt-Esc/
\s`w:::hEsi \ Pressecnrtea:I:nGyo:npager
Ctrl-EscSwitch PM User PM AppInterfaceKernelAppShellpMApp
Peal Mode Screen Group(MS-DOSApplication)
Ctrl-Esc -grjrswitch
\Alt-Esc /Alt-Esc
Protected Mode
Screen Group
(OS/2 Kernel Application)
• Figure 1.1..
OS|2 screen groups
Multitasking
and Interprocess Communication
OS/2 supports multitasking at three distinct levels. Running mul-
tiple concurrent screen groups, discussed in the previous section, repre-
sents the highest level. As the next level of multitasking, OS/2 provides
facilities for executing several programs simultaneously within a single
protected mode screen group. The Presentation Manager uses these
facilities to run multiple applications within windows on the screen.
Also, a given Presentation Manager application can execute other
programs as concurrent child processes. For example, the text editor
presented in this book could execute a compiler as a child process and
continue providing editing functions while the compiler runs. See
Chapter 12 for more information on managing multiple processes.
The lowest level of multitasking under OS/2 is its support for multi-
ple threads of execution within a single program. It is possible to ex-
ecute several sections of the same program simultaneously. Using
Orientation 7 .
Virtual Memory
Under the real mode of Intel processors, a memory address con-
sists of a 16-bit physical segment address and a 16-bit offset within that
segment. In the protected mode, however, the physical segment ad-
dress is replaced with a 16-bit scJccfo7`. The selector is not a physical
address, but rather is an index into a table in memory known as a
dcscrz.pfor £¢Z7Jc; the index points to an entry in this table termed a scg-
77zc7tf dcscr{.pfor. The segment descriptor contains the actual physical
memory address of the segment, as well as other information regarding
the segment. Note that under OS/2, memory segments have variable
lengths, with a maximum length of 64 kilobytes. See Figures 1.2 and 1.3
for a comparison of the addressing mechanisms used in real and
protected modes.
The use of selectors and segment descriptors in the protected mode of-
fers many advantages. First, the operating system can allocate memory
to application programs in excess of the amount of physical memory in-
stalled in the machine. Segments that do not fit into physical memory
can be temporarily stored on disk; the segment descriptor contains a bit
indicating whether the segment is currently present in memory or has
been swapped to the disk. This larger-than-life address space is known
as virtual memory. Virtual memory not only allows protected mode ap-
plications to contain considerably more code and data than would be
possible under the real mode, but also simplifies programming. A pro-
gram directly accesses all segments that have been allocated to it as if
they were entirely present in memory; the processor and operating sys-
tem invisibly handle all the details of swapping and rearranging mem-
ory segments.
For example, an application such as the text editor developed in this
book can read an entire large file directly into memory; if the file size
• 8 Programmer's Guide to the os/2 PresentationManager
exceeds the amount of free memory, the operating system will automat-
ically store the excess data on disk and retrieve it when the program a`d-
dresses it. A similar application under MS-DOS would typically have to
read only a portion of the file at a time, and explicitly maintain a set of
temporary disk files to store modified data.
A second advantage of the virtual memory addressing scheme is that
it allows the system to differentiate code and data segments (the seg-
ment descriptor contains a bit indicating whether the associated
segment is executable). The operating system does not normally allow a
program to modify a code segment; since a program cannot corrupt its
own code, several instances of the same program that are loaded into
memory can safely sfe¢re the same code segment, resulting in an efficient
use of memory. (In contrast, data segments either can be private for each
instance of a program, or can be shared by several instances.)
• Figure 1.2..
The real mode addressing scheme
Orientation 9 .
• Figure 1.3..
The protected mode addressing scheme
• 10 Programmer's Guide to the os/2 PresentationManager
memory for the program's code and data segments at load-time; once
the program begins running, you can dynamically allocate and release
adlditional segments by calling the appropriate Presentation Manager
or OS/2 services. Chapter 3 explains how to use Presentation Manager
functions to allocate and manage dynamic memory.
Dynamic Linking
In addition to the standard linking mechanism used by MS-DOS,
OS/2 supports a radically new process known as dy71¢77zz.c Jz.77kt.77g.
Under the standard linking method, the linker must bind the target
code for all call instructions directly into the executable file. Figure 1.4
illustrates the standard linking procedure for an MS-DOS or OS/2 pro-
gram that calls routines belonging to a conventional function library.
The linker physically combines the program object code (contained in
an .OBJ file) with the object code for any library modules that are called
(contained in .LIB files), producing a sz.7tgJc executable file on the disk.
When the program is run, this entire file is loaded into memory,
generating a single executable image containing both program and
function library code.
In contrast, Figure 1.5 illustrates the dynamic linking procedure for
an OS/2 protected mode application that calls external functions
belonging to a dy7t¢77#'cJz.77k Jz.Z7r¢7ry. The primary distinguishing feature
of the dynamic linking mechanism is that the external function code is
77of bound into the executable (.EXE) file, but rather is stored in a
dynamic-link library file (with a .DLL extension), which is kept on the
user's disk and is read into memory when the program is loaded. In
other words, binding of code is delayed from link-time to load-time.
In the same manner as the standard linking mechanism, the linker
processes both an object file (.OBJ) and a library file (.LIB). Although the
library file used for dynamic linking is given the usual .LIB extension, it
is a special file known as an z'77zporf Jz.I"#7t/. An import library does 71o£
contain the actual function code; rather, for each dynamic-link function,
it contains a dc/z.7iz.£z.o# record that gives the name of the dynamic-link
library file that contains the function, and the entry point of the func-
tion within this library. This information is stored in the .EXE ffle header
in rcJocofz.o7i records that are used when the program is loaded. Thus, ex-
ternal function references are resolved not by binding in actual code,
• 12 Programmer's Guide to the os/2Presentation Manager
but by writing a record for each function that tells the loader how to
resolve the references to the function when the program is run.
When the program is run, the loader first reads the program code
into memory; it then loads all referenced dynamic-link library files that
• Figure 1.4..
The standard linking mechanism
Orientation 13 .
have not already been loaded. Finally, it ``fixes up" all references within
the program code to dynamic-link functions by supplying the actual far
address (that is, selector and offset) of the function in memory. Thus,
calls to dynamic-link functions become direct intersegment calls to the
entry points of the functions in memory.
An important feature of dynamic-link libraries not indicated in Fig-
ure 1.5 is that several concurrent applications can sfe¢7ie a single
• Figure 1.5..
The dynamic linking mechanism
• 14 Programmer's Guide to the os/2 Presentation Manager
The code for the OS/2 API services is contained in a variety of dynamic-
link libraries, such as DOSCALL1.DLL and VIOCALLS.DLL.
A second reason for the importance of the dynamic linking
mechanism is that the Presentation Manager itself is implemented as a
collection of dynamic-link modules. A Presentation Manager applica-
tion is one that calls dynamic-link functions belonging to the Presenta-
tion Manager API. As you begin developing a Presentation Manager
application, you will notice that although the program calls a large
number of Presentation Manager functions, the .EXE file remains quite
small. The small size is due to the fact that the executable file does 77of
contain the actual Presentation Manager function code, but only
dynamic-link records in the .EXE header. The actual function code is
stored in dynamic-link libraries with names such as PMWIN.DLL on
your disk and on the disk of the ultimate user of the program. When the
first Presentation Manager application is run (normally the User Inter-
face Shell), the loading process is quite lengthy, since a great amount of
dynamic-link code must be loaded and initialized. Subsequent Presen-
tation Manager applications, however, load quickly and use the
dynamic-link code already present in memory.
Note that although the Presentation Manager is an extension added
to the original version of OS/2, the protocol for calling its functions is
identical to that of the basic OS/2 API. Such seamless extensions to the
operating system are made possible through the dynamic linking
mechanism. A final reason for the importance of dynamic linking is that
any software developer can provide custom extensions to the operating
system (or to the Presentation Manager in particular) by writing a set of
• 16 Programmer's Guide to the os/2 Presentation Manager
The OS/2
Application Program Interface
As mentioned in the previous section, the services of the OS/2 ap-
plication program interface (API) are implemented as dynamic-link
libraries and can be called directly by OS/2 kcr7icJ progr#77ts (that is, non-
Presentation Manager applications); many of these functions can also
be called by Presentation Manager applications. The OS/2 API func-
tions fall into four basic categories; the first three letters of the function
name indicate the general category of the function. For example, Vio-
Wrtcharstr belongs to the set of video functions. The following are the
four groups of OS/2 API functions:
PRESENTATION
• MANAGERFEATURES
This section provides a brief overview of some of the general fea-
tures of the Presentation Manager to help you gain an understanding
of the context in which Presentation Manager applications run. Most of
the features of the Presentation Manager are explored in subsequent
chapters when they are first encountered while developing the example
application that forms the heart of the book. This section covers the fol-
lowing introductory topics:
• TheTaskManagerwindow
• Theprogramstarterwindow
• The presentation Manager control panel
• The presentation Manager Filing system
Task Manager allows you to shut down the system in preparation for
turning off the machine; this procedure automatically terminates all
running programs.
Note that the Task Manager handles not only applications running
within Presentation Manager windows, but also kernel programs in
other screen groups. If you have con figured the system to include the
DOS compatibility box, the DOS command prompt appears in the list
of running programs; you can switch to this screen group and run MS-
DOS applications from the command prompt.
applications. The following are among the operations you can perform
using this utility:
• Setthesystemdateandtime
• Adjusttheblinkrateof thecursor
• Modifythebehaviorof themouse
• Select window colors and border style
• Specify country-specific information
• Manage the printer, serial port, and other devices
• Add new character fonts
Types of Programs
Managed by the Presentation Manager
As mentioned in the previous section, the Presentation Manager
User Interface Shell allows you to run or switch to any program in the
• 22 Programmer's Guide to the os/2 Presentation Manager
MS-DOS Applications
MS-DOS applications can be run only if you have installed the real
mode screen group (using the PROTECTONLY=NO configuration
command). You can start these applications by selecting the DOS com-
mand prompt from the Task Manager and running the programs from
the command line. MS-DOS programs are suspended when you switch
away from the real mode screen group.
Kernel Applications
That Cannot Run in a Window
Kcr71cJ applications are those that use the basic OS/2 API services.
These are applications that have 77of been written specifically for the
Presentation Manager and therefore do 7tof call Presentation Manager
API functions. Many kernel applications can run within a window in
the Presentation Manager screen group; the programs in this category,
however, ccz7t7tof run within a window because they perform some ac-
tion that is incompatible with the Presentation Manager environment.
The following are among the actions that would render a kernel pro-
gram incompatible with the Presentation Manager:
these programs can use many of the Dos functions of the OS/2 API, but
should not call KZ7d or Mot/ services, and only applications that make
proper use of the advanced Vc.o Presentation Manager functions (men-
tioned in the next section) may call OS/2 Vz.o services.
Comments
The text editor developed in this book is, of course, a Presentation
Manager application as defined in this section. Note that applications in
the last three categories (the protected mode programs) should have a
flag in their .EXE file headers indicating to which of these three
categories they belong. This flag enables the Presentation Manager to
handle these programs correctly when they are loaded. The flag, how-
ever, may be absent from protected mode applications prepared with
earlier versions of the linker; such unmarked kernel programs cannot
run within a window (unless they are run through the Program Starter
window and you have explicitly changed the installation information
to indicate that the program can be run in a window). Microsoft, how-
ever, provides a utility (MARKEXE.EXE) that enables you to correctly
mark the .EXE header for these programs.
• CONCLUSION
This chapter has provided a brief overview of the context in which
Presentation Manager applications run. It has summarized the general
features of the OS/2 kernel and the Presentation Manager user inter-
face. It has also introduced the Presentation Manager programming in-
tei.face, which will be described in subsequent chapters. The remaining
chapters in this book explore the specifics of creating a Presentation
Manager application.
2:J.
.I
his chapter presents the rudiments of the Presentation
Manager text editor that win slowly evolve, chapter by
chapter, into a complete and useful application. The ver-
sion given here simply displays a window on the screen
and prints a line of text at the top of the window. You win see, however,
that coustmcting even a minimal Presentation Manager application re-
quires writing several procedures and calling quite a number of functions.
This program contains most of the essential elements of a Presenta-
tion Manager application and provides a basic framework for sub-
sequent versions. Even though it seems that the Presentation Manager
exacts a large overhead merely to place a window on the screen, this
window is not a simple inert object. A window cannot be placed on the
screen with other programs unless it has a basic set of capabilities. The
staindard window created in this chapter has components that allow
you to move it on the screen, change its size, minimize or maximize it,
and terminate the program. You can perform these actions either
through a menu or by acting on a set of graphic objects with the mouse.
Furthermore, the window must be able to repaint itself whenever any
of its data are destroyed as the user moves and manipulates the objects
on the screen.
In this chapter, you will learn how an ordinary C program becomes a
Presentation Manager application; you will learn the message-based ar-
chitecture of Presentation Manager programs; and you will learn how
to display data within a window. You will also become familiar with
several important services of the Presentation Manager API, and two
Presentation Manager messages.
BECOMING A PRESENTATION
• MANAGER APPLICATION
When you write a Presentation Manager application in the C lan-
guage, you must include the header file OS2.H, which provides a large
number of vital function declarations, type definitions, and constant
definitions for both the basic OS/2 API and for the Presentation
Manager API. Also furnished is a collection of macros useful for
manipulating the data used by Presentation Manager functions and
• 28 Programmer's Guide to the os/2 PresentationManager
Step 1: Initialize
the Presentation Manager
A Presentation Manager application must first call the function
Winlnitialize to initialize the Presentation Manager system for the cur-
rent program and to obtain an ¢7icfeor bzock fe¢7idJc. The anchor block
handle is a value that identifies the application to the Presentation
Creatingawindow 29 .
void main ()
(
HAB HAncBlk; /* Anchor block handle.
HMQ HMesQue; /* Message queue handle.
HWND HFrame, Hclient; /* Frame/client window handles.
QMSG QueMess; /* Message queue structure.
ULONG CtlData = /* Control windows to include.
FCF MINRAX /* Minimize/maximize box.
FCF-SHELLPOSITION /* Make window visible on screen.
FCF-SIZEBORDER /* Wide sizing border.
FCF-SYSMENU /* System menu.
F'CF-TASKLIST /* Display program name in Task Manager.
FCF-TITLEBAR; /* Title bar.
/*** Initialize the Presentation Manager and obtain an anchor block handle. **/
HAncBlk = Winlnitialize /* Returns an anchor block handle. */
(0); /* Initialization options: must be 0. */
/*** Create a message queue for the current thread. **************************/
HMesQue = WincreateMsgQueue /* Returns a message queue handle. */
(HAncBlk, /* Anchor block handle. */
0); /* Minimum queue size: 0 means default size.*/
• Figure 2.1..
The function "aiin of the exanple program
• 30 Programmer's Guide to the os/2 Presentation Manager
• Figure 2.1..
The function rr\a;in of the example program (continued)
Manager; you must save this number and pass it as the first parameter
to several other Presentation Manager functions.
Winlnitialize is described in Figure 2.2. As each new Presentation
Manager function is encountered in the discussions in this book, it is
described in an accompanying figure. Note that these descriptions focus
on the features relevant to the techniques presented in the book, and do
not always include all of the options available for a given function. For
complete details, and for documentation on functions not treated in the
book, consult the OS/2 programming reference cited in the Bibliog-
raphy. Note also that Appendix 8 provides an alphabetical summary of
the functions discussed in this book, and the inside book covers list these
functions according to the types of services they provide.
The function Winlnitialize is declared as follows within one of the
OS/2 header files that is incorporated in your program when you in-
clude OS2.H:
The special types HAB, APIENTRY, and USHORT are defined within
the OS/2 header files. HAB is a type identifier for an anchor block
handle; it resolves, through several layers of type definitions, to the
basic C type
void far *
Creatingawindow 31 .
Winlnitialize
Purpose..
Initializes the Presentation Manager system for use by the
current program.
Prototype..
IIAB APIENTRY Winlnitialize
(USHORT fsoptions ) ,. Initialization options; must be NULL.
Return Value ..
An anchor block handle.
Notes..
An application must call this function before it can use the
other services of the Presentation Manager. The anchor block
handle should be saved so that it can be passed to sub-
sequent Presentation Manager functions.
• Figure 2.2..
The Winlr\i+ialire Presentation Manager f unction
pascal far
The Presentation Manager API services (as well as all OS/2 API ser-
vices and dynamic-link library functions) are far functions, meaning
that they are located in a separate segment in memory and are called
through an address consisting of both a segment selector and an offset.
These functions are also of type pascal, which implies the following
conventions:
• Parameters are pushed on the stack in the s¢777c order that they
are listed in the parameter list (by default in C, they are pushed
in the opposz.fc order).
• 32 Programmer's Guide to the os/2 PresentationManager
The function must remove the parameters from the stack before
returning (the default in C is for the calling program to remove
all parameters from the stack).
Each function has a fixed number of parameters (this is a result
of the first two features; a default C function can accept a vari-
able number of parameters).
• The function name is converted to uppercase before being placed
in the object file toy default, Microsoft C preserves the case of
function names and places an underscore at the beginning of the
name).
unsigned int
Note that the function main in Figure 2.1 declares the variable HAnc-
Blk using the same type identifier, IIAB, that is used in the function
declaration in the OS/2 header files; this variable stores the anchor
block handle returned by Winlnitialize. It is generally easiest simply to
use the type definitions given in the function declarations and
documentation, without paying attention to the equivalent basic C
types. These definitions are used consistently throughout the header
files and the technical documentation, and within this book. They pro-
vide more information regarding the purpose of the object than the
simple C data types (for example, knowing that a variable is a handle to
an anchor block is more useful than knowing merely that it is a void far
pointer). Also, it is possible that the basic C types could cfe¢7igc if the
Presentation Manager were ported to another computer system (for ex-
ample, USHORT might be defined as an unsigned short); if you have
consistently used the OS/2 type definitions, your program types will
remain valid.
Note that to facilitate using this book in conjunction with the Presen-
tation Manager technical documentation, the function descriptions use
the s¢777c parameter names found in this documentation. These names
begin with a prefix in lowercase letters, which indicates the fypc of the
parameter (the data type, such as pch, which is a far pointer to a charac-
ter, or the general use of the parameter, such as f, which is a flag). Fol-
lowing the prefix is an optional identifier, which begins with an
Creatingawindow 33 .
uppercase letter and identifies the specific instance of the general type.
For example, the parameter pfnwndproc (passed to WinRegisterclass
and listed in Figure 2.4) is a pointer to a function (pfn) that is used
specifically to pass the address of the window procedure (Wndproc).
WincreateMsgQueue
Purpose..
Establishes a message queue that receives messages sent to
all windows created by the current thread.
Prototype..
HMQ APIENTRY WincreateMsgQueue
(RAE hab, Anchor block handle obtained by a prior call
to Winlnitialize.
SHORT cmsg) ,. Maximum size of the queue; a value of o
requests the default size.
Return Value ..
A message queue handle, or NULL if unsuccessful.
Notes..
You should call this function after Winlnitialize, but before
calling other Presentation Manager functions. A given
thread can call this function only once.
Related Function..
Winlnitialize (Figure 2.2)
• Figure 2.3..
The Wincreate:MsgQueue Presentation Manager function
• 34 Programmer's Guide to the os/2PresentationManager
and stores messages sent to all windows created by the current program
thread; an application must establish a message queue before it can cre-
ate a window. The program presented in this chapter consists of a single
thread and creates several windows. The system places messages sent
to any of these windows within the queue created by the call to Win-
CreateMsgQueue. As you will see shortly, the system sends messages
to a window to notify it of a wide variety of events; for example, it sends
a specific message when the window needs to redraw a portion of its
data. You will also soon learn how to process these messages. Note that
a value of 0 is passed as the second parameter, which causes the func-
tion to use the default queue size.
WincreateMsgQueue accepts the anchor block handle returned by
Winlnitialize and returns a message queue handle (of type HMQ,
stored in the variable HMesQue). The message queue handle is saved
so that it can later be passed to the function that destroys the message
queue before program termination (WinDestroyMsgQueue). Note that
WincreateMsgQueue, like many Presentation Manager functions,
returns a value of NULL if it is unsuccessful (NULL is defined as 0 in the
C include files STDDEF.H and STDIO.H). The topic of testing for error
return codes, and displaying error messages within message boxes, is
introduced in Chapter 3.
Note that in a multiple-thread application (discussed in Chapter 12),
every thread that creates one or more windows must call Wincreate-
MsgQueue to establish a message queue; furthermore, a given thread
can create only 071c message queue.
WinRegisterclass
Purpose..
Registers a window class.
Prototype..
BOOL APIENTRY WinRegisterclass
(HAB hab, Anchor block handle obtained
from Winlnitialize.
PSZ pszclassName , Pointer to a null-terminated
string containing the class
name to be associated with the
window procedure.
PFNWP pfnwndproc, Address of the window
procedure that is to be
associated with the class name.
ULONG flstyle, The default window style,
which can be one or more of
the class styles (CS_) listed in
Table 2.1; styles specified when
the window is created are
added to the default styles
specified with this parameter.
USHORT cbwindowData) ,. Bytes of storage that should be
reserved for each window
belonging to this class that is
created; this data can be
accessed by functions such as
Winsetwindowushort and
WinQuerywindowushort.
Return Value ..
TRUE if successful, and FALSE if an error occurs.
Related Functions ..
Wincreatestdwindow (Figure 2.5)
Wincreatewindow
• Figure 2.4..
The WinRegisterclass Presentation Manager function
• 36 Programmer'sGuidetotheos/2 Presentation Manager
Asyouwillsee,whenawindowiscreated,itisassignedtoawindow
class; using object-oriented terminology, the window is said to be an I.71-
sf¢7ice of this class. A window can be assigned to a prereg{.sfercd window
class provided by the Presentation Manager for various types of win-
dows; in this case, the system supplies the window procedure that
processes the messages sent to this window. System-supplied window
procedures are located in a Presentation Manager dynamic-link library
and perform minimal default processing in response to messages sent
to the window.
Although the system window procedures associated with pre-
registeredwindowclassesaresuitableformanytypesofwindows,you
should supply your own procedure for the cJ€.c71f ztJ2.#doztL The client
window, as you will see under step 4, is the primary window used for
displaying program data, which is a job that must be performed by
your own window procedure in response to the messages it receives.
Accordingly, you must write a window procedure (Wndproc in the ex-
ample program, listed in Figure 2.16) and call WinRegisterclass to
register a window class that is associated with this procedure (you pass
theaddressoftheprocedureasoneoftheparameters).Asyouwillsoon
see, when you subsequently create the client window, you can make it
an instance of this class; accordingly, all messages sent to this window
will cause your procedure to receive control.
Note that a given window class can have more than one instance; in
other words, several windows can be assigned to a single window class
whentheyarecreated.Consequently,awindowproceduremayhaveto
process messages for multiple windows (the identity of the target win-
dow is supplied as part of the message). However, the window class
created by the example program (which is associated with the window
procedure Wndproc) has only a single instance+the client window.
Atthispointintheprogram,nowindowshaveactuallybeencreated.
WinRegisterclass performs the following three primary functions in
preparation for creating a window:
the styles listed in Table 2.1. These styles are identified with con-
stants (defined in an OS/2 header file) that have the CS_ (class
style) prefix; if you want more than one style, you must combine
the identifiers with the bitwise OR operator ( I ). The example
program does not require any styles, and therefore passes a
value of 0. If, however, you select one or more styles, all win-
dows subsequently created with this class will automatically ac-
quire the chosen style (in ¢dd£.£1.o71 to any styles specified when
creating the window).
Wincreatestdwindow
Purpose..
Creates a standard window.
Prototype..
HWND APIENTRY Wincreatestdwindow
(HWND hwndparent, The handle of the parent window; the
value HWND DESKTOP indicates
that the parenTis the Presentation
Manager desktop, which results in a
main (top-level) window; the value
HWND OBJECT creates an object
window-(which has no parent).
ULONG flstyle, Frame window style; can be a
combination of the window styles
(WS_) hsted in Table 2.2 or the frame
styles (FS_) listed in Table 2.3.
PVOID pctlData, Pointer to a ULONG variable that has
been assigned a combination of
window control styles, which have the
FCF_ prefix and are listed in Table 2.4.
These styles specify the control
windows that should be included, and
are combined with the bitwise OR
operator.
pSz pszclientclass, Pointer to a string containing the class
name for the client window; this value
should either be the same as the class
name string that was passed to
WinRegisterclass, or the value
NULL; if the value is NULL, the
system will not create a client window.
PSZ pszTitle, Pointer to a string containing the text
to be displayed in the title bar; this
parameter is ignored if there is no title
bar (that is, FS TITLEBAR is not
specified in flstyle).
• Figure 2.5..
The Wincreatestdwindow Presentation Manager function
• 40 Programmer's Guidetothe os/2Presentation Manager
Return Value ..
The frame window handle or NULL if the function is
unsuccessful.
Relate d Function..
WinRegisterclass (Figure 2.4)
• Figure 2.5..
Tffe Wincreatestdwindow Presentation Manager f unction (continued)
Creatingawindow 41 .
another child window (known as its sz.Z7Jz.7ig), but a parent window can-
not overlap its child.
The first parameter passed to Wincreatestdwindow (hwndparent)
is the handle of the parent of the frame window. The example program
passes the value HWND_DESKTOP, which is the handle of the dcskfop
window, or the entire Presentation Manager screen. Since its parent is
the desktop window, the frame window can be placed anywhere on the
screen; such a window is known as a 77!¢!.7z or fopJcz7cJ window. Win-
Ci.eatestdwindow returns the handle of the frame window, which is
stored in the variable HFrame.
The second parameter (flstyle) specifies the style of the frame win-
dow. This parameter can be assigned any of the window styles (which
have the WS_ prefix) or frame styles (which have the FS_ prefix); these
styles are combined with the bitwise OR operator (I ). The win-
dow styles apply to windows in general and are described in Table 2.2.
The frame styles apply specifically to frame windows and are described
in Table 2.3.
The example program specifies a single window style, WS_VISIBLE,
which causes the frame window and all its children to be immediately
visible. When you specify WS_VISIBLE, the frame window is given an
initial size and position on the screen that is assigned by the Presentation
Manager shell. If you do not select the WS_VISIBLE style, the frame win-
dow and its children are initially invisible. In this case, you can sub-
sequently render these windows visible by calling Winshowwindow.
The example program does not specify any of the frame styles (FS_)
in the second parameter. As you will see in later chapters, two of the
values that can be passed in this parameter (FS ACCELTABLE, ex-
plained in Chapter 7, and FS_ICON, explained in-Chapter 10) do not
directly affeet the frame style, but rather cause the system to load
specific resources when the window is created.
The third parameter (pctlData) supplies the address of a ULONG
variable that specifies the control windows that are to be included in the
standard window collection (such as a title bar or a system menu). This
variable can be assigned any of the styles listed in Table 2.4 (the con-
stants for these styles have the FCF_ prefix). Note that the FCF_ styles
include not only a set of control windows, but also all of the styles that
can be specified through the scco71d parameter. For example, you can
cause the system to load an icon cz.ffecr by assigning FS_ICON to the
• 42 Programmer's Guide to the os/2 PresentationManager
can open this window by clicking on the icon with the mouse, or
by pressing the Alt-Spacebar key combination.
FCF_TASKLIST, which lists the program within the Task
Manager window, allowing the user to switch to the window
or to terminate the program.
• FCF_TITLEBAR, which adds a title bar window at the top of the
frame window that displays the text specified by the fifth
parameter (pszTitle). This control window becomes highlighted
when the frame window is active, and can also be used to move
the window with the mouse (you can additionally move the win-
dow through the system menu).
As you will see in Chapter 7, you can call the function Winsetwindow
at any time to specify the exact text shown in the title bar.
Finally, the seventh and eighth parameters provide information
regarding the program rcsot/rccs that are used only if the standard win-
dow includes an accelerator table, an icon, or a menu (requested as con-
trofl window styles through the third parameter). Since none of these
frame styles is specified in this program, parameters seven and eight
are assigned a value of 0. Menus, accelerator tables, and resources in
general are discussed in Chapter 7. Chapter 10 describes icons and
other specific resources.
Figure 2.6 illustrates the appearance of the window created by the can
to Wincreatestdwindow. Each of the individual windows is labeled,
except for the frame window, which underlies the entire area and is not
visible. Figure 2.7 illustrates the parent-child relationships of these win-
dows. Note that even though the example program creates only a single
top-level window (the frame), other Presentation Manager applications
currently sharing the screen may also have created top-level windows;
in the diagram, each of these is labeled Other Top-Level Window.
• 48 Programmer's Guide to the os/2 PresentationManager
• Figure 2.6..
The basic components of the window created by the example program
DesktopWindow
I I
• Figure 2.7..
Genealogy of the windows created by `NincreaLtestd:Window
Creatingawindow 49 .
control over the windows it creates. Note also that a program can create
several top-level windows, each of which could subsequently create
one or more child windows.
WinGetMsg
Purpose..
Extracts the next message from the message queue belong-
ing to the current thread.
Prototype..
BcOL APIENTRY WinGetMsg
(RE hab' Anchor block handle.
PQMSG pqpsg, Pointer to a QMSG structure
that is to be assigned the
content of the message; see the
text for a description of this
structure.
HWND hwndFilter, The ``window filter''; if this
parameter contains a window
handle, only a message for that
window will be obtained; if it
is assigned NULL, the next
message for ¢77y window is
extracted.
USHORT msgFilterFirst , The ID of the first message of
the desired range of messages;
if this parameter and
msgFilterLast are both 0, then
there is no range constraint,
and the next message will be
extracted without regard to its
ID.
USHORT msgFilterLast) ,. The ID of the last message of
the desired range, or 0 if there
is no range constraint.
• Figure 2.8..
The WinGct:Mss Presentation Manager function
Creatingawindow 51 .
Return Value ..
TRUE, unless the message is WM_QUIT, Which causes the
function to return FALSE.
Notes..
This function waits, if necessary, until a message that satis-
fies the specified criteria (if any) is available. It extracts the
71cxf available message, unless the second parameter speci-
fies a particular window, or the third and fourth parameters
indicate a restricted range of message identifiers.
Related Function..
WinDispatchMsg (Figure 2.9)
. Figure 2.8..
The WinGct:Mss Presentation Manager function (continued)
the extracted message into the QMSG structure, the address of which is
paLssed as the second parameter. This structure is defined as follows:
WinDispatchMsg
Purpose..
Causes the system to call a window procedure.
Prototype..
ULONG APIENTRY WinDispatchMsg
(HAD hab, Anchor block handle.
PQMSG pqusg) ,. Pointer to a QMSG message queue structure;
information from this structure is passed to
the window procedure; see the text for a
description of this structure.
Return Value ..
The value returned by the window procedure that is called.
Notes®.
RelatedFunctions..
WinGetMsg (Figure 2.8)
WinsendMsg (Figure 4.8)
• Figure 2.9..
The WLnDispatchMs8 Presentation Manager function
Creatingawindow 53 .
Once the call to WinGetMsg has extracted a message from the queue,
the example program immediately gives this message back to the sys-
tem by calling WinDispatchMsg, passing the address of the structure
containing the message. WinGetMsg normally returns a value of
TRUE; if, however the extracted message has the identifier WM_QUIT,
then WinGetMsg returns FALSE, which causes termination of the mes-
sage loop. Thus, WM_QUIT is the only message that is not immediately
dispatched, but rather serves to end the program. In the example pro-
gram, the system places this message in the queue when the user selects
the Close option from the system menu. The WM_QUIT message is
described in Figure 2.10.
It might seem that by immediately calling WinDispatchMsg, the
program relinquishes its opportunity to act upon relevant messages;
WM_QUIT
Purpose:
This message is posted to the message queue to terminate
the application.
Parameters..
REARAM mpl Reserved; must be NULL.
rmARAM mp2 Reserved; must be NULL.
Return Value ..
Not applicable (message is not processed by a window
procedure).
Notes..
This message causes WinGetMsg to return FALSE (this
function normally extracts a message from the queue and
returns TRUE). A FALSE return value is a signal that the pro-
gram should end; this message, therefore, would typically
never be passed to a window procedure.
• Figure 2.10..
The WM_QUIT Presentation Manager message
• 54 Programmer's Guide to the os/2 Presentation Manager
- hand,.
USHORT msg,.
rmAEun mpl ,.
rmAEun mp2 ,.
• Figure 2.11..
Steps for implementing the window procedure
• 56 Programmer's Guide to the os/2 PresentationManager
Step 6: Release
Presentation Manager Resources
When the function WinGetMsg in the example program extracts
the message WM_QUIT from the queue, it returns a value of FALSE,
and the while loop terminates. Before exiting, the program releases the
resources it has acquired from the Presentation Manager. First it calls
WinDestroywindow (Figure 2.13) to dispose of the frame window and
® Figure 2.12:
The Presentation Manager message-handling mechanism
• 58 Programmer's Guide to the os/2 PresentationManager
• PROCESSING MESSAGES
As explained in the previous section, the system calls the proce-
dure associated with a particular window whenever a message is sent
WinDestroywindow
Purpose..
Destroys the specified window and all its descendant win-
dows.
Prototype..
BOOL APIENTRY WinDestroywindow
(HWND hwnd) ,. Handle of window to destroy.
Return Value ..
TRUE if the function was successful, FALSE otherwise.
Notes..
The window must have been created by the same thread that
calls this function. When a window is destroyed, the
WM_DESTROY message is sent to the window.
• Figure 2.13..
The WLnDestray:W±r\dow Presentation Manager function
Creatingawindow 59 .
to this window. Therefore, all messages sent to the client window cause
the system to call the function Wndproc, which is part of the example
program and is listed in Figure 2.16.
The window procedure must test the second parameter (msg) to
determine the identity of the message, and branch to the appropri-
ate section of code to handle this message. This action is most easily
accomplished with a switch statement. When the window procedure
has completed processing the message, it should return a value of either
TRUE or FALSE, depending upon the particular message. The window
procedure does 7tof have to process all messages; it can select certain
messages to handle and then pass all other messages to the system for
default processing by calling WinDefwindowproc (Figure 2.17).
The function Wndproc processes only the WM_PAINT message and
lets the system worry about all other messages by passing them to Win-
Defwindowproc. The WM_PAINT message is sent to the client window
WinDestroyMsgQueue
Purpose..
Destroys the specified message queue.
Prototype..
BOOL APIENTRY WinDestroyMsgQueue
(IIMQ hmq) ,. The handle of the message queue to be
destroyed.
Return Value ..
TRUE if the function was successful, and FALSE otherwise.
Notes..
This function is normally called after destroying all program
windows, but before calling WinTerminate, in preparation
for program exit.
• Figure 2.14..
The W±nDestrvyMsgQuoue Presentation Manager function
• 60 Programmer's Guide to the os/2PresentationManager
WinTerminate
Purpose..
Signals the Presentation Manager that the calling thread has
finished using the services of the Presentation Manager, and
releases all Presentation Manager resources held by this
thread.
Prototype..
BOOL APIENTRY WinTerminate
(HAB hab) ,. The anchor block handle held by the current
thread.
Return Value ..
TRUE if the function is successful, FALSE otherwise.
Notes..
This function is normally called immediately before the pro-
gram terminates, after it has completed calling all other
Presentation Manager functions.
• Figure 2.15..
The W±nTerrwinate Presentation Manager function
Creatingawindow 61 .
DISPLAYING DATA
• WITHIN THE WINDOW
The client window procedure in the example program cans the
function Paint whenever it receives the WM_PAINT message. This func-
tion, hsted in Figure 2.18, serves to update the data displayed within the
program's client window. Specifically, the function clears the entire area
within the window and prints a string at the upper left corner.
} /* end Wndproc */
• Figure 2.16..
The function Wr\dproc of the example progran
• 62 Programmer's Guide to the os/2 Presentation Manager
WinDefwindowproc
Purpose..
Passes a message to the system for default processing.
Prototype,
MRESULT APIENTRY WinDefwindowproc
(HWND hwnd, Handle of the window to which the message
was originally sent.
USHORT msg, Message identifier.
REARAM mpl , Message parameter 1.
I@ARAM mp2) ,. Message parameter 2.
Return Value ..
The return value depends upon the specific message.
Notes
A window procedure normally calls this function to handle
messages that it does not want to process itself. The window
procedure should pass this function the s¢777c parameters that
it received when it was invoked.
• Figure 2.17..
The WLnDef:Windowproc Presentation Manager function
Creatingawindow 63 .
message. (If, however, the overlying window was created with either
the CS_SAVEBITS or the WS_SAVEBITS style, the system will automat-
ically save and restore the overwritten data, and will not need to send a
WM_PAINT message.) Note that when the window is 777oz7cd, the sys-
tem directly transfers the data without sending WM_PAINT.
MRESULT EXPENTRY Paint (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
HPS Hpresspace; /* Presentation space handle.
RECTL Rect; /* Window rectangle, in window coordinates
static char Message [] = /* Text to display.
''This line is displayed by the window procedure.";
) /* end Paint */
• Figure 2.18..
The function Halul of the example program
• 64 Programmer's Guide to the os/2PresentationManager
WM PAINT
Purpose..
This message is sent by the system to a window whenever
the entire window, or any portion of it, needs redrawing.
Parameters..
REARAM mpl NULL (Reserved value).
MPARAM mp2 NULL (Reserved value).
Return Value ..
NULL.
Notes..
When this message is received, the window procedure must
explicitly draw the data within the invalid section of the win-
dow. The function WinBeginpaint (Figure 2.20) supplies the
coordinates of the invalid region, and WinEndpaint (Figure
2.21) informs the Presentation Manager that the window is
now completely valid.
• Figure 2.19..
The WM_PAINT Presentation Manager message
Creatingawindow 65 .
the screen. Therefore, all window output can be handled through the
section of the window procedure that responds to the WM_PAINT mes-
sage. Accordingly, you can cc71£r¢J!.zc all screen-drawing code within a
single all-purpose function (in this example, the function Paint), and
you do not need to have drawing functions scattered throughout the
program. This is a fortunate design feature, since, as you will see in the
next section, drawing within a window is not a trivial task.
WinBeginpaint
Purpose..
Obtains a handle to a presentation space that is associated
with the specified window.
Prototype..
HPS APIENTRY WinBeginpaint
(IIWND hwnd, Handle of the window to receive data.
Hps hps , Handle of an existing presentation
space to be associated with the
window given by hwnd; if this
parameter is NULL, the system
supplies a cache presentation space.
PRECTL prclpaint) ,. Address of a RECTL structure to
receive the window coordinates of the
smallest rectangle bounding the
invalid region(s) of the window; this
structure is defined in Figure 2.22.
Return Value ..
The handle of the presentation space.
Notes..
The presentation space obtained by this function is ready for
drawing onto the specified window. Note that after this
function is called, the system considers the window data
completely valid (that is, the invalid region of the window is
set to NULL). You must call WinEndpaint after the window
has been updated.
RelatedFunction..
WinEndpaint (Figure 2.21)
• Figure 2.20..
The W±nBeginp aint Presentation Manager f unction
Creatingawindow 67 .
WinEndpaint
Purpose..
Signals the system that the updating of the window (which
occurs typically in response to a WM_PAINT message) is
complete.
Prototype..
BOOL APIENTRY WinEndpaint
(Eps hps) ,. Handle of presentation space that was used
for painting the window.
Return Value ..
TRUE if the function was successful, FALSE otherwise.
Notes..
After you have called WinBeginpaint and have completed
updating the window display, you must call WinEndpaint.
If the call to WinBeginpaint supplied a cache presentation
space, WinEndpaint returns this presentation space to the
cache.
Related Functions ..
WinBeginpaint (Figure 2.20)
• Figure 2.21..
The W±nEndp ELiul Presentation Manager f unction
• 68 Programmer's Guide to the os/2 PresentationManager
you must call WinEndpaint before returning from processing the cur-
rent message.
Once a handle to a presentation space has been secured, the function
Paint obtains the current dimensions of the client window by calling
WinQuerywindowRect (Figure 2.22). This function assigns the dimen-
sions to a RECTL structure (defined in Figure 2.22); note that since the
WinQuerywindowRect
Purpose..
Returns the coordinates of the specified window.
Prototype..
BOOL APIENTRY WinQuerywindowRect
(I]wND hwnd, Window handle.
PRECTL prcIDest) '. 5:L£:#tto°raecRe¥vceTtE:t:::r¥::#eesfi:nfetfe
window.
Structure..
typedef struct
(
LONG xLeft,.
LONG yBottom,.
LONG xRight ,.
LONG yTop,.
)
RECTL,.
RetumValue..
Returns TRUE if successful, and FALSE otherwise.
Notes..
The coordinates are given relative to the lower left comer of
the window; thus xLeft and yBottom are both 0.
• Figure 2.22..
The WinQuerywindowRect Presentation Manager f unction
Creatingawindow 69 .
dimensions provided are relative to the lower left corner of the window,
the fields xLeft and yBottom are both set to 0. The window dimensions
are used by the two subsequent function calls.
The function Paint next erases the former contents of the window by
calhng WinFillRect (Figure 2.23). WinFillRect draws a rectangle filled
with a specified color; by passing the dimensions of the entire window,
and by specifying the desired background color (white), this function ef-
fectively clears the window. Note that WinFillRect is passed the handle
to the presentation space obtained from the call to WinBeginpaint.
Once the screen has been filled with the desired background color,
the program calls WinDrawText (Figure 2.24) to draw a string within
the window. This function justifies a string within a specified rectangle.
The program sets this rectangle to the dimensions of the entire screen
and requests that the string be justified at the top and left of the rec-
tangle; therefore, the string is drawn starting at the upper left corner of
the window. WinDrawText also allows you to specify the foreground
and background colors used to draw the string. The function call selects
a black foreground, and it also selects a white background to match the
background painted by WinFillRect. The window thus displays black
letters on a white background.
WinFillRect
Purpose..
Draws a rectangle filled with a specified color.
Prototype..
BOOL APIENTRY WinFillRect
(HPS hps, Handle of the presentation space onto which
the rectangle is to be drawn.
PRECTL prcl, Pointer to a RECTL structure containing the
coordinates of the rectangle to draw; see
Figure 2.22 for the definition of this structure.
• Figure 2.23..
The WLnFLIIRect Presentation Manager f unction
• 70 Programmer's Guide to the os/2 PresentationManager
Identifier Meaning
CLR BACKGROUND Default window
color
CLR NEUTRAL Default
foreground color
Return Value ..
TRUE if the function was successful, FALSE otherwise.
• Figure 2.23..
The WLnErllRect Presentation Manager f unction (continued)
Note that the function Paint makes no attempt to determine the sec-
tion of the window that is actually invalid, but rather redraws the entire
window. Subsequent versions of the example program enhance ef-
ficiency by updating only the invalid section.
Creatingawindow 71 .
WinDrawText
Puxpose..
Prints a text string within a specified rectangle, using the cur-
rent font.
Prototype..
SHORT APIENTRY WinDrawText
(Hps hps , Handle of the presentation space on which
the string is to be drawn.
SHORT cchText , Number of characters contained in the
string; the value Oxffff means that the string
is null-terminated and the function will
calculate its length.
PCH pchText, Pointer to the string to print.
PRECTL prcl, Pointer to a RECTL structure containing the
dimensions of the rectangle inside of which
the string is to be drawn; see Figure 2.22 for
the definition of this structure.
LONG clrFore, The foreground color; see Figure 2.23 for a
list of colors you can specify.
LONG clrBack, The background color; see Figure 2.23 for a
list of colors you can specify.
USHORT rgfond) ,. The mode in which the string is to be drawn;
you may assign one or more of the following
values:
Value Meaning
DT LEFT Left-justify text.
DT CENTER Center text.
DT RIGHT Right-justify text.
DT VCENTER Vertically center text.
DT TOP Top-justify text.
DT BOTTOM Bottom-justify text.
Return Value ..
The actual number of characters drawn.
• Figure 2.24..
The WLnDra;wTch Presentation Manager f unction
• 72 Programmer's Guide to the os/2 PresentationManager
BUILDING A PRESENTATION
• MANAGER APPLICATION
Figures 2.25, 2.26, and 2.27 (at the end of the chapter) list the three
basic files used to build the example program: a MAKE file, a linker
definition file, and the complete C source code file.
The MAKE file in Figure 2.25 can be used to prepare the example pro-
gram by means of the Microsoft MAKE utility. See the Microsoft
documentation for instructions on using this utility. The C source code
is compiled with the following command line:
Switch Meaning
/W2 Provides a high level of compiler warnings; the de-
fault level is 1, and the highest level is 3. This flag is
helpful for compiling fl77y type of C program, espe-
cially Presentation Manager applications, which in-
volve many data types and many possibilities for
type nrismatches.
/c Compiles without linking. The linker is invoked on a
separate line in the MAKE file.
/Zp Packs structures (that is, places each structure field on
the next available byte address rather than aligning
certain fields on even addresses); this option is impor-
tant because certain OS/2 or Presentation Manager
API functions may assume that the structures passed
to them are packed.
/G2 Enables instructions specific to the 80286 and later
model processors. Since the Presentation Manager re-
quires at least the 80286 processor, why not allow the
compiler to take advantage of these more efficient
instructions?
Creatingawindow 73 .
Command Effect
NAME FIG2 27 Names the application and specifies
the program as an application rather
than a dynamic-link module.
• 74 Programmer's Guide to the os/2 PresentationManager
Finally, the complete C source code is listed in Figure 2.27. Many of the
fouowing chapters in this book win also hit the complete set of files you
need to build the version of the text editor presented in that chapter. These
filesaegivenattheendofthechapter,andconsistinitiallyofaMAREfile
(.MAK), a hiker definition file (.DEF), and a C source file (.C). Chapter 8
will add resource files (.DLG and .RC) and a header file (.H) to this set.
• CONCLUSION
In this chapter, you have seen the basic sequence of function cans
that constitute a minimal Presentation Manager application. A feature
common to many of these function calls is the use of handles. In
general, when a Presentation Manager function allocates an object to an
application (such as a window), it returns a handle; this handle must be
supplied to subsequent function calls that manipulate the same object,
and it serves to identify the specific instance of a given type of object.
The actual value of a handle has meaning only to the system, and not to
the application (such variables or parameters are therefore known as
``magic cookies''). The first handle supplied to an application is the
anchor block handle, which is returned by Winlnitialize and identifies
the basic set of resources and information that the Presentation
Creatingawindow 75 .
Although the example program will become much larger and more
complex in subsequent chapters, the version presented here illustrates
most of the essential concepts involved in programming under the
Presentation Manager. If you are accustomed to a conventional
programming environment, some of these concepts may now seem
somewhat alien; however, as the basic ideas are reinforced in sub-
sequent chapters, you will not only become more comfortable with
these concepts, but you will probably come to enjoy the unique and in-
teresting logic of the Presentation Manager.
# Figure 2. 25
# This MAKE file prepares the program of Figures 2.26 and 2.27
#
FIG2 - c|27.ORE
/Ti(2
: FIG2 27.C
/c /rz;p /r:%NS FT!f :2_2:J .C
FIG2 - link
27.EXE : FIG2 27.OEU FIG2 26.DEF
/NOD FIG2 27.OBT,, NUL, OS2.LIB SLIBCE.LIB, FIG2 26.DEF
• Figure 2.25..
A MAKE file for preparing the example program
Figure 2.26
; Linker® definition file for the program listed in Figure 2.27
NAME FIG2 27
PROTMODE
HEAPSIZE 1024
STACKSIZE 8192
EXPORTS Wndproc
• Figure 2.26..
A linker definition file for preparing the example program
• 76 Programmer's Guide to the os/2 Presentation Manager
/*
Figure 2.27
Version 1 of the Presentation Manager text editor example program.
This version performs the following tasks:
o Initializes the Presentation Manager system
o Creates a message queue
o Registers a window procedure
o Creates a standard window
o Processes window messages
o Writes a line of text at the top of the window from the
window procedure
o Relinquishes Presentation Manager resources before termination
*/
#include <OS2.H>
MRESULT EXPENTRY Wndproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2) ;
void main ()
(
HAB HAncBlk; /* Anchor block handle.
HMQ HMesQue; /* Message queue handle.
HWND HFrame, Hclient; /* Frame/client window handles.
QMSG QueMess; /* Message queue structure.
ULONG CtlData = /* Control windows to include.
FCF MINMAX /* Minimize/maximize box.
FCF-SHELLPOSITI0N /* Make window visible on screen.
FCF-SIZEBORDE-R /* Wide sizing border.
FCF-SYSMENU /* System menu.
FCF-TASKLIST /* Display program name in Task Manager.
FCF-TITLEBAR; /* Title bar.
/*** Initialize the Presentation Manager and obtain an anchor block handle. **/
HAncBlk = Winlnitialize /* Returns an anchor block handle. */
(0) ; /* Initialization options: must be 0. */
/*** Create a message queue for the current thread. **************************/
HMesQue = Wincrii::¥:!%Teue ;: :::::::b::::::::i:¥:u:e:::d:::auLt size. ;;
• Figure 2.27..
The source code file for the example program
Creatingawindow 77 .
• Figure 2.27..
The source code file for the example program (continued)
• 78 Programmer's Guide to the os/2 Presentation Manager
} /* end Wndproc */
) /* end Paint */
• Figure 2.27..
The source code file for the example program (continued)
i pter three
Managing
Memory
81.
.I
he version of the Presentation Manager text editor pre-
sented in this chapter accepts the name of a file from the
command line, reads the file into an internal buffer, and
then displays the beginning of the file within the win-
dow. Although this version displays only as many lines from the head
of the file as will fit within the client window, the entire file is loaded
into data structures in memory that will allow subsequent versions of
the program to efficiently access, display, and manipulate the file data.
The memory used to store the file is allocated dynamically, so that the
program can accommodate files of various lengths without reserving a
data segment of fixed arbitrary size. Also, if the user enlarges the win-
dow on the screen, the program automatically displays additional lines
from the file so that the window area is always filled (provided the file
is sufficiently large).
In this chapter, you will learn how to use the Presentation Manager
heap-management functions for dynamically allocating blocks of
memory; you will learn how to handle Presentation Manager errors;
and you will learn how to display multiple lines of text within a win-
dow in a manner that is independent of the size of the window and the
resolution of the display device. The chapter also discusses the design
of the data structures used to store and manage the file data, describes
the collection of programming macros provided by OS/2, and presents
several new Presentation Manager functions and messages. Finally, the
program describes the techniques for loading and displaying specific
Presentation Manager fonts.
Note that the complete source code listing for the current version of
the example program is given in Figure 3.33, at the end of the chapter.
Several of the Presentation Manager functions called by this program
require portions of the OS/2 header files that are not automatically in-
corporated simply by including OS2.H. To force the compiler to include
the required header information, the program defines two constants
Z7e/ore including OS2.H. Defining the constant INCL_WIN causes in-
clusion of all header information for the window-management (Wz.7£)
functions, and defining INCL_GPI includes all information for the
graphics (Gpl.) functions. Table 3.1 lists the most general of these con-
stants and the header data they cause the compiler to include. In addi-
tion to the constants listed in this table, there are many other constants
• 82 Programmer's Guide to the os/2 Presentation Manager
that you can define to include smaller portions of the header informa-
tion; for example, the constant INCL_WINHEAP incorporates informa-
tion for only a s#Z7sef of the window-management functions
(specifically, the heap-management functions, such as those described
in this chapter). In Table 3.1,. the expression `foy default'' refers to por-
tions of the header files that are automatically included through the
#include <OS2.H> statement.
• MANAGINGTHEHEAP
In the example program, the functions and data stmctures used to
read the file and manage the internal data buffer are grouped into a dis-
tinct module; this module is located within the single source code file,
although it could easily be placed within a separate file. The module
consists of a public section and a private section. The public section
comprises the constant definitions, variable definitions, and function
declarations used by both the function module and the main Presenta-
tion Manager program; it is listed in Figure 3.1. The private section con-
sists of the functions themselves and the data structures and definitions
used internally by these functions.
The public section is placed above the function main in the example
program, and the private section is placed near the end of the file (see
the complete listing in Figure 3.33). If the private section of the module
were located in a separate sourc`e file, the public section could be placed
in a header file that is included both by the module and by the main
program. The reason for encapsulating the file-handling functions
within a separate module is to simplify the logic of the main application
and to permit you to modify the implementation details of the buffer-
management code without disturbing the main program. Note that
under OS/2, you can also implement modules of supporting functions
• Figure 3®1..
The public declarations of the file |buffer-management module
• 84 Programmer's Guide to the os/2 Presentation Manager
} /* end Buflnit */
• Figure 3.2..
The function Buflrhi from the exanple program
To extract the selector and offset, the program uses two of the macros
that are supplied by the OS/2 header files. The macro SELECTOROF
extracts the selector from a far address, and OFFSETOF extracts the of-
fset. Some of these macros are supplied by the general OS/2 header files
(such as OS2DEF.H), and some are provided by the header files specific
to the Presentation Manager (for example, PMWIN.H). Table 3.2 lists a
collection of the more useful macros, including all of those used by the
versions of the example program presented in this book. The macros
specific to the Presentation Manager can be grouped into the following
categories, according to the functions they serve:
General-Puxpose Macros
HHeap = WincreateHeap
(0, /* Segment address: 0 means allocate new segment.
Heapsize /* Initial heap size.
0, /* Minimum increase size: 0 means use default.
0, /* Minimum # of dedicated free lists: none.
0' /* Maximum # of dedicated free lists: none.
0); /* Options: none.
/*** Obtain selector to heap segment. ****************************************/
/*** Read each line in file into a separate block allocated from heap. *******/
LastLine = -1;
while (fgets (LineBuffer,LINEBUFSIZ-1,PtrFile) != NULL)
(
/*** Test for line limit --update 'LastLine'. *********************/
if (++LastLine >= MAXLINES)
return (ERRMAXLINES) ;
• Figure 3.3..
The function ReaLdFhe from the example program
ManagingMemory 91 .
} /* end of ReadFile */
• Figure 3.3..
The function ReaLdHle from the example progran (continued)
ReadFile first opens the file by calling fopen. Note that ReadFile
employs the high-level file-management functions fopen, fgets, and
fclose, which are provided by the standard C library. Although these
functions may not be the most efficient means for reading the file and
extracting individual lines, they are convenient to use, are familiar to C
programmers, and permit the example code to focus on the unique fea-
tures of Presentation Manager programming. The section on Enhance-
ments, near the end of the chapter, offers some suggestions for
improving the file-handling efficiency.
Once the file is opened, ReadFile tests the length of the file by calling
the C function filelength. If the file is larger than 50,000 bytes, ReadFile
returns an error message. Therefore, 50,000 bytes is the maximum file
size that can be handled by the current version of the text editor, for
reasons that will be explained shortly. Suggestions for greatly increas-
ing this limit are discussed in the Enhancements section.
• 92 Programmer's Guide to the os/2 PresentationManager
WincreateHeap
Purpose..
Creates and initializes a heap for dynamically allocating
blocks of memory.
Prototype..
HHEAP APIENTRY WincreateHeap
(USHORT selHeapBase, Selector of the segment to contain the
heap (the application program must
have already explicitly allocated a
segment for the heap). A value of 0
means cz.£fecr to locate the heap at the
end of the application's automatic data
segment (if the next parameter,
cbHeap, is also 0), or to allocate a new
segment for a heap (if the next
parameter is not 0).
USHORT cbHeap, J7iz.£z.¢J size of heap in bytes (note that
the system will automatically expand
the heap to fill memory requests up to
the 64-kilobyte segment limit). A value
of 0 means cz.ffecr that the heap is being
placed in the program's automatic
data segment (if the first parameter,
selHeapBase, is 0), or that the program
has already explicitly allocated a new
segment for the heap (if the first
parameter contains a selector).
• Figure 3.4..
The WincreaLteHeaLp Presentation Manager function
ManagingMemory 93 .
• Figure 3.4..
The WincreateHeap Presentation Manager function (continued)
®94 Programmer's Guide to the OS/2 Presentation Manager
Return Value ..
A heap handle if the heap was successfully created, and 0
otherwise.
Notes..
The cbMinDed and cbMaxDed parameters allow you to
specify a range of block sizes that will be placed on dedi-
cated free lists. A dedicated free list is a list of free blocks of a
given size; such a list allows these blocks to be allocated with
maximum efficiency.
Relate d Functions ..
WinDestroyHeap (Figure 3.5)
WinAllocMem (Figure 3.7)
WinFreeMem (Figure 3.10)
• Figure 3.4..
The WincreateHeaLp Presentation Manager function (continued)
prograLm's automatic data segment. The aLulorr\at±c (or default) data seg-
ment contains the program's initialized, uninitialized, and constant
data, as well as the program stack. (A large data model C program may
have one or more additional segments to contain data that does not fit
within the automatic segment. The size of the stack is determined by the
STACKSIZE statement in the linker definition, .DEF, file.) You can also
reserve a given number of bytes for a JocoZ heap at the end of the auto-
matic data segment through the HEAPSIZE statement in the linker
definition file; the example program reserves 1024 bytes for a local
heap. By assigning 0 to the first two parameters passed to Wincreate-
Heap (selHeapBase, the heap selector, and cbHeap, the heap size), you
cause the Presentation Manager to initialize a heap within the area at
the end of the automatic data segment that was reserved for this
ManagingMemory 95 .
purpose; the size of this heap is the size given by the HEAPSIZE state-
ment. The advantage of locating the Presentation Manager heap within
the automatic data segment is that you can efficiently address this
memory using near pointers (that is, pointers containing only the offset
portion of the address; the selector for the automatic data segment is ¢Z-
rc¢dy contained in the DS register, and therefore pointers do not have to
include the selector value).
Alternatively, you can locate the heap within an entirely separate
segment that is 71of reserved when the program is loaded, but rather is
allocated after the program begins running. By assigning 0 to the first
parameter (selHeapBase, the heap selector) and by assigning the
desired initial heap size to the second parameter (cbHeap), the example
program causes WincreateHeap to allocate a 71czu segment from the
operating system and initiahze this segment as a heap. The initial size
requested for this heap is based upon the length of the file. The ad-
vantage of placing the heap within a newly allocated data segment is
that the program need allocate only the amount of memory actually re-
quired for storing the file; if the heap were located within the automatic
data segment, you would have to reserve an arbitrary large amount of
memory through the HEAPSIZE definition file command in order to ac-
commodate various file sizes. Also, a separate segment can contain a
larger heap than the automatic data segment, which must also hold the
program's stack and data.
Note that the value passed as the second parameter to Wincreate-
Heap (cbHeap) specifies the z.71z.fz.¢J heap size; the Presentation Manager
will automatically enlarge the heap (up to the 64-kilobyte segment size
limit) if it cannot fill a given allocation request. The example program
requests an initial heap size that is 20 percent larger than the length of
the file so that the Presentation Manager need not immediately expand
the heap; this added memory will accommodate any additional infor-
mation the system must store to maintain the heap, and it will allow the
user to add data to the file. If the file size continues to grow, the Presen-
tation Manager will eventually have to call the OS/2 kernel to expand
the segment containing the heap.
Since the heap is stored within a single segment, however, it cannot
grow beyond the segment size limit of 64 kilobytes (an unfortunate con-
sequence of the segmented architecture of the 80286 processor). Conse-
quently, the program will not process a file that is longer than 50,000
• 96 Programmer's Guide tothe os/2PresentationManager
bytes (allowing for file expansion). Also, if the file size grows to the
maximum size (in later versions of the program that allow data entry),
the program will save the current contents of the file and will quit with
an error message. As mentioned in the section on Enhancements, you
can use multiple heaps to overcome this size limitation and take ad-
vantage of the large memory space afforded OS/2 applications.
The next parameter to WincreateHeap, cbGrow, specifies the mini-
mum number of bytes by which the system will expand the heap when
additional memory is required. The function ReadFile sets this
parameter to 0 to request the default amount (512 bytes). The next two
parameters, cbMinDed and cbMaxDed, specify a range of specific
block sizes that are to be managed with dedicated free lists. The system
can place a collection of free blocks that have the same size within a
dedicated list to increase the efficiency of allocating these blocks. If all of
the blocks used by a program are the same size (or if there is a narrow
range of sizes), it should request the system to use a dedicated free list
(or lists, if there is a range of sizes) for these blocks. As you will see,
however, the example program allocates separate blocks from the heap
for each line of the file; since these blocks are of random lengths, the
program assigns 0 to cbMinDed and cbMaxDed, indicating that no
dedicated lists are desired. Note that WincreateHeap returns a handle
to the heap (stored in HHeap), which must be passed to all subsequent
heap functions.
Before the application terminates (in the Quit function, described in
the next section) it calls WinDestroyHeap (Figure 3.5) to free the
memory segment containing the heap.
Although WincreateHeap returns a handle, you may have noticed
that an important value is still missing: the selector of the memory seg-
ment that contains the heap (remember that since the heap is 71of in the
automatic data segment, the program needs the selector to construct the
far pointer used to address locations within the heap). The far address
of a heap is returned by the Presentation Manager function WinLock-
Heap (Figure 3.6); the program calls this function and then extracts the
selector value and stores it in the variable Heapselector.
The function ReadFile now enters the main while loop that reads
lines from the file and inserts them into the heap. With each repetition of
the loop, the program performs the following steps:
ManagingMemory 97 .
It reads the next line from the file into the temporary buffer Line-
Buffer, by calling the C library function fgets.
It updates the variable LastLine, which contains the number of
the last line stored in the heap (and quits if the maximum num-
ber of lines, MAXLINES, is exceeded).
• It calculates the length of the line (by calling strlen) and allocates
a block of memory from the heap just large enough to contain
the line, including the newline character and the terminating
null. The block is allocated by calling the Presentation Manager
function WinAllocMem (Figure 3.7). Note that if the line is over-
sized (that is, it exceeded the maximum buffer length passed to
fgets and therefore does not contain a newline character), the
program inserts a newline.
WinDestroyHeap
Purpose..
Destroys a heap previously created by WincreateHeap.
Prototype..
HHEAP APIENTRY WinDestroyHeap
(HHEAp hHeap) ,. Heap handle, returned by a prior call to
WincreateHeap.
Return Value ..
0 if the function is successful, and a nonzero value if an error
occuITed.
Related Functions ..
WincreateHeap (Figure 3.4)
• Figure 3.5..
The W±nDestrvyHeaLp Presentation Manager function
• 98 Programmer's Guide to the os/2PresentationManager
It copies the line from the temporary buffer into the newly allo-
cated block in the heap, using the C library function movedata,
which supports intersegment data moves. Unfortunately, it is not
possible to read the data directly into the heap block, since the
length of the line must be calculated before this block is allocated.
• It places the far address of the line (constmcted using the os/2
macro MAKEP) and the length of the line into the next available
entry in the line table, LineTable.
WinLockHeap
Purpose,
Supplies the far address of the base of the segment contain-
ing the specified heap.
Prototype..
PVOID APIENTRY WinLockHeap
(HHEAp hHeap) ,. The heap handle returned by a prior call to
WincreateHeap.
Return Value ..
A far pointer to the base of the memory segment containing
the heap.
Notes..
You must call this function to obtain the selector required to
access a heap that is not located within the program's auto-
matic data segment.
Related Functions ..
WincreateHeap (Figure 3.4)
• Figure 3.6..
The WLnLoc:ldleaLp Presentation Manager function
ManagingMemory 99 .
• After the last line is safely stored in the heap, the loop exits and
the program closes the file by calling the C library function
fclose.
WinAllocMem
Purpose..
AllocatesablorkofmemoryfromaPresentationManagerheap.
Prototype..
NPBYTE APIENTRY WinAllocMem
(HHEAp hHeap, Handle to the heap returned by
WincreateHeap.
USHORT cb) ,. Size of the requested block in bytes.
Return Value ..
The offset address of the allocated block, or NULL if the
function fails.
Notes..
If the heap is currently not large enough to supply the re-
quested block, WinAllocMem attempts to enlarge the seg-
ment containing the heap. If, however, it is unable to expand
the heap, it returns NULL. Note that this function returns a
near address (offset only); to address a heap located outside
of the program's automatic data segment, you must use a far
pointer containing the heap segment selector (which can be
obtained from WinLockHeap).
Related Functions ..
WincreateHeap (Figure 3.4)
WinLockHeap (Figure 3.6)
WinFreeMem (Figure 3.10)
• Figure 3.7..
The W±nA:Iloc:Mern Presentation Manager function
• 100 Programmer's Guide to the os/2PresentationManager
static struct
(
PCH LineAddress,. /* Far address of line
/* in heap.
unsigned char LineLength,. /* Length of line,
/* including \n, \0.
)
LineTable [MAXLINES] ,.
Storing the addresses in this table provides the program rapid ran-
dom access to any line in the file. Storing the line lengths eliminates the
need for the window procedure to calculate the length of a each line
that it displays (as you will see, the function used to print a line in the
window requires the line length as a parameter).
The main application obtains the address of a given line by passing
the line number to the function GetLineAddr, and obtains the length of
a line by passing the line number to GetLineLength. Both of these func-
tions simply check that the line number is within the valid range and
then return the desired value from the appropriate entry in LineTable.
Note that the main application does not have direct access to Line-
Table this encapsulation of data makes it simple to modify the data
structure used to manage the file without affecting the main program.
GetLineAddr and GetLineLength are both contained within the buffer-
management module and are listed in Figure 3.8.
ManagingMemory 101 .
Note that the number of lines that the program can accommodate is
limited by the number of elements in LineTable, which is currently set
to 4096 (MAXLINES); this is a generous number of lines, considering
that the file size is presently limited to less than 64 kilobytes. The overall
data structure used to access and manipulate the lines of the file is il-
lustrated in Figure 3.9.
Memory blocks allocated from the heap may be freed by calling Win-
FreeMem. This function is described in Figure 3.10, although it is not
used until the version of the example program presented in Chapter 6.
• HANDLING ERRORS
The basic OS/2 services (Dos, KZ7d, Vz.o, and Mow functions) use a
simple and consistent scheme for reporting errors: if the function is suc-
cessful, it returns 0; otherwise, it returns a nonzero error code. The
return values of these functions are therefore reserved for communicat-
ing the error status. (Other values are returned by assigning them to
variables, the addresses of which are passed as parameters.) Many of
} /* end GetLineLength */
} /* end GetLineAddr */
• Figure3.8:
The functions GetLineLer\gth and GetLineAddr from the example program
• 102 Programmer's Guide to the os/2PresentationManager
• Figure 3.9..
The data structure used to manage the file lines
ManagingMemory 103 .
code; the high-order word contains a code for the severity level, and the
low-order word contains a code indicating the specific error. You can in-
clude identifiers in your program for both of these types of errors by
defining the constant INCL_ERRORS before including OS2.H. See the
latest version of the appropriate header file (PMWIN.H for the Wz.71
functions and PMGPI.H for the Gp£. functions) for a list of the error iden-
tifiers and the corresponding codes that can be returned by the Presen-
tation Manager functions (the error code constants begin with the
prefix PMERR_).
WinFreeMem
Purpose..
Frees a memory block from a heap managed by the Presen-
tation Manager.
Prototype..
NPBYTE APIENTRY WinFreeMem
(HHEAp hHeap, Handle to the heap returned by
WincreateHeap.
NPB¥TE npMem, Offset of the memory block to be
freed, returned by a prior call to
WinAllocMem (or WinReallocMem).
USHORT cbMem) ,. The size of the block to be freed.
Return Value ..
NULL if the function is successful; otherwise, it returns the
value passed in the npMem parameter.
Related Functions ..
WincreateHeap (Figure 3.4)
WinAllocMem (Figure 3.7)
• Figure 3.10..
The W±nEreeMe" Presentation Manager function
• 104 Programmer's Guide to the os/2 PresentationManager
• Tlabl,e3.3.. S ecial Error Return Values the Presentation Mama er Functions Used in This Cha
WinGetLastError
Purpose..
Returns the system error code set by the last Presentation
Manager function that failed, and resets the system error
code to 0.
Prototype..
ERRORID APIENTRY WinGetLastError
(HAD hab) ,. Anchor block handle.
Return Value ..
A 32-bit error code, containing the following values:
Related Functions ..
WinGetErrorlnfo
WinFreeErrorlnfo
• Figure 3.11..
The WinGctLaLstEITor Presentation Manager f unction
• 106 Programmer's Guide to the os/2 Presentation Manager
In summary, you can handle an error condition that occurs when calling
a Presentation Manager function through the fonowing series of steps:
For example, the following code fragment handles the error condi-
tions that may occur when calling WinAllocMem.
ERRORID Error,.
NPCH Heapoffset ,.
default :
/* Manage any other heap-allocation error. */
)
)
Note that you can also call the Presentation Manager functions Win-
GetErrorlnfo and WinFreeErrorlnfo to obtain more detailed error in-
formation. See the Presentation Manager technical documentation for
information on these two functions.
To simplify the code, the example programs presented in this book
perform only minimal error checking. Correct programming should
eliminate most errors; some errors, however, cannot easily be
prevented. For example, if the user enters more data into the file than
can be held within the single segment used to contain the heap, the
function WinAllocMem returns the special value NULL to indicate that
the maximum heap size has been reached. In this case, the function
ReadFile simply returns the value ERRALLCX= indicating a general
memory-allocation failure, without calling WinLastError to determine
the specific error (if WinLastError were called, it would return the value
PMERE HEAP MAX SIZE REACHED). Note that ERRORALLOC is
one of a set of Elrror codes that can be returned by the buffer-manage-
ment module; these codes are defined at the top of the example pro-
gram and are listed in Figure 3.1. The buffer-management module also
provides a function, ErrorMessage (listed in Figure 3.12), that returns
the string corresponding to a given error code.
When the main part of the example program encounters a fatal error,
it calls the utility function ErrorQuit (listed in Figure 3.13), passing it an
error message. ErrorQuit formats the message and then cans Win-
MessageBox (Figure 3.14) to display the message. It then terminates the
program by calling the function Quit (also listed in Figure 3.13). Note
that both the functions main and ErrorQuit terminate the program by
calling Quit, which releases the heap and performs the other final tasks
required of a Presentation Manager program that were explained in
Chapter 2.
The function WinMessageBox displays a message box, which is a
temporary window containing a specified title and message, and one of
four standard icons. The message box also contains one or more p#sfe
Z7##o7is (explained in Chapter 8) that you specify when you call this
• 108 Programmer's Guide to the os/2 Presentation Manager
) /* end ErrorMessage. */
• Figure 3.12..
The function EITorMessaL8e from the example program
ManagingMemory 109 .
void Quit
(int Errorcode) /* Process termination status.
Calls Presentation Manager termination functions and ends program
with specified error code.
(
if (HHeap != NULL)
WinDestroyHeap (HHeap) ;
WinDestroywindow (HFrame) ;
WinDestroyMsgQueue (HMesQue) ;
WinTerminate (HAncBlk) ;
exit (Errorcode) ;
) /* end Quit */
• Figure 3.13..
The functions EITorQuft and Quit from the example program
• 110 Programmer's Guide to the os/2 Presentation Manager
WinMessageBox
Purpose..
Displays a message box window.
Prototype..
USHORT APIENTRY WinMessageBox
(HWND hwndparent , The parent of the message box
window (HWND DESKTOP if the
message box is to-be a top-level
window).
Hve hwndovner, The owner of the message box
window; this window is activated
when WinMessageBox returns.
PSZ pszText, Address of the null-terminated string
to be displayed within the message
box; you can insert carriage-return
characters within this string to display
multiple lines.
PSZ pszcaption, Address of a null-terminated string to
be displayed as the title of the message
box; if this parameter is NULL, the
default title fr7`or is displayed.
USHORT idwindow, The window ID of the message box
window; if no ID is required, you can
set this parameter to 0.
USHORT flstyle) ,. The message box style; you can specify
one or more of the following style
values (they should be combined
using the I operator):
Style Effect
MBOK Include push
button labeled
Ok
MB OKCANCEL Include Ok and
C¢71ccJ push but-
tons
MB RETRYCANCEL Include Rcfny
and Cfl77ccJ push
buttons
• Figure 3.14..
The WLn:MessaLgeBox Presentation Manager f unction
ManagingMemory 111 .
• Figure 3.14..
The W"essaLgeBox Presentation Manager function (continued)
• 112 Programmer's Guide to the os/2PresentationManager
Return Value ..
One of the following values, indicating which button the
user selected or an error status:
• Figure 3.14..
The W±n:MessageBox Presentation Manager function (continued)
PM Text Editor
: © ::°mg::in Error: Must specify fi|e
:cE
• Figure 3.15..
The message box displayed by the example progran
the frame window has been created though the call to Wincreatestd-
Window. The example program, however, must call ReadFile Z7c/ore
creating the window (remember that creating the window causes the
WM_PAINT message to be sent to the window procedure, which dis-
plays file data from the buffer). Accordingly, the function main retains
the error code returned from ReadFile, and then tests; this code-pos-
sibly calling ErrorQuit-after the call to Wincreatestdwindow.
• DISPLAYING TEXT
The version of the example program presented in Chapter 2 simp-
ly displayed a string that was justified at the upper left corner of the
client window. This version illustrated the concept df cc71fr¢Zz.zt.71g all
code for drawing window data within a single routine, which is in-
voked whenever an event external to the program requires that data be
redrawn, or whenever the program itself needs to modify the display.
The version of the example program presented in the present chapter
prints as many lines from the beginning of the file as Will fit within the
• 114 Programmer's Guide to the os/2 Presentation Manager
used the default system font; also, the system displays titles, menu
labels, and other textual data using the default font. Therefore, these
items all appear with proportionally spaced characters.
The function Create next calls WinGetps (Figure 3.19) to obtain a
handle to a presentation space. WinGetps supplies a cache presenta-
tion space, which was explained in Chapter 2. This function is called be+
cause the next function invoked (GpiQueryFonts) requires a
presentation space handle.
Once the program has obtained a presentation space, it calls Gpi-
QueryFonts (Figure 3.20) to obtain detailed information on a selected
font. Note that a given font file typically contains several distinct fonts;
once the font file is loaded, au of the fonts it contains are available to the
WM CREATE
Purpose..
Sent by the system to a window when it is first created. It
allows the window procedure to perform initializations.
Parameters..
REARAM mpl Address of control data that was passed to
the function Wincreatewindow.
I@ARAM mp2 Address of a CREATESTRUCT stmcture
containing information on the window that
is being created.
Return Value ..
Return FALSE to continue window creation.
Notes..
This message is sent after the window is created but before it
becomes visible.
• Figure 3.16..
The WM_CREATE Presentation Manager message
• 116 Programmer's Guide to the os/2 Presentation Manager
MRESULT EXPENTRY Create (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
HPS Hpresspace; /* Presentation space handle.
FONTMETRICS Metrics; /* Structure to hold font dimensions.
LONG Numberstructs = 1; /* Number of structures from GpiQueryFonts
} /* end Create */
• Figure 3.17..
The function Create from the exanple program
ManagingMemory 117 .
GpiLoadFonts
Purpose..
Loads one or more fonts from a font file.
Prototype..
BOOL APIENTRY GpiLoadFonts
(HAD hab, Anchor block handle.
pSz pszFilename) ,. A NULL-terminated string containing
the full path name of the file
containing the definition of the fonts to
be loaded (the file has the .FON
extension).
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Relate d Function..
GpiQueryFonts (Figure 3.20)
• Figure 3.18..
The GPILoaLdEor\ts Presentation Manager function
• 118 Programmer's Guide to the os/2 Presentation Manager
returns the number of remaining fonts for which information has 7zof
been read, thus allowing you to determine the total number of fonts
available that match the specified face name. You could dynamically al-
locate a temporary block of memory from the operating system to hold
the font information.)
The information supplied by GpiQueryFonts is received in the fields
of one or more FONTMETRICS structures (defined in OS2DEF.H). Since
the example program requests information on only a single font, it allo-
cates and passes the address of a single FONTMETRICS structure
(Metrics). The program uses the font information obtained from Gpi-
QueryFonts for two basic purposes.
WinGetps
Purpose..
Obtains a cache presentation space.
Prototype..
EPS APIENTRY WinGetps
(HWND hwnd) ,. Handle of the window to obtain a
presentation space.
Return Value ..
The handle of the presentation space; returns NULL if an
error occurs.
Notes..
The presentation space must be released by calling Win-
Releaseps.
RelatedFunctions..
WinReleaseps (Figure 3.22)
• Figure 3.19:
The WinGctps Presentation Manager function
ManagingMemory 119 .
GpiQueryFonts
Purpose..
Returns information on one or more of the fonts that are cur-
rently available.
Prototype..
LONG APIENTRY GpiQueryFonts
(EPS hps, Presentation space handle.
UI.ONG floptions , A flag indicating the type of
fonts to be queried; you can
pass one or both of the
fonowing values (combined
with the I operator):
Value Type of Font
QF_PUBLIC System font
QF_PRIVATE Fonts loaded by the
application ®y caning
GpiLoadFonts)
• Figure 3.20..
The GPLQueryForits Presentation Manager function
•120 Programmer's Guide to the OS/2 Presentation Manager
Return Value ..
The number of matching fonts for which information was
71of returned. A return value of zero indicates that informa-
tion was supplied for flJJ matching fonts (it does not indicate
an error); a nonzero value indicates that you can obtain in-
formation on additional fonts by passing a larger value in the
pcFonts parameter.
Notes..
By examining the data returned by this function, you can
choose the font most suitable for the application. To select
the desired font, you must call the functions GpicreateLog-
Font and Gpisetcharset.
Related Functions ..
GpiLoadFonts (Figure 3.18)
GpicreateLogFont (Figure 3.26)
Gpisetcharset (Figure 3.27)
• Figure 3.20..
The GPTQueryF ouls Presentation Manager function (continued)
First, it saves the value for the total character height (supplied in the
lMaxBaselineExt field of Metrics) in the global program variable
ycharTot, and the value for the height of the character descenders (sup-
plied in the lMaxDescender field) in the variable ycharDesc. These
dimensions will be used each time the WM_PAINT message is received
by the client window, and they are illustrated in Figure 3.21. Note that
in the example program, these dimensions are given in screen pixels. By
employing the actual dimensions used to display the font on the current
ManagingMemory 121 .
display device, the routine that processes the WM_PAINT message can
properly position the lines of text within the window and can maintain
a consistent screen appearance regardless of the current graphics
resolution.
Second, the function Create uses the font information it has obtained
from GpiQueryFonts to assign appropriate values to the fields of a
FATTR structure (FontAttributes) . As you will see in the section describ-
ing the WM_PAINT message, the FATTR structure is used to specify the
current font that is to be employed for displaying characters. Note that
• Figure 3.21..
The character dimensions obtained from Gp±QueryForrfe
• 122 Programmer's Guide to the os/2 Presentation Manager
WinReleaseps
Purpose..
Releases the presentation space obtained though WinGetps.
Prototype..
BOOL APIENTRY WinReleaseps
(Hps hps) ,. Handle of the presentation space returned
by WinGetps.
Return Value ..
TRUE if the function is successful, and FALSE if an error
occurred.
Relate d Functions ..
WinGetps (Figure 3.19)
• Figure 3.22..
The WLnRcteaseps Presentation Manager function
ManagingMemory 123 .
WM SIZE
Purpose..
Sent by the system to a window whenever its size changes.
Parameters..
REA- mpl
low-order word: Previous width.
high-order word: Previous height.
REAFLEN mp2
low-order word: Current width.
high-order word: Current height.
Return Value ..
FALSE.
• Figure 3.23..
The WM_SIZE Presentation Manager message
• 124 Programmer's Guide to the os/2PresentationManager
MRESULT EXPENTRY Size (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/*** Obtain vertical dimension of client window. ****************************/
ywin = SHORT2FROMMP (mp2) ;
return FALSE;
)/ * end Size */
• Figure 3.24..
The size function of the example program
1. WM CREATE
2. WM SIZE
3. WM PAINT
MRESULT EXPENTRY Paint (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
register int Line; /* Loop counter.
HPS Hpresspace; /* Presentation space handle.
RECTL Rect; /* Window coordinates, in pixels.
SHORT StopLine; /* Last line to paint.
POINTL Start; /* Starting position to print string.
SHORT LineLength; /* Length of each line displayed.
Hpresspace = WinBeginpaint
(hwnd, /* Window handle.
0, /* Handle of PS to have clipping region set. */
0) ; /* Address of variable to set to update region.*/
/*** Print lines from beginning of file within client window. ****i************/
Start.x -0;
for (Line = 0, Start.y = ywin -ycharTot + ycharDesc; Line <= StopLine;
++Line, Start.y -= ycharTot)
(
if ((LineLength = GetLineLength (Line)) == 0)
continue ;
GpicharstringAt /* Prints string at given position.
(Hpresspace, /* Presentation space handle.
• Figure 3®25..
The function Pa;ir\+ of the example program
• 126 Programmer's Guide to the os/2 PresentationManager
WinEndpaint (Hpresspace) ;
return FALSE;
) /* end Paint */
• Figure 3.25..
The f unction Pal:irit of the example program (continued)
GpicreateLogFont
Puxpose..
Creates a logical definition of a font.
Prototype..
BOOL APIENTRY GpicreateLogFont
(Hps hps, Handle of the presentation space for which
the font is to be defined.
PSTR8 pchName, Pointer to a logical font name, which can be
used to identify the logical font; you can
assign any name consisting of up to eight
characters.
LONG laid, The value that will be used to identify the
logical font; you can supply a value between
1 and 254; the value must not already refer
to a font or bitmap; when your subsequently
call Gpisetcharset to cause the system to
use the font, you must pass this s¢77tc value
(as the second parameter).
pFATTRs pfat) ,. Pointer to a FATRS structure (defined in
OS2DEF.H) that defines the attributes of the
logical font that is to be created; note that if
there is no font that matches the attributes
exactly, the system uses the font, of those
available, that most closely matches the
requirements; you can obtain: the attributes
for any avaiable font by calling
GpiQueryFonts.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
• Figure 3.26..
The Gp±CreateLo8Eorit Presentation Manager function
• 128 Programmer's Guide to the os/2PresentationManager
Notes..
To define a logical font using this function, the font must al-
ready have been loaded from a font file (by calling GpiLoad-
Fonts). Alternatively, if the face name in the FATTR structure
pointed to by pfat is NULL, and all of the attributes except
the code page are set to zero, the system default font is
selected in the specified code page. After calling Gpicreate-
LogFont, you must call Gpisetcharset to force the system to
start L/sz.71g the font.
Related Functions
GpiLoadFonts (Figure 3.18)
GpiQueryFonts (Figure 3.20)
Gpisetcharset (Figure 3.27)
• Figure 3.26..
The GplcreateLogForit Presentation Manager function (continued)
The macro min is defined in the C header file STDLIB.H. Since ywin is
the total number of vertical pixels in the window, and ycharTot is the
ManagingMemory 129 .
Gpisetcharset
Purpose..
Sets the current character set used for displaying textual data
within the specified presentation space.
Prototype..
BOOL APIENTRY Gpisetcharset
(Hps hps, Handle of the presentation space for which
the character set is to be set.
LONG lcid) ,. The identifier for the character set, which
can be one of the following values:
Identifier Meaning
LCID DEFAULT The default character
set (you can use this
option to restore the
default font after
temporarily using a
locally loaded font)
1 to 254 A logical font defined
by GpicreateLogFont;
you must pass the s¢777c
identifier within this
range that was passed
to GpicreateLogfont
(in the third parameter)
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Relate d Functions ..
GpicreateLogFont (Figure 3.26)
• Figure 3.27..
The GplsetchaLrset Presentation Manager function
• 130 Programmer's Guide to the os/2 PresentationManager
GpicharstringAt
Purpose..
Draws a line of text at a specified starting position.
Prototype..
LONG APIENTRY GpicharstringAt
(HPS hps, Handle of the presentation space.
PPOINTL pptlstart, Pointer to a POINTL structure (defined
below) containing the starting position.
LONG cchstring, Number of characters in the string to
be displayed.
PCH pchstring) ,. Address of character string to be
displayed.
Structure..
typedef struct POINTL
(
LONG x,.
LONG y,.
I
POINTL,.
Return Value ..
Returns a nonzero value if the function is successful, and
GPI ERROR if an error occurs.
Notes..
This function is equivalent to calling these two functions:
GpiMove (hps, pptlstart)
Gpicharstring (hps, cchstring, pchstring)
When the function has completed drawing the string, it
moves the current pointer to the end of the string.
RelatedFunctions..
GpiMove (Figure 11.22)
Gpicharstring
• Figure 3.28..
The Gp±CharstringALt Presentation Manager function
ManagingMemory 131 .
total number of vertical pixels required for a single line of text, Stop-
Line is assigned the total number of co777pJcfc lines (integer division
truncates a partial line) that fit within the window, or the value Last-
Line if the file does not contain sufficient lines to fill the window.
GpicharstringAt must be passed the address of a POINTL structure
(defined in Figure 3.28) specifying the starting point of the line of text.
Positions within a window are specified according to a coordinate sys-
tem that has its origin at the lower left corner of the window. Accord-
ingly, the point (x=0, y=0) represents the lower-leftmost pixel in the
window, and coordinates increase moving up and to the right. This
coordinate system is illustrated in Figure 3.30 (the value xwin is the
horizontal size of the window that is also supplied by the WM_SIZE
message, but is not used until Chapter 4). GpicharstringAt places the
lower left pixel-on the baseline-of the first character in the string at
the specified starting point (this position is illustrated in Figure 3.21).
Gpisetcolor
Purpose..
Sets the foreground color used by Gpz. functions such as Gpi-
CharstringAt.
Prototype..
BOOL APIENTRY Gpisetcolor
(Hps hps, Handle of the presentation space.
LONG IColor) ,. The color; you can select any of the color
values listed in Figure 2.23 (the description
of WinFillRect).
Return Value ..
TRUE if the function is successful, FALSE if an error occurs.
• Figure 3.29..
The GPTsetcofor Presentation Manager function
• 132 Programmer's Guide to the os/2 Presentation Manager
The program calculates the starting point of the first line using the
following expressions :
Start.x = 0,.
Start.y = ywin -ycharTot + ycharDesc,.
These expressions place the first line at the top of the window and jus-
tify the string at the left window edge. Finally, the vertical starting point
is decremented after each line is displayed using the following expres-
sion within the for statement:
Start.y -= ycharTot,.
This expression places each subsequent line from the file on the next
lower line position within the window.
The GpicharstringAt function is passed the length of each line. If a
line is longer than will fit within the window, the Presentation Manager
automatically clips the portion that falls outside the current window
dimensions (that is, the inappropriate points do not cause an error but
are simply not displayed). In general, when calling Presentation
Manager display functions, you can safely specify coordinates outside
• Figure 3.30..
The coordinate system used for specifying points within a window
ManagingMemory 133 .
the dimensions of the window; only the portions of a figure within the
window (if any) will be visible.
You may also have noticed that the for loop seemingly attempts to
print one more line than will fit within the window (Line ranges from 0
up to and including StopLine). Remember, however, that StopLine is
the number of co777pJcfc lines that can fit within the window. By printing
StopLine + 1 lines, the portion of any partial line that falls within the
window will be displayed; the section of this partial line that falls out-
side of the window is clipped.
Note that the current display routine always repaints the entire win-
dow. More accurately, the program only ¢ffc777pfs to repaint the entire
screen; actually, the presentation space provided by WinBeginpaint
automatically clips all data outside the current invalid window region;
ineffectual calls to GpicharstringAt, however, waste time. The pro-
gram in Chapter 4 enhances the efficiency of the display routine by
redrawing only the invalid section of the client window.
• ENHANCEMENTS
This section offers several suggestions for enhancing the version
of the example program presented in this chapter. These enhancements
are beyond the scope of the book, and are not developed in subsequent
chapters. You can use them as exercises in Presentation Manager
programming and to increase the usefulness of the example program.
First, one of the major limitations of the example program is the
restriction on file size. You cannot load a file that is larger than 50,000
bytes, and you cannot increase the file size beyond the maximum heap
size (the segment containing the heap has a maximum size of 64
kilobytes). To overcome this limitation and yet continue to use the
Presentation Manager memory-allocation functions, your program can
manage more than one heap. The following are some, suggested steps
for greatly increasing the maximum file size by using multiple heaps:
Note that as memory blocks are allocated and deallocated, the pro-
gram should limit the number of partially filled heaps. Alternatively,
you could possibly attain greater efficiency by completely bypassing
the Presentation Manager heap functions, and writing your own heap-
management routines; the raw memory for your heap could be ob-
tained directly from the operating system through the DosAllocHuge
function, which allocates blocks of memory consisting of more than one
segment.
As a second possible enhancement to the example program, you
could increase the efficiency of the routine that reads data from the file
and extracts individual lines. For simplicity, this routine calls the stand-
ard high-level C function fgets to extract each line from the file. Altema-
tively, you could read the entire file (or 64-kilobyte blocks of the file, if
the file is longer than this size) directly into a temporary buffer. You can
dynamically allocate this buffer from the operating system though the
DosAllocseg OS/2 function, and you can read the file directly into the
buffer with a single call to the DosRead system routine (you must open
and close the file using Dosopen and Dosclose). You can then write
your own routine to efficiently extract individual lines and copy them
into the heap. (If you have written your own heap-management
module, you may even be able to leave the lines in the buffer into which
they were initially read, eliminating the copy operations!)
ManagingMemory 135 .
• CONCLUSION
The MAKE file for preparing the current version of the example
program is provided in Figure 3.31, the definition file is given in Figure
3.32, and the complete program listing is in Figure 3.33.
This chapter has introduced the basic data structures and routines for
reading the file and managing the file data within the internal program
buffer. Later chapters will add features for inserting and deleting data
in the file buffer.
The chapter has also presented a basic routine for displaying multi-
ple evenly spaced lines within the window. Subsequent chapters will
add features that allow the program to scroll the contents of the win-
dow and to force the updating of specific window areas.
# Figure 3.31
# This MAKE file prepares the program of Figures 3.32 and 3.33.
#
FIG3 33.OBJ : FIG3 33.C
cl /W2 /c /7;p /C;%Ns FT!f :3_33.C
• Figure 3.31..
A MARE file for preparing the example program
Figure 3.32
; Linker definition file for the program listed in Figure 3.33®
NAME FIG3 33
I I
PROTMODE
HEAPSIZE 1024
STACKSIZE 8192
EXPORTS Wndproc
• Figure 3.32..
A linker definition file for preparing the exanple progran
• 136 Programmer's Guide to the os/2PresentationManager
/*
Figure 3.33
;i;R:::::;:i:i::i:::I::::ii::L (; ::::s:::i::::::i:;::;nE:::::i.
int LastLine = -1; /* Number of last line in buffer.
HHEAP HHeap = NULL; /* PM heap handle.
• Figure 3.33..
The source code file for the example program
ManagingMemory 137 .
(
int ReadError = 0; /* Error occurred reading file.
int UsageError = 0; /* No file name given on command line.
HWND Hclient; /* Handle to main client window.
QMSG QueMess; /* Message structure.
ULONG CtlData = /* Control windows to include.
FCF MINmx /* Minimize/maximize box.
FCF-SIZEBORDER /* Wide sizing border.
FCF-SHELLPOSITION /* Make window visible on screen.
FCF-SYSMENU /* System menu.
FCF-TASKLIST /* Display program name in Task Manager.
FCF-TITLEBAR; /* Title bar.
/*** Initialize the buffer-management module. ********************************/
Buflnit () ;
• Figure 3.33:
The source code file for the erample program (continued)
• 138 Programmer's Guide to the os/2 Presentation Manager
if (ReadError)
ErrorQuit (ErrorMessage (ReadError) ) ;
} /* end main */
• Figure 3.33..
The source code file for the example program (continued)
ManagingMemory 139 .
} /* end switch */
} /* end Wndproc */
MRESULT EXPENTRY Create (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
HPS Hpresspace; /* Presentation space handle.
FONTMETRICS Metrics; /* Structure to hold font dimensions.
LONG Numberstructs = 1; /* Number of structures from GpiQueryFonts
} /* end Create */
• Figure 3.33..
The source code file for the example program (continued)
• 140 Programmer's Guide to the os/2 Presentation Manager
MRESULT EXPENTRY Paint (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
register int Line; /* Loop counter.
HPS Hpresspace; /* Presentation space handle.
RECTL Rect; /* Window coordinates, in pixels.
SHORT StopLine; /* Last line to paint.
POINTL Start; /* Starting position to print string
SHORT LineLength; /* Length of each line displayed.
Hpresspace WinBeginpaint
(hwnd /* Window handle.
0, /* Handle of PS to have clipping region set. */
0); /* Address of variable to set to update region.*/
/*** Create a logical font for this presentation space. **********************/
GpicreateLogFont
( Hpresspace , /* Presentation space handle.
( PSTR8 ) NULL , /* Logical font name: none.
ID COURIER, /* Local font ID.
&F6ntAttributes) /* Struct. specifying font from GpiQueryFonts.
/*** Make the logical font the current character set. ************************/
Gpisetcharset
( Hpresspace , /* Presentation space handle.
ID COURIER) ; /* Local font ID.
WinQuerywindowRect /* Get dimensions of window.
( hwnd , /* Window handle.
&Rect) ; /* Structure to receive coordinates.
WinF i l lRect /* Erase window.
(Hpresspace , /* Presentation space handle.
&Rect, /* Structure containing window coordinates.
CLR WHITE) ; /* Color to use (white) .
/*** Set foreground color used by 'GpicharstringAt'. *************************/
Gpisetcolor
(Hpresspace, /* Presentation space handle. */
CljR BIACK); /* Color to use: black. */
/*** Print lines from beginning of file within client window. ****************/
Start.x -0;
for (Line = 0, Start.y = ywin -ycharTot + ycharDesc; Line <= StopLine;
++I,ine, Start.y -= ycharTot)
(
if ((LineLength = GetLineLength (Line)) == 0)
continue;
GpicharstringAt /* Prints string at given position.
(Hpresspace, /* Presentation space handle.
• Figure 3.33..
The source code file for the example program (continued)
ManagingMemory 141 .
WinEndpaint (Hpresspace) ;
return FALSE;
) /* end Paint */
MRESULT EXPENTRY Size (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/*** Obtain vertical dimension of client window. ****************************/
ywin = SHORT2FROMMP (mp2) ;
return FALSE;
} /* end Size */
} /* end Buflnit */
• Figure 3.33®®
The source code file for the example program (continued)
• 142 Programmer's Guide to the os/2 Presentation Manager
(
''no error",
''file open failure",
''file too large",
''maximum lines exceeded",
"heap memory allocation failed",
''unidentified error''
in
if (ErrorNumber >= sizeof (MessageTable) / sizeof (char *))
ErrorNumber = sizeof (MessageTable) / sizeof (char *) - 1;
return MessageTable [ErrorNumber] ;
} /* end ErrorMessage */
• Figure 3.33..
The source code file for the exJrmple program (continued)
ManagingMemory 143 .
/*** Read each line in file into a separate block allocated from heap. *******/
LastLine = -1;
while (fgets (LineBuffer,LINEBUFSIZ-1,PtrFile) != NULL)
(
/*** Test for line limit --update 'LastLine'. *********************/
if (++LastLine >= MAXLINES)
return (ERRMAXLINES) ;
} /* end of ReadFile */
• Figure 3®33..
The source code file for the example program (continued)
• 144 Programmer's Guide to the os/2PresentationManager
} /* end GetLineLength */
} /* end GetLineAddr */
void Quit
(int Errorcode) /* Process termination status.
/*
Calls Presentation Manager termination functions and ends program
with specified error code.
*/
(
if (HHeap != NULL)
WinDestroyHeap (HHeap) ;
WinDestroywindow (HFrame) ;
WinDestroyMsgQueue (HMesQue) ;
WinTerminate (HAncBlk) ;
exit (Errorcode) ;
) /* end Quit */
• Figure 3.33..
The source code file for the example program (continued)
147.
.I
he version of the example program presented in this
chapter allows you to view any portion of the file that is
specified on the command line. Horizbntal and vertical
scroll bars are added to the standard Window, allowing
you to scroll through the file in any direction using either the mouse or
thekeyboard.Althoughthisversiondoesnotyetperinityoutomodify
or add file data, it serves as a convenient utility for viewing a text file
within a Presentation Manager window, and you might want to keep a
copy of the program for this purpose.
In this chapter you will learn how to create horizontal and vertical
i
scroll bars and how to maintain the scroll bar sliders in their correct
relativepositions;youwillleamhowtoscrouthecontentsofthescreen
in response to messages from the scroll bars; and you will learn how to
invoke the window-drawing routine whenever needed. You will also
discover how to increase efficiency by redrawing only the portion of the
window that requires updating (the invalid region). Finally, the chapter
offers several suggestions for enhancing the program.
Note that the buffer-management module is unaltered from the pre+
vious version; the current version, however, is able to display any por-
tion of the data within the buffer and not just the first page. The complete
program listing is given in Figure 4.25, at the end of the chapter.
actions; these codes are explained later in the chapter.) By clicking the
mouse pointer on various parts of the horizontal scroll bar, you can
scroll the window right or left either by a single column or by a ``page"
(in this program, a page is six columns). You can also move the screen to
any horizontal position in the file by clicking and dragging the slider
(that is, clicking the mouse with the pointer on the slider and moving
the pointer with the button held down). Scrolling horizontally enables
you to view various portions of lines that are longer than the current
width of the window. The position of the slider indicates the relative
horizontal position of the window with respect to the file.
You can use the vertical scroll bar in a similar fashion to scroll up and
down by one line or one page (a page is an entire screen of data), and to
move up or down to any relative position in the file. As you will see, the
program also allows you to scroll through the file using the arrow keys
and the Pgup and PgDn keys.
Note that in this book, the term scrozJ€7ig #p means that the view
within the window moves toward the beginning of the file (even
though the lines actually move down), and scroJJz.77g dozo77 means that
the view moves toward the end of the file. Also, scrozzj7zg r3.gJtf means
moving the view in the window toward the right ends of the lines, and
scroJJj77g Jc# means moving the view toward the beginnings of the lines.
• Figure 4.1..
The standard window created by the current version of the exanple program
UsingscrollBars 149 .
SLIDER
Drag to Move to Plelative File Position
(SB_SLIDEBPOSITION)
€ +
• Figure 4.2..
The anatony of the horizontal and vertical scroll bars
•150 Programmer's Guide to the OS/2 Presentation Manager
The window with the focus is the one that receives keyboard input
through messages (note that at a given time, there may be no focus win-
dows). The focus must be assigned to the client window so that the
client window procedure will receive any messages generated by the
WinsetFocus
Purpose..
Assigns the focus to the specified window.
Prototype..
BO0L APIENTRY WinsetFocus
(HWND hiirndDesktop, Handle of the desktop window,
HWND DESKTOP.
HWND hwndsetFocus) ,. Handle of the window to receive the
focus (which must be a descendant
window of the desktop window).
Return Value ..
TRUE if the function was successful; FALSE otherwise.
Notes..
You can determine the window that has the current focus by
calling WinQueryFocus.
RelatedFunctions..
WinQueryFocus (Figure 5.10)
• Figure 4.3..
The WinsetFocus Presentation Manager function
UsingscrollBars 151 .
arrow or Pgup/PgDn keys. Note that the window with the focus ap-
pears on top of all other windows.
There are two more common terms related to the concept of the focus
window. First, the ¢c£1.zJc zt7!.#dozu is the top-level window (that is, an im-
mediate child of the desktop window) that is placed above all other top-
level windows. If the active window is a standard window, its title bar
and sizing border appear highlighted; if it is a dialog box (see Chapter
8), its entire border is highlighted to indicate the active status. The focus
window (if one currently exists) is always either the active window or a
descendant of the active window. The active and focus windows are set
either by a program action (such as calling WinsetFocus), or by a user
action (through the keyboard or mouse). Second, th.e program that cur-
rently owns the active window is known as the ¢cfi.z7c ¢ppJ1.co£!.o71.
Other than specifying the two scroll bar styles in the call to Win-
Createstdwindow, and calling WinsetFocus to assign the focus to the
client window, the function main is the same as it was in the previous
version of the example program. To initialize and maintain scrou bars,
however, the window procedure of the current version must provide
some additional code in the routines that process the WM_CREATE
and WM_SIZE messages (these messages were described in Chapter 3).
MRESULT EXPENTRY Create (HWND hwnd, USHORT msg, MPAFun mpl, MPARAM mp2)
(
/*** Get handles to horizontal and vertical scroll bar windows. **************/
HHScroll = WinwindowFromlD
(WinQuerywindow (hwnd, QW_PARENT,FALSE) , /* Handle to parent */
/* window (frame). */
FID HORZSCROLL) ; /* Identifier for vertical scroll bar. */
HVscroll = WinwindowFromlD
(WinQuerywindow (hwnd, QW_PARENT,FALSE) , /* Handle to parent */
/* window (frame). */
FID VERTSCROLL) ; /* Identifier for vertical scroll bar. */
return FALSE;
} /* end Create */
• Figure 4.4..
The function Create from the example program
UsingscrollBars 153 .
WinwindowFromlD
Purpose..
Returns the handle belonging to a child window.
Prototype..
IIWND APIENTRY WinwindowFromlD
(IIWND hwndparent , Handle of the parent of the window.
USHORT id) ,. Identifier of the child window.
Return Value ..
If successful, returns the handle of the window that is the
child of the window specified by the first parameter, and
that has the ID given by the second parameter. If an error oc-
curs, the value NULL is returned.
• Figure 4.5..
The WENindowFrornlD Presentation Manager function
• 154 Programmer's Guide to the os/2 Presentation Manager
WinQuerywindow
Purpose..
Returns the handle of the window that has the selected
relationship to a specified window.
Prototype..
IIWND APIENTRY WinQuerywindow
(HWND hwnd, Handle of the window to query.
SHORT cnd, Specifies the relationship of the window
whose handle is to be returned to the
window specified by hwnd; you can select
one of the following values:
Value Meaning
QW_NEXT Next window below
QW_PREV Next window above
QW_TOP Top-most child
window
QW_BOTTOM Bottom-most child
window
QW_NEXTTOP Next top-level
window that would
be activated by the
Alt-Esc key of the
user interface
QW_PREVTOP Previous top-level
window in the
sequence of windows
activated by the
Alt-Esc key
QW_OWNER Owner of the window
QW_PARENT Parent of the window
• Figure 4.6..
The WinQnery:Window Presentation Manager function
UsingscrollBars 155 .
Return Value ..
The handle of the window related to hwnd, or NULL if an
error occurred.
• Figure 4.6..
The WLriQnery:Window Presentation Manager function (continued)
client window; both of these values will be used by this function and by
the routines that process subsequent messages, such as WM_PAINT.
Next, the function Size calculates the value of TopLineMax, which
contains the largest line number that will be placed at the top of the
window as the window data are scrolled. The expression used to calcu-
late this value,
assures that the window is not scrolled down farther than necessary to
show the last line in the file (remember that file lines are numbered
beginning with 0). Note that as the window becomes smaller vertically,
TopLineMax becomes larger (except in the case where the file data does
not completely fill the window; in this case TopLineMax remains 0).
Therefore, TopLineMax must be recalculated each time the window
changes size; accordingly, the expression is placed in the function Size
rather than in Create.
Once TopLineMax has been calculated, the program reassigns the
variable TopLine, which is the number of the file line currently dis-
played at the top of the window, to make sure that it does not exceed the
maximum value contained in TopLineMax. (TopLine is initialized to 0.)
Note that the WM_PAINT message is sent shortly after the WM_SIZE
1.
UsingscrollBars 157 .
message; the routine that processes WM_PAINT will use the updated
value of TopLine to paint the appropriate lines within the window.
At this point, the function Size sets the range and position of the
slider within the vertical scroll bar (see Figure 4.2). Note that your pro-
gram is responsible for maintaining the slider; the scroll bar does 7io£
perform this action automatically (as you will see, the only automatic
lmESULT EXPENTRY Size (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/*** Update 'TopLine' and adjust vertical scroll bar position. **************/
TopLineMax = max (0,LastLine -ywin / ycharTot + 1) ;
TopLine = min (TopLine,TopLineMax) ;
/*** Enable scroll bar only if needed (TopLineMax > 0). ****************/
WinEnablewindow
return FALSE;
} /* end Size */
• Figure 4.7:
The function Size from the example progran
• 158 Programmer's Guide to the os/2 Presentation Manager
action taken by a scroll bar is to send messages to report input from the
user). You must set the following two values for the slider:
slider position (the low-order word is set to the position and the high-
order word is 0), and the second gives the slider range (the low-order
word contains the minimum range value and the high-order word the
maximum value). These parameters are constructed using the OS/2
macro MPFROM2SHORT, described in Table 3.2.
Note that WinsendMsg causes the system to send a message by
directly calling the window procedure belonging to the target window;
the message is rzof placed in the message queue. In contrast, the Presen-
tation Manager function WinpostMsg sends a message by placing it in
the message queue of the target window.
The function Size next makes sure that the vertical scroll bar window
is enabled only if the file contains sufficient data to warrant vertical
scrolling. If the scroll bar window is disabled, it still appears on the
screen; however, if the user clicks the mouse on this window, the win-
dow procedure merely beeps and does 71of send messages to the client
window. The program sets the enabled status of this window by calling
the Presentation Manager function WinEnablewindow (Figure 4.10).
The first parameter to this function is the handle of the specific window;
if the second parameter is TRUE, the window is enabled, and if it is
FALSE, the window is disabled. The program passes the handle of the
vertical scroll bar window, and enables this window only if TopLine-
Max is greater than 0 (otherwise, no scrolling is possible).
The program next calculates the value of the program variable First-
ColMax based upon the current window dimensions. This variable
contains the number of the greatest file column that can be displayed at
the far left of the window (the file column number is the offset of a char-
acter within a line in the file buffer). The expression used to calculate
this value,
assures that the window does not scroll farther to the right than is neces-
sary to display the longest possible line in the file (LINEBUFSIZ -2). The
program then updates the value of Firstcol, which contains the num-
ber of the file column currently displayed at the far left of the window,
to make sure that this variable does not exceed the maximum value
contained in FirstcolMax.
Finally, the program sends a message to set the range and position of
the horizontal scroll bar slider in the same manner that it set the vertical
• 160 Programmer's Guide to the os/2 PresentationManager
WinsendMsg
Purpose,
Sends a message to the specified window.
Prototype..
MRESULT APIENTRY WinsendMsg
(HWND hwnd, Handle of the target window.
USHORT msg, The identifier of the message that is being
sent.
MPARAM mpl , The first message parameter; the meaning is
specific to the message.
MPARAM mp2 ) ,. The second message parameter; the meaning
is specific to the message.
Return Value ..
The value that is returned by the window procedure of the
target window.
Notes..
This function causes the system to directly invoke the win-
dow procedure belonging to the target window; the message
is not placed in the window's message queue (you can place
a message in the target window's queue by calling Winpost-
Msg). WinsendMsg does not return until the message has
been processed (unlike WinpostMsg, which returns imme-
diately after the message is placed in the queue).
Relate d Functions ..
WinpostMsg (Figure 12.11)
• Figure 4.8..
The Winser\d:Mss Presentation Manager function
UsingscrollBars 161 .
SBM SETSCROLLBAR
Purpose..
This message is sent to a horizontal or vertical scroll bar win-
dow to cause it to set the range and position of the scroll bar
slider.
Parameters..
ueARAM mpl
low-order word: Slider position.
high-order word: 0
REARAM mp2
low-order word: Low value of range.
high-order word: High value of range.
Return Value ..
TRUE if the operation was successful, or FALSE if an error
occurred.
Notes..
The system procedure for the scroll bar window immedi-
ately redraws the scroll bar to reflect the requested values.
See also SBM_SETPOS (Figure 4.17), which sets only the
slider position.
• Figure 4.9..
The SBM~SETSCROLLBAR Presentation Manager message
• 162 Programmer's Guide to the os/2PresentationManager
WinEnablewindow
Purpose..
Enables or disables the specified window.
Prototype..
BOOL APIENTRY WinEnablewindow
(HWND hwnd, The window handle.
BooL fEnable) ,. If this parameter is TRUE thewindowis
enabled; if it is FALSE, the window is
disabled.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
If the enabled state of the target window is changed through
this function call, this window is sent a WM_ENABLE mes-
sage. The changes in the window's appearance and function
between the enabled and disabled state depend upon the
specific window.
• Figure 4.10..
The WinEnablewindow Presentation Manager message
UsingscrollBars 163 .
PROCESSING
• THE SCROLLBARMESSAGES
As mentioned earlier in the chapter, the only action initiated by
the scroll bar windows is to send messages to the client window to
report input from the user. To generate the actual scrolling of data and
to update the scroll bar slider positions, the client window procedure
must receive and process these messages. The horizontal scroll bar
sends the general message WM_HSCROLL, and the vertical scroll
bar sends the general message WM_VSCROLL. Each of these messages
is accompanied by a code indicating the exact scrolling activity that has
taken place. (Actually, the scroll bar windows send these messages to
their owner, the frame window; the frame window then passes the mes-
sages to the client window.)
Accordingly, the main switch statement of the client window proce-
dure (Wndproc) must contain branches for processing these two new
messages. The current version of Wndproc is listed in Figure 4.11. Note
that this function also contains a branch for the WM_CHAR message,
which will be explained in the next main section, Rerouting Keyboard
Input.
} /* end switch */
} /* end Wndproc */
• Figure 411..
The Wndproc function of the example program
WM HSCROLL
Purpose..
Sent by a horizontal scroll bar window to its owner to report
relevant scroll bar events.
Parameters..
REARAM mpl The scroll bar window identifier.
REARAI mp2
low-order word: Contains the position of the slider if
the high-order word equals
SB SLIDERPOSITION or
SB-SLIDERTRACK; otherwise, it is set
to FALSE.
high-order word: A code for the specific event; these
codes are described in Table 4.2.
Return Value ..
FALSE.
• Figure 4.12..
The WM_HSCROLL Presentation Manager message
MRESULT EXPENTRY HScro|| (HWND hwnd, USHORT msg, MPARAM mpl, MPAEN mp2)
(
case SB LINELEFT:
Delta --1;
break;
case SB LINERIGHT:
Delta -1;
break;
case SB PAGELEFT:
Delta --6;
break;
case SB PAGERIGHT:
Delta -6;
break;
case SB SLIDERPOSITION:
Delta = SHORTIFROMMP (mp2) -Firstcol;
break;
default:
Delta -0;
break;
)
Delta = max (-Firstcol, min (Delta,FirstcolMax -Firstcol)) ;
if (Delta)
(
/*** Adjust first column value. ************************************/
Firstcol += Delta;
/*** Scroll the window data. ***************************************/
Winscrollwindow
(hwnd, /* Handle of client window.
-Delta * xchar, /* Horizontal scroll amount.
0, /* Vertical scroll amount.
0' /* Must be o.
0, /* Must be o.
0, /* Must be o.
0, /* Must be o.
SW INVALIDATERGN) ; /* Invalidate "exposed" region.
} /* end HScroll */
• Figure 4.13..
The function HScroll of the example progran
• 168 Programmer's Guide to the os/2PresentationManager
Once the program has determined the initial value for Delta, it ad-
justs this value to make sure that when Delta is combined with First-
Col, the result is within the valid range from 0 to FirstcolMax. This
adjustment is accomplished through the following expression:
Next, provided that Delta is not 0, the program updates the value of
Firstcol, scrolls the window data, forces repainting of the resulting in-
valid region of the window, and adjusts the horizontal scroll bar posi-
tion. The value of Firstcol is adjusted by the number of columns stored
in Delta. As you will discover, the subsequent actions of this routine
will cause the system to invoke the window-painting function Paint
(through the WM_PAINT message); Paint will use the value in Firstcol
to display the correct portions of the file lines (that is, it will display the
lines beginning with the character having the offset given by Firstcol).
The program scrolls the data within the window by calling the
Presentation Manager function Winscrollwindow (Figure 4.14). This
function scrolls the data in the specified window (hwnd, the client win-
dow) horizontally by the amount specified in the second parameter
(dx), which is assigned the following value:
-Delta * xchar
The - sign is required, because a positive Delta means to scroll the zuz.7z-
dozo to the right and therefore move the d¢f¢ to the left; to move the data
left, however, you must pass Winscrollwindow a negative dx value.
Therefore, Delta and dx must have opposite signs. Note from Figure
4.14 that the scrolling distance is specified in cZczJ1.cc I/71z.fs; for the presen-
tation space used by the example program, these units are screen pixels
(conveniently, the same units used for the total window size and for the
character dimensions).
The last parameter to Winscrollwindow (rgfsw), specifies the scroll-
ing options. The example program passes the value SW_IN-
VALIDATERGN, which causes the function to 1.7it7¢Zz.d¢£c the region of
the window that is left behind when the existing data are moved.
Remember from Chapter 2 that an invalid region of a window is an area
that must be repainted, and when a section of a window becomes
UsingscrollBars 169 .
Winscrollwindow
Purpose..
Scrolls the contents of a window a specified horizontal and
vertical distance.
Prototype..
SHORT APIENTRY Winscrollwindow
(- hund, Handle of window to scroll.
SHORT dr[, The amount (in device units) to move
the window data to the right with
respect to the window (a negative
value moves the data left).
SHORT dy' The amount (in device units) to move
the window data up with respect to
the window (a negative value moves
the data down).
PRECTL prclscroll, Points to a RECTL structure (Figure
2.22) containing the dimensions of the
rectangular section of the window to
be scrolled; a value of NULL causes
the entire window to be scrolled.
PRECTL preclclip, Points to a RECTL structure containing
the dimensions of the clip rectangle.
mGIN hrgnupdate , If not NULL, hrgnupdate is assigned
the region uncovered by the scroll.
PRECTL prclupdate, Points to a RECTL structure that will
be assigned the dimensions of the
rectangle invalidated as a result of
scrolling.
• Figure 4.14..
The Winscldrl:Window Presentation Manager f unction
• 170 Programmer's Guide to the os/2 Presentation Manager
Option Meaning
SW SCROLLCHILDREN Scroll an child
windows
SW INVALIDATERGN Invalidate the
region(s) of the
screen that
remain after the
data is scrolled
Return Value ..
One of the following codes, indicating the shape of the in-
valid region remaining after scrolling the window.
Notes..
If the window data is scrolled both vertically and horizontal-
ly, a complex invalid region can result (not a simple rec-
tangle). The dimensions of the update rectangle returned by
the WinBeginpaint function, however, are for the smallest
simple rectangle that bounds the entire invalid region.
Related Functions ..
WinBeginpaint (Figure 2.20)
• Figure 4.14..
The WLnscachl:Window Presentation Manager f unction ( continued)
UsingscrollBars 171 .
I,
his is line one
his is line two
his is line thre
his is line fou
his is line five
• Figure 4.15..
The invalid area created by scrolling a window horizontally
UsingscrollBars 173 .
Winupdatewindow
Purpose..
Causes the system to send a WM_PAIP`IT message to the
specified window by directly calling the window procedure.
Prototype..
BOOL APIENTRY Winupdatewindow
(IIWND hwnd) ,. The handle of the window to be updated.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
The window procedure of the specified window is called
directly with the WM_PAIP`IT message; this message is 71of
placed in the window's message queue. If the target window
belongs to the current thread, this function does not return
until the WM_PAINT message has been processed.
• Figure 4.16..
The WLnupdate:Window Presentation Manager function
SBM SETPOS
Purpose..
This message is sent to a horizontal or vertical scroll bar win-
dow to cause it to set the position of the scroll bar slider.
Parameters..
REAEN mpl
low-order word: New position of slider.
high-order word: 0.
I@ARAM mp2 0.
Return Value ..
TRUE if the operation was successful, or FALSE if an error
occurred.
Notes..
The system procedure for the scroll bar window immedi-
ately redraws the scroll bar to reflect the requested values.
See also the message SBM_SETSCROLLBAR (Figure 4.9),
which sets both the slider position and the slider range.
• Figure 4.17..
The SBM_SETPOS Presentation Manager message
WM VSCROLL
Purpose..
Sent by a vertical scroll bar window to its owner to report
relevant scroll bar events.
Parameters..
IffARAM mpl The scroll bar window identifier.
REAEN mp2
low-order word: Contains the position of the slider if
the high-order word equals
SB SLIDERPOSITION or
SB-SLIDERTRACK; otherwise, it is set
to FALSE.
high-order word: A code for the specific event; these
codes are described in Table 4.3.
Return Value ..
FALSE.
• Figure 4.18..
The WM_VSCROLL Presentation Manager message
ywin / ycharTot
MRESULT EXPENTRY Vscroll (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
if (Delta)
(
/*** Adjust top line value. ****************************************/
TopLine += Delta;
/*** Update the position of the vertical scroll bar slider. ********/
WinsendMsg
(HVscroll , /* Handle to vertical scroll bar. */
SBM SETPOS /* Set position of slider. */
• Figure 4.19..
The function Vscro+i of the example program
• 178 Programmer's Guide to the os/2 Presentation Manager
} /* end Vscroll */
• Figure 4.19..
The function Vscrchl of the example program (continued)
• Figure 4.20..
The invalid area created by scrolling a window vertically
UsingscrollBars 179 .
MRESULT EXPENTRY Character (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/*** Send arrow and Pgup/PgDn key messages to appropriate scroll bars. *******/
switch (CHARMSG (&msg) ->vkey)
(
case VK UP: /* Up-arrow key.
case VK-DOWN: /* Down-arrow key.
case VK-PAGEUP: /* Page Up key.
case VK-PAGEDOWN: /* Page Down key.
return WinsendMsg (HVscro'll, in;g, mpl, mf>2) ;
} /* end Character */
• Figure 4.21..
The function ChaLracteT of the example program
Note that the arrow and Pgup/PgDn keys are among the keystrokes
identified by zJz.rftMJ codes (used to label keys that do not have simple
ASCII character codes). The virtual code is contained in one of the mes-
sage parameters, and it is extracted using the special macro for charac-
ter messages, CHARMSG; virtual keys and the CHARMSG macro will
be explained in Chapter 6. Table 4.4 lists the codes for each virtual key,
the identity of the key, the scroll bar that is sent the key message, and
the message that the scroll bar sends to the client window when it
receives the key.
this structure the dimensions of the invalid region of the client window.
Accordingly, the subsequent call to the function WinFillRect (Figure
2.23), which is passed the address of Rect, erases only the invalid area.
(Note that the call to WinQuerywindowRect is no longer needed.)
Theprogramnowcalculatestherangeoffilelinesthatneedtobedis-
played within the invalid area. StartLine is the first line in this range
and StopLine is the last. These values are calculated as follows:
MRESULT EXPENTRY Paint (HWND hwnd, USHORT msg, MPARAM mpl, MPARjun mp2)
(
register int Line; /* Loop counter.
HPS Hpresspace; /* Presentation space handle.
RECTL Rect; /* Window coordinates, in window coordinates.
SHORT StartLine; /* First file line to paint.
SHORT Stopljine ; /* Last line to paint.
POINTL Start; /* Starting position to print string.
SHORT LineLength; /* Length of each line displayed.
/*** Get presentation space and coordinates of invalid region in window.
Hpresspace = WinBeginpaint
(hwnd,
0' /: ¥::a:: ::ns.:eto have clipping region Set. :/
&Rect) ; /* Address of struct. to set to invalid region.*/
GpicreateLogFont /* Create a logical font for presentation space*/
(Hpresspace,
( PSTR8 ) NuljL ,
ID COURIER,
&F6ntAttributes)
;; :§§:::::;:::D;::::f::i::e:onstant. ;;
/* Struct. specifying font from GpiQueryFonts. */
Gpisetcharset /* Make logical font the current character set.*/
(Hpresspace , /* Presentation space handle. */
ID COURIER) ; /* Local font ID. */
WinFillRect
• Figure 4.22..
The function Palul of the example program
UsingscrollBars 183 .
i:::i;:::;;;:?::::,,,;;i!:i:i:::::::::i::::a:::::I::.posltlon.;j
)
WinEndpaint (Hpresspace) ;
return FALSE;
) /* end paint */
• Figure 4.22..
TirefunctionPalritoftheexampleprogram(continued)
lines above the end of the invalid region to TopLine; using the min
macro, however, assures that StopLine will not be assigned a value
larger than the number of the last line in the file (LastLine).
Next, the program determines the pixel coordinates of the starting
point of the first line to be displayed (at the top of the invalid region).
The y-coordinate of the starting point, Start.y, is calculated as follows:
Remember that Firstcol is the offset of the character within the file
line that is to appear at the left edge of the window. The call to Gpi-
CharstringAt, however, always specifies the address of the beg{.777i!.7ig
of the line (the address of character 0 within this line). If Firstcol is 0,
then Start.x is assigned 0, and character 0 gets printed at the left of the
• 184 Programmer's Guide tothe os/2Presentation
Manager
• ENHANCEMENTS
As mentioned at the beginning of the chapter, the current version
of the example program can be used as a practical utility for viewing
text files within a Presentation Manager window. You might want to en-
hance the program for this purpose by adding one or more of the fol-
lowing features (the techniques are described in subsequent chapters):
You could display the name of the current file within the title bar
using the WinsetwindowText function. This technique i5 also
presented in Chapter 8.
UsingscrollBars 185 .
• CONCLUSION
Youcanpreparethecurrentversionoftheexampleprogramusing
the MAKE file listed in Figure 4.23. A linker definition file is given in
Figure 4.24, and the complete source listing for the program is provided
in Figure 4.25.
This chapter has described how to use the facilities of the Presenta-
tion Manager programming environment to view any portion of the file
contained in the internal data buffer. Before presenting the methods for
modifying and saving this data, however, Chapter 5 explores the tech-
niques for creating and mo.ving a cursor to any position within the file.
# Figure 4#ThisMAK .23Efile prepares the program of Figures 4.24 and 4.25
#
FIG4 25.OBJ : FIG4 25.C
I
cl /W2 /c /7;p /r:%Ns FT!f 34_2:F>.C
FIG4 25.EXE : -
FIG4 25.OBT FIG4 24.DEF
link /N OD FIGZ 25.OBJ,, NUL, OS2.LIB SLIBCE.LIB, FIG4_24.DEF
• Figure 4.23..
A MAKE file for preparing the example program
NAME FIG4 25
PROTMODE
HEAPSIZE 1024
STACKSIZE 8192
EXPORTS Wndproc
• Figure 4.24..
A linker definition file for preparing the example program
• 186 Programmer'sGuidetothe os/2Presentation
Manager
Figure 4.25
MRESULT EXPENTRY Wndproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2) ;
• Figure 4.25..
The source code file for the example program
UsingscrollBars 187 .
WinsetFocus
(HWND DESKTOP, /* Handle for desktop window.
Hclierit) ; /* Client window handle.
• Figure 4.25..
The source code file for the example program (continued)
• 188 Programmer's Guide to the os/2 Presentation Manager
Quit (0) ;
} /* end main */
• Figure 4.25..
The source code file for the example program (continued)
UsingscrollBars 189 .
} /* end switch */
} /* end Wndproc */
MRESULT EXPENTRY Character (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/*** Send arrow and Pgup/PgDn key messages to appropriate scroll bars. *******/
switch (CIIARMSG (&msg) ->vkey)
(
case VK UP: /* Up-arrow key.
case VK-DOWN: /* Down-arrow key.
case VK-PAGEUP: /* Page Up key.
case VK-PAGEDOWN: /* Page Down key.
return WinsendMsg (HVscroll, msg, mpl, mp2) ;
case VK LEFT: /* Left-arrow key.
case VK-RIGHT: /* Right-arrow key.
return WinsendMsg (HHScroll, msg, mpl, mp2) ;
default:
return FALSE;
)
} /* end Character */
MRESULT EXPENTRY Create (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
HPS Hpresspace; /* Presentation space handle.
FONTMETRICS Metrics; /* Structure to hold font dimensions.
LONG Numberstructs = 1; /* Number of structures from GpiQueryFonts
GpiLoadFonts /* Load Courier font.
(HAncBlk, /* Anchor block handle.
"\\OS2\\DLL\\COURIER.FON") ; /* Full path name of font file.
• Figure 4.25..
The source code file for the erample program (continued)
• 190 Programmer's Guide to the os/2 Presentation Manager
/*** Get handles to horizontal and vertical scroll bar windows. **************/
HHScroll = WinwindowFromlD
(WinQuerywindow (hwnd, QW_PARENT , FALSE ) ,
/: :::8:: i:r:::;Tt :/
FID_HORZSCROLL) ; /* Identifier for vertical scroll bar. */
HVscroll = WinwindowFromlD
(WinQuerywindow (hwnd, QW_PARENT , FALSE ) , /* Handle to parent */
/* window (frame). */
FID_VERTSCROLL) ; /* Identif ier for vertical scroll bar. */
return FALSE;
} /* end Create */
MRESULT EXPENTRY HScroll (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
SHORT Delta; /* Amount to scroll. */
case SB LINELEFT:
Delta --1;
break;
case SB LINERIGHT:
Delta -1;
break;
case SB PAGELEFT:
Delta --6;
break;
• Figure 4.25..
The source code file for the example program (continued)
UsingscrollBars 191 .
case SB PAGERIGHT:
Delta -6;
break;
case SB SLIDERPOSITION:
Delta = SHORTIFROMMP (mp2) -Firstcol;
break;
default:
Delta -0;
break;
)
Delta = max (-Firstcol, min (Delta,FirstcolMax -Firstcol)) ;
/*** Scroll the window if necessary. *****************************************/
if (Delta)
(
/*** Adjust first column value. ************************************/
Firstcol += Delta;
/*** Scroll the window data. ***************************************/
Winscrollwindow
(hwnd, /* Handle of client window.
-Delta * xchar, /* Horizontal scroll amount.
0, /* Vertical scroll amount.
0, /* Must be 0.
0, /* Must be o.
0, /* Must be o.
0, /* Must be o.
SW INVALIDATERGN) ; /* Invalidate "exposed" region.
/*** Update the position of the horizontal scroll bar slider. ******/
W±nse:::S:=:::5 , /: g::d::s::i::r:=o::::e::roll bar.
} /* end IIScroll */
MRESULT EXPENTRY Paint (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
register int Line; /* Loop counter.
HPS Hpresspace; /* Presentation space handle.
RECTL Rect; /* Window coordinates, in window coordinates.
SHORT StartLine; /* First file line to paint.
SHORT StopLine; /* Last line to paint.
POINTL Start; /* Starting position to print string.
SHORT LineLength; /* Length of each line displayed.
/*** Get presentation space and coordinates of invalid region in window.
• Figure 4.25..
The source code file for the example program (continued)
• 192 Programmer's Guide to the os/2PresentationManager
Hpresspace = WinBeginpaint
( hwnd , /* Window handle. */
0' /* Handle of PS to have clipping region set. */
&Rect) ; /* Address of struct. to set to invalid region.*/
GpicreateLogFont /* Create a logical font for presentation space*/
( Hpresspace , /* Presentation space handle. */
( PSTR8 ) NULL , /* Logical font name: none. */
ID COURIER, /* Local font ID: define a constant. */
&F6ntAttributes) /* Struct. specifying font from GpiQueryFonts. */
Gpisetcharset /* Make logical font the current character set.*/
( Hpresspace , /* Presentation space handle. */
ID COURIER) ; /* Local font ID. */
/*** Erase invalid region only. **********************************************/
WinFillRect
(Hpresspace, /* Presentation space handle.
&Rect, /* Structure containing window coordinates.
CLR WHITE); /* Color to use (white).
WinEndpaint (Hpresspace) ;
return FALSE;
) /* end Paint */
MRESULT EXPENTRY Size (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
• Figure 4.25..
The source code file for the example program (continued)
UsingscrollBars 193 .
/*** Adjust range and position of vertical scroll bar slider. ****************/
WinsendMsg /* Send window message.
(HVscroll, /* Recipient handle: vertical scroll bar.
SBM SETSCROLLBAR, /* Set position & range.
MPFEOM2SHORT (TopLine, 0) , /* Position.
MPFROM2SHORT (0, TopLineMax) ) ; /* Range.
/*** Adjust range and position of horizontal scroll bar slider. **************/
WinsendMsg /* Send message.
(HHScroll, /* Recipient handle: vertical scroll bar.
SBM SETSCROLLBAR, /* Set position & range.
MPFROM2SHORT (Firstcol, 0) , /* Position
MPFROM2SHORT (0, FirstcolMax) ) ; /* Range.
return FALSE;
} /* end Size */
MRESULT EXPENTRY Vscroll (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
SHORT Delta; /* Amount to scroll. */
• Figure 4.25..
The source code file for the example program (continued)
• 194 Programmer's Guide to the os/2 Presentation Manager
case SB PAGEUP:
Delta = -ywin / ycharTot;
break;
case SB PAGEDOWN:
Delta = ywin / ycharTot;
break;
case SB SLIDERPOSITION:
Delta = SHORTIFROMMP (mp2) -TopLine;
break;
default:
Delta -0;
break;
)
Delta = max (-TopLine, min (Delta,TopLineMax -TopLine)) ;
return FALSE;
} /* end Vscroll */
• Figure 4.25..
The source code file for the example program (continued)
UsingscrollBars 195 .
LineTable [MAXLINES] ;
} /* end Buflnit */
} /* end ErrorMessage */
• Figure 4.25..
The source code file for the example program (continued)
• 196 Programmer's Guide to the os/2 Presentation Manager
/* Read each line in file into a separate block allocated from heap.
LastLine = -1;
while (fgets (LineBuffer,LINEBUFSIZ-1,PtrFile) != NULL)
* Test for line limit --update 'LastLine'.
f (++LastLine >= MAXLINES)
return (ERRMAXLINES) ;
} /* end of ReadFile */
• Figure 4.25..
The source code file for the example program (continued)
UsingscrollBars 197 .
} /* end GetLineLength */
} /* end GetLineAddr */
void Quit
(int Errorcode) /* Process termination status.
/*
Calls Presentation Manager termination functions and ends program
with specified error code.
*/
(
if (HHeap != NULL)
WinDestroyHeap (HHeap) ;
WinDestroywindow (HFrame) ;
WinDestroyMsgQueue (HMesQue) ;
WinTerminate (HAncBlk) ;
exit (Errorcode) ;
) /* end Quit */
• Figure 4.25..
The source code file for the example program (continued)
I pter five
Controlling th
C:ursor
199.
.I
his chapter adds a cursor to the emerging Presentation
Manager text editor. The cursor serves to mark the cur-
rent z.77scrfz.o71 poz.7if within the file, which is the position
where characters will be either inserted or deleted in
later versions of the program. The code presented in this chapter creates
a cursor and places it initially at the upper left corner of the screen; you
can then use the arrow keys to move the cursor within the window. The
arrow keys thus are no longer used for directly scrolling the file; how-
ever, if you move the cursor beyond the current edges of the window,
the contents of the screen are scrolled to reveal additional file lines or
columns. Thus, the cursor functions indirectly as a scrolling mecha-
nism. This chapter also presents routines for using the Home and End
keys to reposition the cursor at the beginning or end of the line. The
Pgup and PgDn keys, as well as the horizontal and vertical scroll bars,
serve the same function as in the previous version of the program.
In this chapter you will learn how to create, maintain, and move the
cursor. You may be surprised that an entire chapter is required to ex-
plain the logic of the cursor; under the Presentation Manager, however,
managing the cursor is much more complex than in traditional
programming environments, for several reasons. First, you must ex-
plicitly create the cursor each time the client window obtains the input
focus, and destroy the cursor whenever the window loses the focus.
Also, you must adjust the cursor position each time the window chan-
ges size; and finally, you must explicitly reposition the cursor whenever
the user scrolls the window, moves the cursor, or inserts, overwrites, or
deletes characters.
This chapter lists all of the basic routines required to manage the cur-
sor. You can incorporate these additions into the previous version of the
text editor to obtain a program that displays a file and allows you to
move the cursor to any position within this file. The complete listing of
the current version of the example program is given in Figure 6.24, at
the end of Chapter 6. This listing incorporates all of the features dis-
cussed in the current chapter, plus the full keyboard interface and
routines for editing the file that are presented in Chapter 6.
• 200 Programmer's Guide to the os/2PresentationManager
1. WM CREATE
2. WM SIZE
3. WM SETFOCUS (mp2 is set, indicating that the focus is being
recei-ved)
4. WM PAINT
WM SETFOCUS
Purpose..
Sent by the system to a window whenever it is about to
receive or lose the input focus.
Parameters..
mJ- xpl If the focus is being received, contains the
handle of the window that previously
owned the focus, or NULL if no
window owned the focus. If the focus is
being lost, contains the handle of the
window that is receiving the foous, or NULL
if no window is receiving the focus.
reAEun xp2 TRUE if the window is rccc!.z7{.7tg the focus, or
FALSE if the window is Jos!.7ig the focus.
Return Value ..
FALSE.
• Figure 5.1..
The WM_SETFOCUS Presentation Manager message
hwnd as the first parameter so that the cursor will be displayed within
the client window. The second two parameters specify the initial posi-
tion of the cursor with respect to this window. These values are given in
pixel coordinates, which are the same units used to specify the dimen-
sions of the window, the metrics of the character font, and the starting
positions of strings printed within the window. The cursor-position
coordinates specify the location of the lower left pixel of the cursor.
Note that these values specify a position within the standard window
coordinate System illustrated in Figure 3.27, in which the origin (the
position x=0, y=0) is at the lower left corner of the window.
The program maintains two global variables, CursorLine and
Cursorcol, which store the current row and column position of the
character associated with the cursor (which is displayed immediately to
the right of the cursor; the cursor shape and position will be explained
shortly). Note that the row and column positions in CursorLine and
• 202 Programmer's Guide to the os/2 Presentation Manager
MRESULT EXPENTRY SetFocus (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/*** If client window is RECEIVING focus, create cursor. *********************/
if (LONGFROMMP (mp2))
(
Wincreatecursor /* Create a new cursor.
(hwnd, /* Client window handle.
(Cursorcol - Firstcol) * xchar, /* x position of cursor.
ywin - (CursorLine - TopLine + 1) * ycharTot, /* y position
0' /* x size of cursor: nominal border.
ycharTot, /* y size of cursor.
CURSOR SOLID /* Solid cursor.
CURSOR-FIASH /* Flashing cursor.
NULL) ; /* Clipping rectangle: entire window.
/*** Make the cursor visible. *******************************************/
Winshowcursor
(hwnd, /* Client window handle. */
TRUE) ; /* Show it! */
)
/*** If client window is LOSING focus, destroy the cursor. *******************/
else
WinDestroycursor (hwnd) ;
return FALSE;
} /* end SetFocus */
• Figure 5.2..
The function SetEocus of the example program
Cursorcol refer to the location of the associated character zt7z.£fez.71 ffec ¢.Zc
Z7##er, and not the character's position within the window. These two
variables are initialized to 0, so that the cursor is initially associated
with the first character in the file (rows and columns within the file are
numbered beginning with 0). Since the position of the cursor on the
screen passed to Wincreatecursor must be specified in pixel units, the
row and column positions are converted to absolute pixel coordinates
within the window. The horizontal coordinate is calculated using the
expression
Wincreatecursor
Purpose..
Creates a cursor within the specified window.
Prototype..
B00L APIENTRY Wincreatecursor
(Hue hund, Handle of window to have the cursor.
SHORT x, Horizontal position of cursor within the
window.
SHORT y, Vertical position of cursor within the
window.
SHORT cx, Width of cursor; 0 means to use the
nominal system border width.
SHORT cy, Height of cursor; 0 means to use the
nominal system border height.
USHORT fs, The cursor style; you may combine one or
more of the fonowing values:
Value Meaning
CURsOR SOLID Solid oursor
CURsOR HALF- Halftone cursor
TONE
curoR RECT Solid rectan-
gular cursor
CURSOR FRAME Rectangular
frame cursor
CURsOR FLASH Blinking oursor
• Figure 5.3..
The WincreaLtecursor Presentation Manager function
• 204 Programmer's Guide to the os/2 Presentation Manager
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
When the cursor is first created it is invisible; you must call
Winshowcursor to make it visible. A window should create
a cursor whenever it receives the focus, and it should destroy
the cursor (WinDestroycursor) whenever it loses the focus.
RelatedFunctions..
WinDestroycursor (Figure 5.6)
Winshowcursor (Figure 5.5)
• Figure 5.3..
The WLriclea;tecursor Presentation Manager f unction ( continued)
Controllingthecursor 205 .
• Figure 5.4..
The cursor created by the exanple progran
Controllingthecursor 207 .
Winshowcursor
Purpose..
Makes visible or hides the cursor associated with the
specified window.
Prototype..
BOOL APIENTRY Winshowcursor
(HWND hwnd, Handle of the window owning the cursor
(created by calling Wincreatecursor).
BooL fshow) ,. A value of TRUE causes the function to
make the cursor visible, and a value of
FALSE causes it to hide the cursor.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Related Functions ..
Wincreatecursor (Figure 5.3)
• Figure 5.5..
The Winshowculsor Presentation Manager function
• 208 Programmer's Guide to the os/2PresentationManager
WinDestroycursor
Purpose..
Destroys the cursor associated with the specified window.
Prototype..
BOOL APIENTRY WinDestroycursor
(HWND hwnd) ,. Handle of the window owning the cursor
(created by calling Wincreatecursor).
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Related Functions ..
Wincreatecursor (Figure 5.3)
• Figure 5.6..
The W±nDestrayculsor Presentation Manager function
the Size function that automatically scrolls the file data, if necessary, so
that the insertion point always remains visible within the window. This
code is listed in Figure 5.7; note that the flag Update is defined and ini-
tialized within the Size function as follows:
The routine first determines whether the line containing the cursor
(CursorLine) falls bcJozu the last line visible in the window. If this condi-
tion is true, it adjusts the top line displayed in the window (TopLine) so
that CursorLine falls just inside the lower window boundary. Similarly,
the program tests whether the cursor falls to the ri.gfef of the visible por-
tion of the file, adjusting Firstcol if necessary. If either of these adjust-
ments is made (indicated by setting the Update flag), the program
explicitly invalidates the entire window by calling the Presentation
Manager function WinlnvalidateRect (Figure 5.8).
Invalidating a region of a windowutr the entire window-through
the WinlnvalidateRect function causes the system to send a
WM_PAINT message to the window procedure to give it an oppor-
tunity to repaint the invalid area. As described in Chapter 4 (in the sec-
tion on The WM_HSCROLL Message), this function provides a slow
• Figure 5.7..
The routine for keeping the insertion point within the window
• 210 Programmer's Guide to the os/2 Presentation Manager
WinlnvalidateRect
Purpose..
Adds a rectangular area to a window's update region.
Prototype..
BO0L APIENTRY WinlnvalidateRect
(IIWND hwnd, Handle of the window to have
its update region modified.
PRECTL prcl , Pointer to a RECTL structure
containing the coordinates of
the rectangle to add to the
window's update region (the
RECTL structure is defined in
Figure 2.22); a value of NULL
means to invalidate the entire
window.
BOOL flncludechildren) ,. If this flag is TRUE, the
function will always include
descendants of hwnd in the
invalid region; if FALSE, the
function will include
descendants in the invalid
region unless the window was
created with the
WS_CLIPCHILDREN style.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
Invalidating a region of a window will cause the system to
send a WM_PAIP\IT message to give the window the oppor-
tunity to repaint this region.
• Figure 5.8..
The WLnlrIv al±dateRect Presentation Manager f unction
Controllingthecursor 211 .
but simple mechanism for scrolling the contents of the window. Since
resizing operations are not performed in rapid succession like scrolling
operations when you hold down an arrow key, the speed of this ap-
proach is sufficient for the Size function.
window. If the user subsequently moves the cursor into the new area of
the window, it will inexplicably disappear.
The solution to both problems is for the WM_SIZE routine to com-
pletely destroy the existing cursor and then recreate the cursor, specify-
ing the new cursor location and a clipping region that is the size of the
current window (by passing NULL as the clipping rectangle
parameter). The code required to perform these steps is listed in Figure
5.9; this code is added to the Size function of the example program,
which processes the WM_SIZE message.
Note, however, that before destroying and recreating the cursor, the
program calls the Presentation Manager function WinQueryFocus (Fig-
ure 5.10) to determine whether the client window currently has the
focus. WinQueryFocus returns the handle of the current focus window.
The program destroys and recreates the cursor only if this handle
matches the handle of the client window, hwnd; otherwise, there is no
cursor associated with the client window (the cursor will be properly
/*** If client has focus, must RE-CREATE the cursor for new size. ************/
if (hwnd == WinQueryFocus /* Does client have focus?
iAF!gET?ESKToP , / : E:s:ogiT:c!e:f:3:w?andle.
(
/*** Destroy existing cursor. *******************************************/
WinDestroycursor (hwnd) ;
• Figure 5.9..
The routine in the function Size for recreating the cursor
Controllingthecursor 213 .
WinQueryFocus
Purpose..
Obtains the handle of the focus window.
Prototype..
HWND APIENTRY WinQueryFocus
(HWND hundDesktop, The handle of the desktop window;
you must assign the value
HWND DESKTOP.
BcoL fLock) ,. Lock indicator: if TRUE, the function
will lock the window (a locked
window cannot be destroyed); if
FALSE, the window will not be locked.
Return Value ..
The handle of the focus window, or NULL if there is no focus
window.
• Figure 5.10..
The WinQueryF oc:us Presentation Manager f unction
• MOVINGTHECURSOR
The two previous sections have shown how to create the cursor and
how to maintain the cursor in proximity with its associated character in
• 214 Programmer'sGuideto the os/2Presentation
Manager
the window. This section describes two situations in the current version
of the example program in which the cursor is moved to another char-
acter (as you will see, moving the cursor to another associated character
does not necessarily change the cursor position with respect to the win-
dow). First, pressing an arrow key, or the Home or End key, directly
repositions the oursor on another character. Second, the cursor is moved
to another character when the window is scrolled using a scroll bar or
the Pgup or PgDn key. (The window may also have to be scrolled when
the cursor is moved beyond the visible section of the file with the arrow,
Home, or End key.) Chapter 6 will describe the movement of the cursor
that occurs when you enter or delete characters in the file.
• Figure 5.11..
The routine for processing arrow keys
Controllingthecursor 217 .
--Cursorcol ;
break;
*******************************************/
/*** Process right-arrow key.
case VK RIGHT:
break;
• Figure 5.11..
The routine for processing arrow keys (continued)
/*** Update cursor position for all cases above that altered 'Cursorl.ine' or
'Cursorcol'. ************************************„***************************/
wincr:::::Trsor /: S::e::s:::::wo:a:::::r.
(Cursorcol - Firstcol) * xchar, /* x position of cursor.
ywin - (CursorLine - TopLine + 1) * ycharTot, /* y position.
• Figure 5.12..
The call to Wincreatecursor for updating the cursor position
Cursorcol = 0;
break;
/*** Process End key. ***************************************************/
case VK END:
• Figure 5.13..
The routines for processing the Home and End keys
• 220 Programmer's Guide to the os/2 PresentationManager
• Figure 5.13..
The routines for processing the Home and End keys (continued)
however, that in keeping with the philosophy that the cursor position
should always be visible within the window, the routine scrolls the win-
dow to the far left if the new cursor position would fall outside the cur-
rently visible range of the file lines (in other words, if Firstcol is not
equal to 0). As in the arrow-key routines, the window procedure easily
generates the appropriate scrolling action by sending a WM_HSCROLL
message to itself, via the WinsendMsg function. Note, however, that
the accompanying action code is set to SB_SLIDERPOSITION (in the
high-order word of mp2), which specifies an absolute position (0,
placed in the low-order word of mp2); the resulting message is the same
as that generated when the user moves the horizontal scroll bar slider to
the beginning of its range.
The Home-key routine concludes with a break statement, which pas-
ses control to the Wincreatecursor function call (listed in Figure 5.12)
to move the cursor to its new position.
The logic for the End key is similar to that for the Home key, but is slight-
ly more complex because the new cursor position (at the end of the dis-
played line) may be either to the right or to the left of the block of file data
Controllingthecursor 221 .
currently displayed in the window. The routine tests for both of these
conditions; if either condition is true, it performs the fouowing actions:
• It calculates a new value for Firstcol that would bring the cursor
just into the visible portion of the window (if the cursor falls to
the right of the window, it is moved to the right edge within the
window; if it falls to the left, it is moved into the window at the
left edge). Note, however, that the new value is ziof assigned to
Firstcol, but is held in the temporary variable NewFirstcol (the
reason will be explained later).
It sets the Update flag, indicating that the window must be
scrolled either right or left.
If the Update flag is set, the program then scrolls the window
horizontally by sending a message to itself, in the same manner as the
Home-key routine, except that the absolute position is specified as
NewFirstcol. Note that you cannot assign the value held in NewFirst-
Col directly to the global variable Firstcol before calling the scrolling
routine, because this routine calculates the new value of Firstcol Z7¢scd
t4po# ffee /or77zer zJ¢Jt4c of ffee z7fl7'i.¢Z7Zc (which must therefore be left intact).
Finally, whether or not the window requires scrolling, the End-key
routine assigns the appropriate new value to Cursorcol to place the
cursor at the end of the line (this value was obtained from the buffer
module function GetLineLength and was stored in the temporary vari-
able Newcursorcol). The routine then issues a break statement so that
control will pass to the call to Wincreatecursor that moves the cursor.
/*** Prc>cess
'case Page Up key.
VK PAGEUP: ***********************************************/
• Figure 5.14..
The routine for processing the Pgup and PgDn keys
Controllingthecursor 223 .
The routine for processing the Pgup and PgDn keys (which is con-
tained in the routine VirtKey) is listed in Figure 5.14. In these two
branches of the switch statement, the window procedure simply sends
itself a WM_VSCROLL message, accompanied by either the
SB PAGEUP or SB PAGEDOWN action code.
Before scrolling the window, the routine calls the function Win-
Showcursor (Figure 5.5), passing a value of FALSE as the
second parameter to hide the cursor. Making the cursor invisible
before scrolling prevents the unpleasant visual effect as the cur-
sor scrolls away from the window edge and then is moved back
to the edge when you repeatedly scroll the window by holding
• 224 Programmer's Guide to the os/2 PresentationManager
down the arrow key (the cursor appears to hammer against the
edge of the window).
At the end of the HScroll function, Wincreatecursor is called to
restore the cursor to its appropriate window location. The func-
tion call is the same as that listed`in Figure 5.12.
• Immediately before returning, HScroll calls winshowcursor
once again, this time passing TRUE as the second parameter to
make the cursor reappear.
• CONCLUSION
A MAKE file for the current version of the example program is
listed in Figure 6.22, and the definition file in Figure 6.23. Figure 6.24
provides a complete program listing that contains all of the features dis-
cussed in this chapter as well as in Chapter 6.
The routines presented in this chapter have added a cursor to the ex-
ample program. Since the cursor marks the current insertion point
within the file, the next logical step is to allow you to begin inserting
characters. Chapter 6 adds a complete keyboard interface to the ex-
ample program, which permits you to enter new characters as well as
delete existing characters.
227.
.I
he version of the Presentation Manager text editor pre-
sented in this chapter finally allows you to edit the con-
tents of the file. (You should not invest too much time
changing the file, however, since you will not be able to
save these changes until the version of the program given in Chapter 7!)
You can type characters directly into the file at the insertion point
marked by the cursor created in Chapter 5, and you can insert new lines
by pressing the Enter key. You can also delete individual characters
with the Del and Backspace keys, or delete entire lines by pressing F9.
The program supports both overwrite and insert modes, and permits
you to edit an existing file or start a new file.
In this chapter, you will learn how to interpret keyboard messages
sent to the client window; you will learn how to process normal charac-
ter keys, as well as the keys identified by virtual codes (such as function
or arrow keys); and you will learn how to manipulate the data struc-
tures containing the file data in order to modify the contents of the file.
The new features of the example program discussed in this chap-
ter reside in the window procedure subroutines that process the
WM_CHAR message, and in the buffer-management module. The
character-handling routines now process most of the keyboard mes-
sages, rather than simply ignoring the majority of keyboard input.
These routines are supported by eight new functions in the buffer-
management module for inserting and deleting characters and lines.
The discussions in this chapter focus on the routines of the window pro-
cedure, which illustrate techniques unique to the Presentation Manager.
A lengthy discourse on the more conventional code within the buffer-
management module would be a digression from the primary topic of
this book; therefore, the chapter clearly illustrates the purpose of each
of these functions when they are first encountered, but discusses only
the most salient points of their implementation.
The complete listing of the current version of the example program is
given in Figure 6.24, at the end of the chapter.
• THEWM CHARMESSAGE
Whenever a key is either pressed or released, the Presentation
Manager records the event by placing an entry in a single keyboard
• 228 Programmer's Guide to the os/2PresentationManager
buffer known as the sysfc77z qt/cwc. This queue is large enough to store
approximately 60 keyboard events, and thus allows you to type keys
well ahead of the processing of these keys by the active application. The
Presentation Manager dispenses with the entries in the system queue by
sending WM_CHAR messages, one at time, to the window that current-
ly owns the input focus.
The system sends WM_CHAR messages by posting them to the mes-
sage queue owned by the window with the focus (in contrast to high-
priority messages sent by directly calling the window procedure). The
Presentation Manager, however, does not post a WM_CHAR message
until tha window procedure has finished processing the previous WM_CHALR
777css¢gc. (The system knows that the procedure has completed process-
ing a message when the window thread calls the WinGetMsg function
to obtain another message.) The system can post only one WM_CHAR
message at a time because the processing of a given message may
cfe¢7igc ffec /oct4s zt7€.7idoco at any time (for example, a window procedure
could call WinsetFocus or WinsetActivewindow to explicitly change
the focus or the active window). If the Presentation Manager posted
a second keyboard message to the focus window before the first mes-
sage was processed, the second message could end up being sent to the
wrong window. Note that if no window currently owns the focus, the
WM_CIIARmessageissenttotheactivewindow(theconceptofthefocus
and active window was discussed in the section of Chapter 4 on Creating
the Scroll Bars).
Figure 6.1 describes the WM_CHAR message. As you can see from
this description, a large amount of information is encoded in the two
messageparameters,mplandmp2,thatarepassedtothewindowproce-
dure. Fortunately, the system provides a macro, CHARMSG, that
simplifies extracting specific values from these parameters. This macro
works in conjunction with a specially defined structure ®oth the macro
and the associated structure are defined in the PMWIN.H header file). The
definition of the macro is somewhat complex; however, its use is simple.
The fouowing table hsts the values you can extract with this macro:
Note that msg is the name of the second parameter (the message iden-
tifier) passed to the window procedure in the example program. If your
program uses a different name for this parameter, substitute this name
in the preceding expressions; otherwise, the expressions should be ex-
actly as listed.
WM CHAR
Purpose..
Sent by the system to the focus window (or active window, if
there is no focus window) to notify it of a keyboard event
(that is, a key pressed or released).
Parameters..
REJ- mpl
low-order 16 bits: Keyboard control flags; the individual
flags can be extracted using the
following identifiers:
• Figure 6.1..
The WM_CHAR Presentation Manager message
• 230 Programmer's Guide to the os/2 Presentation Manager
Return Value ..
Return TRUE if the message was processed, or FALSE if the
message was ignored.
• Figure 6.1..
The WM_CHAR Presentation Manager message (continued)
AddingaKeyboardlnterface 231 .
label (such as ``F1" or ``Home'') does not depend upon the specific key-
board hardware. Therefore, a program that uses these keys will remain
device-independent. Note, however, that the codes in Table 6.1 marked
with an * are not generated by all keyboards; if you use these codes in
your application, you should provide alternative keystrokes.
In the same manner as the character codes, the Presentation Manager
derives the virtual code from the hardware scan code using the current-
ly installed translation table. In general, however, the shift state does
not affect the virtual code.
VKFI 0x20 FI
VKF2 0x21 F2
VKF3 0x22 F3
VKF4 0x23 F4
VKF5 0x24 F5
VKF6 0x25 F6
VKF7 0x26 F7
VKF8 0x27 F8
VKF9 0x28 F9
VK F10 0x29 F10
*F11
VK Fll 0x2A
VK F12 0x2B *F12
0x2C *F13
VK F13
VK F14 0x2D *F14
0x2F *F16
VK F16
0x30 *F17
VK F17
*F18
VK F18 0x31
0x32 *F19
VK F19
VK F20 0x33 *F20
*F21
VK F21 0x34
VK F22 0x35 *F22
Figure 6.2 lists the WM_CIIAR routine within the client window pro-
cedure (Wndproc) of the example program, which uses the keyboard
flags to perform the initial processing of all keyboard messages. This
routine first tests the KC_KEYUP bit of the control flags to determine
whether the key was pressed or released. If the key was released, the
window procedure immediately returns FALSE, which indicates to the
system that the key message was ignored (returning TRUE notifies the
system that the key was processed).
Next, the program tests the KC_CHAR bit of the control flags. If this
flag is set, then the keyboard message contains a valid character code
and control passes to the function Character, which processes all char-
acter keys and is described in the next section. If the message does not
contain a valid character code, then the routine goes on to test the
KC_VIRTUALKEY flag. If this flag is set, then the message has a valid
virtual code, and the program calls the VirtKey function to process
the virtual key; this function is described later in the chapter. Finally, if
neither flag is set, the window procedure returns immediately; theoreti-
cally, this case should never occur.
• 236 Programmer's Guide to the os/2 Presentation Manager
• Figure 6.2..
The initial processing of the WM_CHAR message
• Backspacekey
• Tabkey
• Enterkey
• All remaining character keys
this buffer (LINEBUFSIZ, which currently equals 255 but could easily
be modified) represents the greatest line length that can be managed by
the program. The new overall data structure is illustrated in Figure 6.3.
Lines are not modified directly within the heap, because modifica-
tion usually results in a change in the line length, and the memory
blocks within the heap are the exact sizes of the lines they contain.
When you have completed altering a given line, the characters in that
line are copied into a newly allocated block within the heap, which has
a size that matches the new length of the line. File lines are modified
through the following sequence of steps:
1. When the program begins, the cursor is placed in file line o and
the data for this line is contained in LineBuffer. Accordingly,
LineTable [0] holds the address of LineBuffer rather than that of
a block within the heap.
2. Any character keys you enter cause the modification of the con-
tents of LineBuffer.
3. You can freely move the cursor throughout the file. If, however,
you enter a character key when the cursor is on a new line, then
the program executes a sequence of steps to store line 0 back
into the heap and place the contents of the new line into Line-
Buffer. This sequence of steps is repeated each time you enter a
character key into a 71cw line.
The number of the line that was most recently modified is stored in
the variable LastcursorLine. Accordingly, the function Character first
compares LastcursorLine with CursorLine, the line currently contain-
ing the cursor. If these values are unequal, then the user has moved the
cursor to a new line and is in the process of modifying this line by enter-
ing a character key. Therefore, the program performs the sequence of
steps necessary to store the former line back into the heap and to copy
the new line into LineBuffer. The code that makes this test and per-
forms these steps is as follows:
if (LastcursorLine != CursorLine)
(
ReleaseTempBuf (LastcursorLine) ,.
GetTempBuf (CursorLine) ,.
• 238 Programmer's Guide to the os/2 Presentation Manager
• Figure 6.3..
The data structure used to store and modify the file lines
AddingaKeyboardlnterface 239 .
LastcursorLine = CursorLine,.
)
1. It allocates a block within the heap just large enough to hold the
modified line currently contained in LineBuffer.
void ReleaseTempBuf
(int Line) /* Number of line held in 'LineBuffer' .
/*
This function:
o Allocates a new block of memory just large enough to hold the string in
the 'LineBuffer'
o Copies the string into the new block
o Adjusts the address in 'LineTable'
*/
(
NPCH Heapoffset; /* Offset of block within heap. */
/*** Copy characters from 'LineBuffer' into new block in heap. ***************/
movedata /* Intersegment block copy. */
(Lineselector, /* Source: selector of line buffer. */
Lineoffset, /* Source: offset of line buffer. */
Heapselector, /* Target: selector of heap. */
(unsigned)Heapoffset, /* Target: offset of new block. */
LineTable [Line].LineLength) ; /* Bytes to copy. */
} /* end ReleaseTempBuf */
• Figure 6.4..
The function ReleaseTempBul of the example program
• 240 Programmer's Guide to the os/2 PresentationManager
Note that the data are copied by calling the C function movedata, which
generates an efficient intersegment block-copy operation.
The function GetTempBuf (listed in Figure 6.5) is called next; this
function is also in the buffer-management module. GetTempBuf is
} /* end GetTempBuf */
• Figure 6.5..
The function GeITe"pBuf of the example program
AddingaKeyboardlnterface 241 .
passed the number of the new line that is about to be modified (Cursor-
Line), and performs the following steps:
1. It copies the line that is about to be modified from the heap into
LineBuffer.
2. It-releases the block formerly used to hold this line within the
heap.
3. It adjusts the appropriate entry in LineTable to point to Line-
Buffer rather than to the heap block.
• Figure 6.6..
The changes made by ReleaseTe:mpBuf and GeITe"pBuf to the file data structure
AddingaKeyboardlnterface 243 .
The routine first inserts the character into the file buffer by calling the
function Insertchar (located in the buffer-management module and
/*** Invalidate window from cursor position to end of line (or window) . ******/
Rect.xLeft = (Cursorcol -Firstcol) * xchar;
Rect.xRight = min ((GetLineLength (CursorLine) -Firstcol) * xchar, xwin) ;
Rect.yBottom = ywin - (CursorLine -TopLine + 1) * ycharTot;
Rect.yTop = Rect.yBottom + ycharTot;
WinlnvalidateRect /* Invalidate section to be modified. */
£R:::; ,: ::::::g:: ::i::ta::::°¥; invalid region. :,
FALSE) ; /* Don't include descendants w/ WS_CLIPCHILDREN*/
return TRUE;
• Figure 6.7..
The routine for processing normal character keys
• 244 Programmer's Guide to the os/2PresentationManager
/*** If line would exceed maximum line length, return without inserting. *****/
if (Column > LINEBUFSIZ - 3 I I LineLength >= LINEBUFSIZ && Insert)
return FALSE;
/*** If column is at end of line (common case) , use fast routine to insert. **/
else if (Column == LineLength - 2)
• Figure 6.8..
The function lr\sertchar of the exanple program
AddingaKeyboardlnterface 245 .
(
/*** Copy '\n' and '\0' to new position. ********************************/
LineBuffer [Column + 2] = IiineBuffer [Column + 1] ;
IjineBuffer [Column + 1] = IjineBuffer [Column] ;
/*" If column is BEYOND end of line, must pad line with spaces. *************/
else if (Column > LineLength -2)
(
/*** Copy '\n' and '\0' to new position. ********************************/
LineBuffer [Column + 2] = LineBuffer [LineLength -1] ;
IjineBuffer [Column + 1] = LineBuffer [LineLength -2];
) /* end Insertchar */
• Figure 6.8..
The function lr\sertchar of the example progran (continued)
• 246 Programmer'sGuideto the os/2Presentation
Manager
WinAlarm
Puxpose..
Sounds the computer speaker.
Prototype..
B00L APIENTRY WinAlarm
(HWND hiirndDesktop, Desktop window handle
(INND DESKTOP).
ULONG rgfType) ,. The type of alarm; can be one of the
fonowing values:
WA WARNING
WA-NOTE
WA-ERROR
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
The alarms generated by this function can be enabled and dis-
abled, and also their frequency or duration modified, through
the function Winsetsysvalue. The constants passed to Win-
Setsysvalue to perform these adjustments are as fonows:
Related Functions ..
Winsetsysvalue
• Figure 6.9..
The WLnALla;rm Presentation Manager function
AddingaKeyboardlnterface 247 .
procedure:
Because the KC_VIRTUALKEY bit of the flag word is set (and the
KC_CHAR bit is off), the message is processed by the VirtKey function;
the routine that processes the arrow keys was described in Chapter 5.
Note that this routine provides another example of sending recursive
messages to avoid duplicating code. After control returns from Win-
SendMsg,thecharacterroutinereturnsTRUEtoinformthesystemthat
the key was processed.
/*** Process a tab key by sending equivalent number of space characters. *****/
if (CHARMSG(&msg)->chr == '\t')
(
Col = 5 -Cursorcol % 5;
while (col--)
WinsendMsg /* Send space character message to self .
( hwnd ' /* Client window handle.
WM CHAR, /* Character message.
• Figure 6.10..
The Tab~key routine
AddingaKeyboardlnterface 249 .
spaces between the current cursor position and the next tab stop (the
column numbers of the tab stops are multiples of 5). It then inserts
the calculated number of space characters into the file. Each blank is in-
serted by sending a WM_CIIAR message back to the window proce-
dure, specifying the KC_CIIAR code and the space character.
/*** Adjust 'TopLineMax' and scroll bar range for new file length. */
TopLineMax = max (O,LastLine -ywin / ycharTot + 1) ;
• Figure 6.1.1..
The Enter-key routine
• 250 Programmer's Guide to the os/2PresentationManager
) /* end '\r' */
• Figure 611..
The Enter-key routine (continued)
First, if the insert mode is active, the routine calls the function Insert-
Line, which is contained in the buffer-management module and is
listed in Figure 6.12. This function is passed the numbers of the line and
column containing the cursor (CursorLine and Cursorcol), and inserts
a new line into the file buffer immediately before the cursor position.
InsertLine copies all characters contained in LineBuffer that are Z7c/ore
the cursor position into a newly allocated block within the heap. It then
moves the remaining characters in LineBuffer to the beginning of the
buffer. Finally, it inserts a new entry into LineTable, immediately before
the CursorLine entry, which contains the address of the newly allocated
heap block. These steps are illustrated in Figure 6.13. Note that the pro-
gram can call memmove to move the elements of LineTable using a
single block-copy operation (rather than adjusting the array element by
element), since this C library function properly handles overlapping
source and target addresses.
Rather than returning the error status to the calling program, Insert-
Line handles errors internally. If the maximum number of lines (MAX-
LINES) is exceeded, or if the storage capacity of the heap is reached,
InsertLine directly terminates the program by calling ErrorQuit. In the
AddingaKeyboardlnterface 251 .
/*** Write newline and null to end of new line in heap. **********************/
*(Heappointer + Column) = '\n';
*(Heappointer + Column + 1) = '\0' ;
/*** Move character number 'Column' and all following characters to beginning
o£ 'L±neBuffer' . ********************************************************/
memmove /* Intrasegment block copy. */
(LineBuffer, /* Target address. */
LineBuffer + Column, /* Source address. */
LineTable [Line].LineLength -Column) ; /* Bytes to move. */
• Figure 6.12:
The function luseriLine of the example program
• 252 Programmer's Guide to the os/2PresentationManager
/*** Move all members of 'LineTable' one position toward end of table. *******/
memmove
(&LineTable [Line + 1], /* Target.
&LineTable [Line] , /* Source.
(LastLine -Line) * sizeof (LineTable [0])) ; /* Bytes to move.
/*** Assign address of new heap block to 'LineTable' . ************************/
LineTable [Line].LineAddress = Heappointer;
LineTable [Line] .LineLength = (unsigned char) (Column + 2) ;
} /* end InsertLine */
• Figure 6.12..
The function lnsertLir\e of the example program (continued)
CursorLine |
I
LineTable II
BEFOF3E CALL NG
lnsertLine
'
This line is adoutto bedivided\n\O I
LineBuffer A
cursorIcursorLine +1
------
CursorLine i
I I
LineTableNG 1111
AFTEPI CALLllnsertLine
IIIIIm
1
out to be divided\n\O I
A LineBufferCursorwillbe
I This line is ab\n\O I
A moved here
cursor
• Figure 6.13:
Inserting a new line with the lr\seithine function
• 254 Programmer's Guide to the os/2Presentation
Manager
if (CHARMSG(&msg)->chr == '\b')
(
/*** If cursor is at column 0, must join line to previous line. *********/
if (Cursorcol == 0)
(
/*** NO previous line if cursor is in first line. ******************/
if (CursorLine == 0)
return TRUE;
/*** Move
- cursor to end of line. ***********************„**********/
winse?:::g, /: ::::nEn:i::::ag:n::e:elf.
WM CHAR, /* Character received message.
/*** Adjust 'TopLineMax' and scroll bar range for new file length. */
TopLineMax = max (0,LastLine -ywin / ycharTot + 1) ;
• Figure 6.14..
The Backspace-key routine
AddingaKeyboardlnterface 255 .
Rect.xLeft = 0;
Rect.xRight = xwin;
Rect.yTop = ywin - (CursorLine -TopLine) * ycharTot;
Rect.yBottom = 0;
wLn|nli:§§;:eRej::::i::;ii::i::i::§i:i::i:::;:::;::;;;;;iDREN;j
#W:£AR, /: :::=::t::n::¥e::::i:;ssage.
#:ER8#2§E8R: (5:-¥:R:¥£T¥¥y, i] , /: ¥::t=:; ::¥;
/*** If in overwrite mode, overwrite current character with a space. ****/
else
(
/*** Print a space character. **************************************/
WinsendMsg /* Send space character message to self . */
(hwnd, /* Client window handle. */
WM CHAR, /* Character message. */
MPFROM2SHORT (KC_CHAR,1) , /* Character key. */
MPFROM2SHORT (' I ,0)) ; /* Space character. */
) /* end '\b' */
• Figure 6.14..
The Backspace-key routine (continued)
• 256 Programmer's Guide to the os/2 PresentationManager
If the cursor is beyo7id the first column and the program is in insert
mode, the Backspace-key routine moves the cursor back one space by
sending a left-arrow message to the window procedure, and then
deletes the character at the new position by sending a Del-key message
(the Del key is processed by the VirtKey routine, discussed later in the
chapter). If the program is in the overwrite mode, then the routine
moves the cursor back one space, and writes a space character at the
new position by sending a character message; it must then send a left-
arrow message to restore the cursor position (writing the space ad-
vanced the cursor; the cursor, however, should remain at the newly
blanked position). Note that many editors do not distinguish between
insert and overwrite modes when performing a backspace operation;
however, replacing the preceding character with a space rather than
deleting it prevents shifting left all the remaining characters in line. A
design goal of the example editor is that in the overwrite mode, editing
operations should not normally alter the relative positions of characters
(exceptions are the F9 and Del keys).
If the cursor is at column 0 and the program is in insert mode, then
the routine /.oz.71s the current line with the previous line, conceptually
deleting the preceding newline character (provided, of course, that the
cursor is not in the first line of the file). Note that using the Backspace
key to join lines is one of two common options; alternatively, many
editors join lines when you press the Del key at the end of the preceding
line (and some editors use both methods).
The backspace routine joins lines by moving the cursor to the end of
the previous line and calling the function ToinLine, which is part of the
buffer-management module and is listed in Figure 6.15. JoinLine is
passed the number of the line that is contained in LineBuffer (which, at
this point, is CursorLine + 1); it first moves the characters in this line far
enough toward the end of the buffer to make room for the characters
belonging to the previous line. It then copies the characters from the
previous line into the beginning of LineBuffer. Finally, JoinLine frees
the heap memory occupied by the previous line, and deletes the cor-
responding entry from LineTable. These operations are illustrated in
Figure 6.16.
If JoinLine returns an error code (FALSE), the backspace routine
sounds the alarm by calling WinAlarm and returns. Otherwise, it per-
forms the standard tasks of adjusting the vertical scroll bar range and
invalidating the affected area of the window.
AddingaKeyboardlnterface 257 .
/*** Return if combined length would exceed maximum line length. *************/
if (LineTable [Line].LineLength + LineTable [Line -1].LineLength -2 >
LINEBUFSIZ)
return FALSE;
/*** Move existing characters in 'LineBuffer' to right to make room for the
characters from previous line. ******************************************/
memmove
/*** Move the characters from previous line to beginning of 'LineBuffer' . ****/
movedata
(SELECTOROF (LineTable [Line -1].LineAddress) ,
OFFSETOF (LineTable [Line -1].LineAddress) ,
Lineselector ,
Lineof fset ,
LineTable [Line -1] .LineLength -2) ;
/*** Move all 'LineTable' members above and including 'Line' down one place. */
memmove
return TRUE;
} /* end JoinLine */
• Figure 6.15..
The function Jo3:nLine of the example program
• 258 Programmer's Guide to the os/2 Presentation Manager
• Figure 6.16..
Joining two lines with the Jo±nLine function
AddingaKeyboardlnterface 259 .
• THEVIRTUALKEYS
When the main client window procedure, Wndproc, detects that
the WM_CHAR message contains a valid virtual code, it calls the Virt-
Key function to process the key. This function branches to the ap-
propriate routine according to the virtual code that identifies the
specific key, using the following switch statement:
The codes for the virtual keys are listed in Table 6.1. VirtKey contains
routines for the following subset of these keys:
If the virtual code is not one of those listed above, VirtKey returns
the value FALSE, indicating that the message was ignored. Note that
the only routines not already discussed in Chapter 5 are those for the F9
key, the Del key, and the Ins key.
• 260 Programmer's Guide to the os/2 Presentation Manager
The F9 Key
In response to the F9 key, the program erases the entire line con-
taining the cursor. The routine that handles this key is listed in Figure
6.17. The routine first calls the function DeleteLine, which belongs to
the buffer-management module and is listed in Figure 6.18. DeleteLine
is passed the address of the line containing the cursor (CursorLine) and
performs the following three tasks:
• It calls GetTempBuf, passing it the number of the line that
/oZJozus the line to be deleted. GetTempBuf (listed in Figure 6.5
and explained earlier in the chapter) copies this following line
/*** Adjust 'TopLineMax' and scroll bar range for new file length. */
TopLineMax = max (0,LastLine -ywin / ycharTot + 1) ;
WinsendMsg
(HVscroll, /* Recipient handle.
SBM SETSCROLLBAR, /* Set position & range.
MPFkoM2SHORT (TopLine, 0) , /* Position.
MPFROM2SHORT (0, TopLineMax)) ; /* Range.
WinEnablewindow
(HVscroll, /* Recipient handle. */
TopLineMax ? 1 : 0); /* Enable only if max.!= 0*/
• Figure 6.17..
The F9 routine
AddingaKeyboardlnterface 261 .
/*** Move all LineTable elements beyond deleted line down one element. **/
memmove
(&LineTable [Line] , /* Target.
&LineTable [Line + 1], /* Source.
(LastLine -Line) * sizeof (LineTable [0])) ; /* Number bytes
} /* end DeleteLine */
• Figure 6.18..
The function DeleteLine of the exanple program
If, however, the line to be deleted is the last in the file, DeleteLine simp-
ly truncates this line by writing the `\n' and `\0' characters to the first
two positions in LineBuffer.
After calling DeleteLine, the F9 routine must adjust the vertical scroll
bar range for the new file length. It performs this task in the same man-
ner as the Enter routine and the Size function. Next, it invalidates the
line containing the cursor-and all lines displayed below it-by calling
• 262 Programmer's Guide to the os/2 Presentation Manager
Insert ^= 1,.
AddingaKeyboardlnterface 263 .
• Figure 6.19..
The Del-key routine
/*** Move all characters beyond deleted character one place left. ************/
memmove
(LineBuffer + Column, /* Target.
LineBuffer + Column + 1, /* Source.
LineTable [Line].LineLength -Column -1) ; /* Number of bytes.
return TRUE;
} /* end Deletechar */
• Figure 6.20..
The function Deletechar of the example program
• EDITINGANEWFILE
Since the current version of the example program allows you to
add data to the file, it should permit opening a new file. Consequently,
if you specify a file name on the command line when starting the pro-
gram, this file is read into the buffer as in the previous version. How-
ever, if you do not specify a file name, then rather than terminating with
an error message, the current version of the program calls the function
NewFile, belonging to the buffer-management module and listed in
Figure 6.21.
NewFile initializes the buffer for a new empty file. It allocates a heap
having an initial size of 4096 bytes; remember, however, that the Presen-
tation Manager will automatically expand the heap if it requires more
memory to satisfy an allocation request.
AddingaKeyboardlnterface 265 .
) /* end NewFile */
• Figure 6.21..
The function NewFIle of the example program
• ENHANCEMENTS
This section offers three suggestions for enhancements to the
present version of the example program:
• CONCLUSION
A MAKE file for preparing the current version of the example pro-
gram is given in Figure 6.22, and the linker definition file is in Figure
6.23. The complete source code listing appears in Figure 6.24.
The example program at its current state of evolution provides most
of the basic editing functions for modifying or creating a text file. The
next logical step is to allow you to save the modified version of the file,
and to perform other file functions such as reading a new file. The file
functions will be accessed through a Presentation Manager menu, and
the file names will be entered through a dialog box. Therefore, although
the routines for performing these operations are simple, they are not in-
troduced until dialog boxes have been added in Chapter 8.
# Figure 6. 22
# This RAKE file prepares the program of Figures 6.23 and 6.24
#
- cl
FIG6 24.OBT : FIG6 - 24.C
/W2 /c /7;p /r:?Ns FTJf 36_24.C
FIG6 24.EXE : -
FIG6 24.OBT FIG6 23.DEF
link /NOD FIG6 24.OBJ,, NUL, OS2.LIB SLIBCE.LIB, FIG6 23.DEF
• Figure 6.22..
A MAKE file for preparing the example program
AddingaKeyboardlnterface 269 .
; Figure 6.23
; Linker, definition file for the program listed in Figure 6.24
NAME FIG6 24
PROTMODE
HEAPSIZE 1024
STACKSIZE 8192
EXPORTS Wndproc
• Figure 6®23..
A linker definition file for preparing the exanple progran
/*
Figure 6.24
• Figure 6.24..
The source code file for the example program
• 270 Programmer's Guide to the os/2 Presentation Manager
MRESULT EXPENTRY Wndproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2) ;
• Figure 6.24..
The source code file for the example program (continued)
AddingaKeyboardlnterface 271 .
• Figure 6.24..
The source code file for the example program (continued)
• 272 Programmer's Guide to the os/2PresentationManager
• Figure 6.24..
The source code file for the example program (continued)
AddingaKeyboardlnterface 273 .
} /* end switch */
} /* end Wndproc */
MRESULT EXPENTRY Character (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
This function processes character keys (that is, keys with a valid ASCII
code) .
*/
• Figure 6®24..
The source code file for the example program (continued)
•274 Programmer's Guide to the OS/2 Presentation Manager
/*** Adjust 'TopLineMax' and scroll bar range for new file length. */
TopLineMax = max (0,LastLine -ywin / ycharTot + 1) ;
• Figure 6.24..
The source code file for the example program (continued)
AddingaKeyboardlnterface 275 .
) /* end '\b' */
/*** Process a Tab key by sending equivalent number of space characters. *****/
if (CHARMSG(&msg)->chr == '\t')
(
Col = 5 -Cursorcol % 5;
while (Col--)
• Figure 6.24..
The source code file for the example program (continued)
• 276 Programmer's Guide to the os/2PresentationManager
) /* end '\t' */
/*** Process ET\+er key. ******************************************************/
if (CHARMSG(&msg)->chr == '\r')
(
/*** Adjust 'TopLineMax' and scroll bar range for new file length. */
TopLineMax = max (0,LastLine -ywin / ycharTot + 1) ;
• Figure 6.24..
The source code file for the example program (continued)
AddingaKeyboardlnterface 277 .
} /* ervii `\r' */
/*** Invalidate window from cursor position to end of line (or window) . ******/
Rect.xLeft = (Cursorcol -Firstcol) * xchar;
Rect.xRight = min ((GetLineLength (CursorLine) -Firstcol) * xchar, xwin) ;
Rect.yBottom = ywin - (CursorLine -TopLine + 1) * ycharTot;
Rect.yTop = Rect.yBottom + ycharTot;
wLn|n!i:§§;:eRect ;: i;;i:::i:::i::::;i::i::;s:;;:;;;:;:g:£:iDREN:;
return TRUE;
} /* end Character */
• Figure 6.24:
The source code file for the example program (continued)
• 278 Programmer's Guide tothe os/2Presentation
Manager
MRESULT EXPENTRY Create (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
HHScroll = WinwindowFromlD
(WinQuerywindow (hwnd, QW_PARENT,FALSE) , /* Handle to parent */
/* window (frame). */
FID HORZSCROLL) ; /* Identifier for vertical scroll bar. */
HVscroll = WinwindowFromlD
(WinQuerywindow (hwnd, QW PARENT,FALSE) , /* Handle to parent */
/* window (frame). */
FID VERTSCROLL) ; /* Identifier for vertical scroll bar. */
return FALSE;
} /* end Create */
MRESULT EXPENTRY HScroll (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
SHORT Delta; /* Amount to scroll.
• Figure 6.24..
The source code file for the example program (continued)
Adding a Keyboard Interface 279.
® Figure 6.24..
The source code file for the example program (continued)
• 280 Programmer's Guide to the os/2Presentation
Manager
} /* end HScroll */
MRESULT EXPENTRY Paint (HWND hwnd, USHORT msg, MPARAM mpl, MPA~ mp2)
(
register int Line; /* Loop counter.
HPS Hpresspace; /* Presentation space handle.
RECTL Rect; /* Holds coordinates of rectangle.
SHORT StartLine; /* First file line to paint.
SHORT StopLine; /* Last line to paint.
POINTL Start; /* Starting position to print string.
SHORT LineLength; /* Length of each line displayed.
Hpresspace = WinBeginpaint
(hwnd, * Window handle. */
0' * Handle of PS to have clipping region set. */
&Rect) ; * Address of struct. to set to invalid region.*/
GpicreateLogFont Create a logical font for presentation space*/
( Hpresspace ,
( PSTR8 ) NULL , :::::::a:::: ::::? E:::?e. :/
ID COURIER, Local font ID: define a constant. */
&F6ntAttributes) Struct. specifying font from GpiQueryFonts. */
Gpisetcharset Make logical font the current character set.*/
( Hpresspace ,
ID COURIER) ; :::::n:::E°:D:Pace handle. :/
WinFillRect
( Hpresspace ,
&Rect,
CljR WHITE) ;
/: :::::::::i::n:::::n:a::::;w coordinates. :/
/* Color to use (white). */
Gpisetcolor
( Hpresspace , /* Presentation space handle.
CLR BIACK) ; /* Color to use: black.
• Figure 6.24..
The source code file for the example program (continued)
AddingaKeyboardlnterface 281 .
WinEndpaint (Hpresspace) ;
return FALSE;
) /* end paint */
MRESULT EXPENTRY SetFocus (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/*** If client window is RECEIVING focus, create cursor. *********************/
if (LONGFROMMP (mp2) )
)
/*** If client window is LOSING focus, destroy the cursor. *******************/
else
WinDestroycursor (hwnd) ;
return FALSE;
MRESULT EXPENTRY Size (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
int Update -0;
ywin = SHORT2FROMMP (mp2) ;
xwin = SHORTIFROMMP (mp2) ;
• Figure 6.24:
Tfie source code file for the example program (continued)
®282 Programmer's Guide to the OS/2 Presentation Manager
£ATyLgETPESKT°P , ,: E:S:o:±¥:cfe:::::wpandLe.
(
/*** Destroy existing cursor. *******************************************/
WinDestroycursor (hwnd) ;
/*** Create
-_,_
new cursor. **********************************************„*/
Wincreatecursor /* Create a new cursor. */
(hwnd, /* Client window handle.
(Cursorcol - Firstcol) * xchar, /* x position of cursor.
ywin - (CursorLine - TopLine + 1) * ycharTot, /* y position
0' /* x size of cursor: nominal border.
ycharTot, /* y size of cursor.
CURSOR SOLID /* Solid cursor.
CURSOR-FIASH /* Flashing cursor.
NULL) ; /* Clipping rectangle: entire window.
/*** Display the cursor. ************************************************/
Winshowcursor
(hwnd, /* Client window handle.
TRUE) ; /* Show it!
)
• Figure 6.24..
The source code file for the example program (continued)
AddingaKeyboardlnterface 283 .
return FALSE;
} /* end Size */
MRESULT EXPENTRY VirtKey (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
RECTL Rect; /* Holds coordinates of rectangle.
SHORT NewFirstcol ; /* Temporary storage for new first column pos
SHORT Newcursorcol ; /* Temporary storage for new cursor column.
int Update; /* Flag indicating window update needed.
• Figure 6®24..
The source code file for the example program (continued)
• 284 Programmer's Guide to the os/2 Presentation Manager
( hwnd '
WM VSCROLL,
OL'
MPFROM2SHORT (0,SB LINEDOWN) ) ;
return TRUE;
)
/*** Otherwise, simply adjust 'CursorLine'. ************************/
else
++CursorLine ;
break;
/*** Proce=_5_ ±e_i_€_-arrow key. ********************************************/
case VK LEFT:
break;
/*** Process Page Up key. ***********************************************/
case VK PAGEUP:
Wi=SendMsg /* Send scroll page-up message to self . */
( hwnd ,
" VSCROLL,
OL,
MPFROM2SHORT (0,SB PAGEUP) ) ;
• Figure 6.24..
The source code file for the example program (continued)
AddingaKeyboardlnterface 285 .
return TRUE;
Cursorcol = 0;
break;
• Figure 6.24..
The source code file for the example program (continued)
• 286 Programmer's Guide to the os/2 Presentation Manager
OL,
MPFROM2SHORT (NewFirstcol,
SB SLIDERPOSITION) ) ;
• Figure 6.24..
The source code file for the example program (continued)
AddingaKeyboardlnterface 287 .
/*** Adjust 'TopLineMax' and scroll bar range for new file length. */
TopLineMax = max (0,LastLine -ywin / ycharTot + 1) ;
WinsendMsg
(HVscroll , /* Recipient handle.
SBM SETSCROLLBAR, /* Set position & range.
MPFkoM2SHORT (TopLine, 0) , /* position.
MPFROM2SHORT (0, TopLineMax)) ; /* Range .
WinEnablewindow
(HVscroll , /* Recipient handle.
TopLineMax ? 1 : 0); /* Enable only if max. !=
/*** For all other keys, return FALSE indicating key not processed. *****/
default:
return FALSE;
} /* end VirtKey */
mESULT EXPENTRY Vscroll (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
SHORT Delta; /* Amount to scroll.
• Figure 6®24..
The source code file for the example program (continued)
•288 Programmer's Guide to the OS/2 Presentation Manager
if (Delta)
(
TopLine += Delta;
• Figure 6.24..
The source code file for the example program (continued)
AddingaKeyboardlnterface 289 .
} /* end Vscroll */
} /* end Buflnit */
• Figure 6.24..
The source code file for the example program (continued)
• 290 Programmer's Guide to the os/2PresentationManager
/*** Move all characters beyond deleted character one place left. ************/
memmove
(LineBuffer + Column, /* Target.
LineBuffer + Column + 1, /* Source.
LineTable [Line].LineLength -Column -1) ; /* Number of bytes.
return TRUE;
} /* end Deletechar */
Deletes the specified line ('Line' , which must be the line currently
containing the cursor) from the file buffer.
(
/*** If line to be deleted is the last file line, merely truncate it. ********/
if (Line == LastLine)
(
LineBuffer [0] = '\n';
LineBuffer [1] = '\0';
LineTable [Line].LineLength = 2;
)
else
(
/*** Place the following line into 'LineBuffer'. ************************/
GetTempBuf (Line + 1) ;
/*** Move all LineTable elements beyond deleted line down one element. **/
memmove
• Figure 6.24..
The source code file for the example program (continued)
AddingaKeyboardlnterface 291 .
} /* end DeleteLine */
} /* end ErrorMessage */
} /* end GetLineAddr */
• Figure 6.24..
The source code file for the example program (continued)
• 292 Programmer's Guide to the os/2PresentationManager
This function:
o Copies the string in the specified line into 'LineBuffer'
o Frees the block formerly holding the string
o Adjusts the address in 'LineTable'
*/
(
/*** Copy string into 'LineBuffer'. ******************************************/
movedata /* Intersegment block copy.*/
(SELECTOROF (LineTable[Line].LineAddress) , /* Source segment. */
OFFSETOF (LineTable[Line].LineAddress) /* Source offset. */
Lineselector , /* Target segment. */
Lineof fset , /* Target offset. */
LineTable [Line] .LineLength) ; /* p;rytes to copry. */
/*** Release block formerly holding line. ************************************/
if (WinFreeMem
(HHeap, /* Handle of heap from 'WincreateHeap' .
(BYTE NEAR *)OFFSETOF (LineTable [Line].LineAddress) , /* Offset.
LineTable [Line].LineLength) /* Length of block to free.
!-NULL)
(
sprintf (Message, "managing heap; line %d",_LINE_) ;
ErrorQuit (Message) ;
)
} /* end GetTempBuf */
/*** If line would exceed maximum line length, return without inserting. *****/
if (Column > LINEBUFSIZ - 3 I I LineLength >= LINEBUFSIZ && Insert)
return FALSE;
/*** If column is at end of line (common case) , use fast routine to insert. **/
else if (Column == LineLength -2)
(
/*** Copy '\n' and '\0' to new position. ********************************/
LineBuffer [Column + 2] = LineBuffer [Column + 1];
LineBuffer [Column + 1] = LineBuffer [Column];
• Figure 6.24..
The source code file for the example program (continued)
AddingaKeyboardlnterface 293 .
/*** If column is BEYOND end of line, must pad line with spaces. *************/
else if (Column > LineLength -2)
(
/*** Copy '\n' and '\0' to new position. ********************************/
LineBuffer [Column + 2] = LineBuffer [LineLength -1];
LineBuffer [Column + 1] = LineBuffer [LineLength -2];
} /* end Insertchar */
• Figure 6.24..
The source code file for the example program (continued)
• 294 Programmer's Guide to the os/2 Presentation Manager
/*** Write newline and null to end of new line in heap. **********************/
*(Heappointer + Column) = '\n' ;
*(Heappointer + Column + 1) = '\0';
/*** Move character number 'Column' and all following characters to beginning
o£ `L±neBu££er` . ********************************************************/
memmove /* Intrasegment block copy. */
i:::::¥=::r+ co|umnJ /: :::::: :::=:::: :/
LineTable [Line].LineLength -Column) ; /* Bytes to move. */
/*** Move all members of 'LineTable' one position toward end of table. *******/
memmove
(&LineTable [Line + 1], /* Target.
&LineTable [Line] , /* Source.
(LastLine -Line) * sizeof (LineTable [0])); /* Bytes to move.
• Figure 6.24..
The source code file for the example program (continued)
AddingaKeyboardlnterface 295 .
/*** Return if combined length would exceed maximum line length. *************/
if (LineTable [Line].LineLength + LineTable [Line -l].LineLength -2 >
LINEBUFS I Z )
return FALSE;
/*** Move existing characters in 'LineBuffer' to right to make room for the
characters from previous line. ******************************************/
me:nmove
(LineBuffer + LineTable [Line -1].LineLength - 2, /* Target
LineBuffer, /* Source
LineTable [Line].LineLength) ; /* Number of bytes
/*** Move the characters from previous line to beginning of 'LineBuffer' . ****/
movedata
(SELECTOROF (LineTable [Line -1].LineAddress) ,
OFFSETOF (LineTable [Line -1].LineAddress) ,
Lineselector ,
Lineoffset,
LineTable [Line -1] .LineLength -2) ;
/*** Move all 'LineTable' members above and including 'Line' down one place. */
memmove
(&LineTable [Line -1], /* Destination. */
&LineTable [Line] , / * ScfAIrc:a. */
• Figure 6.2.4:
The source, code file for the example program (continued)
• 296 Programmer's Guide to the os/2PresentationManager
} /* end ToinLine */
} /* end NewFile */
• Figure 6.24..
The source code file for the example program (continued)
AdldingaKeyboardlnterface 297 .
return (ERROPEN) ;
• Figure 6.'.?.4o.
The source code file for the erample program (continued)
• 298 Programmer's Guide to the os/2 Presentation Manager
) /* end of ReadFile */
void ReleaseTempBuf
(int Line) /* Number of line held in 'LineBuffer'. */
/*
This function:
o Allocates a new block of memory just large enough to hold the string in
the 'LineBuffer'
o Copies the string into the new block
o Adjusts the address in 'LineTable'
*/
(
NPCH Heapoffset; /* Offset of block within heap. */
/*** Copy characters from 'LineBuffer' into new block in heap. ***************/
movedi::::::::::or, ;: :i:::::g::::::::::i:::x:u:::::r. :;
Heapselector, /* Target: selector of heap. */
(unsigned)Heapoffset, /* Target: offset of new block. */
LineTable [Line].LineLength) ; /* Bytes to copy. */
} /* end ReleaseTempBuf */
• Figure 6.24..
The source code file for the example program (continued)
AddlingaKeyboardlnterface 299 .
void Quit
(.Lnt Errorcode) /* Process termination status.
Calls Presentation Manager termination functions and ends program
with specified error code.
/
iF (HHeap != NULL)
WinDestroyHeap (HHeap) ;
WinDestroywindow (HFrame) ;
WinDestroyMsgQueue (HMesQue) ;
WinTerminate (HAncBlk) ;
exit (Errorcode) ;
) /* end Quit */
• Figure 6.24..
The source code file for the example program (continued)
J pter seven
tJsing Menus
and Accelerators
301.
.T
tion of features for the Presentation Manager text editor.
Menus are a high-level facility offered by the Presenta-
tion Manager, and they are an important part of the uni-
form user interface. The example program uses a menu to implement
commands for managing files, for terminating the program, for locating
strings or specific line numbers, and for selecting program options.
Many of the menu commands can also be directly activated through
keystrokes that are termed keyboard ¢ccczcr¢fo7's.
Menus and keyboard accelerators are among the objects known as
Presentation Manager 7'cso#7'ccs. In this chapter, you will learn how to
design menus and designate accelerator keys using a resource script;
you will learn how to incorporate a menu into the standard window
collection and how to install accelerator keys; and you will learn how to
manage menus and accelerators by processing the messages these ob-
jects send to the client window. The chapter will also show you how to
implement the menu commands that do not require dialog boxes or
other features presented in later chapters. Specifically, the chapter
describes routines for saving the existing file, creating a new file, ter-
minating the program, displaying an About box (a program informa-
tion window), searching for a string, moving the cursor to a specific line
number, and toggling between insert and overwrite editor modes.
In this chapter, you win be introduced to two new buffer-management
functions and five new supporting uthity functions. The next complete
program hsting is Figure 8.38, which is given at the end of Chapter 8; this
hsting incorporates the features described in this chapter as wen as the
dialog boxes and dialog procedures presented in Chapter 8.
CREATING MENUS
• AND ACCELERATORS
Menus and accelerator keys are examples of Presentation Man-
ager resources. Resources are a special form of read-only data that are
stored directly in the executable program file on disk (the .EXE file), and
are read into memory when required at run-time. Resource data differ
• 302 Programmer's Guide to the os/2PresentationManager
OS2.H(SystemDefinitions)
APP.H(DefinitionsforF3esources)
APP.C APP.PC
(C Source File) (Pesource Script Text File)
Icl/cAPP.C'
APP.OBJ(ObjectFile)
rc /r A PP.PC
IlinkAPP.OBJ'
APP.EXE APP.BES
(Without Pesources) (Binary Pesource Data)
rc APP.PES'
APP.EXE
(With Besources)
• Figure 7.1..
Creating Presentation Manager resources
• 304 Programmer's Guide to the os/2 PresentationManager
#include <OS2.H>
#include ''FIG7 3.H"
• Figure 7.2..
The resource script used to create a menu and define accelerator keys for the example program
UsingMenusandAccelerators 305 .
• Figure 7.3..
Constant definitions used for the menu and accelerator-key resources
when creating the standard window collection through the call to Win-
Createstdwindow. The menu definition contains two types of top-
level entries: those identified with the keyword MENUITEM and those
identified with SUBMENU. For each of these top-level items, the key-
word is followed by a string, which will appear permanently on the
horizontal menu bar at the top of the window, and an identifier, which
will be used by the program to manage the item. When the user selects
an item labeled with MENUITEM, the program immediately executes
the associated command; when, however, the user selects a SUBMENU
item, the system temporarily displays a pull-down submenu. An item is
selected either by clicking on it with the mouse, or by pressing the Enter
key while the item is highlighted.
The menu definition in Figure 7.2 contains the top-level items listed
in Table 7.1. The horizontal menu containing these top-level entries is
illustrated in Figure 7.4. Note that the submenus associated with each
top-level SUBMENU item are defined as nested lists of MENUITEM
entries; these entries are displayed in a temporary vertical pull-down
menu when the user selects the associated top-level item. When the
user subsequently selects a submenu item, the related command is im-
• 306 Programmer's Guide to the os/2 PresentationManager
sEinRATOR
• Figure 7.4..
The top-level menu displayed by the example program
UsingMenusandAccelerators 307 .
• Figure 7.5..
The pull-down menu displayed when the user selects the File submenu
• 308 Programmer's Guide to the os/2PresentationManager
The second part of Figure 7.2 defines the list of accelerator keys. This
resource is labeled with the keyword ACCELTABLE, followed by the
identifier ID_FRAME_RESOURCE; note that the identifier must be
the same as that used for the menu, since, as you will see, only a single
constant is passed to the Wincreatestdwindow function to identify
both resources.
The definition of each accelerator key consists of three main fields. The
first field identifies the keystroke by supplying either a virtual-key code or
a string containing thLe appropriate character. The virtual-key codes, such
as VK_DELETE for the Del key, are hsted in Table 6.1. The caret symbol (^)
preceding a character in a quoted keystroke indicates that the Ctrl key
must be pressed in conjunction with the character key; for example, ``^F"
represents the Ctrl-F keystroke.
The second field gives the identifier of the menu item that is to be ac-
tivated by the accelerator key. In other words, pressing the accelerator
key will generate a message containing this identifier exactly as if the
corresponding menu item had been selected; this process is explained
in the next section.
The third field specifies one or more options, separated by commas
(7tof combined with the bitwise OR operator). The VIRTUALKEY value
indicates that the first parameter contains a virtual-key code (otherwise,
the resource compiler will assume that the first parameter supplies a
quoted character). The SHIFT option specifies that the Shift key must be
down when the accelerator key is pressed, and the CONTROL option
similarly specifies that the Ctrl key must be pressed in conjunction with
the accelerator key. (You can likewise use the ALT option for the Alt key;
see the technical documentation for explanations of the other options.)
For example, the line
rc /r FIG8 36.RC
rc FIG8 36.RES FIG8 38.EXE
The first command, which is executed only if the resource script has
been modified, converts the script file (FIG8_36.RC) into a binary
resource file (FIG8_36.RES). The second command is performed each
time a new .EXE file is prepared; this command inserts the binary data
from FIG8_36.RES directly into the executable file, FIG8_38.EXE. You
can perform both of these steps using the following single command:
The MAKE file of Figure 8.33, however, performs these steps separately
to avoid unnecessarily recompiling the resource script each time the
.EXE file is prepared. As you can see from the MAKE file, the script is
compiled only if the .RC file (or the header file it includes) has been
modified.
When the executable file is loaded, the resource segments are 7iof
automatically read into memory. Rather, the system reads a specific
resource segment only when the information is required. In the ex-
ample program, the resource data for the menu and accelerator table
are read when the standard window is created through the call to Win-
Createstdwindow. The latest version of the call to this function is listed
in Figure 7.6. Note that the second parameter (which specifies the frame
window styles) now includes the value FS_ACCELTABLE, which
causes the function to install an accelerator table. Also, the value as-
signed to the variable CtlData (the address of which is passed as the
third parameter) now includes the identifier FCF_MENU, which adds a
menu to the set of control windows included in the standard window.
The seventh parameter is set to 0, which indicates that the resources are
contained within the program .EXE file (if the resource segments are lo-
cated within a dynamic-link module, this parameter must contain the
module handle returned by the DosLoadModule OS/2 function).
Finally, the eighth parameter contains the resource ID for both the
menu and the accelerator (this is the ID assigned to these resources in
the script file, which must be the same for both resources).
• 310 Programmer's Guideto the os/2Presentation
Manager
• Figure 7.6..
The call to the function Wincreatestdwindow
The window menu handle stored in the global variable HMenu is used
later in the program. The function WinwindowFromlD is described in
Figure 4.5.
The resource data supply all the information the system needs to con-
struct the menu and accelerator table according to the specifications
supplied in the original resource script. The next section discusses the
messages sent when the user either selects a menu item or presses an
accelerator key.
Using Menus and Accelerators 311.
MANAGING MENUS
• AND ACCELERATORS
Onceyouhaveinstalledamenuandacceleratortablethroughthe
call to Wincreatestdwindow, the system displays the menu and al-
lows the user to access submenus and select menu items. The system
window procedure manages the menu, automatically performing such
tasks as displaying and removing pull-down submenus, and moving
the highlight from one menu item to another in response to the arrow
keys. The system sends messages to the client window whenever
relevant events occur. Your program, therefore, need only respond to
these messages and perform the requested commands.
The example program processes the following three general mes-
sages sent by the menu window procedure:
Menu Identifier
(Low-order Word of mpl) Cause of Message
WM INITMENU
Purpose..
This message is sent by the system to the client window
when a menu item is about to become active.
Parameters..
REARAM mpl
low-order word: Identifier of the menu item becoming
active.
high-order word: 0.
REARAM mp2 Menu window handle.
Return Value ..
NULL.
Notes..
This message gives the client window procedure an oppor-
tunity to perform any necessary initializations before a sub-
menu is displayed.
• Figure7.7..
The WM_INITMENU Presentation Manager message
Using Menus and Accelerators 313.
MRESul,T EXPENTRY InitMenu (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/*** 13ranch on the code for the specific submenu that is being displayed. ****/
switch (SHORTIFROMMP (mpl) )
(
case ID EDIT: /* 'Edit' submenu.
return FALSE;
case ID SEARCH: /* 'Search' submenu. */
WinsendMsg /* Set attribute of 'Find Next' item.*/
(HMenu,
MM SETITEMATTR, /: g::d::t::b:::uo¥±::::. item. :/
MPFROM2 SHORT
(ID_FINDNEXT, /* 'Find Next' menu item.
TRUE) , /* Include submenus.
MPFROM2 SHORT
(MIA DISABLED, /* Disabled attribute.
/* Disable if no search string given.*/
• Figure7.8..
The function lnit:Menu of the example progran
• 314 Programmer'sGuidetothe os/2Presentation
Manager
return F`ALSE ;
case ID OPTIONS: /* Options submenu.
return FALSE;
default :
return FALSE;
} /* end switch */
} /* end InitMenu */
• Figure7.8..
The function lritMeou of the example progran (continued)
MM SETITEMATTR
Purpose..
This message is sent to a menu window to set the attributes
of a menu item.
Parameters..
REAEN mpl
low-order word: Identifier of the menu item (as
assigned in the resource script).
high-order word: A flag indicating. whether to search
submenus for an item with the
identifier given in the low-order word.
REAFEN mp2
low-order word: A mask for the attribute (s) you would
like to set; you can specify one or more
of the following values (combined
with the logical OR operator):
• Figure 7.9..
The MM_SETITEMATTR Presentation Manager message
UsingMenusandAccelerators 317 .
Return Value ..
The menu window procedure returns TRUE if the service
has been successfully performed, and FALSE if an error
occurred.
Notes..
The original attributes of a menu item are specified in the
resource script; this message, however, can be used to
modify one or more attributes.
If the high-order word of mpl is set to TRUE and the menu
does not have an item with the specified identifier, the proce-
dure searches submenus for the matching item.
Note that each attribute is represented by a single bit in a
bit mask; the attribute is enabled if the corresponding bit is
on. The high-order word of mp2 is a bit mask specifying
which attributes you want to modify; the low-order word is
a bit mask indicating the actual desired value of each of these
attributes. For example, if you wanted to c7i¢Z7Jc the check
mark but dz.s¢Z7Zc the frame, you would assign the high-order
word of mp2 the value
MIA CHECKED I MIA FFLAMED
• Figure 7.9..
The MM_SETITEMATTR Presentation Manager message (continued)
Therefore, the initialization routine sets the text of this submenu item
according to the current value of the Insert flag. The text is set by send-
ing the MM_SETITEMTEXT message directly to the menu window.
This message is described in Figure 7.10.
®318 Programmer's Guide to the OS/2 Presentation Manager
MM SETITEMTEXT
Purpose..
This message is sent to a menu control window to specify the
text displayed for a given menu item.
Parameters..
REAEun mpl
low-order word: Identifier of the item (as assigned in
the resource script).
high-order word: 0.
REARAM mp2 Far pointer to a null-terminated string
containing the item text.
Return Value ..
The menu window procedure returns TRUE if the service
has been successfully performed, and FALSE if an error
occurred.
Notes..
The original text for the menu item is specified in the
resource script; this message, however, can be used to
change the item text.
• Figure 7.10..
The MM_SETITEM:TEXT Presentation Manager message
WM COMMAND
Purpose..
This message is sent by a control window to its owner to
report a significant event.
Parameters..
REAEun "pl
low-order word: The command value.
high-order word: 0.
REJ- mp2
low-order word: Source of the message, which may be
one of the following values:
Return Value ..
NULL.
Notes..
See also a similar message, WM_CONTROL (Figure 8.18).
• Figure 7.1.1..
The WM_COMMAND Presentation Manager message
• 320 Programmer's Guide to the os/2 PresentationManager
This use of this macro is exactly analogous to the use of the CHARMSG
macro, explained in Chapter 6 (in the section on The WM_CIIAR Message).
The menu selections listed in Table 7.2 are processed within the Com-
mand function.
Note that the descriptions of routines within this chapter are in the
section on The Menu Commands. As mentioned previously, not all
routines are described in the current chapter, since some of them require
dialog boxes or other features presented later in the book. The routines
described in Chapter 7 or 8 are implemented in the complete program
listing given in Figure 8.38; for routines that require techniques
presented in later chapters, this version of the program calls the func-
tion NotYet. The NotYet function simply displays a message box in-
dicating that a given routine has not yet been implemented (the name of
the nonimplemented routine is passed as a parameter). The function
NotYet is listed in Figure 7.12.
/* Format message.
sprintf (Buffer,"Not Yet Implemented: %s",Message) ;
WinMessageBox /* Display a message box.
(HIND DESKTOP, /* Handle of parent -- try frame.
HFrame , /* Handle of owner.
Buffer, /* Message text.
''PM Text Editor", /* Caption.
0' /* Help window ID: not needed.
MB_OK I /* Display an 'OK' button.
MB ICONASTERISK) ; /* Display an asterisk.
} /* end NotYet */
• Figure 7.12..
The function NotYct of the example program
• THEMENUCOMMANDS
This section describes the routines for executing the menu com-
mands that do not require dialog boxes or other features treated in sub-
sequent chapters. Each of these routines is contained in a branch of the
switch statement, within the function Command.
} /* end if Modified */
ReleaseFile () ; /* Free current heap.
NewFile (); /* Initialize a new file.
FileName [0] = '\0'; /* New file is untitled.
ShowFileName () ; /* Display ''Untitled" in title bar.
::::::::o: % , ,: 3::e:nT:::fi::n:::7;ursor values.
return FALSE;
• Figure 7.13..
The routine for the New command of the File submenu
• 324 Programmer's Guide to the os/2 PresentationManager
selected. If the user chooses to save the file, the program then sends a
WM_COMMAND message (with an ID_SAVE command code) back to
the client window. This recursive message activates the Save routine,
described later in the chapter, exactly as if the user had selected this
item from the File submenu.
The routine now performs a series of steps to reinitialize the file buff-
er and the data displayed within the window for a new, empty, and un-
named file. First, it calls the function ReleaseFile (Figure 7.14), which is
in the buffer-management module and serves to release the current file
data by destroying the Presentation Manager heap that had been allo-
cated when the file was first created or read from the disk. It then calls
the function NewFile, described in Chapter 6, to initialize a new, empty
file within the file buffer.
The routine next assigns the value NULL to the first character of the
string FileName. FileName is a global string that contains the fully
qualified name of the current file (that is, the file name including the
drive and full directory path specifications). Whenever the file is cur-
rently unnamed, the first character of this string is set to NULL.
In the present version of the example program, the function main as-
signs an initial value to FileName. If the user has not entered a file name
on the command line, it sets the first character of FileName to NULL to
indicate an unnamed file. If, however, the user included a file name on
the command line, main assigns the fully qualified version of this name
to FileName. The fully qualified path name corresponding to a given
return ;
} /* end ReleaseFile */
• Figure 7.14:
The ReleaLseErle function of the example program
UsingMenusandAccelerators 325 .
file is obtained through the function Qualify, which is called from func-
tion main as follows:
} /* end Qualify */
• Figure 7.1.5:
The Qual.lfy function of the example program
• 326 Programmer's Guide to the os/2PresentationManager
• Figure 7.16..
The GetpaLth utility function of the example program
UsingMenusandAccelerators 327 .
program did not store the drive and directory associated with the cur-
rent file, this file could easily be written to the wrong directory when it
is saved.
Once FileName has been set to an empty string indicating an un-
named file, the routine for the New command calls the ShowFileName
utility function (listed in Figure 7.17) to update the file name displayed
in the window title bar. The present version of the example program
displays the name of the current file along with the name of the pro-
gram within the title bar. The function main specifies an empty title (``'')
in the call to Wincreatestdwindow and then immediately calls Show-
FileName to set the appropriate title. The function ShowFileName sets
the title text by calling the Presentation Manager function Winset-
WindowText, which is described in Figure 7.18. Before setting the title
bar, the function ShowFileName formats the title bar text using the fol-
lowing command:
The file name written to the title bar text (Title) by this command is
either the current file name, or the string ``(Untitled)" if FileName is
empty. Note, however, that rather than displaying the fully qualified
file name, the program obtains the simple file name by calling the utility
function Unqualify (listed in Figure 7.19).
• Figure 7.1-/'..
The ShowHLltENarne function of the example program
• 328 Programmer's Guide to the os/2PresentationManager
Unqualify locates the simple file name (that is, the name and exten-
sion without the drive or directory specifications) within the string con-
taining a fully qualified name that is passed as a parameter. It then
converts the simple name to uppercase letters, and returns a pointer to
the portion of the string containing this name. The characters of the
simple name are converted to uppercase using the Presentation
Manager function Winupper, which is described in Figure 7.20. Thus,
all file names displayed in the title bar are simple names in uppercase
letters, in conformance with the Presentation Manager style guidelines.
WinsetwindowText
Purpose..
Sets the text associated with a window.
Prototype..
BOOL APIENTRY WinsetwindowText
(HWND hwnd, Handle of the window.
psz pszText) ,. A nun-terminated string containing the text
to be assigned to the window given by hwnd.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
The manner in which the text passed to this function is used
depends upon the specific target window. If hwnd is the frame
window handle, the specified text is displayed in the title bar
control window.
Relate d Function..
WinQuerywindowText (Figure 8.16)
• Figure 7.18..
The W±nsetwindowText Presentation Manager f unction
UsingMenusandAccelerators 329 .
Finally, after resetting the Modified flag to 0, the New file routine
calls the utility function Initwindow to initialize the window for a
new file. This function is listed in Figure 7.21, and performs the follow-
ing tasks:
while (Ptrch
* ( Ptrch-1 )
* ( Ptrch-1 )
--Ptrch ;
wj'Lnupper /* Convert unqualified name to upper case.*/
(HAncBlk, /* Anchor block handle. */
NULL, /* Code page: use current. */
NULL, /* Country code: use default. */
Ptrch) ; /* Address of string to be converted. */
return (Ptrch) ;
} /it end Unqualify */
• Figure 7.19..
The Unqudify function of the example program
• 330 Programmer's Guide to the os/2 Presentation Manager
Winupper
Purpose..
Converts the characters in a string to uppercase.
Prototype..
SHORT APIENTRY Winupper
(HAB hab, Anchor block handle.
USHORT idcp, Code page to use; a NULL value causes the
function to use the code page for the current
process.
USHORT idcc, Country code; a NULL value causes the
function to use the default country specified
in the CONFIG.SYS file.
psz psz) ,. Pointer to the string to be converted.
Return Value ..
The length of the converted string.
Notes..
The function directly modifies the characters in the string
passed through the parameter psz (that is, the string is
modified in place).
• Figure 7.20..
The WLnupper Presentation Manager function
• Figure 7.21..
The function lr\i+Window of the example progran
• 332 Programmer's Guide to the os/2PresentationManager
empty), the routine saves the file under this name and returns; if, how-
ever, the file is unnamed, the Save routine drops fferottgfe to the Save As
routine (described in Chapter 8), which obtains a file name from the
user before saving the file.
The file is saved by calling the SaveFile function of the buffer-
management module (listed in Figure 7.22), which is passed the fully
qualified file name. SaveFile is similar to ReadFile (described in Chap-
ter 3); it opens and closes the file using the high-level C functions fopen
and fclose, and writes each file line using the fputs function. See the
section on enhancements, at the end of the chapter, for several sugges-
tions on improving this routine.
} /* end SaveFile */
• Figure 7.22..
The SaveEIle function of the example program
UsingMenusandAccelerators 333 .
Insert ^= 1,.
• 334 Programmer's Guide to the os/2 Presentation Manager
• ENHANCEMENTS
This section offers two suggestions for improving the file-saving
routine, SaveFile, described earlier in this chapter.
When SaveFile writes a file, it simply overwrites the previous version
ofthisfileonthedisk.Thefirstenhancementwouldbetomodifythisfunc-
tion so that it maintains a backup copy of the prior version of the file that is
being saved. For example, if the file is named MEMO.TXT, you could
maintain a backup copy through the fouowing steps:
1. If the file MEMO.BAK exists in the same directory where the file
is being saved, it should be deleted (you can use the C function
unlink or remove, or the OS/2 service DosDelete).
2. If the file MEMO.TXT exists in the same directory where the file
is being saved, it should be renamed to MEMO.BAK (you can
use the C function rename, or the OS/2 service DosMove).
3. Write the current contents of the buffer to a new file named
MEMO.TXT.
pointers. Accordingly, SaveFile must copy each file line into a local
buffer before writing the line with fputs.
Because the OS/2 function Doswrite accepts a far pointer to the
source buffer, you can write the data directly from the heap to the file
without an intermediate copy operation. Note, however, that you will
have to insert a carriage-return character (ASCII 13) at the end of each
line, since the lines stored in the heap contain only a newline character
('\n', or ASCII 10). (C functions such as fputs automatically translate
the newline character to a newline/carriage-return pair if the file was
opened in text mode.)
• CONCLUSION
The next, and final, complete listing of the example program is
provide in Figure 8.38, at the end of Chapter 8, together with a MAKE
file and the required definition, resource, and header files.
This chapter has added a complete menu and set of accelerator keys
to the example program, and several of the menu commands have been
fully implemented. For many of these commands, however, the pro-
gram must provide additional information to the user and solicit the
user's responses. For example, the Open command of the File submenu
should display a list of files on the disk and allow the user to enter a file
name. Such interaction with the user is easily accomplished through the
medium of dialog boxes, which are the topic of the next chapter.
hapter eight
Designing
Dialog Boxes
337.
.tw tional interaction with the user. The text for each of these
commands is followed by an ellipsis (...), indicating that
the program must ehcit further information before it can execute the
command. This information is obtained through the dialog boxes de-
scribed in this chapter. A dialog box is a window managed by a system
procedure that contains an organized collection of child control win-
dows, such as text strings, edit fields, and push buttons; the child control
windows are used to display data and obtain information from the user.
The dialog boxes employed by the example program are displayed
when the user selects the related menu item, and they are removed when
the user dismisses them.
In this chapter, you will learn how to design a dialog box using the
Dialog Box Editor; you will learn how to display a dialog box from
the client window procedure; and you will learn how to write a proce-
dure to process the messages that are sent to a dialog box. The complete
listing of the current version of the example program is given in Figure
8.38, at the end of the chapter, accompanied by the other files needed to
build the executable program.
• CREATINGADIALOGBOX
This section describes how to design a dialog box and how to dis-
play a dialog box from the client window procedure; the next main sec-
tion discusses how to manage a dialog box once it has already been
displayed.
When you request the system to display a dialog box, you must
supply a fc77zpJ¢£c, which is a collection of data describing the dimen-
sions and styles of the dialog box and all the child control windows that
it contains. You can furnish these data in the form of a Presentation
Manager resource, in the same manner that you supply the data re-
quired to create menus and accelerator tables. As described in the pre-
vious chapter, the first step in creating resource data is to define these
data in a resource script, which is then translated into binary format
and inserted into the executable file using the resource compiler.
• 338 Programmer's Guide to the os/2 PresentationManager
The resource script used to create the dialog boxes for the example
program is listed in Figure 8.1. Just as a menu is defined following the
keyword MENU and an accelerator table definition follows the keyword
ACCELTABLE, each dialog template definition is labeled with the
keyword DLGTEMPLATE. Note that you must define a separate
resource for each dialog box; as you can see in Figure 8.1, the resource
script defines five dialog boxes.
Fortunately, you never have to create a resource script such as the one
in Figure 8.1. Rather, you can generate the script file using the Dialog
Box Editor. The Dialog Box Editor is a Presentation Manager program
that allows you to interactively create one or more dialog boxes; once
you have designed the dialog boxes, you can use this utility to automat-
ically generate a resource script that you can subsequently process with
the resource compiler (the script in Figure 8.1 was generated by the
Dialog Box Editor).
Each of the dialog templates in Figure 8.1 contains a large and con-
fusing collection of fields that specify the dimensions, locations, iden-
tifiers, and attributes for both the dialog box and its child control
windows. Using the Dialog Box Editor, however, you can easily select
all dialog box objects and their attributes directly from program menus.
Also, you can specify dimensions and locations by directly moving and
resizing objects on the screen using the mouse, rather than by supplying
numeric values. Accordingly, instead of describing the individual fields
and identifiers of the script file, this section explains how to create a
dialog box template through the Dialog Box Editor. Following a general
description of using this utility, the section illustrates each of the dialog
boxes employed by the example program and lists the options that were
selected from the Dialog Box Editor to create these dialog boxes.
/*
Figure 8.1
• Figure 8.1:
Resource script defining the dialog templates for the example program
•340 Programmer's Guide to the OS/2 Presentation Manager
END
END
• Figure 8.1..
Resource script defining the dialog templates for the exanple program (continued)
resource script (note that further details are given in the next section,
which describes each of the dialog boxes used by the example pro-
gram):
1. Select the New Dialog item of the Edit menu to begin designing
the first dialog box. The editor will subsequently request an iden-
tifier (through one of its own dialog boxes); you should assign
each dialog box a unique identifier, since you must pass this
value to the system to display a specific dialog box from your
Program.
DesigningDialogBoxes 341 .
2. The new dialog box appears within the Dialog Box Editor win-
dow, which simulates the ozo7icr of the dialog box. You can move
the dialog box to the desired location relative to this window by
dragging it with the mouse pointer. Note that when the dialog
box is ultimately displayed by your program, it will appear at
the same relative position with respect to the lower left comer of
its owner, which is normally the client window.
3. When you click the mouse within the dialog box, a thick sizing
border will be drawn around its edges. The object currently sur-
rounded by this border is known as the scJecfcd object, and you
can adjust the dialog box to the desired size by manipulating the
edges of this border with the mouse in the same manner that
you resize a standard Presentation Manager window.
4. Select the Styles item of the Edit menu to assign or modify the
dialog box styles (the styles chosen for each of the dialog boxes
of the example program are described in the next section).
Add controls to the dialog window (such as push buttons,
text strings, and edit fields) by selecting each control from the
• Figure 8.2..
The Dialog Box Editor
•342 Programmer's Guide to the OS/2 Presentation Manager
Once you have generated a resource script using the Dialog Box
Editor, you can convert this file to binary format and insert the data into
the executable program, as described in Chapter 7. Since the current
version of the example program also defines resources for a menu and
an accelerator, the script for the dialog boxes is included within the
general resource script (Figure 8.36, listed at the end of the chapter),
using the following statement:
This statement assumes that the script file generated by the Dialog
Box Editor is FIG8 35.DLG. When the resource compiler encounters
this statement, it r=ads and processes the dialog box script file and
adds the dialog box templates to the collection of resources in the
.RES file that will ultimately be inserted into the executable program
file. (Note that the .RES resource file generated directly by the Dialog
Box Editor, which initially would contain only dialog box resources,
is not the one loaded into the .EXE file of the example program.
However, you must save this file if you want to add, remove, or
modify dialog box definitions, since the current version of the Dialog
Box Editor reads in the .RES file rather than the .DLG file when you
specify an existing file name.) For details, see the general resource
file (Figure 8.36), the dialog resource script (Figure 8.35), and the
MAKE file (Figure 8.33) listed at the end of the chapter.
Once you have designed the collection of dialog boxes and have
placed the dialog box templates within resource segments in the ex-
ecutable file, you can display any of these dialog boxes and use it to col-
1ect data from the user. Before explaining how to display and manage
dialog boxes, however, the following section describes each of the
dialog boxes used within the example program so that you will be able
to create them; the following section also serves to describe many of the
specific control windows and styles that you can choose from the Dia-
log Box Editor.
• Figure 8.3..
The About dialog box
DesigningDialogBoxes 345 .
The third field gives the nuneric identifier, and the corresponding con-
stant if one has been defined (ID_ABOUTDLG is defined in the pro-
gram header file, listed in Figure 8.37, and DID_OK is defined in the
system header file PMWIN.H).
The final column lists all styles, features, or options that were
selected through the Styles item of the Dialog Box Editor Edit menu.
These styles are given exactly as they appear in the Dialog Box Editor.
For example, the first text control (labeled 1, and containing the string
``Presentation Manager'') was defined as shown in Figure 8.4.
IDof StylesITeatures/
Eiagbuerleig.3 5ybi:cotf Object Options
0 Dialog Box 256 Options
(ID_ABOUT- Dialog Frame
DLG)
1 Text control -1 Basic Styles
Text
Text Styles
Horiz. Centered
Top Aligned
2 Text control -1 Basic Styles
Text
Text Styles
Horiz. Centered
Top Aligned
3 Text control -1 Basic Styles
Text
Text Styles
Horiz. Centered
Top Aligned
4 Push-Button 1(DID OK) Types
Control Push Button
Options
Default
• 346 Programmer's Guide to the os/2Presentation
Manager
As you can see from Table 8.1, the About dialog box is given a d€.¢Jog
/r¢77te, which is the standard thin, double-line border normally used for
dialog boxes. Note that this is not a wide sizing border, and therefore
the user cannot resize the dialog box. Also, since the dialog box is not
given a title bar, the user cannot move it on the screen. The dialog box
identifier, 256 (ID_ABOUTDLG), will be passed to the system when the
program displays the dialog box.
The three text controls serve to display static text strings. These controls
are assigned styles so that the text they display is aligned at the top of the
control and is horizontauy centered. Since these three objects are not
manipulated by the program, they are given identification values of -1.
Finally, the push-button control is specified as a dc/##Jf push button.
A default push button is given a thicker border than a normal push but-
ton; also, if the user presses the Enter key, the system sends a message
bearing the identifier of the default push button. (If a dialog box con-
tains several push buttons, only one should be designated as default.)
As you will see, the system also sends a message accompanied by the ID
of this push button if the user clicks the mouse button with the pointer
within its borders. The user can therefore dismiss the About box either
by pressing Enter or by clicking on the button; the program also allows
• Figure 8.4..
The definition of the first text control in the About dialog box
DesigningDialogBoxes 347 .
theusertoremovethedialogboxbypressingtheEsckey.Thepushbut-
ton is assigned the identifier DID_OK, which is defined as 1 in the sys-
tem header file PMWIN.H and is the standard value used for a default
push button.
11
i......... .................`.'.'.'.'.'.'.'.'.I.'.'.'.`.'.....,'.'.'.''`'''''`..'.'''''''''''..''`''''''''''''.'.'.''.'-``'..'''.'''' i
i Find: I, li
(M- G-i----------iI i
11
• Figure 8.5..
The Find dialog box
• 348 Programmer's Guide to the os/2PresentationManager
This dialog box is given two push buttons. The push button labeled
``Find" is made the dc/##Jf push button; therefore, if the user presses the
Enter key or clicks on this button, the system will send a message con-
taining the button's ID (DID_OK). The push button labeled ``Esc=Can-
cel" is given the same ID that is sent when the user presses Esc
(DID_CANCEL); as you will see, when the program receives a message
with this ID, it immediately removes the dialog window without per-
forming the find operation. Therefore, the user can abort the operation
by clicking on the Esc=Cancel button or by pressing Esc.
i...................................'..................................-..;GotoLineNumber:|lI
: GEED Esc=Cance,
I I............................
34
• Figure 8.6..
The Go to Line dialog box
• 350 Programmer's Guide to the os/2 Presentation Manager
IDof StylesITeatures/
Eiagbuerleig.6 5ybi:c:f Object Options
Dialog Box 259 (ID_GO- Styles
TODLG) Dialog Frame
Text control -1 Basic Styles
Text
Text Styles
Left Aligned
Top Aligned
Edit control 259 (ID_GO- Text Alignment
TOEDIT) Left Aligned
Options
Auto Horiz. froll
Margin
Push-Button 1(DIDOK) Types
Control Push Button
Options
Default
Push-Button 2 (DID_CAN- Types
Control CEL) Push Button
-E=
Save File AS:
- llli
...................................I.................................................I..............................................i
\1
• Figure 8.7..
The Save As dialog box
DesigningDialogBoxes 351 .
ID of Stylesffeatures/
Efgbuerleig.7 5ybi:c?f Obj ect Options
0 Dialog Box 257 (ID_SAVE-Options
ASDLG) Dialog Frame
1 Text control 258 (ID_SAVE-Basic styles
ASCD) Text
Text Styles
Left Aligned
Top Aligned
2 Text control -1 Basic Styles
Text
Text Styles
Left Aligned
Top Aligned
3 Edit control 257 (ID_SAVE-Text Alignment
ASEDIT) Left Aligned
Options
Auto Horiz. Scron
Margin
4 Push-Button 1(DIDOK) Types
Control Push Button
Options
Default
5 Push-Button 2 (DID_CAN- Types
Control CEL) Push Button
• Figure 8.8..
The Open dialog box
The Open dialog box displays the current drive and directory and al-
lows the user to enter the name of the file that is to be opened. In addi-
tion to the controls contained in the dialog boxes described previously,
this dialog box includes a list box. The list box displays all files that have
a .C or .TXT extension within the current directory, and contains a verti-
cal scroll bar that can be used to scroll through the list. The list box also
displays all subdirectories (including the parent directory) belonging to
the current directory, and the letters of all disk drives that are currently
installed.
If the user highlights a file name ®y moving the highlight to the item
with the arrow keys or by clicking on the item with the mouse), the pro-
gram displays this name automatically in the edit control. If the user
selects a file name by pressing Enter when the name is highlighted, or
by double-clicking on the item, the program opens the file and removes
the dialog box. If the user selects a directory name in the same manner
DesigningDia]logBoxes 353 .
WinDlgBox
(HWND DESKTOP, /* Handle of parent window: */
/* desktop. */
t"ryd I / * Handle of owner: client. */
Aboutproc, / * Address of dialog procedure. */
NULL ' / * Resource module: the .EXE file. */
ID ABOUTDLG, /* Name ID of dialog window: About.*/
NULL) ,. /* Pointer to procedure data: n/a. */
When the client window procedure makes this call, the system dis-
plays a dialog box that conforms to the template stored as a resource in
the .EXE file. The value NULL, passed as the fourth parameter, indicates
that the dialog resource is located in the .EXE file, rather than in
a dynamic-link module. Note that the dialog-box identifier passed as
the fifth parameter (ID_ABOUTDLG) is the same value assigned to the
dialog box within the resource script.
The third parameter supplies the address of a diezog proccdt/rc; as
you will see in the next section, the dialog procedure is a function that
DesigningDialogBoxes 355 .
WinDlgBox
Purpose..
Loads, displays, and processes a dialog box.
Prototype,
USHORT APIENTRY WinDlgBox
(IIWND hwndparent , Handle of the parent window (usually
HWND DESKTOP).
IIWND hwndowner , Handle:ftheownerwindow(usuauy
the client window).
PFNWP pfnDlgproc, Address of the dialog procedure.
"ODULE hood, Handle of the module containing the
resource for the dialog box; if the
resource is contained in the .EXE file,
this value should be NULL; if the
resource is in a dynamic-link hbrary
file, this parameter should be assigned
the handle returned by
DosLoadModule.
USHORT idDlg, The dialog-box identifier (that is, the
ID assigned to the dialog box in the
resource script).
pvolD pcreateparams) ,. A pointer to dialog procedure data, or
NULL if no data is passed to the
dialog procedure.
Return Value ..
The value that the dialog procedure passes as the second
parameter to WinDismissDlg, or DID_ERROR if an error
occurred.
Notes..
This function does not return until the application dialog
procedure issues the function WinDismissDlg.
Relate d Functions ..
WinDismissDlg (Figure 8.11 )
• Figure 8.9..
The W±nDLgBox Presentation Manager f unction
• 356 Programmer's Guide to the os/2 PresentationManager
you write to process the messages sent to the dialog box window. Win-
DlgBox does not return control until the dialog procedure explicitly dis-
misses it (through the function WinDismissDlg, discussed in the next
section). While the dialog box is displayed-and the dialog procedure is
processing the messages it is sent-the user cannot switch the focus to
another window within the current application (such a dialog box is
described as 777od¢J).
The first parameter supplies the handle of the parent of the dia-
log box. Since the desktop window (the entire screen, identified by
HWND_DESKTOP) is assigned as the parent, the dialog box is a top-
level window and can appear outside the boundaries of the
application's standard window. The second parameter specifies that
the owner of the dialog window is the client window; accordingly, the
dialog box will appear in the same position relative to the lower left
corner of the client window that it appeared relative to the simulated
owner window in the Dialog Box Editor (that is, the coordinates for the
dialog-box position that are written to the resource script are relative to
the lower left corner of the owning window). Note that this chapter ex-
plains only one of several methods that can be used to display a dialog
box under the Presentation Manager.
• MANAGINGADIALOGBOX
Once the system loads and displays a dialog box in response to the
WinDlgBox function, all messages sent to the dialog-box window are
received by the dialog procedure. A dialog box is thus managed by the
associated dialog procedure in the same way that a client window is
managed by the client window procedure assigned to the window's
class. A dialog procedure has the following features in common with a
client window procedure:
WinDefDlgproc
Purpose..
Provides default processing for a message sent to a dialog
procedure.
Prototype..
ULONG APIENTRY WinDefDlgproc
(IIWND hwndDlg, Dialog window handle.
USHORT msgid, Message identifier.
REARAM mpl , Message-specific information.
MPARAM mp2 ) ,. Message-specific information.
Return Value ..
The message return data; the meaning of this value depends
upon the message.
Notes..
This function is called by a dialog procedure; the four
parameters passed to the function should be the s¢777c as the
parameters passed to the dialog procedure. The function is
analogous to WinDefwindowproc, called by normal win-
dow procedures.
Related Functions ..
WinDefwindowproc (Figure 2.17)
• Figure 8.10..
The W±nDefDlgproc Presentation Manager f unction
DesigningDialogBoxes 359 .
WinDismissDlg
Purpose..
Removes the current dialog box and causes the function
WinDlgBox to return control.
Prototype..
BO0L APIENTRY WinDismissDlg
(HWND hwndDlg, Dialog window handle.
USHORT usResult) ,. Value that is to be returned by
WinDlgBox.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
This function hides but does not actually destroy the dialog
box; the dialog box is subsequently destroyed when control
reverts to the function WinDlgBox, which was originally
used to display the dialog box.
Related Functions ..
WinDlgBox (Figure 8.9)
• Figure 8.11..
The WinDis:rr\issD18 Presentation Manager function
The Commands
Now that the general techniques for designing, displaying, and
managing dialog boxes have been described, this section discusses each
of the menu commands of the example program that is implemented
using a dialog box. Note that the dialog box for each of the following
commands was discussed in the section on The Program Dialog Boxes,
earlier in the chapter.
• 360 Programmer's Guide,to the os/2 Presentation Manager
• Figure 8.12..
The routine for the About menu command
DesigningDialogBoxes 361 .
MRESULT EXPENTRY Aboutproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
/*
Prcicess dialog messages for the 'About' dialog box.
*/
(
switch (msg)
(
/*** Process WM COMMAND messages sent by 'About' dialog box controls. ***/
case WM COMMAND:
} /* end Aboutproc */
• Figure 8.13..
The function Atooulproc of the example program
• 362 Programmer's Guide to the os/2 Presentation Manager
button was designated as the default push button (this style was
selected from the Dialog Box Editor); therefore, the system also sends
the identifier of this button if the user presses the Enter key.
The system sends a WM_COMMAND message with the DID_CAN-
CEL command value whenever the user presses the Esc key. (As you
will see in the next routine, the system also sends this co]rm.and if the
user has selected a button that was assigned the value DID_CANCEL as
its identifier; the About box, however, contains no such button.)
If Aboutproc receives either of these two corrmand messages, it
simply calls WinDismissDlg to remove the dialog box. Accordingly,
the user can dismiss the dialog box by selecting the Ok button, or by
pressing either Enter or Esc.
return FALSE;
return FALSE;
)
return FALSE;
• Figure 8.14..
The routines for the Find and Find Next menu commands (continued)
DesigningDialogBoxes 365 .
.`:!``:I:;T'I,'.` F.XPENTRY Findproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
.I
i;:::5R:u5:::t:2±;FALSE; /: ::::Si:::::t::a::::£:r°:i::::r::d:::en::::i. :/
switch (msg)
(
• Figure 8.15..
The function Findproc of the exanple program
• 366 Programmer's Guide to the os/2 Presentation Manager
default:
return FALSE;
)
/*** Process WM INITDLG message sent when dialog box first displayed. ***/
• Figure 8.15:
The function F±ndproc of the example program (continued)
DesigningDialogBoxes 367 .
case WM INITDLG:
• Figure 8..15:
The function Findproc of the example program (continued)
Note that the function SearchBuf may have changed the values of
Cursorcol or CursorLine. The cursor is actually placed at this new
position by the function SetFocus, which is automatically activated
through the WM_SETFOCUS message sent when the client window
regains the keyboard focus after the dialog window is removed.
In general, control windows notify their owners of significant events
either through the WM_COMMAND message (already discussed), or
through the WM_CONTROL message (described in Figure 8.18). The
Findproc dialog procedure processes the WM_CONTROL message sent
WinQuerywindowText
Purpose,
Copies the text associated with a window into a program
buffer.
Prototype..
SHORT APIENTRY WinQuerywindowText
(HWND hwnd, Window handle.
SHORT cchBufferMax, Length of buffer to receive text.
pSz pszBuffer) ,. Address of buffer to receive text.
Return Value ..
The length of the window text copied into the buffer.
Notes..
This function will not copy more than ccBufferMax-1
characters.
Relate d Functions ..
WinsetwindowText (Figure 7.18)
• Figure 8.16..
The WinQnery:WindowText Presentation Manager f unction
DesigningDialogBoxes 369 .
by the edit control window whenever the text it contains is altered (the
text can be altered either by the user or by the program through the
WinsetwindowText function).
Whenever its text is modified, the edit control sends a WM_CONTROL
message with its own identifier (ID_FINDEDIT) in the low-order word of
mpl, and the code EN_CIIANGE in the high-order word of mpl. The
dialog procedure processes this message by obtaining the first character
containedintheeditfield(throughthefunctionWinQuerywindowText).
It then calls WinEnablewindow (Figure 4.10) to c7i¢Z7Zc the Find button
if the string contains at least one character or to d{.s¢bJe the button if the
string is empty. When the Find button is disabled, its text is displayed in a
halftone font, and the system does 72of send the DID_OK command when
Searches f ile buf fer for string 'Findstring', from position given by
'I..Lne' and 'Column'. If string is found, updates 'Line' and 'Col' to
pos;ition immediately after the string in buffer, and returns TRUE. If
string is not found, function does not update 'Line' and 'Col', and it
returns FALSE.
(
register int i, j;
char far *Fptrch;
Fptrch = LineTable [*Line].LineAddress + *Col;
i = i.Line;
for (;;)
(
while (*Fptrch)
(
for (j = 0; Findstring [j] == Fptrch [j] && Findstring [j]; ++j)
} /* end SearchBuf */
• Figure 8.17..
The function Sea;rch;But of the exanple program
• 370 Programmer's Guide tothe os/2PresentationManager
the button is selected or the user presses Enter. Accordingly, the user
does not attempt to search for a NULL string.
Finally, the Findproc function processes the WM_INITDLG message
(Figure 8.19), which is sent when the dialog box is first displayed. The
initialization routine calls WinsetwindowText to set the text in the edit
control to the string currently contained in Findstring (which is either
empty or contains a string from a previous execution of the Find menu
command).
WM CONTROL
Purpose..
This message is sent by a control window to its owner to
report a significant event.
Parameters..
MPAEun mpl
low-order word: Identifier of control window.
high-order word: The notify code, which indicates the
specific event; the meaning of this field
depends upon the control window
class.
REJ- mp2 Control-specific information.
Return Value ..
NULL.
Notes..
See also a similar message, WM_COMMAND (Figure 7.17).
• Figure 8.18..
The WM_CONTROL Presentation Manager message
DesigningDialogBoxes 371 .
WM INITDLG
Puxpose..
This message is sent by the system to a dialog window when
it is first created, before it becomes visible.
Parameters..
REA- mpl Handle of the dialog control window that
will receive the initial keyboard focus.
REJ- mp2 Pointer to an optional data structure passed
as the last parameter to WinDlgBox.
Return Value ..
The dialog procedure should return TRUE if it has assigned
the focus to a control window other than that given in mpl
(by calling WinsetFocus; this would be done to alter the con-
trol that receives the initial keyboard focus). The procedure
should return FALSE if it has 71of changed the focus.
Notes..
This message allows the dialog procedure to perform in-
itialization tasks.
• Figure 8.19..
The WM_INITDLG Presentation Manager message
update the window display. Note, however, that the function Win-
Createcursor is called to explicitly reposition the cursor; this step is
necessary because the routine does not display a dialog box, and there-
fore the SetFocus function is not automatically invoked as the focus is
passed from the dialog window back to the client window.
return FALSE;
• Figure 8.20..
The routine for the Go to Line menu command
DesigningDialogBoxes 373 .
specified line number. Most of the processing for this command occurs
within the dialog procedure, which returns a value of TRUE if the com-
mand was executed (the user selected the Go to Line push button), or
FALSE if the command was aborted (the user selected the Cancel but-
ton). If the command was executed, as indicated by a TRUE return
value, the routine invalidates the entire window to force the Paint func-
tion to display the appropriate data for the new file position.
The dialog procedure for this command is named Gotoproc, and it is
listed in Figure 8.21. This function is quite similar to the dialog proce-
dure for the Find command, discussed in the previous section. If the
procedure receives a WM_COMMAND message with the DID_OK
command, it extracts the text from the edit control and calls the C
library function atoi to convert the string to a numeric value. If the
resulting line number is valid (that is, greater than 0), it is first decre-
mented because the user counts lines beginning with 1, whereas the
program enumerates lines beginning with 0. If the number is invalid,
the function simply returns, which terminates processing of the current
message but causes the dialog box to remain active.
The routine next sets the global variable CursorLine to the newly ob-
tained line-number value, and adjusts TopLine so that the line contain-
ingthecursorisdisplayedhalfwaydownthescreen.Finally,Cursorcol
and Firstcol are set so that the first colu]rm will be visible and will con-
tain the cursor, and the dialog box is dismissed, returning a value of
TRUE to force the client window procedure to update the window dis-
play. (Note that when the dialog box is removed, the SetFocus function
performs the actual repositioning of the cursor.)
In the same manner as the Findproc function, Gotoproc processes
the WM_CONTROL message sent by the edit control when its text is
changed. This routine enables the Go to Line push button only if the
edit control contains at least one character.
Finally, Findproc processes the WM_INITDLG message. This routine
calls WinEnablewindow to initially disable the Go to Line button, since
the edit control does not yet contain text.
• 374 Programmer's Guidetothe os/2Presentation
Manager
MRESULT EXPENTRY Gotoproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
char NumberBuf [33];
char Buffer [2];
SHORT LineNumber;
switch (msg)
(
/*** Process WM_COMMAND messages sent by dialog controls. ***************/
case WM COMMAND:
• Figure 8.21..
The function Gotoproc of the example progran
Designing Dialog Boxes 375.
(
case ID GOTOEDIT:
switch (SHORT2FROMMP (mpl) )
(
/*** User altered the text. *************************/
case 7!-gEF::; text. */
WinQuerywindowText
((END) mp2,
2,
Buf fer) ;
/* Enable 'Go to' button if text present. */
WinEnablewindow
(WinwindowFromlD (hwnd, DID_OK) ,
Buffer [0]) ;
return FALSE;
default:
return FALSE;
)
default:
return FALSE;
)
/*Jf* Process WM_INITDLG message sent when dialog box first displayed. ***/
case WM INITDLG:
default:
return WinDefDlgproc (hwnd, msg, mpl, mp2) ;
)
} /* end Gotoproc */
® Figure 8®21..
Tire fu.nction Gotoproc of the exanple program (continued)
when control drops through from the Save routine (the Save routine
precedes the Save As routine, and allows control to pass to the Save As
routine if the file is currently unnamed). The routine serves only to ac-
tivate the appropriate dialog box, and is listed in Figure 8.22.
The dialog procedure for the Save As command, SaveAsproc, is
listed in Figure 8.23. When the user selects the Save dialog button, this
function extracts the contents of the edit control, and-if the string is
not empty-it calls the function SaveFile (described in Chapter 7). If
SaveFile returns TRUE, indicating that it successfully saved the file
under the new name, the fully qualified version of this name is stored in
the global variable FileName, the new name is displayed in the title bar
(by calling ShowFileName), and the Modified flag is reset to 0. If Save-
File returns FALSE, the procedure displays a message box to inform the
user that the file could not be saved. Whether or not the save operation
was successful, the dialog box is dismissed.
SaveAsproc also processes the WM_CONTROL message that is sent
whenever the text in the edit control is modified. The routine that
processes this message performs the same tasks as the routines belong-
ing to the dialog procedures that have already been described.
Finally, the SaveAsproc function processes the WM_INITDLG mes-
sage to initialize the dialog box. The initialization routine first sends
the message EM_SETTEXTLIMIT (Figure 8.24) to the edit control. This
message is sent to an edit control of a dialog box to set the maximum
number of characters that can be entered into the control (either by the
user or by the program when it calls WinsetwindowText; the default
number of characters is 32). The maximum is set to the value PATH-
LENGTH (currently 128), so that the edit control can accommodate a
• Figure 8.22..
The routine for the Save As menu command
Designing Dialog Boxes 377.
MRESuljT EXPENTRY Saveasproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
*/
/* Remove dialog box.
WinDismissDlg (hwnd, TRUE) ;
• Figure 8.23..
The function SaveALsproc of the example program
• 378 Programmer's Guide to the os/2Presentation
Manager
return FALSE;
)
return FALSE;
case WM CONTROL:
switch (SHORTIFROMMP (mpl) )
(
/*** Message sent by edit box. ********************************/
case ID SAVEASEDIT:
/*** Process WM_INITDLG message sent when dialog box first displayed. **
case WM INITDLG:
• Figure 8.23..
The function Sa:veAsproc of the example program (continued)
DesigningDialogBoxes 379 .
default:
/* Execute default processing for all other messages.
return WinDefDlgproc (hwnd, msg, mpl, mp2) ;
)
• Figure 8.23..
The func,tion Sa:veAsproc of the example program (continued)
full file path specification. Note that the message is sent using the func-
tion WinsendDlgltemMsg (Figure 8.25) rather that the usual Win-
SendMsg function. This function allows you to send a message to a
dialog control window that is specified according to its identifier and
the handle of its parent, rather than by its own handle (which is not nor-
mally known). The call to WinsendDlgltemMsg is slightly simpler
than the following equivalent call to WinsendMsg:
Winsenc"sg
(WinwindowFromlD (hwnd, ID SAVEASEDIT) ,
EM SETTEXTLIMIT,
RE=ROM2SHORT (PATHI-ENGTH, 0) ,
0),.
EM SETTEXTLIMIT
Purpose..
This message is sent to an edit control of a dialog box to set
the maximum number of characters that can be entered
into the control.
Parameters..
ueJ- mpl
low-order word: The maximum number of characters.
high-order word: 0.
REARAM mp2 NULL.
Return Value ..
The edit control returns TRUE if the function was successful,
or FALSE if an error occurred.
Notes..
This message sets the limit of the number of characters that
can be entered by the user, or assigned to the edit control
through the WinsetwindowText function.
• Figure 8.24..
The EM_SETTEXTHMIT Presentation Manager message
DesigningDialogBoxes 381 .
in Table 8.6. Note that the first values given for mpl in the table repre-
sent the low-order words passed to the dialog procedure in this
parameter, and the second values represent the high-order words. Each
of these messages is now discussed.
WinsendDlgltemMsg
Purpose..
Sends a message to a child control window within a dialog
box; the target control window is specified by its identifier
and the parent window handle (rather than by its own win-
dow handle).
Prototype..
ImESULT APIENTRY WinsendDlgltemMsg
(HWND hwndDlg, A Dialog window handle.
USHORT idltem, Identifier of child control window.
USHORT msg, Message identifier.
REARAM mpl , Message parameter 1 (message-specific
meaning).
REARAM mp2 ) ,. Message parameter 2 (message-specific
meaning).
Return Value ..
The value returned by the control window procedure.
Notes..
This function is equivalent to calling WinsendMsg, specify-
ing the handle of the child control window.
Relate d Functions ..
WinsendMsg (Figure 4.8)
• Figure 8.25..
The WinsendDlglte"Msg Presentation Manager function
• 382 Programmer's Guide to the os/2Presentation
Manager
• Figure 8.26..
The routine for the Open menu command
WM_COMMAND / DID OK
The WM_COMMAND message with the DID_OK command
value is sent when the user selects the Open push button or presses the
Enter key. In response to this message, the dialog procedure first calls
WinQuerywindowText to extract the file name entered into the edit
control. If the file buffer contains unsaved data (which is indicated if the
Modified flag is set to 1), the procedure gives the user the opportunity
to save the current file before reading the new file. Note that rather than
duplicating the code for saving the file, the routine simply sends a
WM_COMMAND message-with an ID_SAVE command code-
directly to the client window; this is exactly the same message that is
sent to the client when the user selects the Save item from the File sub-
menu. (Note also that if the current file has not been assigned a name,
the client window procedure will display the Save As dialog box. It is
thus possible to display a dialog box on top of an already active dialog
box; when the second dialog box is dismissed, the first one is uncovered
and resumes processing.)
Next, the procedure frees the current contents of the heap by calling
ReleaseFile, and reads the new file by calling ReadFile. If the read
operation fails, the program sets FileName to NULL and initializes a
new, empty file by calling NewFile. If the read operation is successful,
the fully qualified version of the new file name is stored in FileName. In
either case, the file name is displayed in the title bar (ShowFileName),
the Modified flag is reset to 0, and the window is initialized for the new
file (Initwindow). Finally, the procedure calls WinDismissDlg to
remove the dialog box.
DesigningDialogBoxes 383 .
MRESULT EXPENTRY Openproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
/*
Processes messages sent to 'Open' dialog box.
*/
(
SHORT Selectlndex; /* Index of selected item in 'Open' list box. */
:E:=±:u:i:= £±E:£ath [pAT££E£:¥£:;ary st;=aE:]€:rfE:=t;ath string. :,
USHORT Reply; /* Response from message box. */
switch (msg)
(
/*** Process WM_COMMAND messages sent by dialog controls. ***************/
case WM COMMAND:
• Figure 8.27..
The function Oper\Proc of the example program
DesigningDialogBoxes 385 .
} /* end if Modified */
ReleaseFile () ; /* Free current heap.
return FALSE;
/*** Process WM CONTROL messages sent by edit box or list box. **********/
case WM CONTROL:
• Figure 8„27..
The function Openproc of the example program (continued)
• 386 Programmer's Guide to the os/2 Presentation Manager
• Figure 8.27..
The function Openproc of the example program (continued)
DesigningDialogBoxes 387 .
default:
return FALSE;
)
/*** Process WM_INITDLG message sent when dialog box first displayed. ***/
case WM INITDLG:
• Figure 8.2'.7:
The function Oper\Proc of the example program (continued)
• 388 Programmer's Guide to the os/2 PresentationManager
MPFROM2SHORT (PATHLENGTH, 0) ,
0);
return FALSE;
default:
/* Execute default processing for all other messages.
return WinDefDlgproc (hwnd, msg, mpl, mp2) ;
) /* end switch */
} /* end Openproc */
• Figure 8.27..
The function Oper\Proc of the example program (continued)
WM COMMAND/DID CANCEL
In response to the Cancel command, the dialog procedure simply
calls WinDismissDlg to dismiss the dialog box.
LM_QUERYSELECTION
Purpose..
This message is sent to a list box control window to obtain
the index of the currently selected item.
Parameters..
REARAM mpl 0.
rmARAM mp2 0.
Return Value ..
The index of the selected item.
Notes..
You can obtain the text for the selected item by sending the
LM_QUERYITEMTEXT message (Figure 8.29).
• Figure 8.28..
The LM_QUER:Y SELECTION Presentation Manager message
• 390 Programmer's Guide to the os/2PresentationManager
LM_QUERYITEMTEXT
Purpose..
This message is sent to a list box control window to obtain
the text for a specific item within the list box.
Parameters..
ueJ- mpl
low-order word: The index of the item.
high-order word: The length of the receiving buffer.
REARAM mp2 The far address of the receiving buffer.
Return Value ..
The actual length of the item text.
Notes..
You can obtain the index of the item that is currently selected by
sending the LM_QUERYSELECTION message (Figure 8.28).
• Figure 8.29..
The LM_QUEKYITEMTEXT Presentation Manager message
to update the contents of the list box (InitDlg is explained later, in the
section on the WM_INITDLG message). Likewise, if the current selec-
tion contains a directory specification, the procedure calls the OS/2
function DoschDir to change to the new directory, and then calls Init-
Dlg to update the dialog box data.
Finally, if the selected item is a file name, the procedure sends itself a
WM_COMMAND message with a DID_OK command code to cause it
to save the file under the selected name. (You may have noticed that the
LN ENTER routine obtains the file name from the list box, while the
DID_OK routine obtains the file name from the edit control. It might
seem, therefore, that when sending this recursive message, the DID_OK
routine would not access the correct file name. Note, however, that the
LN_SELECT message, described next, is always sent bc/ore the
LN_ENTER message; and, as you will see, the LN_SELECT message
copies the selected text from the list box to the edit control.)
DesigningDialogBoxes 391 .
WM INITDLG
The initialization routine invoked through the WM_INITDLG
message first sends the EM_SETTEXTLIMIT message to the edit control
to expand its text limit to accommodate a full path specification. Next,
it calls WinEnablewindow to initially disable the Open push button,
and finally, it calls InitDlg (Figure 8.30) to display the required data for
the current drive and directory.
The InitDlg function is called when the dialog box is initialized, and
whenever the current drive or directory changes. It performs the fol-
lowing sequence of tasks:
/*** Display current drive and directory path in 'Current Directory' field. **/
WinsetwindowText
(WinwindowFromlD (hwnd, ID OPENCD), /* ID of 'Current
/* Directory' field
Buf fer) ; /* Buffer containing text to display.
/*** Obtain current default disk and mapping of installed drives. ************/
DosQCurDisk
( & Dr iveNumber , /* Receives number of current drive. */
&LogicalDrives) ; /* Receives mapping of installed drives. */
/*** Clear all existing entries from the list box. ***************************/
*/
WinsendDlgltemMsg /* Send message to dialog item.
( hwnd ' /* Handle of dialog window. */
ID OPENLIST, /* ID of list box. */
LM-DELETEALL, /* Delete all entries. */
0, /* mpl: not used. */
0); /* mp2: not used. */
• Figure 8.30..
The function lr\itDL8 of the example program
DesigningDialogBoxes 393 .
i:i:i:;;;::dBuf, , ;; i;:;:¥:;:::::=::i;::e±::;::::i:nrf:::on;;
/* Process each matching file. */
while (Filecount)
* If match is a directory, but NOT '.', insert it in list box. */
f (FindBuf .attrFile & OxOO10 &&
!(FindBuf.achName [0] == I.I && FindBuf.achName [1] == '\0'))
(
sprintf (Buffer,"[%s]",FindBuf.achName) ;
WinsendDlgltemMsg /* See above. */
( hwnd '
ID OPENLIST,
"-INSERTITEM
MPFROM2SHORT (LIT SORTASCENDING, 0) ,
MPFROMP (Buffer) )T
)
/* If match is a normal file, insert only if it has the .TXT or
/* .C extension.
else if (strcmp ((Ptrch = Extension (FindBuf.achName)) ,"TXT") == 0
I I strcmp (Ptrch,"C") == 0)
WinsendDlgltemMsg /* See above.
( hwnd ,
ID OPENLIST,
IIM-INSERTITEM,
MPFROM2SHORT (LIT SORTASCENDING, 0) ,
MPFROMP (FindBuf .achName) ) ;
) /* end InitDlg */
• Figure 8.30..
The function mrhiD\g of the example program (continued)
• 394 Programmer's Guide to the os/2 Presentation Manager
Note that selecting only files with the .C or .TXT extension is an ar-
bitrary feature. You could, of course, alter this function to display ¢JJ
files, or files selected according to another criterion (or allow the user to
specify the criterion).
LM DELETEALL
Purpose..
This message is sent to a list box control window to delete all
items in the list box.
Parameters..
MPARAM mpl 0.
mARAM mp2 0.
Return Value ..
TRUE if the operation was successful, or FALSE if an error
occurred.
• Figure 8.31..
The LM_DELETEALLL Presentation Manager message
DesigningDialogBoxes 395 .
LM INSERTITEM
Purpose..
This message is sent to a list box control window to cause it
to add an item to the list.
Parameters..
REJ- "pl
low-order word: One of the following flags, indicating
where the item is to be inserted:
Flag Position
LIT END At end of list
LIT SORTASCEND- In ascending order
ING-
LIT SORTDESCEND- In descending order
ING_
high-order word: 0.
REARAM "p2 The far address of buffer containing
the text for the item.
Return Value..
The index of the inserted item, or one of the following error
codes if the function is unsuccessful:
Code Meaning
LIT MEMERROR The list box does not have
sufficient memory to allocate
space for the item.
LIT ERROR AIl other errors.
• Figure 8.32..
The LM_INSERTITEM Presentation Manager message
• 396 Programmer's Guide to the os/2 Presentation Manager
• CONCLUSION
Listed at the end of this chapter is the complete set of files required
to prepare the current version of the example program. The following
files are provided:
Figure File
The linker definition file of Figure 8.34 is the same as those provided
for previous versions of the example program, except that each of the
dialog procedures is listed under the EXPORTS statement. Note that
the dialog resource script of Figure 8.35 is generated directly by the
Dialog Box Editor; this file is included by the general resource script
file of Figure 8.36. The resource script of Figure 8.36 is processed by the
resource compiler, and is the same as the script file described in Chap-
ter 7 except for the statement that includes the dialog resource script.
The header file of Figure 8.37 is included both in the resource script
(Figure 8.36) and in the C source file (Figure 8.38).
This chapter concludes the treatment of basic Presentation Manager
features. The version of the example text editor program given here is
the last complete listing of this application provided in the book. The
remaining chapters discuss more advanced Presentation Manager fea-
tures, and offer suggestions for incorporating these features into the
current version of the example program. The example listings given in
subsequent chapters consist of short programs and program fragments.
You can, however, add these features to the example program listed in
this chapter both to increase the usefulness of this application and as an
exercise in Presentation Manager programming.
DesigningDialogBoxes 397 .
i ;I§§:;;±§iFIG836RES
#
FIG8 38.OBT : FIG8 38.C FIG8 37.H
ct iw2± ic i7;+ ic;%Ns FTif riR>_38.c
• Figure 8.33..
A MAK:1E file for preparing the example program
Figure 8.34
definition file for the program of Figure 8.38
FIGS 38
1024
8192
Wndproc
Openproc
Saveasproc
Aboutproc
Findproc
Gotoproc
• Figure 8.34..
The linker defroition file for the example program
• 398 Programmer's Guide to the os/2 Presentation Manager
/*
Figure 8.35
BEGIN
CONTROL "Save File As:", -1, 3, 50, 63, 8, WC STATIC,
SS_TEXT I DT_LEFT I DT_TOP I WS_GROUP-I WS_VISIBLE
CONTROL "", 257, 5, 31,170, 13, WC_ENTRYFIELD, ES_LEFT I ES_AUTOSCROLL
ES_MARGIN I WS_TABSTOP I WS_VISIBLE
CONTROL ''Current Directory:", 258, 3, 61,174,11, WC_STATIC, SS_TEXT I
DT_LEFT I DT_TOP I WS_GROUP I WS_VISIBLE
CONTROL "Esc=Cancel", 2, 99, 7, 56, 16, WC_BUTTON, BS_PUSHBUTTON I
WS VISIBLE
CoNTROL Wsaven, 1, 25, 8, 53, 14, WC_BUTTON, BS_PUSHBUTTON I BS DEFAULT
WS_TABSTOP I WS VISIBLE
END
END
• Figure 8.35..
The dialog resource script for the example progran
DesigningDialogBoxes 399 .
• Figure 8.35o.
Tire dialog resource script for the example program (continued)
• 400 Programmer's Guide to the os/2 Presentation Manager
Figure 8.36
#include <OS2.H>
#include "FIG8 37.H"
VIRTUALKEY
VIRTUALKEY
VIRTUALKEY
VIRTUALKEY , SHIFT
• Figure 8.36..
The general resource script for the exanple progran
DesigningDialogBoxes 401 .
Figure 8.37
Header file to be included in the resource file of Figure 8.36 and the
C source file of Figure 8.38
*/
• Figure 8.37..
The header containing definitions for the example program resources
• 402 Programmer's Guide to the os/2PresentationManager
Figure 8.38
MRESULT EXPENTRY Wndproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2) ;
• Figure 8.38..
The C source code file for the example program
DesigningDialogBoxes 403 .
i;::;::i:::::i:::::::;;;i;:;;; , #:i:;;::;::¥::¥:::;;:i:;:i:e
int SearchBuf (char *Findstring, PSHORT Line, PSHORT Col); /* Find string
• Figure 8.38..
The C source code file for the example program (continued)
®404 Programmer's Guide to the OS/2 Presentation Manager
/*** If no file name given, set 'FileName' to NULL and open new file. ********/
if (argc < 2)
(
FileName [0] = '\0';
NewFile ();
)
/*** If file name given, save fully qualified name and read file. ************/
else
(
Qualify (argv [1],FileName) ;
ReadError = ReadFile (FileName) ;
)
• Figure 8.38..
The C source code file for the exanple program (continued)
Designing Dialog Boxes 405.
) /* end main */
• Figure 8.38..
Tire C source code file for the example program (continued)
• 406 Programmer's Guide tothe os/2Presentation
Manager
/*** Process WM_COMMAND message sent when user selects a menu item. *****/
case WM COMMAND:
return Command (hwnd, msg, mpl, mp2) ;
/*** Process WM_HELP message sent when user selects help or presses F1. */
case WM HELP:
return Help (hwnd, msg, mpl, mp2) ;
case WM HSCROLL: /* Message sent on horizontal scroll activity. */
return HScroll (hwnd, msg, mpl, mp2) ;
/*** Process WM_INITMENU message sent when menu item is first selected. */
case WM INITMENU:
return InitMenu (hwnd, msg, mpl, mp2) ;
case WM PAINT: /* Message sent when window data is invalid. */
• Figure 8.38..
The C source code file for the example program (continued)
Designing Dialog Boxes 407.
} /* end switch */
} /* end Wndproc */
MRESULT EXPENTRY Character (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
w|nse¥;::!i::E8::(5:_¥:=i:?:;:;:¥:=::;::::;::;::;:;:;:
wLnse#5::§£§E8R:t5:_¥±R{:3:;:i:::;::::;;:::i:i;;;:g=ey
• Figure 8.38..
Tire C source code file for the example program (continued)
• 408 Programmer's Guide to the os/2Presentation
Manager
return TRUE;
if (!.oinLine (CursorLine + 1)) /* Join lines. */
(
WinAlarm (HWND DESKTOP, WA ERROR) ;
return TRUE;
)
LastcursorLine = CursorLine;
TopLineMax = max (0,LastLine -ywin / ycharTot + 1) ;
WinsendMsg /* Send message to vertical scroll bar.
(HVscroll, /* Recipient handle.
£BfEgE:?:53!L?3:;Line, o, , /* Se;*p3::::::n: range.
MPFROM2SHORT (0, TopLineMax) ) ; /* Range.
wLn|n|i:§§;;eRe;::::i::;*!::i:;i::i::i:::;::::::;;:;;iDREN;;
• Figure 8.38..
The C source code file for the example program (continued)
DesigningDialogBoxes 409 .
) /* end '\b' */
if (CI-IARESG(&msg)->chr == '\t') /* Process a Tab key.
(
Col = 5 -Cursorcol % 5;
whLLew£:::ri:i:i;:§E8R:(¥:i::;:::;:cec}:r;i::i:::::;:;::;::::f
return TRUE;
) /* end '\t' */
if (CHARMSG(&msg)->chr == '\r') /* Process an Enter key.
WLnEn:i:::::::: ? 1 {:o:::E::e;:i::::I:C:::;t::::::::i±lo?ar) . :;
• Figure 8.38..
Tfie C source code file for the example program (continued)
•410 Programmer's Guide to the OS/2 Presentation Manager
if (Insert)
LastcursorLine = CursorLine;
winse?!::a, /: ::::nEo::n5:¥ E::a::: to self.
WM CHAR, /* Character received message.
) /* end '\r' */
if (!I::=:::±::e, /* Insert normal key into file buffer.
CHARMSG ( &msg ) ->chr ,
Cursorcol ,
Insert) )
(
WinAlarm (HWND_DESKTOP, WA ERROR) ;
return TRUE;
)
} /* end Character */
• Figure 8.38..
The C source code file for the example program (continued)
DesigningDialogBoxes 411 .
MRESULT EXPENTRY Command (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
USHORT Result; /* WinDlgBox return code. */
USHORT Update = FALSE; /* Flag indicating whether window update needed*/
USHORT Reply; /* Response from message box. */
/*** Branch according to code for the menu item selected. ********************/
switch (COMMANDMSG (&msg)->cmd)
(
case ID NEW: /* 'New' file menu item.
if (Modif led) /* File is modified.
(
/* Warn user and elicit response on saving file.
Reply = WinMessageBox
(HWND DESKTOP,
hwnd '
"File unsaved; Save?",
''PM Text Editor",
0,
MB YESNO I
MB-ICONQUESTION) ;
• Figure 8.38..
The C source code file for the example program (continued)
• 412 Programmer's Guide to the os/2Presentation
Manager
else
/* Save successful; therefore reset 'Modified' flag*/
Modified = 0;
return FALSE;
)
/* IF 'FileName' IS NULL, DROP THROUGH TO ID SAVEAS CASE. */
• Figure 8.38..
The C source code file for the exanple program (continued)
DesigningDialogBoxes 413 .
return FALSE;
case ID ABOUT: /* 'About' item 'File' submenu.
• Figure 8.'38:
The C source code file for the example program (continued)
• 414 Programmer's Guide to the os/2Presentation
Manager
return FALSE;
case ID FINDNEXT: /* 'Find Next' item of 'Search' submenu. */
return FALSE;
)
• Figure 8.38..
The C source code file for the example program (continued)
DesigningDialogBoxes 415 .
return FALSE;
return FALSE;
• Figure 8.,38..
The C source code file for the example program (continued)
•416 Programmer's Guide to the OS/2 Presentation Manager
default :
return FALSE;
} /* end switch */
} /* end Command */
MRESULT EXPENTRY Create (HWND hwnd, USHORT msg, MPAFun mpl, MPARAM mp2)
(
• Figure 8.38..
The C source code file for the exanple program (continued)
DesigningDialogBoxes 417 .
HVscroll = WinwindowFromlD
(WinQuerywindow (hwnd, QW PARENT,FALSE) , /* Handle to parent */
/* window (frame). */
FID VERTSCROLL) ; /* Identifier for vertical scroll bar. */
return FALSE;
} /* end Create */
MRESULT EXPENTRY Help (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
NotYet ("Help Window") ;
return FALSE;
) /* end Help */
MRESULT EXPENTRY HScroll (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
SHORT Delta; /* Amount to scroll.
switch (SHORT2FROMMP (mp2) ) /* Branch according to code for the
{ /* scrolling event.
case SB LINELEFT:
Delta --1;
break;
case SB LINERIGHT:
Delta -1;
break;
case SB PAGELEFT:
Delta --6;
break;
case SB PAGERIGHT:
Delta -6;
break;
case SB SLIDERPOSITION:
Delta = SHORTIFROMMP (mp2) -Firstcol;
break;
default:
Delta -0;
break;
)
Delta = max (-Firstcol, min (Delta,FirstcolMax -Firstcol)) ;
if (Delta) /* Generate scrolling, if necessary.
(
Firstcol += Delta;
Cursorcol += Delta;
Winshowcursor /* Hide cursor.
( hwnd , /* Client window handle.
FALSE) ; /* Hide it!
Winscrollwindow /* Scroll window horizontally.
• Figure 8.3.8:
The C source code file for the example program (continued)
• 418 Programmer's Guide to the os/2PresentationManager
} /* end HScroll */
MRESULT EXPENTRY InitMenu (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/*** Branch on the code for the specific submenu that is being displayed. ****/
switch (SHORTIFROMMP (mpl) )
(
case ID EDIT: /* 'Edit' submenu.
WinsendMsg /* Set attribute of 'Cut' menu item.
( HMenu , /* Handle of menu window.
MM SETITEMATTR, /* Set attribute of menu item.
MPFROM2SHORT
( I D_CUT ' /* 'Cut' menu item.
TRUE) ' /* Include submenus.
MPFROM2SHORT
(MIA DISABLED, /* Disabled attribute.
• Figure 8.38..
The C source code file for the example program (continued)
DesigningDialogBoxes 419 .
return FALSE;
case ID SEARCH: /* 'Search' submenu. */
WinsendMsg /* Set attribute of 'Find Next' item.*/
( HMenu , /* Handle of menu window. */
MM SETITEMATTR, /* Set attribute of menu item. */
MPFROM2SHORT
( I D_FINDNEXT , /* 'Find Next' menu item. */
TRUE) , /* Include submenus. */
MPFROM2 SHORT
(MIA DISABLED, Disabled attribute */
Disable if no search string given.*/
Findstring [0] : MIA DISABLED) ) ;
return FALSE;
return FALSE;
default:
• Figure 8.38..
The C source code file for the example program (continued)
• 420 Programmer's Guide to the os/2PresentationManager
return FALSE;
) /* end switch */
} /* end InitMenu */
MRESULT EXPENTRY Paint (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
register int Line; /* Loop counter.
HPS Hpresspace; /* Presentation space handle.
RECTL Rect; /* Holds coordinates of rectangle.
SHORT StartLine; /* First file line to paint.
SHORT StopLine; /* Last line to paint.
POINTL Start; /* Starting position to print string
SHORT LineLength; /* Length of each line displayed.
Hpresspace = WinBeginpaint
( hwnd ' /* Window handle. */
0, /* Handle of PS to have clipping region set. */
&Rect) ; /* Address of struct. to set to invalid region.*/
GpicreateLogFont /* Create a logical font for presentation space*/
( Hpresspace , /* Presentation space handle. */
( PSTR8 ) NULL , /* Logical font name: none. */
ID COURIER, /* Local font ID: define a constant. */
&F6ntAttributes) /* Struct. specifying font from GpiQueryFonts. */
Gpisetcharset /* Make logical font the current character set.*/
( Hpresspace , /* Presentation space handle. */
ID COURIER) ; /* Local font ID. */
WinF i l lRect
( Hpresspace , /* Presentation space handle. */
&Rect , /* Structure containing window coordinates. */
CLR WHITE) ; /* Color to use (white) . */
Gpisetcolor
(Hpresspace, /* Presentation space handle. */
CLR BI.ACK); /* Color to use: black. */
StartLine = TopLine + (ywin - (SHORT)Rect.yTop) / ycharTot;
StopLine = min (LastLine, TopLine + (ywin - (SHORT)Rect.yBottom)
/ ycharTot) ;
Start.y = ywin -ycharTot * (StartLine -TopLine + 1) + ycharDesc;
Start.x = xchar * (-Firstcol) ;
for (Line = StartLine; Line <= StopLine; ++Line, Start.y -= ycharTot)
(
if ((LineLength = GetLineLength (Line)) == 0)
continue;
GpicharstringAt Prints string at given position
(Hpresspace , Presentation space handle.
&Start, Structure containing starting position. *
( LONG ) LineLength , Number of characters to print. *
GetLineAddr (Line) ) Address of line. *
• Figure 8.38..
The C source code file for the example program (continued)
DesigningDialogBoxes 421 .
WinEndpaint (Hpresspace) ;
return FALSE;
MRESULT EXPENTRY SetFocus (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
if (LONGFROMMP (mp2)) /* Client window RECEIVING focus.
(
Wincreatecursor /* Create a new cursor.
(hwnd, /* Client window handle.
(Cursorcol - Firstcol) * xchar, /* x position of cursor.
ywin - (CursorLine - TopLine + 1) * ycharTot, /* y position
0' /* x size of cursor: nominal border
ycharTot , /* y size of cursor.
CURSOR_SOLID I /* Solid cursor.
CURSOR FIASH, /* Blinking cursor.
NULL) ; /* Clipping rectangle: entire window.
Winshowcursor /* Make cursor visible.
( hwnd , /* Client window handle.
TRUE) ; /* Show it!
)
} /* end SetFocus */
MRESULT EXPENTRY Size (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
int Update = 0;
• Figure 8.38..
The C source code file for the exanple program (continued)
• 422 Programmer's Guide to the os/2 PresentationManager
return FALSE;
} /* end Size */
MRESULT EXPENTRY VirtKey (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
• Figure 8.38..
The C source code file for the exanple program (continued)
DesigningDialogBoxes 425 .
Cursorcol = Newcursorcol;
break;
case VK DELETE: /* Delete key. */
if (Deletechar (CursorLine,Cursorcol) )
(
/* Deletion successful -- invalidate update region. */
Rect.xLeft = (Cursorcol -Firstcol) * xchar;
Rect.xRight = min
((GetLineLength (CursorLine) + 1 -Firstcol) * xchar,
xwin) ;
Rect.yBottom = ywin - (CursorLine -TopLine + 1) * ycharTot;
Rect.yTop = Rect.yBottom + ycharTot;
WinlnvalidateRect /* Invalidate region to be updated. */
( hwnd '
&Rect,
FALSE) ;
• Figure 8.38..
The C source code file for the example program (continued)
• 426 Programmer's Guide to the os/2 Presentation Manager
• Figure 8.38..
The C source code file for the example program (continued)
DesigningDialogBoxes 427 .
MRESULT EXPENTRY Vscroll (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
SI-[ORT Delta; /* Amount to scroll.
switch (SHORT2FROMMP (mp2)) /* Switch on code for scrolling event. */
(
case SB LINEUP:
Delta --1;
break;
case SB LINEDOWN:
Delta -1;
break;
case SB PAGEUP:
Delta = -ywin / ycharTot;
break;
case SB PAGEDOWN:
Delta = ywin / ycharTot;
break;
case SB SLIDERPOSITION:
Delta = SHORTIFROMMP (mp2) -TopLine;
break;
default:
Delta -0;
break;
)
Delta = max (-TopLine, min (Delta,TopLineMax -TopLine)) ;
if (Delta)
(
TopLine += Delta;
CursorLine += Delta;
Winshowcursor /* Hide the cursor.
( hwnd ' /* Client window handle.
FALSE) ; /* Hide it!
Winscrollwindow /* Scroll window vertically.
( hwnd ' /* Handle of client window.
0, /* Horizontal scroll amount.
ycharTot * Delta, /* Vertical scroll amount.
0, /* Must be 0.
0, /* Must be 0.
0' /* Must be 0.
0' /* Must be 0.
SW INVALIDATERGN) /* Invalidate "exposed" region.
Winupdatewindow /* Force window update.
(hwnd) ; /* Handle of client window.
WinsendMsg /* Adjust vertical scroll bar.
(HVscroll, /* Handle to vertical scroll bar.
SBM SETPOS, /* Set position of slider.
• Figure 8.'38:
The C source code file for the exanple program (continued)
• 428 Programmer's Guide to the os/2 Presentation Manager
} /* end Vscroll */
MRESULT EXPENTRY Aboutproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
/*
Process dialog messages for the 'About' dialog box.
*/
(
switch (msg)
(
/*** Process WM_COMMAND messages sent by 'About' dialog box controls. ***/
case WM COMMAND:
• Figure 8.38..
The C source code file for the exanple program (continued)
DesigningDialogBoxes 429 .
} /* end Aboutproc */
MRESULT EXPENTRY Findproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
char Buffer [2]; /* Holds first character of entered file name. */
USHORT Update = FALSE; /* Flag indicates whether window update needed.*/
switch (msg)
(
/* Process WM_COMMAND messages sent by dialog controls. *****************/
case WM COMMAND:
• Figure 8.,38..
The C so'urce code file for the example program (continued)
•430 Programmer's Guide to the OS/2 Presentation Manager
default:
return FALSE;
)
case WM CONTROL:
default:
return FALSE;
• Figure 8.38..
The C source code file for the exanple program (continued)
DesigningDialogBoxes 431 .
/*** Process WM_INITDLG message sent when dialog box first displayed. ***/
case WM INITDljG:
} /* end Findproc */
MRESULT EXPENTRY Gotoproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
char NumberBuf [33] ;
char Buffer [2];
S]ioRT LineNumber;
switch (msg)
(
/*** Process WM_COMMAND messages sent by dialog controls. ***************/
case WM COI\"AND:
• Figure8.38:
The C source code file for the example program (continued)
®432 Programmer's Guide to the OS/2 Presentation Manager
default:
return FALSE;
)
case WM CONTROL:
default:
return FALSE;
)
/*** Process WM_INITDLG message sent when dialog box first displayed. ***/
case WM INITDLG:
• Figure 8.38..
The C source code file for the example program (continued)
DesigningDialogBoxes 433 .
} /* end Gotoproc */
VOID InitDlg (HWND hwnd) ; /* Initializes the 'Open' dialog box. */
MRESULT EXPENTRY Openproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
/*
Processes messages sent to 'Open' dialog box.
*/
switch (msg)
(
/*** Process WM COMMAND messages sent by dialog controls. ***************/
case WM COMMAND:
• Figure 8.38..
The C source code file for the example program (continued)
• 434 Programmer's Guide to the os/2 Presentation Manager
WinsendMsg
(Hclient'
" ComND,
MPFROM2SHORT (ID SAVE, 0) ,
OL);
} /* end if Modified */
ReleaseFile () ; /* Free current heap. */
return FALSE;
default:
return FALSE;
• Figure 8.38..
The C source code fie for the exanple program (continued)
DesigningDialogBoxes 435 .
/*** Process WM CONTROL messages sent by edit box or list box. **********/
case WM CONTROL:
• Figure 8.38..
The C source code file for the example program (continued)
• 436 Programmer's Guide to the os/2 Presentation Manager
default:
return FALSE;
)
/*** Process WM_INITDLG message sent when dialog box first displayed. ***/
case WM INITDLG:
• Figure 8.38..
The C source code file for the example program (continued)
DesigningDialogBoxes 437 .
default:
/* Execute default processing for all other messages.
return WinDefDlgproc (hwnd, msg, mpl, mp2) ;
} /* end switch */
} /* end Openproc */
/*** Display current drive and directory path in 'Current Directory' field. **/
W i ns etw i ndowText
(WinwindowFromlD (hwnd, ID OPENCD)' /: 5:r::t::;Tr:::id
Buf fer) ; /* Buffer containing text to display.
/*** Obtain current default disk and mapping of installed drives. ************/
DosQCurDisk
( & Dr iveNumber , /* Receives number of current drive. */
• Figure 8®38:
The C source code file for the example program (continued)
• 438 Programmer's Guide to the os/2Presentation
Manager
/*** Clear all existing entries from the list box. *„"**"*****************/
WinsendDlglte"sg
L7ir`CanAnl~T+,^_`f-~ 7. ~
/* Send message to dialog item. */
( hwnd , /* Handle of dialog window. */
ID OPENLIST, /* ID of list box. */
"-DELETEALL, /* Delete all entries. */
0, /* mpl: not used. */
0);
/* mp2: not used. */
/*** Insert drive letters into list box. ********************"*„************/
for (Drive = 'A'; Drive <= 'Z'; ++Drive)
(
if (LogicalDrives & 1)
(
sprintf (Buffer,"[-%c-]",Drive) ;
WLnsei§:§§;;;T¥;:M, ;; i;:i:::§§::i:i:gd:::3gw:ten.
MPFROMP (Buffer));
/* Order.
/* Address of item text.
)
LogicalDrives >>= 1;
)
i:!§:::;;:?dBuf) , ;; ¥::;::::;:::=:¥:::i:i;::::i::::::on;;
¢:i::°:i::e::::tTatch±ng file. *,
• Figure 8.38..
The C source code file for the exanple program (continued)
DesigningDialogBoxes 439 .
/* .C extension.
else if (strcmp ((Ptrch = Extension (FindBuf.achName)),"TXT") == 0
I I strcmp (Ptrch,"C") == 0)
WinsendDlgltemMsg /* See above.
( hwnd ,
ID OPENLIST,
I"-INSERTITEM,
MPFROM2SHORT (LIT SORTASCENDING, 0) ,
MPFROMP (FindBuf .=chName) ) ;
) /* end InitD19 */
MRESul\T EXPENTRY Saveasproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
• Figure 8.38..
The C source code file for the example program (continued)
•440 Programmer's Guide to the OS/2 Presentation Manager
(HWND DESKTOP,
hwnd '
''Error --Cannot Save File",
''PM Text Editor",
0,
MB_OK I
MB_ICONASTERISK) ;
else
(
/* Store fully qualified path name.
Qualify (Filepath, FileName) ;
return FALSE;
case WM CONTROL:
switch (SHORTIFROMMP (mpl) )
(
/*** Message sent by edit box. ********************************/
case ID SAVEASEDIT:
#:8:: r;:Tn::::;xt */
((HWND) mp2,
2'
Buf fer) ;
/* Enable 'Save' button if text present. */
• Figure 8.38..
The C source code file for the example program (continued)
DesigningDialogBoxes 441 .
WinEnablewindow
(WinwindowFromlD (hwnd, DID_OK) ,
Buffer [0]) ;
return FALSE;
default:
return FALSE;
)
default:
return FALSE;
)
/.it** Process WM_INITDLG message sent when dialog box first displayed. ***/
Case y¥-=¥::::Giext limit in edit box to full file path length. */
WinsendDlgltemMsg
( hwnd ,
ID SAVEASEDIT,
EM-SETTEXTLIMIT ,
MPFROM2SHORT (PATHLENGTH, 0) ,
0);
default:
/* Execute default processing for all other messages.
return WinDefDlgproc (hwnd, msg, mpl, mp2) ;
)
} /* end Saveasproc */
• Figure 8.38..
The C source code file for the example program (continued)
• 442 Programmer's Guide to the os/2Presentation
Manager
/* Format message.
sprintf (Buffer,"Not Yet Implemented: %s",Message) ;
} /* end Buflnit */
• Figure 8.38..
The C source code file for the exanple program (continued)
DesigningDialogBoxes 443 .
return TRUE;
} /* end Deletechar */
Deletes the specified line ('Line' , which must be the line currently
containing the cursor) from the file buffer.
*/
If line to be deleted is the last file line, merely truncate it. */
(Line == LastLine)
(
LineBuffer [0] = '\n';
LineBuffer [1] = '\0';
LineTable [Line].LineLength = 2;
)
else
(
/* Place the following line into 'LineBuffer' .
GetTempBuf (Line + 1) ;
/* Move all LineTable elements beyond deleted line down one element*/
memmove
(&LineTable [Line] , /* Target.
&LineTable [Line + 1], /* Source.
(LastLine -Line) * sizeof (LineTable [0])) ; /* Number bytes
--LastLine ;
)
} /* end DeleteLine */
• Figure 8.38..
The C source code file for the example program (continued)
• 444 Programmer's Guide to the os/2PresentationManager
} /* end ErrorMessage */
} /* end GetLineAddr */
} /* end GetLineLength */
• Figure 8.38..
The C source code file for the example program (continued)
DesigningDialogBoxes 445 .
• Figure 8.38:
The C sou',rce code file for the example program (continued)
•446 Programmer's Guide to the OS/2 Presentation Manager
} /* end Insertchar */
• Figure 8.38..
The C source code fr]e for the example program (continued)
DesigningDialogBoxes 447 .
(
sprintf (Message,"out of heap memory; line %d", LINE );
ErrorQuit (Message) ;
)
} /* end InsertLine */
Combines the line in the file buffer given by 'Line' with the previous
i ine .
• Figure 8.38:
The C source code file for the example program (continued)
• 448 Programmer's Guide to the os/2PresentationManager
return FALSE;
/* Move all 'LineTable' members above and including 'Line' down one */
/* place. */
memmove
(&LineTable [Line -1], /* I)estination. */
&LineTable [Line] , /* !5ource. */
(LastLine -Line + 1) * sizeof (LLneTable [0])); /* Bytes to move.*/
--LastLine ;
return TRUE;
} /* end ToinLine */
• Figure 8.38..
The C source code file for the example program (continued)
DesigningDialogBoxes 449 .
LastLine = 0;
} /* end NewFile */
• Figure 8.,38..
The C source code file for the example program (continued)
®450 Programmer's Guide to the OS/2 Pres(mtation Manager
} /* end of ReadFile */
return ;
} /* end ReleaseFile */
• Figure 8.38..
The C source code file for the exanple program (continued)
DesigningDialogBoxes 451 .
void ReleaseTempBuf
(irlt Line) /* Number of line held in 'LineBuffer' .
/*
This function:
o Allocates a new block of memory just large enough to hold the string in
the 'LineBuffer'
o Copies the string into the new block
o Adjusts the address in 'LineTable'
(
NPCH Heapoffset; /* Offset of block within heap.
} /* end ReleaseTempBuf */
• Figure 8.38..
The C source code file for the example program (continued)
• 452 Programmer's Guide to the os/2PresentationManager
} /* end SaveFile */
(
register int i, j;
char far *Fptrch;
Fptrch = LineTable [*Line] .LineAddress, + *Col;
i - *Line;
for (;;)
(
while (*Fptrch)
(
for (j = 0; Findstring [j] =:= Fptrch [j] && Findstring [j]; ++j)
} /* end SearchBuf */
• Figure 8.38..
The C source code file for the example program (continued)
DesigningDialogBoxes 453 .
(
while (*FileName)
if (*FileName++ == '.')
return (FileName) ;
return (FileName) ;
} /* end Extension */
• Figure 8.38..
The C source code file for the exanple program (continued)
• 454 Programmer's Guide to the os/2PrestmtationManager
return ;
} /* end Getpath */
• Figure 8.38..
The C source code file for the exanple program (continued)
DesigningDialogBoxes 455 .
0,
CURSOR SETPOS,
NULL) ;
} /* end Qualify */
• Figure 8.38..
The C source code file for the example program (continued)
• 456 Programmer's Guide to the os/2 Pres9ntationManager
*/
(
USHORT Reply; /* Response from message box. */
if (HHeap != NULL)
WinDestroyHeap (HHeap) ;
WinDestroywindow (HFrame) ;
WinDestroyMsgQueue (HMesQue)
WinTerminate (HAncBlk) ;
exit (Errorcode) ;
) /* end Quit */
• Figure 8.38..
The C source code file for the exanple program (continued)
DesigningDialogBoxes 457 .
Returns a pointer to the simple file name within the string 'Qual' ,
which contains a partially or fully specified file path. Converts the
unqualified f ile name to uppercase.
(
char *Ptrch;
Ptrch = Qual + strlen (Qual) ;
while (Ptrch
* ( Ptrch-.1 )
* ( Ptrch-.1 )
--Ptrch ;
Winupper /* Convert unqualified name to uppercase.
(HAncBlk, /* Anchor block handle.
NULL, /* Code page: use current.
NULL, /* Country code: use default.
Ptrch) ; /* Address of string to be converted.
return (Ptrch) ;
} /* end Unqualify */
• Figure 8.38..
The C source code file for the example program (continued)
PART
Advanced
Features
J pter nine
.T
ferring data. Once an application has placed a block of
data into the clipboard, the data can be accessed by the
same application, or by any other program running
within a Presentation Manager window. The clipboard thus provides a
single, convenient mechanism for moving blocks of data within a pro-
gram, and for effecting data exchange among separate applications.
In this chapter you will learn how to place data into the clipboard,
and how to access data contained in the clipboard; you will learn how
to use the clipboard to implement commands for cutting, copying, and
pasting data within a single program or among separate applications;
and you will learn how to add a clipboard interface to the example pro-
gram developed in the first part of the book. The chapter focuses on the
basic methods for exchanging data in a standard text format; the last
section, however, introduces some of the advanced features of the
Presentation Manager clipboard, and includes a discussion of alterna-
tive data formats.
block of data, the previous clipboard contents are destroyed. (More ac-
curately, the clipboard can contain only a single block of data in a given
format; the clipboard can hold several blocks of data, as long as each
block has a distinct format. This feature allows an application to insert
the sfl777c data selection in several different formats so that the data can
be used by a greater variety of receiving applications.) This section
describes the methods for adding blocks of data that conform to the
standard fcxf format.
The fonowing are the five basic steps that an apphcation must perform
to add a block of textual data to the Presentation Manager clipboard:
USHORT Selectionsize,.
SEL SelclipData,.
Interfacingwiththeclipboard 463 .
DosAllocseg
( Selectionsi ze ,
&SelclipData,
SEG GETTanl.E) ,.
The first parameter in this example specifies the length of the segment
in bytes. You should request a segment large enough to hold the data
selection that is to be inserted into the clipboard (in this example, the
variable Selectionsize has presumably been assigned the number of
bytes in the current data selection). The second parameter supplies the
address of the variable that is to receive the segment selector. The final
parameter passes the flag SEG_GETTABLE, which specifies that the
segment is to be shared through the DosGetseg OS/2 function, which
will be explained in the section on Accessing Data in the Clipboard,
later in the chapter.
Note that your application does not have to free the segment contain-
ing the clipboard data. Rather, the Presentation Manager automatically
frees this segment (by calling DosFreeseg) when the clipboard data are
replaced through a subsequent data submission or are explicitly cleared
by means of the WinEmptyclipbrd Presentation Manager function
(Figure 9.6, discussed later in the chapter).
Note also that when allocating a segment for the clipboard, you
should call DosAllocseg rather than DosAllocshrseg. Both of these
functions can be used to obtain shared memory segments. DosAlloc-
Shrseg, however, provides a 77¢771cd shared memory segment, which
another process cannot access unless it knows the segment name. Dos-
Allocseg, on the other hand, provides what is termed a gz.zJc¢zu¢y shared
memory segment; the Presentation Manager clipboard can grant access
to this type of segment to another process by simply passing it the seg-
ment selector. (See the section on Accessing Data in the Clipboard for
details on how the second process obtains segment access once it has
received the selector.)
DosAllocseg
Purpose,
Allocates a memory segment.
Prototype..
USHORT APIENTRY DosAllocseg
(USHORT ussize, The size of the segment in bytes (from
0 to 65,535; the value 0 allocates a
65,536-byte segment).
PSEL psel, Address of the variable to receive the
segment selector.
USHORT fAlloc) ,. The allocation flags, which can be a
combination of one or more of the
following values:
Value Effect
0 Creates a nonsharable,
nondiscardable segment
SEG GIVEABLE Calling process can call
DosGiveseg to obtain
a selector that can be
used by another
process to access the
Segment
SEG GETABLE Another process can
obtain access to the
segment by passing the
selector (psel) to the
DosGetseg function
SEG DISCARDABLE Creates a discardable
Segment
• Figure 9.1..
The DosAIlocseg OS/2 kernel function
Interfacingwiththeclipboard 465 .
Return Value ..
Returns 0 if the function is successful, or the value
ERROR NOT ENOUGH MEMORY if insufficient memory
isavaila-bletoiillthealloc-ationrequest.
Notes..
The segment can be freed by calling the DosFreeseg function.
Relate d Functions ..
DosFreeseg (Figure 10.27)
DosGetseg (Figure 9.7)
• Figure 9.1..
The DosA;Ilocseg OS|2 kernel function (continued)
• Each line should end with a carriage-return ('\r') and line feed
('\n') combination. Note that C programs typically use only the
' \n' character to terminate individual lines within textual data;
movedata
(SELECTOROF (Ptrselection) , /* Source selector.
OFFSETOF (Ptrselection) , /* Source offset.
SelclipData, /* Target selector.
0, /* Target offset.
DataLength) ,. /* Bytes to copy.
This example uses the C library function movedata, which copies data
from one segment to another. Note that it does not perform data trans-
lation; it assumes that the data are already in the proper format. This ex-
ample also assumes that Ptrselection has been assigned the far address
of the data selection within the program, that SelclipData contains the
selector of the sharable segment supplied by DosAllocseg, and that
DataLength has been assigned the number of bytes contained in the
data selection that is to be copied into the sharable segment.
HAB mcBlk,.
Winopenclipbrd
(HmcBlk) ,. /* Anchor block handle.
Winopenclipbrd
Purpose..
Opens the clipboard for the current thread, to provide this
thread exclusive access to the clipboard.
Prototype..
BOOL APIENTRY Winopenclipbrd
(HAB hab) ,. Anchor block handle.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
If another thread already has the clipboard open, this func-
tion does not return until this thread has closed the clip-
board. The clipboard is closed by calling Wincloseclipbrd.
Related Functions ..
Wincloseclipbrd (Figure 9.4)
• Figure9.2..
The Winopenclipbrd Presentation Manager function
• 468 Programmer's Guide to the os/2 PresentationManager
HAB ELincBlk,.
SEL SelclipData,.
WinsetclipbrdData
(rmcBlk,
(ULONG)MAKEP (SelclipData, 0) ,
CF TEXT,
0),.
The first parameter passed to this function is the anchor block handle
returned by the call to Winlnitialize. The expression passed as the
second parameter generates a far pointer to the base of the sharable seg-
ment that was allocated through DosAllocseg. (DosAllocseg assigns
the segment selector to SelclipData, which is combined here with a 0
offset.) The third parameter specifies the data format; the value
CF_TEXT indicates the standard text format that was described earlier
in the chapter (in the section entitled Copy the Data). Note that the data
format is stored in the clipboard along with the data address; as you
Interfacingwiththeclipboard 469 .
WinsetclipbrdData
Purpose..
Places a block of data into the clipboard.
Prototype..
BOOL APIENTRY WinsetclipbrdData
(ELne hab, Anchor block handle.
ULONG ulData, Handle to the block of data to be
inserted into the clipboard. If the data
is formatted as text, this parameter
supplies the far address of the base of
the sharable segment containing the
data; if the data is a bitmap or metafile,
this parameter contains the handle to
the object. Passing a value of NULL
indicates that the clipboard owner will
delay rendering the data until it
receives a WM RENDERFMT message.
USHORT fmt, Format of the data; you can specify a
private format or one of the following
predefined formats:
Identifier Format
CF TEXT Standard text format
CF BITMAP Bitmap format
CF METAFILE Metafile format
CF DSPTEXT Text display format
associated with a
private format
CF DSPBITMAP Bitmap display format
associated with a
private format
• Figure 9.3..
The WinsetalpbrdD ataL Presentation Manager function
•470 Programmer's Guide to the OS/2 Presentation Manager
• Figure 9.3..
The WinsetcILpbrdD ataL Presentation Manager function ( continued)
Interfacingwiththeclipboard 471 .
Return Value ..
TRUE if the data was placed into the clipboard, or FALSE if
the data was not added to the clipboard (either because of an
error, or because the handle ulData was NULL).
Notes..
If you specify a predefined data format (text, bitmap, or
metafile), you do not need to assign a memory model
through the rgfFmtlnfo parameter.
Related Functions ..
WinQueryclipbrdData (Figure 9.5)
• Figure 9.3..
Tire WLnsetcILpbrdData Presentation Manager f unction ( continued)
will see, when a program accesses data within the clipboard, it must re-
quest a specific data format. (Formats other than text are listed in the
last section of the chapter.)
The last parameter supplies additional information concerning the
block of data specified by the second parameter. When submitting data
in the standard text format, you do not need to specify any of the values
that may be passed through this parameter. (Some of the possible
values for this parameter listed in Figure 9.3 are described in the last
section of the chapter.)
Note that once your program has called WinsetclipbrdData to sub-
mit the address of the shared data segment to the system, it should no
longerusethisaddress.Rather,ifyourprogramrequiressubsequentaccess
to the block of data, it should fouow the standard procedures for accessing
datawithinthechpboard,deseribedlaterinthechapter.(Databelongingto
the chpboard must be accessed through the system so that at a given time
only one program thread can add, read, or remove data. Also, the system
may have freed the original segment selector passed to Winsetclipbrd-
Data; using such a selector will generate a protection fault.)
• 472 Programmer's Guide to the os/2 Presentation
Manager
Wincloseclipbrd
Purpose..
Closes the clipboard, previously opened through Winopen-
Clipbrd.
Prototype..
BOOL APIENTRY Wincloseclipbrd
(HAB hab) ,. Anchor block handle.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
By calling this function, an application relinquishes its ex-
clusive access to the clipboard, and other applications are
free to open the clipboard.
RelatedFunctions..
Winopenclipbrd (Figure 9.2)
• Figure 9.4..
The Wincloseaipbrd Presentation Manager function
Interfacingwiththeclipboard 473 .
ThefollowingisanexampleofacautotheWincloseclipbrdfunction:
HAB ELincBlk,.
Wincloseclipbrd
(-cBlk) ,.
ACCESSING DATA
IN THE CLIPBOARD
This section describes the techniques for obtaining a block of data
from the clipboard. A program typicauy requests data from the cupboard
inresponsetoapastecommandissuedbytheuser(thatis,acommandto
copy a block of data from the clipboard and insert it into the data main-
tained by the program). When requesting a block of data, your program
mustspecifyaparticularformat;ifthechpboardcontainsablockthatcon-
forms to this format, it will supply the data handle (in the case of textual
data, the handle is the far address of the segment holding the data). The
blockthatthesystemprovidesistheonewiththerequisiteformatthathas
most recently been added to the cupboard (remember that the cupboard
maintainsonlyasingleblockinagivenformat).Thisblockmayhavebeen
placed in the clipboard by your program, or by another Presentation
Manager apphcation. This section describes the methods for accessing
blocks of data that conform to the standard fcxf format.
Note that obtaining a block of data from the clipboard merely allows
your program to read or copy this block; it does 71of remove it from the
clipboard. Therefore, the same block can be repeatedly accessed. (The
block is not removed until another block with the same format is added,
or a program calls WinEmptyclipbrd, described later in Figure 9.6.)
The following five steps can be used to access a block of textual data
contained in the clipboard:
1. Opentheclipboard.
2. Obtainthe address of theblock.
• 474 Programmer's Guide to the os/2PresentationManager
RE rmcBlk,.
Winopenclipbrd
(HAncBlk) ,. /* Anchor block handle. */
PCH PtrData,.
HAB ELincBlk,.
Interfacingwiththeclipboard 475 .
WinQueryclipbrdData
Purpose..
Returns a handle to the block of data in the clipboard that
has the requested format.
Prototype..
ULONG APIENTRY WinQueryclipbrdData
(HAB hab, Anchor block handle.
USHORT fmt) ,. Desired data format (see Figure 9.3 for a list
of the predefined formats).
Return Value ..
Handle to the data block having the requested format, or
NULL if the clipboard does not contain a block with this for-
mat or if an error occurred. If the block is in text format, the
handle is the far address of the memory segment containing
the data.
Relate d Functions ..
WinsetclipbrdData (Figure 9.3)
• Figure9.5..
The WinQuerycILpbrdDataL Presentation Manager function
• 476 Programmer's Guide to the os/2PresentationManager
WinEmptyclipbrd
Purpose,
Removes all data blocks from the clipboard, freeing the as-
sociated data handles.
Prototype..
BOOL APIENTRY WinEmptyclipbrd
(IIAB hab) ,. Anchor block handle.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
• Figure 9.6..
The WLnE"ptyc1±pbrd Presentation Manager function
Secure Access
to the Shared Memory Segment
If the handle returned by WinQueryclipbrdData is not NULL,
the next step is to call DosGetseg (Figure 9.7) to secure access for the
current process to the segment containing the clipboard data. Although
WinQueryclipbrdData returns a far pointer to this segment, this ad-
dress may have been supplied by ¢7ioffecr p7'occss (which would be the
case if the data in the clipboard were inserted by ¢7ioffecr application).
Even though the other process may have allocated the memory block as
a sharable segment (by passing DosAllocseg the SEG_GETABLE flag),
the selector portion of this address is not automatically valid within the
current process. Before using this selection, your program must call
DosGetseg to make the selector valid within the current process.
The following is an example of a call to DosGetseg:
PCH PtrData,.
Interfacingwiththeclipboard 477 .
DosGetseg
(SELECTOROF (PtrData) ) ,.
This example assumes that PtrData contains the far pointer to the clip-
board data returned by WinQueryclipbrdData; note that only the
selector portion is passed to DosGetseg. After calling this function, the
program may safely use PtrData to access the clipboard data.
DosGetseg
Purpose..
•Secures access to a shared memory segment for the current
process.
Prototype..
USHORT APIENTRY DosGetseg
(SEL sel) ,. The selector of the shared memory segment.
Return Value ..
Zero if the function was successful, or a nonzero error code if
the function failed.
Notes..
A selector to a shared memory segment obtained from Dos-
Allocseg can be passed to a second process. The second
process, however, must call DosGetseg before it can use this
selector. The call to DosAllocseg must have included the
SEG_GETABLE allocation flag in the third parameter.
Related Functions ..
DosAllocseg (Figure 9.1)
• Figure9.7..
The DosGetseg os/2 kernel function
®478 Programmer's Guide to the OS/2 Presentation Manager
IMPLEMENTING
• A CLIPBOARD INTERFACE
The first sections in this chapter have described the basic Presenta-
tion Manager facilities that allow a program to insert a data selection
into the clipboard or to obtain the data selection that is currently con-
tained in the clipboard. This section describes a typical program inter-
face that permits the user to access these underlying facilities, and offers
suggestions for using the clipboard within the text editor example pro-
gram that was presented in the first part of the book. The user interface
described in this section follows the recommended style guidelines (as
described in the Microsoft Windows AppJ£.c¢f}.o7i SfyJc G%2.de, cited in the
Bibliography). Note that this section focuses on the techniques for
selecting and exchanging fcxf #¢J data (as opposed to graphical data; the
last section in this chapter briefly discusses nontext formats).
In a Presentation Manager application such as a text editor, there is a
one-to-one correspondence between the block of data contained in the
clipboard and the current program seJec£2.o71. The selection is a section of
data chosen by the user and typically highlighted within the window
display; at a given time, there may or may not be a selected block of
data. When the user requests a ct/i clipboard operation, the selected
data are copied to the clipboard and removed from the program. A copy
operation copies the selected data into the clipboard but leaves the data
within the program. A p¢sfc command copies the contents of the clip-
board into the program data; if a block of program data is currently
selected, the block of data copied from the clipboard typically replaces
the program selection. Finally, a cJc¢r operation deletes the selection
from the program but does not add the data to the clipboard. Concep-
tually, the clipboard stores a single program selection (although it can
actually maintain several blocks of data that have distinct formats).
Accordingly, the first step in implementing a clipboard interface is to
provide a mechanism for selecting a block of data and for highlighting
the selection within the window display. In a program such as a text
editor, the user should be able to make a data selection using either the
keyboard or the mouse. The recommended keystroke for extending a
selection is the Shift key in combination with one of the four arrow
keys; with the Shift key held down, an arrow key extends the selection
in the corresponding direction. You can process these keystrokes in the
®480 Programmer's Guide to the OS/2 Presentation Manager
GpisetBackMix
Purpose..
Specifies the way the background color generated by
graphics functions (such as GpicharstringAt) is combined
with the existing color within the presentation space.
Prototype..
BOOL APIENTRY GpisetBackMix
(Hps hps , Handle to the presentation space.
LONG IMixMode) ,. The mode, which can be one of the following
values:
Value Effect
BM DEFAULT The default value
(same as
BM LEAVEALONE)
BMOR The pixel colors are
combined using the OR
operator
BM OVERPAINT The object background
color replaces the
existing color
BM XOR The pixel colors are
combined using the
exclusive-OR operator
BM LEAVE- The existing color in
AL6NE the background areas is
left unaltered (the
default)
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Related Functions ..
GpicharstringAt (Figure 3.28)
GpisetBackcolor (Figure 9.9)
• Figure 9.8..
The Gp±SetBaLck:MLx Presentation Manager f unction
• 482 Programmer's Guide to the os/2 PresentationManager
GpisetBackcolor
Purpose..
Sets the background color generated by graphics functions
such as GpicharstringAt.
Prototype..
BOOL APIENTRY GpisetBackcolor
(Hps hps , Handle to the presentation space.
LONG IColor) ,. The color value; the following basic
colors can be specified:
CLR WHITE
CLR-BLACK
CLR-BLUE
CLR-RED
CLR_PINK
CLR-GREEN
CLR-CYAN
CLR-YELLOW
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
If the mode set by GpisetBackMix is BM_LEAVEALONE
(the default), the background color set by this function will
not be drawn.
Relate d Functions ..
GpicharstringAt (Figure 3.28)
GpisetBackMix (Figure 9.8)
• Figure 9.9..
The Gp±SetBaLckcchor Presentation Manager function
Interfacingwiththeclipboard 483 .
In the table, the 777c7it/ co777777¢7id is the suggested label that appears in
the Edit pull-down submenu. The 777c71t/ 77771c777o713.c is the recommended
underlined letter within this label that can be used to quickly select the
associated command once the Edit submenu is displayed. The table also
gives the recommended accelerator keystrokes for each command; the
menu should display each of these keystrokes next to the associated
menu item.
The menu added to the example program in Chapter 7 includes an
Edit submenu with items for the Cut, Copy, and Paste commands. This
submenu is illustrated in Figure 9.10. Remember that the client window
receives a WM_COMMAND message, accompanied by the identifier of
the menu item, whenever the user selects one of these menu items or
presses the associated accelerator key. The final version of the example
program processes each of these messages by simply displaying a mes-
sage informing the user that the command has not been implemented.
You can fully implement each of these three commands using the tech-
niques presented in this chapter and in the first part of the book.
To execute the Copy command, you could add a function to the buff-
er-management module to copy the selected data directly from the
Presentation Manager heap into the sharable segment allocated for
the clipboard. The routine for the Cut command could begin by calling
• Figure 9.10:
The Edit submenu of the example program
Interfacingwiththeclipboard 485 .
OTHER FEATURES
• OFTHECLIPB0ARD
This section briefly introduces the following three additional fea-
tures of the Presentation Manager clipboard facility:
Note that some of the functions referenced in this section do not have
accompanying explanatory figures; you can obtain more information
on these functions and on the techniques discussed here from the
Presentation Manager technical references (see the Bibliography).
• 486 Programmer's Guide to the os/2 PresentationManager
C:reating Icons,
Bitrnaps, and
Otfier Resources
491.
.r
hapter 7, which discussed menus and accelerator keys,
introduced the topic of Presentation Manager resources.
Chapter 8 then described dialog boxes, which are
another important resource. This chapter continues the
treatment of resources with a discussion of icons, pointers, bitmaps,
strings, and programmer-defined resource types.
• ICONSAND POINTERS
An icon is a fixed-size graphic image that you can design and dis-
play from your Presentation Manager application. The most common
use for an icon is to represent the program window when it has been
minimized. If you install a custom icon, the system will automatically
display this icon whenever the application window is minimized. (If
you do not install an icon, the system displays a small image of the cur-
rent program window, which may not clearly identify the application to
the user.) As you will see in this section, the application can also display
an icon within the client window or within a dialog box.
This section first describes how to design an icon using the Icon
Editor. It then explains how to install an icon so that it is displayed
when the application window is minimized, and how to explicitly dis-
play the icon within the client window or within a dialog box. Finally, it
introduces the closely related topic of mouse pointers, which are
described fully in Chapter 13.
The topics in this section are illustrated by the Presentation Manager
application presented in Figures 10.1 through 10.6. This program in-
stalls an icon that the system automatically displays when the window
is minimized. It also explicitly displays this same icon within the client
window, and provides an ``About" dialog box that displays the icon in
addition to a line of text and an OK push button. Figure 10.1 provides a
MAKE file for preparing this program; Figure 10.2 lists the linker defini-
tion file; Figure 10.3 contains the dialog box resource script generated
by the Dialog Box Editor; Figure 10.4 gives the general resource script;
Figure 10.5 provides the header file, which is included in the listings of
Figures 10.4 and 10.6; and Figure 10.6 lists the C source code.
• 492 Programmer'sGuidetothe os/2Presentation
Manager
Figure 10.1
This MAKE file prepares the program of Figures 10.1 through 10.6
FIG10 6.OBJ : FIG10 6.C FIG10 5.H
El /W2 /c /Zp 7G2ws FIG16 6.C
• Figure 10.1..
A MAKE file for preparing the program of Figure 10 .6
Figure 10.2
; Linker definition file for the program listed in Figure 10.6®
NAME FIG10 6
PROTMODE
HEAPSIZE 1024
STACKSIZE 8192
EXPORTS Wndproc
Aboutproc
• Figure 10.2..
Linker definition file for the program of Figure 10 .6
/*
Figure 10.3
Dialog resource script for the program of Figure 10.6
*/
DLGTEMPIIATE 256 LOADONCALL MOVEABLE DISCARDABLE
BEGIN
DIALOG MM, 256, 119, 31, 82, 84, Fs_NOByTEALIGN I Fs_DroBORDER
WS_VISIBLE I WS_CLIPSIBIINGS I WS_SAviBIfs
• Figure 10.3..
Dialog box resource script for the program of Figure 10 .6
Creating Icons, Bitmaps, and Other Resources 493.
/*
Figure 10.4
General resource script for the program of Figure 10.6
*/
#include <OS2.H>
#include "FIG10 5.H"
a Figure 10.4..
General resource script for the program of Figure 10 .6
/*
Figure 10.5
Header file included in Figure 10.6 and Figure 10.4
*/
#def ine ID FRAME RESOURCE 1
#define ID ABOUT 10
• Figure 10.5..
Header file included in the listings of Figures 10 .4 and 10 .6
•494 Programmer's Guide to the OS/2 Presentation Manager
/*
Figure 10.6
MRESULT EXPENTRY Wndproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2) ;
void main ()
(
HAB HAncBlk; /* Anchor block handle.
HMQ HMesQue; /* Message queue handle.
HWND HFrame, Hclient; /* Frame/client window handles.
QMSG QueMess; /* Message queue structure.
ULONG CtlData = /* Control windows to include:
FCF MENU /* Menu.
FCF-MINMAX /* Minimize/maximize box.
FCF-SHELLPOSITION /* Make window visible on screen.
FCF-SIZEBORDER /* Wide sizing border.
FCF-SYSMENU /* System menu.
FCF-TASKLIST /* Display program name in Task Manager.
FCF-TITLEBAR; /* Title bar.
HAncBlk = Winlnitialize /* Initialize the PM. */
(0); /* Initialization options: must be 0. */
HMesQue = WincreateMsgQueue /* Create a message queue. */
(HAncBlk, /* Anchor block handle. */
0); /* Minimum queue size: 0 means default size.*/
WinRegisterclass /* Register window class for client window.
(HAncBlk, /* Anchor block handle.
''mlN„ ,
/* Window class name.
Wndproc , /* Window procedure associated with class.
CS SIZEREDRAW, /* Invalidate entire window on size change.
o)T /* Bytes of data storage for each window.
/*** Create standard window and load icon. ***********************************/
HFrame = Wincreatestdwindow /* Create a standard window collection.
(HWND DESKTOP, /* Parent window handle.
WS_VISIBLE I /* Frame window style: visible.
FS ICON, /* Load an icon.
&ctlData' /* Address of control data.
''RAIN„ ,
": Icon Demo", /* Client window class name.
/* Text for title bar.
OL, /* Client window style: none specified.
0, /* Resource module handle: EXE file.
ID FRAME RESOURCE, /* Resource identification.
&HElientT; /* Address to receive client window hand.
• Figure 10.6..
An application illustrating the use of icons
Creatinglcons,Bitmaps,andotherResources 495 .
} /* end Wndproc */
• Figure 10.6..
An application illustrating the use of icons (continued)
• 496 Programmer'sGuidetothe os/2Presentation
Manager
MRESULT EXPENTRY Aboutproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
switch (msg)
(
case WM COMMAND:
} /* end Aboutproc */
MRESULT EXPENTRY Command (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
USHORT Result;
} /* end Command */
MRESULT EXPENTRY Create (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/*** Load the icon. ************************************************"********/
Hlcon = WinLoadpointer
(HWND DESKTOP, /* Handle of desktop window.
• Figure 10.6..
An application illustrating the use of icons (continued)
Creatinglcons,Bitmaps,andotherResources 497 .
} /* end Create */
mESULT EXPENTRY Destroy (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/*** Remove the icon resource from memory. ***********************************/
WiriDestroypointer
(Hlcon) , /* Icon handle.
ret.urn FALSE ;
} /* end Destroy */
MRESULT EXPENTRY Paint (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
*/
::i;TF.pE:::Pace ; ,: ::::::t:::::n::::e±:a:€::;w coordinates. */
static char Message [] = /* Text to display. */
"This window displays an icon.";
WinDrawpointer
5Tpresspace , /: ::::::::::o:o:::::a::?dle. :/
0, /* Vertical coordinate. */
Hlcon, /* Icon handle. */
• Figure 10.6..
An application illustrating the use of icons (continued)
• 498 Programmer'sGuidetothe os/2Presentation
Manager
) /* end Paint */
• Figure 10.6..
An application illustrating the use of icons (continued)
Designing an Icon
The first step is to design the icon using the Icon Editor,
ICONEDIT.EXE. The Icon Editor is a Presentation Manager application
that provides a rectangular drawing area having the proportions of a
standard icon. You can use the mouse to draw the desired icon within
this area, pixel-by-pixel. You can assign each of these pixels one of the
following four colors:
The left mouse button toggles between the black and white colors, and
the right mouse button toggles between the screen and inverse-screen
colors. Pixels that are assigned the screen color show the underly-
ing color of the screen and are thus invisible. Pixels assigned the in-
verse-screen color always contrast with the underlying color; for
example, if the current underlying color is yellow, the icon pixel will be-
come the inverse color, blue.
Figure 10.7 illustrates the Icon Editor containing the icon that is dis-
played by the application of Figure 10.6. The rectangular area on the
right is the editing window used to draw the icon, which is displayed
much larger than its actual size. The rectangular area on the left is the
Creating Icons, Bitmaps, and Other Resources 499.
viewing window, which displays a true scale replica of the icon. The
icondepictedinFigure10.7hasawhitebackgroundwithablackborder
and black letters; it is thus visible over any background screen color.
Note that assigning certain color combinations may render the icon in-
visible when it is displayed on top of some backgrounds; for example,
an icon that is given a screen-colored background and a black
foreground will disappear when displayed within a black screen area.
Before you create a new icon with the Icon Editor (through the New
item of the File submenu), you must specify the number of pixels that
the icon is to contain. You can choose one of the following values:
• Figure 10.7..
The Icon Editor with an example icon
• 500 Programmer's Guide to the os/2Presentation
Manager
screen always has approximately the same size, the actual number of
pixels used to draw the icon depends upon the current screen resolu-
tion. For example, if you create an icon with 32 % 16 pixels (the number
of pixels used to draw the icon with a CGA adapter), and then display
the icon with an EGA system, the Presentation Manager must duplicate
every other row of pixels. Likewise, if you designate an icon with 64 %
64 pixels and then display this icon on a EGA system, the Presentation
Manager must eliminate every other row and column. Because adding
or removing pixels degrades the original image designed in the Icon
Editor, it is best to designate the same number of pixels that will ul-
timately be used to display the icon. However, if the program must run
on a variety of target machines, the best choice might be the medium
resolution, 32 % 32 pixels.
When you have completed designing the icon, you should save the
data in a file through the File submenu. If you do not specify a file ex-
tension, it is automatically given the .ICO extension. For further infor-
mation, see the documentation and online help information provided
with the Icon Editor.
Installing an Icon
This section describes how to associate an icon with the standard
window so that the system automatically displays this icon when the
application window is minimized.
First, because the data for an icon is stored as a Presentation Manager
resource, you must write a script to direct the resource compiler to in-
clude these data in a resource segment in the executable file. An icon is
defined within the resource script with the keyword POINTER, fol-
lowed by an identifier and the name of the file generated by the Icon
Editor. The example resource script in Figure 10.4 assumes that the icon
created with the Icon Editor was saved in the file FIG10 6.ICO, and it
defines the icon using the following line:
POINTER ID FRARE RESOURCE FIG10 6.ICO
Note that if you are going to associate an icon with the standard win-
dow, and if the application also uses a menu or accelerator table, you
must assign the icon the scz777c identifier used for the menu and
Creating Icons, Bitmaps, and OtherResources 501 .
HFrame = Wincreatestdwinow
(Hum DESKTOp. /* Parent window handle.
WS VI;IBLE I /* Frame window style: visible.
FS ICON /* Load an icon.
&CtlData, /* Address of control data.
\\RAIN,, , /* Client window class name.
"Icon Demo'', /* Text for title bar.
OL, /* Client window style:
/* none specified.
0, /* Resource module handle:
/* .EXE file.
ID FRARE RESOURCE /* Resource identifier.
&Hclient) ,. /* Address to receive
/* client window hand.
Once a custom icon has been associated with the standard window
through the call to Wincreatestdwindow, the system automatically
displays this icon whenever the user minimizes the window; no further
program action is required to manage the icon.
Displaying an Icon
within the Client Window
If you have designed an icon and included the icon data in a pro-
gram resource segment as described in the previous section, you can
also display the icon at any position within the client window. To ex-
plicitly display the icon in the client window, you should perform the
following three steps from the client window procedure:
Note that rather than creating a custom icon, and obtaining a handle
to this icon by calling WinLoadpointer, you can obtain the handle to a
pointer provided by the system by calling the WinQuerysyspointer
function (Figure 11.7). System icons can be displayed within the client
window by calling WinDrawpointer. Chapter 11 explains the Win-
Querysyspointer function and illustrates the system icons.
Creating Icons, Bitmaps, and OtherResources 503 .
WinLoadpointer
Purpose..
Loads an icon or mouse pointer into memory from a
resource segment contained in a disk file.
Prototype..
HPOINTER APIENTRY WinLoadpointer
(HWND hwndDesktop, Eh;gtBiesrKoi6hp: desktop window/
RetumValue..
The handle of the newly loaded icon or pointer, or the value
NULL if an error occurred.
Notes..
When the resource loaded by this function is no longer re-
quired, it should be released by calling WinDestroypointer.
Related Functions ..
WinDestroypointer (Figure 10.10)
• Figure 10.8..
The W±r\LoaLdpointer Presentation Manager function
• 504 Programmer'sGuidetothe os/2Presentation
Manager
WinDrawpointer
Purpose..
Draws an icon.
Prototype..
BOOL APIENTRY WinDrawpointer
(Hps hps , Handle of the presentation space in which
the icon is to be drawn.
SHORT x, x-coordinate of position where lower left
corner of icon should be placed.
SHORT y, y-coordinate of position where lower left
corner of icon should be placed.
HPolNTER hptr, Handle oftheiconretumed by
WinLoadpointer.
USHORT fs) ,. Flags specifying how the icon is to be drawn;
you can choose from the following values:
Value Effect
DP NORMAL Draw the icon
without modification
DP HALFTONED Drawtheblackareas
of the icon with a
halftoned pattern
DP INVERTED Invert the icon colors;
that is, substitute
black for white and
white for black
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Related Functions ..
WinLoadpointer (Figure 10.8)
• Figure 10.9..
The W±nDra:wPo±uler Presentation Manager function
Creating Icons, Bitmaps, and Other Resources 505.
WinDestroypointer
Purpose..
Destroys an icon or pointer.
Prototype..
BOOL APIENTRY WinDestroypointer
(HpolNTER hptr) ,. Pointer handle returned by
WinLoadpointer.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Related Functions ..
WinLoadpointer (Figure 10.8)
• Figure 10.10..
Tire WLnDestraypointer Presentation Manager function
HPOINTER Hlcon,.
Hlcon = WinLoadpointer
(HWND DESKTOP, /* Handle of desktop window. */
• 506 Programmer'sGuide tothe os/2Presentation
Manager
WinDestroypointer
(Hlcon) ,. /* Icon handle. */
WM DESTROY
Purpose..
This message is sent by the system to a window when it is
about to be destroyed.
Parameters..
I@ARAM mpl NULL.
MPARAM mp2 NULL.
Return Value ..
NULL.
Notes..
This message is sent to the window procedure after the win-
dow has been hidden on the screen, and it allows the ap-
plication to perform any final tasks required before the
window is destroyed.
• Figure 10.11..
The WM_DESTROY Presentation Manager message
Creatinglcons,Bitmaps, and otherResources 507 .
TheprogramofFigure10.6processestheWM_PAINTmessageinthe
function Paint. This function performs the following series of steps:
WinDrawpointer
(Hpresspace, /* Presentation space handle.
0, /* Horizontal coordinate.
0, /* Vertical coordinate.
Hlcon, /* Icon handle.
DP NORMAI.) ,. /* Flag: normal pointer appearance.
Note that the second and third parameters supply the location within
the client window where the system places the lower left corner of the
icon; this call therefore causes the icon to appear in the lower left comer
of the window, touching the left and bottom window edges. You do not
need to specify the dimensions of the icon, since it is drawn with a fixed
size (the icon is always given the same size, whether it is used to repre-
sent a minimized window, or is drawn within the client window or
within a dialog box). Alternatively, bitmaps, which are discussed later
in the chapter, can be drawn to fill any given rectangular dimensions.
You may have noticed that the call to WinRegisterclass in the ex-
ample program of Figure 10.6 specifies the CS_SIZEREDRAW style
(explained in Table 2.1). This style forces the system to invalidate the en-
tire client window (and thus send a WM_PAINT message) whenever
the user changes the window size. Previous examples in the book did
• 508 Programmer's Guide to the os/2 PresentationManager
not require this style, because all data displayed by these programs
were aligned with respect to the upper left corner of the client window,
and the system ¢#fo77z¢£!.c¢JJy realigns data with respect to this corner
whenever the window size is changed. (If the CS_SIZEREDRAW style
is 7tof specified, the system does not invalidate the window or send a
WM_PAINT message when the window size is reduced; when the win-
dow is enlarged, the system sends a WM_PAINT message but in-
validates only the newly exposed area.) The current example program,
however, justifies the text string in the cc7ifcr of the window, and aligns
the icon with the Jozucr left corner of the window. Thus, the
CS_SIZEREDRAW style is mandated (you might try recompiling the
program without this style to observe the difference).
A 7iofc ¢Z7o#f cr¢s3.7ig #7c cJz.c7if zu3.7zdoztr Unlike the WM_PAIP\IT routines
presented previously in the book, the current version of Paint does not can
WinFillRect to explicitly erase the client window. Rather, when this func-
tion cans WinDrawText (Figure 2.24), it includes the value DT_ERASE-
RECT within the flag parameter (the last parameter), as fouows:
WinDrawText
(Hpresspace, /* Presentation space handle.
Oxffff, /* Length of string:
/* Oxffff means 0-terminated.
Message, /* Text to be displayed.
&Rect, /* Coordinates of rectangle
/* to contain text.
CLR BI.ACK, /* Foreground color.
CLR WHITE, /* Background color.
/* Drawing specifications :
DT CENTER I /* Center text horizontally.
DT VCENTER I /* Center text vertically.
DT-ERASERECT) /* Erase the rectangle
/* (entire window) .
the entire window before displaying the string. (The program therefore
calls WinDrawText before calling WinDrawpointer!)
Note that when erasing the client window by calling WinFillRect, or
WinDrawText with the DT_ERASEFLAG, you can specify an explicit
color value to be used to fill the window, which thereby becomes the
window background color. You can alternatively specify the value
CLR BACKGROUND, which refers to the current default background
color~that has been set by the user through the Control Panel utility
described in Chapter 1. If you specify the default background color by
passing CLR_BACKGROUND when erasing the client window, you
should also specify the default foreground color, CLR_NEUTRAL,
when displaying characters through WinDrawText or Gpicharstring-
At (otherwise, you could end up with an undiscernible color combina-
tion such as white characters on a white background). The possible
color values are listed in Figure 2.23.
An alternative method for erasing the client window with the default
backgroundcoloristocallthePresentationManagerfunctionGpiErase
(Figure 10.12), which erases the entire window associated with the
GpiErase
Purpose..
Erases the specified presentation space by filling the area
with the default system background color (CLR_BACK-
GROUND).
Prototype..
BOOL APIENTRY GpiErase
(Hps hps) ,. Handle of the presentation space.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
• Figure 10.12..
The GPIEraLse Presentation Manager function
• 510 Programmer'sGuidetothe os/2Presentation
Manager
p±rs^int`he`Pply.TERde.finition|ntheresourcefile.Your\eedtoassigr\tLe
ID Symbol field a unique value only if you are going to reference
the icon within the C program.
The example application of Figure 10.6 displays an About dialog box
when the user selects the About menu item (which is the only item in
the program menu). This dialog box is illustrated in Figure 10.13; note
that it displays the program icon in addition to a text string and a push
button. Figure 10.14 illustrates the manner in which the icon styles were
defined in the Dialog Box Editor; the Static Styles box appears when the
icon control is first positioned and whenever you choose the Styles item
of the Edit submenu when the icon is selected. Note that the Text field is
assigned the value 1 (ID_FRAME_RESOURCE), which is the identifier
given to the icon in the POINTER statement within the resource file
(Figure 10.4). The ID Symbol field is assigned -1, since the icon does not
need to be referenced within the C source code.
The program menu is created and managed as described in Chapter
7, and the About dialog box is displayed and dismissed in the same
Creating Icons, Bitmaps, and OtherResources 511 .
• Figure 10.13..
The About dialog box
• Figure 10.14..
Defining the icon in the Dialog Box Editor
• 512 Programmer's Guideto the os/2Presentation
Manager
® BITMAPS
As stated in Chapter 9, a bitmap is a data structure that stores a
graphic image; it consists of a sequence of off and on bits that indicate
the values of the actual screen pixels used to create the image. Bitmaps
Creatinglcons,Bitmaps,andotherResources 513 .
# Figure 10.15
#
# This MAKE file prepares the program of Figures 10.15 through 10.19
#
FIGlo l9.OBT : FIG1019.C FIG1018.H
El /W2 /c /Zp /E2ws FIG101i.C
• Figure 10.15..
A MAKE file for preparing the program of Figure 10 .19
Figure 10 .16
; Linker, definition file for the program listed in Figure 10.19
NAME FIG10 19
PROTMODE
HEAPSIZE 1024
STACKSIZE 8192
EXPORTS Wndproc
• Figure 10.16..
Linker definition file for the program of Figure 10 .19
/*
Figure 10.17
STRINGTABLE
BEGIN
ID PROGNAME, '': Bitmap Demo"
EN5
• Figure 10.17..
General resource script for the program of Figure 10 .19
Creatinglcons,Bitmaps, and otherResources 515 .
/*
Figure 10.18
• Figure l0®18..
Header file in.cluded in the listings of Figures 10 .17 and 10 .19
/*
Figure
*/
MRESULT EXPENTRY Wndproc (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2) ;
void main ()
(
HAB RAncBlk; /* Anchor block handle.
HMQ HMesQue; /* Message queue handle.
HWND HFrame, Hclient; /* Frame/client window handles.
QMSG QueMess; /* Message queue structure.
char ProgName [32] ; /* Holds program name string.
ULONG CtlData = /* Control windows to include:
FCF MINMAX /* Minimize/maximize box.
FCF-SHELLPOSITI0N /* Make window visible on screen.
FCF-SIZEBORDER /* Wide sizing border.
FCF-SYSMENU /* System menu.
FCF-TASKLIST /* Display program name in Task Manager.
FCF-TITLEBAR; /* Title bar.
HAncBlk = Winlnitialize /* Initialize the PM. */
(0); /* Initialization options: must be 0. */
HMesQue = WincreateMsgQueue /* Create a message queue. */
(HAncBlk, /* Anchor block handle. */
0); /* Minimum queue size: 0 means default size.*/
WinRegisterclass /* Register window class for client window.
(HAncBlk, /* Anchor block handle.
''MAIN„ ,
/* Window class name.
Wndproc , /* Window procedure associated with class.
CS SIZEREDRAW, /* Invalidate entire window on size change.
o)T /* Bytes of data storage for each window.
• Figure 10.19:
An application that loads and displays a bitmap
• 516 Programmer's Guide to the os/2PresentationManager
WinLoadstring
(HAncBlk, /* Anchor block handle.
NULL, /* Module handle: in EXE file.
ID PROGNAME, /* String identifier.
sizeof (ProgName) /* Size of rec.eiving buffer.
ProgName) ; /* Receiving buffer.
HFrame = Wincreatestdwindow /* Create a standard window collection.
(HWND DESKTOP, /* Parent window handle.
WS VISIBLE, /* Frame window style: visible.
&cEIData, /* Address of control data.
''RAIN„ ,
/* Client window class name.
ProgName , /* Text for title bar.
OL, /* Client window style: none specified.
0, /* Resource module handle: n/a.
0, /* Resource identification: none.
&Hclient) ; /* Address to receive client window hand.
while (WinGetMsg /* Get messages until WM_QUIT.
(HAncBlk, /* Anchor block handle.
&QueMess , /* Address of message structure.
0' /* Window filter: any window.
0, /* First message identifier: n/a.
0)) /* Last message identifier: n/a.
WinDispatchMsg (HAncBlk, &QueMess) ; /* Dispatch messages.
MRESULT EXPENTRY Create (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2) ;
MRESULT EXPENTRY Destroy (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2) ;
MRESULT EXPENTRY Paint (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2) ;
• Figure 10.19..
An application that loads and displays a bitmap (continued)
Creatinglcons,Bitmaps,andotherResources 517 .
} /* end Wndproc */
M:RESULT EXPENTRY Create (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
HPS IJpresspace;
HBitmap = GpiLoadBitmap
( Hpresspace , /* Handle to presentation space.
NULL' /* Resource module handle: EXE file.
ID BITmp, /* Identifier of bitmap resource.
OL, /* Width to stretch bitmap: no stretch
OL); /* Height to stretch bitmap: no stretch
/*** Release the presentation space. *****************************************/
WinReleaseps (Hpresspace) ;
ret,ui-n FALSE ;
} /* end Create */
MRESULT EXPENTRY Destroy (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/*** Remove the bitmap resource from memory. *********************************/
GpiDeleteBitmap
(HBitmap) ; /* Bitmap handle.
ret.urn FALSE;
} /* end Destroy */
MRESULT EXPENTRY Paint (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
• Figure 10.19:
An applica.IL.ion that loads and displays a bitmap (continued)
• 518 Programmer's Guide to the os/2PresentationManager
WinDrawBitmap
( Hpresspace , /* Presentation space handle. */
HBitmap , /* Bitmap handle from GpiLoadBitmap. */
NULL, /* Section of bitmap to draw: NULL = ALL.*/
( PPOINTL) &Rect , /* Pointer to rectangle to fill. */
CLR NEUTRAL, /* Foreground color: system default. */
CLR-BACKGROUND, /* Background color: system default. */
DBM-STRETCH) ; /* Flag: fill rectangle with bitmap. */
WinEndpaint (Hpresspace) ; /* Tells Presentation Manager that */
/* redrawing is complete. */
return FALSE;
) /* end Paint */
• Figure 10.19..
An application that loads and displays a bitmap (continued)
This example assumes that the bitmap designed in the Icon Editor was
saved under the name FIG10 19.BMP. Note that the identifier ID BIT-
MAP, which is defined in the header file of Figure 10.18, win be us-ed to
refer to the bitmap within the C source code of Figure 10.19.
Creatinglcons,Bitmaps,and otherResources 519 .
• Figure 10.20..
The example bitmap within the Icon Editor
Once the bitmap data have been placed in a resource segment within
the executable file, you can display the bitmap within the client win-
dow by performing the following function calls:
HPS Hpresspace,.
HBitmap = GpiLoadBitmap
(Hpresspace, /* Handle to presentation space. */
NULL, /* Resource module handle: .EXE file.*/
ID BITMAP, /* Identifier of bitmap resource. */
OL, /* Width to stretch bitmap: */
/* rro fg+rcatc:A. *I
OL) ,. /* Height to stretch bitmap: */
/* rro Es+rcitc:A. */
WinReleaseps (Hpresspace) ,.
GpiLoadBitmap
Purpose..
Loads a bitmap from a resource segment into memory.
Prototype..
HBITMAP APIENTRY GpiLoadBitmap
(Hps hps , Handle to a presentation space.
USHORT hModule , Resource module handle; if the
resource is contained within the
exeoutable file, this parameter must be
assigned NULL; if the resource is in a
dynamic-link module, the parameter
must contain the module handle
returned by DosLoadModule.
USHORT idBitmap, The identifier assigned to the bitmap
within the resource file.
LONG Iwidth, The width in pixels to be given the
bitmap when it is copied into memory;
if 0, the bitmap is given its original
width.
LONG IHeight) ,. The height in pixels to be given the
bitmap when it is copied into memory;
if 0, the bitmap is given its original
height.
Return Value ..
The handle of the bitmap in memory, or the value
GPI ERROR if an error occurred.
• Figure 10.21..
The GPILoaLdB±t"aLp Presentation Manager function
® 522 Programmer's Guide to the os/2PresentationManager
WinDrawBitmap
Purpose,
Draws a bitmap within the specified presentation space.
Prototype..
BO0L APIENTRY WinDrawBitmap
(HPS hpsDst, Handle of the presentation space in
which the image is to be drawn.
HBITrm hbm, Handle of the bitmap to be drawn.
PRECTL pwrcsrc, Pointer to a RECTL structure (defined
in Figure 2.22) containing the
coordinates of the portion of the
bitmap that is to be drawn; if this
parameter is NULL, the entire bitmap
is drawn.
PPOINTL pptlDst, Pointer to a POINTL structure (defined
in Figure 3.28) containing the
coordinates of the point within the
presentation space where the lower
left corner of the bitmap is to be
placed; if, however, the f s flag
parameter contains the switch
DBM_STRETCH, this parameter
should point to a RECTL structure
containing the coordinates of the
rectangle that is to be ¢.JJcd with the
bitmap.
LONG clrFore, Foreground color to be used for
drawing the bitmap.
LONG clrBack, Background color to be used for
drawing the bitmap.
• Figure 10.22..
The W±nDrawB±t"ap Presentation Manager function
Creatinglcons,Bitmaps, and otherResources 523 .
Value Effect
DBM NORMAL Bitmap drawn
normally
DBM n\IVERT Bitmap colors
inverted
DBM HALFTONE Bitmap drawnwith a
halftone pattern
DBM STRETCH Bitmap is stretched to
fill the rectangle
specified by the
pptlDst parameter,
which must point to a
RECTL structure
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
• Figure 10.22..
The WLnDra;wBLhaap Presentation Manager function (continued)
GpiDeleteBitmap
Purpose..
Frees a bitmap.
Prototype..
BOOL APIENTRY GpiDeleteBitmap
(HBITMAp hbm) ,. Handle of bitmap to be freed.
• Figure 10.23..
The GPIDcteteBit"aLp Presentation Manager function
• 524 Programmer's Guide to the os/2Presentation
Manager
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
When a process calls this function, it relinquishes its access to
the specified bitmap; the bitmap is not actually deleted until
all processes holding handles to the bitmap have called this
function.
• Figure 10.23..
The GPIDeleteBitmap Presentation Manager function ( continued)
GpiDeleteBitmap
(HBitmap, '.
WinDrawBitmap
(Hpresspace, /* Presentation space handle. */
HBitmap, /* Bitmap handle from
/* GpiLoaaeitmap.
FILL ' /* Section of bitmap to draw:
/* NULL = ALL.
(PPOINTL ) &Rect , /* Pointer to rectangle to fill.
CLR NEUTFEL, /* Foreground color:
/* system default.
CLR BACKGROUND , /* Background color:
Creating Icons, Bitmaps, and Other Resources 525.
/* system default. */
DBM STRETCH) ,. /* Flag: */
/* fill rectangle with bitmap. */
Thethirdparametertothisfunctionspecifiesthecoordinatesofthepor-
tion of the bitmap that `is to be drawn; the value NULL causes the func-
tion to display the entire bitmap. The last parameter passes the value
DBM STRETCH; this flag forces the function to adjust the size of the
bitmap so that it fills the rectangular window area specified by
the fourth parameter. Since the fourth parameter is given the dimen-
sions of the client window obtained from WinQuerywindowRect, the
bitmap always fills the entire client window. When the system displays
the bitmap, it adds or subtracts pixels as necessary; as the user resizes
the window, the overall size and proportions of the bitmap change ac-
cordingly. Figure 10.24 illustrates the bitmap image displayed within
the client window; compare this figure with Figure 10.20, which il-
1ustrates the bitmap as it was originally designed in the Icon Editor.
Finally, the fifth and sixth parameters cause the bitmap to be drawn
using the default system foreground and background colors described
• Figure 10.24..
The bitmap as displayed by the program of Figure 10 .19
• 526 Programmer'sGuidetothe os/2Presentation
Manager
previously in the chapter (and hsted in Figure 2.23). Note that unlike
previous versions of this function, Paint does not bother to erase the
client window because the bitmap data always fill the entire window.
• OTHERRESOURCES
This final section discusses two additional Presentation Manager
resources: strings and programmer-defined resource types.
Strings
The Presentation Manager allows you to define a table of strings
within the resource script. Like other resources, the string table is inserted
into one or more resource segments within the executable file. The pro-
gramcansubsequentlycopyastringfromthistableintoaprogrambuffer,
anditcandisplayorotherwiseprocessthecontentsofthestring.
You can place the collection of program error messages, the program
name, or other constant string data within a string table rather than
defining the strings within the C source code. Defining all constant
strings within a string table is especially useful for applications that will
be translated into foreign languages. When such a program is trans-
lated, all strings, menu labels, and other language-specific items are
conveniently located within the resource script rather than dispersed
throughout the source code. Also, modifying the resource script does
not require recompiling the program, typically the slowest step in
building an application.
In the example application of Figures 10.15 through 10.19, presented
in the previous section, the program title is placed in a string table
rather than defined in the C source code. When the program runs, it
copies this string from the resource segment and passes it to the Win-
Createstdwindow function as the window title.
Creating Icons, Bitmaps, and OtherResources 527 .
The first step is to define the string table in the resource script. The
stringtableislabeledwiththekeywordSTRINGTABLEasshowninthe
following example, which defines three strings:
#define ID STRINGONE 0
#define ID-STRINGTWO 1
#define ID STRINGTHREE 2
STRINGTJreLE
BEGIN
ID STRINGONE, ``This is the first string"
ID STRINGTWO, ``This is the second string"
ID STRINGTHREE, ``This is the third string"
END
WinLoadstring
Purpose..
Loads a string from a string table resource into a program
buffer.
Prototype..
SHORT APIENTRY WinLoadstring
(RE hab, Anchor block handle.
"ODULE hood, Resource module handle; if the resource is
contained within the exeoutable file, this
parameter must be assigned NULL; if the
resource is in a dynamic-link module, the
parameter must contain the module handle
returned by DosLoadModule.
USHORT id, Identifier assigned to the string in the
resource script.
SHORT cc"ax, Length of the receiving buffer.
PSZ pchBuffer) ,. The receiving buffer.
Return Value ..
The length of the string copied (excluding the terminating
NULL character; the maximum value is ccMax -1).
Notes..
The function copies at most ccMax - 1 characters and ap-
pends a NULL character to the end of the string in the receiv-
ing buffer.
• Figure 10.25..
The WinLoaLdshir\g Presentation Manager function
The example resource file given in Figure 10.17 defines a string table
containing a single string as follows:
STRINGTABLE
BEGIN
ID PROGNARE, "Bitmap Demo"
END
Creating Icons, Bitmaps, and OtherResources 529 .
In this example, the file HELP.TXT could be a file containing the text
that is displayed by a help utility.
To access the data belonging to a programmer-defined resource type
from your program, you must call the OS/2 kernel function DosGet-
Resource, which returns a selector to the segment containing the
resource data. This segment contains exactly the same data stored in the
file specified in the resource script. For example, the following call ob-
tains a selector that can be used to access the resource declared in the
previous example:
DosGetResource
(NULL, /* Module handle:
/* NULL means the .EXE file.
ID MYTYPE, /* Resource type identifier.
ID-HELPTEXT, /* Resource name identifier.
&S=lRes) ,. /* Address to receive resource
/* selector.
DosGetResource
Purpose..
Loads the specified resource segment into memory.
Prototype..
USHORT APIENTRY DosGetResource
("ODULE hood, :oe::aiLceedmw°}f#]ne thhaenedx[:¢ift:£:er:}i:,utrfes }S
Return Value ..
0 if the function is successful, otherwise one of the following
error codes:
• Figure 10.26..
The DosGetResoouce OS/2 kernel function
® 532 Programmer's Guide tothe os/2Presentation
Manager
Dossizeseg
Purpose.:
\
Obtains the size in bytes of a memory segment.
Prototype..
USHORT APIENTRY Dossizeseg
::::N:e:|isLze) , ;Till:ncLtt:°r:t;;:t:he:rs;#F::I:i°ernetc:;Ve:LtfTeed
by the parameter sel.
Return Value ..
Zero if the function was successful, or a nonzero error code if
the function failed.
• Figure 10.27..
The DosS±zeseg OS|2 kernel function
ipter eleven
Adding a
Mouse Interface
535.
FINDING THE
• MOUSE POINTERLOCATION
Before your program calls a Presentation Manager function to
deternine the mouse location or perform other explicit operations on
the mouse, it can call the WinQuerysysvalue function to determine
whether a mouse is installed. This function, described in Figure 11.1,
can be called to determine any one of a large number of system values.
•536 Programmer's Guide to the OS/2 Presentation Manager
WinQuerysysvalue
Purpose..
Returns the specified system value.
Prototype..
LONG APIENTRY WinQuerysysvalue
(HWND hwndDesktop, The value HWND DESKTOp to
identify the deskto-p window.
SHORT isysvalue) ,. The identifier of the desired system
value; the constants for these
identifiers have the SV_ prefix and are
listed in Table 11.1.
Return Value..
The requested system value, or 0 if an error occurred.
Notes..
Some of the system values can be set through the function
Winsetsystemvalue.
RelatedFunctions..
Winsetsystemvalue
• Figure 11.1..
TheW±r\QuerysyswahaePresentationManagerfunction
Adding a Mouse Interface 537.
listed in Figure 11.14 and described in the next section tests whether a
mouse is present, as follows:
if ( !WinQuerysysvalue
(HEED DESKTOP,
SV MOUSEPRESENT) )
E-rrorQuit ("Program requires mouse'') ,.
Hue Hclient,.
POINTL Mouseposition,.
WinQuerypointerpos
(HIND DESKTOP, /* Desktop window handle.
&Mous=Position) ,. /* Address of POINTL structure.
WinMapwindowpoints
(HEED DESKTOP, /* Existing coordinate space.
Hclient' /* Desired coordinate space.
• 538 Programmer's Guide to the os/2 Presentation
Manager
ThisexampleassumesthatthevariableHclientcontainstheclientwin-
dow handle (returned by Wincreatestdwindow). After the call to Win-
Mapwindowpoints, the structure Mouseposition contains the current
position of the mouse in pixel units, relative to the lower left corner of
the client window. Conveniently, this position is specified in the same
units and is relative to the same coordinate system that has been used
when calling such functions as GpicharstringAt, WinlnvalidateRect,
and WinDrawBitmap in previous examples in the book.
Note that the coordinates used to specify the mouse pointer position
are actually the coordinates of a single pixel within the pointer known
as the feof spot . The hot spot within the standard arrow pointer, for ex-
ample, is the pixel at the tip of the arrow. As mentioned in Chapter 10,
you must designate the hot spot when designing a custom pointer
using the Icon Editor.
The function WinQueryMsgpos also returns the position of the
mouse pointer in screen coordinates. This function, however, does 7iof
• 542 Programmer's Guide to the os/2Presentation
Manager
WinQuerypointerpos
Purpose..
Obtains the current position of the mouse pointer in screen
coordinates.
Prototype..
BOOL APIENTRY WinQuerypointerpos
(HWND hwncoesktop, The value HWND DESKTOp to
identify the deskto-p window.
ppolNTL pptl) ,. Pointer to a POINTL structure (defined
in Figure 3.28) that is assigned the
current coordinates of the mouse
pointer hot spot in screen coordinates.
Return Value ..
TRUE if the function is successful, or FALSE if an error
occurred.
Notes..
Thisfunctiongivesthehorizontalandverticalpositionofthe
mouse relative to the lower left corner of the screc71; to con-
vert these values to coordinates relative to the lower left
corner of a given zuz.7idoz47, you can call WinMapwindow-
Points. You can call Winsetpointerpos to scf the current
position of the pointer.
RelatedFunctions..
WinMapwindowpoints (Figure 11.4)
WinQueryMsgpos (Figure 11.3)
Winsetpointerpos (Figure 11.11)
• Figure 11.2..
The WinQuerypoLulerpos Presentation Manager f unction
Adding a Mouse Interface 543.
WinQueryMsgpos
Puxpose..
Obtains the position of the mouse pointer at the time the last
message extracted from the message queue was posted. The
position is given in screen coordinates.
Prototype..
BOOL APIENTRY WinQueryMsgpos
(HAB hab, Anchor block handle.
ppolNT[. pptL ) '. E[Pin::r3t.28a) :h°a[t¥sT:s::r£Ce¥:a:dceo%::iFtes
of the mouse pointer hot spot.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
To obtain the ct/77e71f pointer position, call the function Win-
Querypointerpos. WinQueryMsgpos gives the horizontal
and vertical position of the mouse relative to the lower left
corner of the scrce7t; to convert these values to coordinates
relative to the lower left comer of a given zt7i.71doztJ, you can
call WinMapwindowpoints.
Rel,ated Functions ..
WinMapwindowpoints (Figure 11.4)
WinQuerypointerpos (Figure 11.2)
• Figure ll.3..
The WinQuery:Msgpos Presentation Manager function
• 544 Programmer's Guidetothe os/2Presentation
Manager
WinMapwindowpoints
Purpose..
Maps the coordinates of one or more points from the coor-
dinate space relative to one window into the coordinate
space relative to another window.
Prototype..
BOOL APIENTRY WinMapwindowpoints
(HWND hwndFrom, Handle of the windowfro777 whose
coordinate space the coordinates of the
points are to be mapped; the value
HWND_DESKTOP indicates that the points
are given in screen coordinates.
Hum hwndTo, Handle of the window fo whose coordinate
space the coordinates of the points are to be
mapped; the value HWND DESKTOP
indicates that the points are-to be converted
into screen coordinates.
PPOINTL pptl, Pointer to an array of POINTL structures
(defined in Figure 3.28) containing the
coordinates of the points that are to be
mapped.
SHORT cwpt) ,. The number of POINTL structures in the
array pointed to by the pptl parameter.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
Since a RECTL structure (defined in Figure 2.22) is equi-
valent to two contiguous POINTL structures, you can con-
vert the coordinates contained in a RECTL structure by
setting pptl to the address of this structure and assigning
cwpt a value of 2.
• Figure 11.4..
The W±r\Mapwindowpoints Presentation Manager function
AddingaMouselnterface 545 .
return the current position; rather, it returns the position of the pointer at
the time the last message obtained from the message queue was posted.
RememberfromChapter2(inthesectionentitledGetandDispatchMes-
sages) that all messages in the message queue contain the position of
the mouse at the time the message was posted (the mouse position is the
sixth and last field of the QMSG structure). When your program calls
WinDispatchMsg to dispatch a message, the system calls the ap-
propriate window procedure, but does not pass this procedure the
mouse position (it passes only the first four fields of QMSG). By calling
WinQueryMsgpos, however, the window procedure can obtain this
position.
The second basic method for the window procedure to obtain the
mouse position is by processing the WM_MOUSEMOVE message (Fig-
ure 11.5). This message is sent whenever the mouse position changes,
and it is accompanied by the new coordinates of the mouse position.
Note that WM MOUSEMOVE is normally sent only to the window
directly below-the mouse pointer (unless a window procedure has
called Winsetcapture, which forces the system to send all subsequent
mouse messages to the specified window regardless of the location of
the pointer). Note also that the coordinates supplied by this message are
relative to the receiving window, and therefore they do not have to be
remapped from screen coordinates. The example programs given in the
following two sections illustrate the use of the WM_MOUSEMOVE
message.
The choice of basic methods for obtaining the mouse pointer posi-
tion+alling a function or processing a message+depends upon the
requirements of the application. Calling WinQuerypointerpos provides
themostcurrentpositionvalue(thewindowprocedurecannotreceivead-
ditional WM_MOUSEMOVE messages until it finishes processing the cur-
rent message; if the user is moving the mouse while a message is being
processed, the value supplied by the last WM_MOUSEMOVE message
may no longer be valid). Obtaining the mouse position by processing the
WM_MOUSEMOVE message, however, has several advantages. First, this
method is more in conformance with the message-based architecture of a
PresentationManagerapplication,anditfreestheprogramfromhavingto
exphcitly poll the system for the mouse position. Also, the coordinates
provided by this message are already relative to the client window, and
•546 Programmer's Guide to the OS/2 Presentation Manager
therefore do not have to be remapped. Finally, as you win see in the ex-
ample programs in the fonowing sections, this message provides a con-
venient signal indicating that the mouse pointer is ourrently located
within the chent window.
WM MOUSEMOVE
Purpose..
This message is sent by the system to the window beneath
the mouse pointer (or to the mouse capture window, if any)
each time the position of the mouse pointer changes.
Parameters..
REAEN mpl
low-order word: The horizontal pointer coordinate
relative to the lower left corner of the
window.
high-order word: The vertical pointer coordinate relative
to the lower left corner of the window.
REZuRAI mp2
low-order word: The result returned from a
WM_HITTEST message, or 0 if a
mouse capture is in progress.
high-order word: 0.
Return Value ..
The window procedure should return TRUE if it has
processed the message, or FALSE if it has not processed the
message.
• Figure 1.1.5..
The WM_MOUSEMOVE Presentation Manager message
AddingaMouselnterface 547 .
SETTING THE
• MOUSE POINTERSHAPE
The default mouse pointer automatically displayed by the system
is the standard single-headed, slanted arrow. You can force the sys-
tem to display an alternative pointer by calling the Presentation
Manager function Winsetpointer (Figure 11.6). Once you call this func-
tion, passing it the handle of the desired pointer, the system uses this
pointer until the function is subsequently called to specify another
pointer.
When you call Winsetpointer you can specify the handle of a pointer
providedbythesystem,orthehandleofacustompointerthatyouhave
created using the Icon Editor. To obtain the handle of one of the pointers
provided by the system, you can call the Presentation Manager function
WinQuerysyspointer (Figure 11.7), passing the identifier of the desired
Winsetpointer
Purpose..
Sets the mouse pointer that is displayed by the system.
Prototype..
BOOL APIENTRY Winsetpointer
(HWND hwndDesktop , The desktop window handle,
HWND DESKTOP.
HpolNTER hptrNew) ,. The handle of the new pointer; if this
value is NULL, the pointer is removed
from the screen.
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
• Figure 11.6..
The Winsetpoinler Presentation Manager function
•548 Programmer's Guide to the OS/2 Presentation Manager
pointer as the second parameter. Note that the identifiers listed in Fig-
ure 11.7 include eight standard mouse pointers as well as five standard
icons. The system mouse pointers are illustrated in Figure 11.8, and the
system icons are illustrated in Figure 11.9 (both the icons and the
pointers are labeled in these figures using the identifiers that are passed
to WinQuerysyspointer). Since the data structure for a pointer is the
same as that for an icon, you could easily pass one of the system icon
handles to Winsetpointer to install the icon as the current mouse
pointer. However, the icons make rather awkward-looking pointers,
and they are best displayed as stationary objects within the client win-
dow using the WinDrawpointer function (Figure 10.9). The example
program in Figure 11.14, explained later in this section, displays each of
the standard system pointers.
WinQuerysyspointer
Purpose..
Returns the handle to the requested system pointer or icon.
Prototype..
HPOINTER APIENTRY WinQuerysyspointer
(HWND hwncoesktop, The value HWND DESKTOp to
identify the deskto-p window.
SHORT iptr, Identifier of the system pointer
desired; you can choose from the
following list:
Identifier Pointer/Icon
SPTR ARROW Standard arrow
pointer
SPTR TEXT I-beam pointer
SPTR WAIT Hourglass pointer
SFTR MOVE Move pointer
SFTR SIZENWSE Double-headed
arrow, sloping from
upper left to lower
right
• Figure ll.7..
The WinQuerysysp oLriter Presentation Manager function
Adding a Mouse Interface 549.
Return Value ..
The pointer handle.
Notes..
If you assign fLoad a value of TRUE, you will obtain a new
copy of the system pointer; you should select this option if
you need to modify the pointer. If you assign FALSE to
fLoad, you will obtain a handle to the system's copy of the
pointer;notethatanattempttodisplaythispointer(through
Winsetpointer, for example) will fail if another process is
currently accessing the same pointer.
Related Functions ..
Winsetpointer (Figure 11.6)
• Figure 11.7:
Tire WinQuerysyspoir\+er Presentation Manager function ( continued)
®550 Programmer's Guide to the OS/2 Presentation Manager
EF ®¢
SFTR SIZENWSE SFTFI SIZENESW SFTR SIZEWE SFTR SIZENS
fe I RI ®
SFTR AFIROW SFTFI TENT SFTR WAIT SFTR MOVE
• Figure 1:1.8..
The system mouse pointers
• Figure 1.1.9..
The system icons
AddingaMouselnterface 551 .
HPOINTER HMouseptr,.
case WM MOUSEMOVE :
Winsetpointer
(rmun DESKTop ,
HMous=Ptr) ,.
As you will see later in the chapter, HMouseptr contains the handle
of the custom mouse returned by WinLoadpointer. The WM_MOUSE-
MOVE message is sent to the client window when the mouse pointer
first enters the window, and subsequently each time the pointer moves
within the window. When the pointer leaves the client window, these
messages are sent to the new underlying window, which presumably
sets the pointer to another appropriate shape. It may seem inefficient to
continually reset the pointer to the s¢77zc value as it moves to various
positions within the client window; however, the Microsoft documenta-
tion indicates that this function is very fast when the specified pointer is
the same as the current pointer. (Unfortunately, the system does not
• 552 Programmer's Guide to the os/2PresentationManager
provide messages that are sent only when the mouse enters or leaves
the client window.)
An application can also set the pointer to various shapes depending
upon the specific position of the mouse pointer within the client win-
dow. For example, an application might display the I-beam system
pointer (identified by the value SPTR_TEXT) in a section of the client
window containing text. To demonstrate this technique, the example
program of Figure 11.14 displays one of the eight standard system
pointers depending upon which section of the client window currently
contains the mouse pointer. See the description of this program later in
this section.
A second possible criterion for selecting the mouse pointer shape is
the` current program activity. For example, while the program is execut-
ing a lengthy operation, during which it cannot accept user input, it
could display the hourglass system icon (identified by the value
SPTR_WAIT). Also, a program currently engaged in moving an object
might display the 771oz7c icon (SPTR_MOVE, shown in Figure 11.8).
Note that an application can display and move a mouse pointer even
if a mouse is not installed. For example, in the absence of a mouse, a
program might nevertheless display the hourglass mouse pointer to in-
dicate a pause in input. Another example is a drawing program that
uses the mouse pointer to indicate the drawing position; if a mouse
were not installed, the program could still display the pointer, but
would have to explicitly move the pointer in response to keyboard
input. You can use the following steps to display and move a pointer in
the absence of a mouse (the previous section in this chapter described
how to determine whether a mouse is installed):
Winshowpointer
Purpose..
Shows or hides the mouse pointer by changing the pointer
hide level.
Prototype..
BOOL APIENTRY Winshowpointer
(HWND hwndDesktop, fdheeny±a#ehE¥¥kpo-pD::nKdTo°w? t°
Return Value ..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
If the pointer hide level is 0, the mouse is displayed; if it is
greater than 0, the mouse is hidden. If a mouse is installed,
the system assigns the hide level an initial value of 0 (which
shows the pointer); if no mouse is installed, the system as-
signs an initial value of 1 (which hides the pointer). The hide
level is not allowed to go below 0 (therefore, calling this
function with f show equal to TRUE when the mouse is al-
ready visible has no effect). You can obtain the current hide
level by calling WinQuerysysvalue, passing an identifier of
SV POINTERLEVEL as the second parameter.
Related Functions ..
WinQuerysysvalue (Figure 11.1)
• Figure 11.10..
The WinshowpoLuler Presentation Manager function
•554 Programmer's Guide to the OS/2 Presentation Manager
Winsetpointerpos
Purpose..
Sets the position of the mouse pointer.
Prototype..
BOOL APIENTRY Winsetpointerpos
(IIWND hwndDesktop, The value HWND DESKTOp to
identify the deskto-p window.
SHORT x, The horizontal position of the pointer
in screen coordinates.
SHORT y) ,. The vertical position of the pointer in
screen coordinates.
Return Value ..
TRUEifthefunctionwassuccessful,orEALSEifanelTororcuned.
Notes..
The mouse position for this function, like the function Win-
Querypointerpos, is specified in screen coordinates (which
are relative to the lower left corner of the screen). You can call
WinMapwindowpoints to convert window relative coor-
dinates to screen coordinates.
Relate d Functions ..
WinMapwindowpoints (Figure 11.4)
WinQuerypointerpos (Figure 11.2)
• Figure ll.11..
The WLnsetpointerpos Presentation Manager f unction
AddingaMouselnterface 555 .
Figure 11.12
This MAKE file prepares the program of Figure 11.14
#
FIG1114.OBJ : FIG1114.C
€1 /W2 /c /Zp /E2ws FIGll_14.C
• Figure 11.,12..
A MAKE file for preparing the progran of Figure 11.14
1024
8192
Wndproc
• Figure 11.13..
A linker definition file for the program of Figure 11.14
• 556 Programmer's Guide to the os/2 Presentation Manager
/*
Figure 11.14
• Figure 11.14..
A program that displays the system mouse pointers
AddingaMouselnterface 557 .
#RE§g:: EX:E#:R¥ S:::::y (E##B :#::; 8§E8R: ::g; #:£¥ :::; #:£¥ :S2) ;
MRESULT EXPENTRY MouseMove (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2) ;
MRESULT EXPENTRY Size (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2) ;
*/
HPOINTEF HandleTable [4][2]; /* Array for holding 8 pointer handles.
*/
static SHORT xQuart; /* 1/4 horizontal dimension of window. */
static SHORT yHalf ; /* 1/2 vertical dimension of window.
MRESULT EXPENTRY Wndproc */
(HWND hwnd, /* Window handle. */
USE.[ORT msg, /* The message. */
MPAEN mpl, /* Message-specific information. */
MPARI" mp2) /* Message-specific information.
(
switch (msg)
(
case WM CREATE:
return Create (hwnd,msg,mpl,mp2) ;
case WM DESTROY:
return Destroy (hwnd,msg,mpl,mp2) ;
case WM ERASEBACKGROUND: /* Have the system erase the window. */
return TRUE;
case WM MOUSEMOVE:
return MouseMove (hwnd,msg,mpl,mp2) ;
case WM SIZE:
return Size (hwnd,msg,mpl,mp2`},``
• Figure 11.14..
A:;program that displays the system mouse pointers (continued)
• 558 Programmer's Guide to the os/2 Presentation
Manager
} /* end Wndproc */
MRESULT EXPENTRY Create (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/* Test for presence of mouse; quit if no mouse is installed.
if ( !WinQuerysysvalue
(HIND DESKTOP,
SV_M06SEPRESENT ) )
ErrorQuit ("Sorry, you must have a mouse.") ;
} /* end Create */
MRESULT EXPENTRY Destroy (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
• Figure 11.14..
A progran that displays the syste:in mouse pointers (continued)
AddingaMouselnterface 559 .
} /* end Destroy */
MRESULT EXPENTRY MouseMove (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/* Assign one of the 8 pointers depending upon the window quadrant
containing the mouse.
Winsetpointer
(HWND DESKTOP,
HandlETable [MOUSEMSG(&msg) ->y / yHalf]
[MOUSEMSG(&msg)->x / xQuart]) ;
return TRUE;
MRESULT EXPENTRY Size (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/* Save dimensions of a single quadrant.
xQuart = SHORTIFROMMP (mp2) / 4 + 1;
yHalf = SHORT2FROMMP (mp2) / 2 + 1;
return FALSE;
} /* end Size */
• Figure 11.14..
A prograiii that displays the system mouse pointers (continued)
®560 Programmer's Guide to the OS/2 Presentation Manager
• Figure ll.14..
A progran that displays the system mouse pointers (continued)
xQuart = SHORTIFRchn@
yHalf = SHORT2FROMMP
Remember that the low-order word of mp2 contains the horizontal size
of the client window, and the high-order word contains the vertical size.
(The + 1 terms in these expressions prevent addressing beyond the
bounds of the HandleTable array in the function call to Winsetpointer,
explained next. Note that the eight quadrants into which the window is
divided are only ¢pproxz.771¢£cJy equal.)
Finally, the function that processes the WM_MOUSEMOVE function
calls Winsetpointer to set the mouse pointer according to the specific
AddingaMouselnterface 561 .
case WM MOUSEMOVE:
Winsetpointer
(HEED DESKTOP,
Handl=Table [MOUSEMSG(&msg) ->y / yHalf]
[MOUSEMSG(&msg) -> x / xQuart] ) ,.
WM ERASEBACKGROUND
_
Purpose..
This message is sent to the client window so that the client
window procedure can either erase the window itself, or
have the system erase the window using the default back-
ground color (CLR_BACKGROUND).
• Figure 11.15..
Tfie WM ERASEBACKGROUND Presentation Manager message
• 562 Programmer's Guide to the os/2 Presentation
Manager
Parameters..
REAIRAI mpl Handle to a presentation space that can be
used to erase the window if the client
window procedure chooses to perform this
operation.
REAEN mp2 Address of a WRECT structure (defined
below) containing the dimensions of the
rectangle to be erased.
Structure..
typedef struct WRECT
(
SHORT xLeft,.
SHORT durmyl ,.
SHORT yBottom,.
SHORT durmy2 ,.
SHORT might,.
SHORT durmy3 ,.
SHORT yTop,.
SHORT dumy4 ,.
)
WRECT,.
Return Value ..
The client window procedure should return TRUE to force
the system to erase the window; it should return FALSE if it
has performed the erasing operation itself.
Notes..
Returning TRUE from this function is an efficient method for
erasing the client window. The message is sent by the frame
window procedure whenever the frame window is in-
validated (it is sent by the routine that processes the
WM_PAINT message); the message is therefore 7iof sent
when the client window alone is invalidated.
• Figure ll.15..
The WM_ERASEBACKGROUND Presentation Manager message (continued)
AddingaMouselnterface 563 .
however, since the message is sent only when the fr¢771e wz.71do" is in-
validated, the technique would fail if the client window alone were in-
validated (for example, the text editor presented in the first part of this
bookfrequentlycallsthefunctionWinlnvalidateRecttoinvalidateo7izy
the client window; this program can therefore not rely upon the
WM ERASEBACKGROUND message for erasing the client window).
LONG NumberButtons ,.
NumberButtons = WinQuerysysvalue
(HIND DESKTOP,
SV CM6USEBUTTONS ) ,.
BOOL Buttonsswapped,.
Buttonsswapped = (BOOL)WinQuerysysvalue
(HIND DESKTOP,
sv swinBUTTONi ,.
(Note that your program can also scf the swapped state of the mouse
buttons by calling the Winsetsysvalue function.)
If your program uses more than one mouse button, you should pro-
videalternativecommandsthatcanbeissuedusingasinglebutton.For
example, in the program listed in Figure 11.21 (described later in this
section), the command issued by pressing mouse button 2 can also be
issued by pressing button 1 in conjunction with the Alt key.
Justasyoucanobtainthepositionofthemousepointereitherbycall-
ing a function or by processing a message, you can likewise determine
the status of the mouse buttons either by calling the WinGetKeystate
function or by processing the appropriate mouse messages.
The WinGetKeystate function (Figure 11.16) can be called to obtain
thestatusofavirtualkey(seetheexplanationofvirtualkeysinChapter
6) or a mouse button. You can pass this function a value identifying a
specific mouse button, and it will return a value less than 0 if the button
is pressed, or a value of 0 or greater if the button is released. A given
mouse button is specified by passing one of the following values:
VK BUTTONI
VK BUTTON2
VK BUTTON3
The following example determines whether mouse button 2 is pressed:
BOOL Button2Pressed,.
Button2Pressed = WinGetKeystate
(HEED DESKTOP,
VA BUETON2) < 0,.
Adding a Mouse Interface 565.
NotethatthebuttonstatusreturnedbyWinGetKeystateisthestatus
of the button at the time the last message obtained from the queue was
posted. This function is thus analogous to WinQueryMsgpos (which
obtains the pointer position at the time the last queue message was
WinGetKeystate
Purpose..
Determines whether a virtual key or mouse button is cur-
rentlypressedorreleased;alsoreturnsthetogglestatusofa
key.
Prototype..
SHORT APIENTRY WinGetKeystate
(Hue hwndDeskt°P, Fdheeny±a;utehFd¥kpo-pD::nKdTo°w? t°
RetumValue..
If the specified key or mouse button is pressed, the high-
order bit of the word value returned by this function is set
(that is, the return value will be negative); otherwise, this bit
will be cleared. If the key is Joggled, the low-order bit of the
return value is set; a key is toggled if it has been pressed an
odd number of times since the system was started.
Notes:
The value returned by this function is the status of the key at
the time the last message obtained from the queue was
posted.
• Figure 11.16..
Tie WinGetKeystate Presentation Manager function
•566 Programmer's Guide to the OS/2 Presentation Manager
posted).ThereisnofunctionanalogoustoWinQuerypointerposforob-
taining the c#7`rc7if button state.
Thesystemalsoinformstheclientwindowofthestatusofthemouse
buttonsbysendingitanappropriatemessagewheneverabuttonisfirst
pressed or released. These messages are summarized in Table 11.2.
Whenever the user presses mouse button 1, the system sends the
WM_BUTTONIDOWN message; when this button is subsequently
released, the system sends WM_BUTTONIUP. The system sends
analogous messages for buttons 2 and 3. The action of pressing and
releasing a mouse button is termed a cJ€.ck. If the user clicks button 1
twice in rapid succession, with the mouse pointer in the same screen
area,thesystemsendsthefollowingsequenceofmessages:
WM_BUTTONIDOWN
WM BUTTONIUP
WM_BUTTONIDBLCLK
WM BUTTONIUP
qualify as a dot/Z7Je cJ1.ck. A double click consists of two clicks that oc-
cur within a certain short time span while the mouse pointer is con-
tained within a certain small screen area. The user can set the time span
through the Control Panel. Also, you can obtain or set the current
values for both the double-click time and the sensitive screen area by
calling WinQuerysysvalue or Winsetsysvalue (passing the constant
SV DBLCLKTIME for the time, SV_CXDBLCLK for the width of the
area, or SV_CYDBLCLK for the height of the area). The system sends
theanalogousmessageslistedinTablell.2forbuttons2and3.
Providingaspecialmessagefordouble-clickingexpandsthepossible
number of commands the user can issue with the mouse. The next sec-
tiondescribeshowthesecommandsaretypicauyusedbyanapplication.
Figures 11.17 through 11.21 provide an example program that
demonstrates how to design and install a custom mouse pointer, and
how to execute commands in response to mouse button activity. Figure
11.171ists a MAKE file for preparing the program; Figure 11.18 is the
linker definition file; Figure 11.19 is a resource script that defines
the mouse pointer; Figure 11.20 is a header file that is included in
Figuresll.19and11.21;andFigurell.21istheCsourcecode.
The custom mouse pointer used in this program was created in the
Icon Editor, as described in Chapter 10; it was then saved in the file
• Figure 11.17:
AjMAKiEfileforpreparingtheprogramofFigurell.21
•568 Programmer's Guide to the OS/2 Presentation Manager
; Figure 11.18
• Figure 11.18..
AlinkerdefinitionfitefortheprogramofFigurell.21
Figure 11.19
#include ''FIG1120.H"
• Figure ll.19..
A resource script for the progran of Figure 11.21
Figure 11.20
• Figure 11.20..
AheaderfileincludedinthelistingsofFiguresll.19and11.21
Adding aMouselnterface 569 .
Figure 11.21
This program displays a custom mouse pointer, and responds to the mouse
buttons by drawing lines within the window.
*/
void main ()
(
HWND Hclient; /* Client window handle.
QMSG QueMess;
/* Message queue structure.
ULONG CtlData = /* Control windows to include:
FCF MINmx /* Minimize/maximize box.
FCF-SHELLPOSITION /* Make window visible on screen.
FCF-SIZEBORDER /* Wide sizing border.
FCF-SYSMENU /* System menu.
FCF-TASKLIST /* I)isplay program name in Task Manager.
FCF-TITLEBAR; /* Title bar.
*/
lIAncBlk = Winlnitialize /* Initialize the Presentation Manager. */
(0), /* Initialization options: must be 0.
*/
I"esQue = WincreateMsgQueue Create a message queue. */
(HAncBlk, Anchor block
All-J|\JL J--+ ,-,---handle.
_-____
0); Minimum queue size: 0 means default size.*/
[#nue'xca#firogramthatdisp|aysacustommousepointerandrespondstothemousebuttons
• Figure 11.21..
•570 Programmer's Guide to the OS/2 Presentation Manager
0,
&Hclient) ;
/* Resource identification: none */
/* Address to receive client window hand. */
while (WinGetMsg
/* Get messages until WM_QUIT.
(HAncBlk, /* Anchor block handle.
&QueMess ,
0,
/* Address of message structure.
0,
/* Window filter: any window.
0))
/* First message identifier: n/a.
/* Last message identifier: n/a.
WinDispatchMsg (HAncBlk, &QueMess) ; /* Dispatch messages.
• Figure 11.21..
Anexampleprogramthatdisplaysacustommousepointerandrespondstothemousebuttons(continued)
Adding a Mouse Interface 571.
case WM MOUSEMOVE:
return MouseMove (hwnd,msg,mpl,mp2) ;
default:
return WinDefwindowproc (hwnd,msg,mpl,mp2) ;
)
} /* end Wndproc */
MRESULT EXPENTRY ButtonlDn (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
HPS Hpresspace;
*/
/I. If hit key is pressed, send a WM_BUTTON2DOEN message.
if (WinGetKeystate
(HIND DESKTOP,
vK Ari) < 0)
(
WinsendMsg
( hwnd ,
WM BUTTON2DOWN,
mpl,
mp2) ,
return TRUE;
)
/.A Otherwise, draw a line from current point to mouse pointer position
H.presspace = WinGetps (hwnd) ; /,: 9P:a:`n, :``:::::n:::::Fr:P:::iL to
G]piMOve /* Set PM cu-rrent graphics point to
( Hpresspace , /* last endpoint.
&Savedpoint) ;
Savedpoint.x = MOUSEMSG(&msg) ->x; /* Adjust 'Savedpoint' to current
Savedpoint.y = MOUSEMSG(&msg) ->y; /* pointer position.
GpiLine /* Draw line from graphics point to
( Hpresspace , /* current mouse pointer position.
&Savedpoint) ;
} /* end ButtonlDn */
mESUI,T EXPENTRY Button2Dn (rmND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
/* Reset 'Savedpoint' to current mouse position.
Savedpoint.x = MOUSEMSG(&msg) ->x;
Savedpoint.y = MOUSEMSG(&msg)->y;
return TRUE;
} /* end Button2Dn */
• Figure ll.21..
[#nue`xca;mL#irogramthatdisp|aysacustommousepointerandrespondstothemousebuttons(Continued)
• 572 Programmer's Guide tothe os/2Presentation
Manager
mESULT EXPENTRY Create (HWND hwnd, USHORT msg, MPA:RAN mpl, MPARAM mp2)
if (HMouseptr == NULL)
ErrorQuit ("Cannot load pointer resource") ;
return FArsE ;
} /* end Create */
lmESULT EXPENTRY Destroy (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
(
WinDestroypointer /* Release pointer handle.
("Ouseptr) ;
} /* end Destroy */
MRESULT EXPENTRY MouseMove (HWND hwnd, USHORT msg, MPZ~ mpl, MPZ~ mp2)
(
/* Set the mouse pointer to the custom pointer while the mouse is in the
client window. */
Winsetpointer
(HWND DESKTOP,
HMousEptr) ;
return TRUE;
} /* end MouseMove */
• Figure ll.21..
An example program that displays a custom mouse pointer and responds to the mouse buttons (continued)
Adding a Mouse Interface 573.
} /* end ErrorQuit */
[X8nuerxea##irogramthatdisp|aysacustommousepointerandrespondstothemousebuttons(continued)
• Figure 1.1.21:
IIMouseptr = WinLoadpointer
(HEED DESKTOP,
RILL ,
ID POINTER) ;
WinDestroypointer
("ouseptr) ,.
• 574 Programmer's Guide to the os/2 Presentation
Manager
Theprogramcausesthesystemtodisplaythecustommousepointer
whilethepointerislocatedwithintheclientwindowbyissuingthefol-
lowing call to Winsetpointer each time the client window procedure
receives the WM_MOUSEMOVE message:
Winsetpointer
(HWND DESKTOP ,
ENous=Ptr) ,.
pointerpositionaccompaniesallmousemessages,anditiseasily
extracted using the MOUSEMSG macro.
4. It calls winReleaseps (Figure 3.22) to release the presentation
Space.
GpiMOve
Purpose..
Sets the current graphics position.
Prototype..
BOOL APIENTRY GpiMove
ReturmValue..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
The current graphics position is initialized to the point (0,0)
when the presentation space is first obtained. GpiMove ex-
plicitlysetsthecurrentgraphicsposition;drawing functions
such as GpiLine also set this position (to the specified en-
ding point of the primitive that is drawn).
Relate d Functions ..
GpiLine (Figure 11.23)
• Figure 11.22..
Tire Gpt:Move Presentation Manager function
• 576 Programmer'sGuidetothe os/2Presentation
Manager
GpiLine
Purpose..
Draws a straight line from the current graphics position to
the specified endpoint, and resets the current graphics posi-
tion to this endpoint.
Prototype..
LONG APIENTRY GpiLine
(Eps hps , Handle to the presentation space in which
the line is to be drawn.
ppolNTL pptl) ,. Address ofa POINTL structure (defined in
Figure 3.28) containing the endpoint.
RetumValue..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
The beginning point of the line is the current graphics posi-
tion; since GpiLine resets the current graphics position to
the specified endpoint, you can draw a sequence of con-
nected line segments in a given presentation space by
repeatedly calling GpiLine, without explicitly setting the
current graphics position between calls. You can call Gpi-
Move, however, if you need to explicitly set the graphics
position.
Related Functions ..
GpiMove (Figure 11.22)
• Figure 11.23..
The GPILine Presentation Manager function
AddingaMouselnterface 577 .
Note that rather than accepting both a starting point and an ending
point, the function GpiLine receives only the ending point of the line.
The starting point of the line is the current graphics position that is
maintained by the Presentation Manager for a given presentation space.
When you first obtain a presentation space, the current graphics posi-
tion is initialized to the point (0,0). You can explicitly set it to an ar-
bitrary point by calling GpiMove; also, certain drawing functions, such
as GpiLine, reset the current position to the endpoint of the object
drawn. Thus, if the desired beginning point of the line is 71of the current
graphics position, you must call both GpiMove and GpiLine to fully
specify the line.
If, however, you are drawing a series of connected line segments
within a given presentation space, you need to call GpiMove only to set
the initial starting point. Since GpiLine automatically resets the current
point to the endpoint of the line drawn, you can draw each subsequent
connected line segment by simply calling GpiLine. (Even though the
linesegmentsdrawnbytheprogramofFigurell.21areconnected,But-
tonlDn must always call GpiMove, since it obtains a handle to a 71cw
presentation space each time it is called.)
In response to mouse button 2, the function Button2Dn resets Saved-
Pointtocontainthecunentmouseposition,usingthefouowingexpressious:
Pressingbutton2thusallowstheusertoresetthestartingpointinorder
to draw a new series of connected line segments.
The function Button2 receives control either when the user presses
mouse button 2 or when the user presses button 1 in combination with the
Altkey(whichisaprovisionforuserswithasinglemousebutton).When-
evertheuserpressesbutton1,thefunctionButtonlDnreceivesinitialcon-
trol; if, however, the Alt key is also pressed, ButtonlDn immediately
passes control to Button2Dn, through the following instructions:
if (WinGetKeystate
(HIND DESKTOP,
VA AIT) < 0)
(
WinsendMsg
• 578 Programmer's Guide tothe os/2Presentation
Manager
(hwnd,
" BUTTON2DOEN,
mpl,
mp2 ) '.
return TRUE,.
)
Note that the program of Figure 11.21 (like the program of Figure
11.14) erases the client window by returning TRUE from the
WM_ERASEBACKGROUND message. Accordingly, the client window
is cleared whenever the frame window is resized. Figure 11.24
illustrates the window and mouse pointer created by the program.
• Figure ll.24..
The window created by the program of Figure 11.21
AddingaMouselnterface 579 .
Action D escription
Mouse Commands
This section lists the standard uses for mouse button 1. The use of
mouse button 2 is application-specific; note, however, that a program
should not depend upon the existence of more than a single button. Ac-
cordingly, a command issued through button 2 should be optional (a
command shortcut, for example), or you should implement an alterna-
tive keyboard command (possibly executed in combination with mouse
• 580 Programmer's Guide to the os/2PresentationManager
button 1). Mouse button 3,if present, is reserved for optional system
commands.
The following commands are recommended for marking selections
within text-based applications (see Chapter 9 for a discussion on text
selections and their relationship with the Presentation Manager clip-
board). Note that the recommended pointer for an area displaying text
is the I-beam (identified by the value SPTR_TEXT).
Note that using the Shift key in conjunction with the mouse button in-
creases the number of commands that could be issued through the basic
mouse actions alone.
The following commands are recommended for selecting items from
lists (for example, selecting files from a list of file names). Note that the
standard arrow pointer (SPTR_ARROW) is recommended for selecting
list items.
Exploiting
Multitasking
and
Interprocess
Cornrnunication,
583.
.r
hapter 1 introduced the topic of multitasking and de-
scribed the three levels of multitasking supported by
OS/2: multiple screen groups, multiple programs, and
multiple threads of execution within a single program.
This chapter focuses on the finest of these three levels: multitasking of
threads. Specifically, it describes how to use multiple threads of execu-
tion within a Presentation Manager application.
AIl of the Presentation Manager programs described so far in this
book have consisted of a sl.71gzc thread. In these programs, when the
function main calls WinDispatchMsg to dispatch a message, control
does not return from WinDispatchMsg until the message has been
fully processed and the window procedure has issued a return state-
ment. Thus, messages are processed one at a time, and only one func-
tion within your program is active at a given time.
In general, using multiple threads of execution within a single ap-
plication is a useful device for increasing program efficiency and
throughput, and for simplifying complex program logic. Specifically,
under the Presentation Manager, starting multiple threads is an impor-
tant technique for performing lengthy tasks in response to keyboard or
mouse commands.
Since a program consisting of a single thread can process only one
message at a time, a message that initiates a lengthy operation (such as
recalculating a spreadsheet or printing a file) blocks the program from
processing further messages until the current operation is complete.
Thus, the program cannot respond to keyboard or mouse input while
the operation is in progress. Furthermore, the system does not allow the
user to switch to another application (using either the keyboard or
mouse) while the active application is processing a message (specifical-
ly, the system delays switching active applications until the window
procedure returns control and the main message-processing loop calls
WinGetMsg to obtain another message). Accordingly, the Presentation
Manager documentation recommends that the window procedure
return control within approximately 0.1 second.
If the program consists of a single thread, the window procedure ob-
viously cannot perform a lengthy operation and return control within
0.1 second. The best solution to this problem is for the window proce-
dure to start a second thread of execution to perform the lengthy opera-
tion, and then return control immediately. While the second thread is
• 584 Programmer's Guide to the os/2PresentationManager
running, the first thread can continue to process messages and the sys-
tern can allow the user to switch to another application.
This chapter describes how to start a new thread to perform a lengthy
operation from the window procedure. It then discusses methods for
synchronizing the activities of the two program threads using
semaphores and shared global variables. The chapter illustrates these
general techniques by describing the specific steps for implementing a
print routine within the Presentation Manager text editor presented in
the first part of the book. Printing a file is a good example of a lengthy
task performed in response to a keyboard or mouse message; also, run-
ning a printing routine as a secondary thread illustrates many of the
ways the activities of multiple threads must be synchronized.
This chapter presents only one of the ways that you can exploit multi-
tasking under the Presentation Manager. In addition to starting secondary
threads of execution, a Presentation Manager application can also run
other programs as child processes (for example, a text editor could run a
compiler as a child process, which would auow the user to continue edit-
ing while the compiler runs in the background). For further general infor-
mation on multitasking and inteaprocess communication under OS/2, see
the Progr¢77177ier's G%€.cZc fo OS/2 (cited in the Bibliography).
• USINGASECONDTHREAD
If the window procedure needs to perform a lengthy operation,
rather than simply calling the function that performs this operation as a
subroutine, it can call the OS/2 function DoscreateThread (Figure 12.1)
to execute the function as a second thread. The window procedure can
then immediately return control to the main message-processing loop;
while the second thread performs its task, the main thread resumes nor-
mal message processing. Figure 12.2 illustrates the difference between
executing a lengthy routine as a subroutine (part A) and running it as a
separate thread (part 8); as you can see in this illustration, the important
benefit of starting a new thread is that it significantly shortens the mes-
sage-processing loop.
Exploiting Multitasking and Interprocess Communication 585.
DoscreateThread
Purpose..
Starts a new thread of execution within the current process.
Prototype..
USHORT APIENTRY DoscreateThread
(volD FJm *pfnFunction (VolD) , Address of thread entry
point.
PTID ptidThread Pointer to variable to
receive the thread
identifier.
PBYTE pbThrdstack) ,. Pointer to the top of the
thread's stack.
Return Value ..
Zero if the function was successful; if an error occurred, the
function returns one of the following nonzero values:
• Figure 12.1..
Tree DoscreaLte:ThreaLd OS /2 f unction
• Figure 12.2..
Using a single thread vs. using two threads to process messages
Exploiting Multitasking and Interprocesscommunication 587 .
+ sizeof (Printstack) ) ;
if (Result) /* 'DoscreateThread' failed.
Wir"essageBox
(END DESKTOP,
hwnd ,
''Cannot start print thread.",
''PM Text Editor",
0,
HB ICONASTERISK I
MB=OK) ,
return FALSE ;
• Figure l'L'..3..
The routine for processing the Print menu command
• 588 Programmer's Guide to the os/2 Presentation
Manager
The significant portion of this code for the present discussion is the
following call to DoscreateThread (most of the other instructions
manage the semaphore, and will be described later in the chapter):
USHORT Result,.
Result = DoscreateThread
(PrintThread,
&IDThread,
Printstack
+ sizeof (Printstack)) ,.
The first parameter supplies the address of the function that the new
thread is to begin executing. This function is declared as follows:
You should use this format when declaring any function that is to be ex-
ecuted as a new thread. Note that there are no parameters; the system
does not pass parameters to the function that receives initial control
when a new thread is started. The function PrintThread will be
described later in the chapter.
The second parameter to DoscreateThread supplies the address of
the variable that is to receive the identifier of the new thread. All threads
running under OS/2 are given unique identifiers (which must be sup-
plied to functions such as DosSuspendThread). The example routine
ignores the thread identifier.
The final parameter contains the address of the fop of the thread's
stack. (The top of the stack is the byte immediately following the
memory block that is reserved for the stack; note that the stack grows
dow# in memory, and the stack pointer is decremented by 2 bc/ore the
first word pushed on the stack is written to memory.) Each thread owns
its own stack; when your program starts a new thread, it is responsible
for reserving the memory for the new thread's stack. The required stack
size depends upon the specific function. A recommended minimum
sizeis512bytes;however,ifthefunctioncallsanyOS/2services(orany
other dynamic-link functions), the recommended minimum is 2048
Exploiting Multitasking and Interprocess Communication 589.
bytes plus the requirements of the function itself . A generous stack size
for the function PrintThread (which, as you will see, calls OS/2 func-
tions) is 4096 bytes; this stack is declared as follows:
} /* end PrintThread */
• Figure l',7..4..
The /7mci!z.07t PrintThread
• 592 Programmer'sGuide to the OS/2 Presentation Manager
DosExit
Purpose..
Terminates either a single thread or an entire process.
Prototype..
VOID APIENTRY DosExit
(USHORT fTerminate, Terminate flag; if assigned
EXIT_THREAD, only the current
thread is terminated; if assigned
EXIT_PROCESS, all threads in the
application are terminated.
USHORT usExitcode) ,. The thread or process exitcode.
Return Value ..
This function does not return.
• Figure 12.5..
The DosExft OS|2 f unction
functiongenerallyincludesastack-checkingroutineatthebeginningof
thecode.Thisroutineexpectsthefunctionstacktobelocatedinthenor-
mal stack area of the automatic data segment; as you have seen, how-
ever, the stack for a new thread is typically located either in the
program's data area or in a separate segment dynamically allocated
through the DosAllocseg function. Accordingly, the stack-checking
routine will abort the program. Remember that stack checking for any
function that you write is turned off through the /Gs option normally
usedwhencompilingaPresentationManagerapplication(thisflagwas
described in Chapter 2).
ThesecondproblemwithstandardClibraryfunctionsisthatmostof
them can be called by only one thread at a given time (such functions
are termed 71o7irce7if7'¢71f). Therefore, if the code executed by the main
thread contains calls to a library function such as sprintf, a function ex-
ecutedbyasecondthreadmustnotcallthisfunction,sinceboththreads
may attempt to execute the function at the same time.
Because of these problems, the example program uses OS/2 Dos
functions rather than C library functions for printing the file. Note,
however, that Microsoft C version 5.1 now supplies a special set of
library functions that can be executed simultaneously by .multiple
threads.Seethecompilerdocumentationforinformationonusingthese
functions.
The previous section discussed the possibility of starting two concur-
rent threads that execute the same body of code (by making a second
identical call to DoscreateThread before the thread started by the first
call has terminated). If your program can perform such an action (the
example program cannot), not only must you reserve a separate stack
for each thread, but you must also appropriately declare all variables
usedbythesethreads.Youshoulddeclarevariablesthataretobesfe¢7`cd
by all instances of a function as external data or as static data declared
within the scope of the function. You should declare variables that are
to be prz.zMfc for each instance as automatic data (data declared within
the function that are not static; these data are located within the stack,
which is distinct for each thread).
• 594 Programmer's Guide to the os/2Presentation
Manager
COMMUNICATING
• BETWEENTHREADS
In general, when two or more threads use or manipulate the same
program object, the threads must synchronize their activities to prevent
conflicts. For example, two threads should not attempt to update the
same section of a file at the same time; nor should they simultaneously
try to read and increment a program counter. Also, separate threads
commonly need to communicate while sharing a common task. For ex-
ample, one thread may fill a buffer with data, while another thread
processes these data; the first thread may have to notify the second
thread when the buffer contains valid data.
Implementing the print routine described in this chapter requires
communication between the two program threads to achieve the fol-
lowing four purposes:
The first three purposes are achieved using an OS/2 semaphore, and
the last is accomplished with a global program variable. This section
discusses using semaphores and global variables within the context of
the example program. It then describes the use of messages as a form
of communication between separate program threads.
Using Semaphores
and Global Variables
A semaphore is a program flag used to communicate simple
``stop" and ``go" information between separate threads or processes. A
semaphore can be in one of two states: cJc¢r, generally indicating that a
Exploiting Multitasking and Interprocess Communication 595.
threadshouldproceed,andsef,indicatingthatathreadshouldstopand
possibly wait for some event. OS/2 provides a large collection of func-
tions for creating and managing semaphores; this section discusses
three of these functions: Dossemset, Dossemclear, and Dossemwait.
Rather than providing a general explanation of the use of semaphores,
this section describes specifically how semaphores are used to imple-
ment the print routine within the example program.
First, the example program creates a semaphore by making the fol-
lowing external declaration at the beginning of the code (outside the
scope of a function):
Dossemset (&Sem) ,.
Dossemclear (&Sem) ,.
Since these two function calls are the only points in the example pro-
gram where the semaphore is either set or cleared, the semaphore is in
thesetstateonlywhiletheprintroutineisactive.Accordingly,theother
• 596 Programmer'sGuide tothe os/2Presentation
Manager
Dossemset
Purpose..
Sets the specified semaphore.
Prototype..
USHORT APIENTRY Dossemset
(HSEM hsem) ,. Semaphore handle; for a RAM semaphore,
this parameter should be the far address of
the semaphore; for a system semaphore, the
parameter should be the handle returned by
Doscreatesem or Dosopensem.
Return Value ..
Zero if the function was successful, or one of the following
nonzero error codes if an error occurred:
Related Functions ..
Dossemclear (Figure 12.7)
Dossemwait (Figure 12.8)
• Figure 12.6..
The Dosserr[Set os/2 function
partsofthecodecantestthissemaphoretodeterminewhethertheprint
routine is currently executing. The program tests the semaphore in
three different situations.
First, before the program issues any instructions that modify the file
buffer, it tests the state of the semaphore. If the semaphore is set, the
modificationisnotperformed.(Attemptingtomodifythefilebufferwhile
its contents are being printed could result in printing erroneous data.) The
Exploiting Multitasking and Interprocess Communication 597 .
Dossemclear
Puxpose..
Clears the specified semaphore.
Prototype..
USHORT APIENTRY Dossemclear
(HSEM hsem) J. :f#a°ieeFearnsdh]:iferbaeife¥=eamdad¥:s°sr:'f
the semaphore; for a system semaphore, the
parametershouldbethehandlereturnedby
Doscreatesem or Dosopensem.
RetumValue..
Zero if the function was successful, or one of the following
nonzero error codes if an error occurred:
Related Functions ..
Dossemset (Figure 12.6)
Dossemwait (Figure 12.8)
• Figure 12.7..
Tfie Dosse"Clea;I OS/2 function
USHORT Result ,.
Result = Dossemwait
(&Sem,
OL) ,.
• 598 Programmer's Guide to the os/2Presentation
Manager
Dossemwait
Purpose..
Waits, if necessary, for the specified semaphore to be cleared,
or until the given timeout has elapsed.
Prototype..
USHORT APIENTRY Dossemwait
(HSEM hsem, Semaphore handle; for a RAM semaphore,
this parameter should be the far address of
the semaphore; for a system semaphore, the
parameter should be the handle returned by
Doscreatesem or Dosopensem.
LONG ITimeout) ,. Specifies the maximum time to wait for the
semaphore to clear; if this parameter is 0, the
function returns immediately, returning 0 if
the semaphore was clear or the nonzero
value ERROR SEM TIMEOUT if the
semaphorew;sset;ifthisparameterisgiven
the value -1, the function waits indefinitely
for the semaphore to clear.
Return Value ..
Zero if the semaphore was cleared; ERROR SEM TIMEOUT
if the semaphore was not cleared by the time tie specified
timeout expired; or one of the following nonzero error codes
if an error occurred:
RelatedFunctions..
Dossemclear (Figure 12.7)
Dossemset (Figure 12.6)
• Figure 12.8..
The DossemwaLft OS/2 f unction
Exploiting Multitasking and Interprocess Communication 599 .
Ifthesemaphoreisset,routines1and2wamtheuserbysoundingthe
speaker,andretumwithoutperformingthefflemodification,asfollows:
if (Result)
(
Wirnlarm (HIPND DESKTOP, WA_ERROR) ,.
return TRUE,.
)
example,thepasteroutinecontainsthefollowingstatementsimmedi-
ately after the call to Dossemwait:
if (Result)
(
WirMessageBox
(HEED DESKTOP,
HFrame,
"Cannot Paste into File\n''
``Print Routine in Progress'',
"PM Text Editor'',
0'
ue OK I
MB ICONASTERISK) ,.
return FALSE,.
)
Thesecondprimaryuseforthesemaphoreistopreventtheprogram
from starting a second instance of the print function, PrintThread,
whilethisfunctionisalreadyactive.Accordingly,theID_PRINTroutine
listed in Figure 12.3 issues the following statements bc/ore calling Dos-
CreateThread to start the new thread:
Result = Dossemwait
(&Sem,
OL) ,.
if (Result)
(
WirMessageBox
(Hue DESKTOp,
HFrane,
``Print Routine Already in Progress'',
"PM Text Editor'',
0,
RE OK I
MB ICONASTERISK) ,.
return FALSE,.
)
Exploiting Multitasking and Interprocess Communication 601 .
The third and final use for the semaphore within the example pro-
gram is to prevent the user from terminating the program while the
print thread is still active. Terminating the program while the print
thread is active not only would interrupt the print job, but also would
probably result in a protection fault. Remember that the termination
routine (the function Quit) first calls WinDestroyHeap to release the
heap memory; if the print thread subsequently attempts to access this
memory, the system immediately ternrinates the program with a
protection fault message.
Topreventaprogramexitwhiletheprintthreadisstillactive,theex-
ample program provides a function (Close, listed in Figure 12.9) to
mESULT EXPENTRY Close (HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2)
::s::i:i:::ssemwalt ;: Tit::i¥::i:i¥j;;diately.
£eply = Wi"essageBox /* Query user whether to abort print.
(END DESKTOP,
hund ,
''Print Routine in Progress\nAbort Print?" ,
''PM Text Editor",
0,
MB YESN0 I
) /* end Close */
• Figure.12®9..
Tfie function Close of the example program
®602 Programmer's Guide to the OS/2 Presentation Manager
WM_CLOSE
Purpose..
This message is sent by the system to the client window
when the user selects the Close item from the system menu
or double-clicks the mouse on the system menu icon.
Parameters..
REARAM mpl NULL.
REARAM mp2 NULL.
Return Value ..
NULL.
Notes..
Thedefaultprocessingforthismessage(performedbyWin-
Defwindowproc) is to terminate the application by posting
the WM_QUIT message to the window's message queue. If
your application processes this message, it can post
WM_QUIT or call WinDefwindowproc to terminate the
program, or simply return NULL to prevent terrfunating
the program.
• Figure 12.10..
The WM_CLOSE Presentation Manager function
Exploiting Multitasking and Interprocess Communication
603.
message, however, you can either post the WM_QUIT message to ter-
minate the program, or simply issue a return statement to allow the
program to continue.
InresponsetotheWM_CLOSEmessage,thefunctionClosefirsttests
the semaphore, as explained above, to determine whether the print
thread is active. If the thread is 7iof active, the function proceeds to ter-
minatetheprogrambypostingtheWM_QUITmessage.Themessageis
postedbycallingtheWinpostMsgfunction(Figure12.11),asfollows:
WinpostMsg
(hund, /* Recipient window: client.
" QUIT, /* Message ID.
OL,
* XPL.. nla.
OL) ,.
* Txp2... n/a.
WinpostMsg
Purpose..
Posts a message to the message queue belonging to the
specified window.
Prototype..
BOOL APIENTRY WinpostMsg
(HWND hwnd, Handle of the target window.
USHORT msg, The identifier of the message that is being
sent.
REARAM mpl , The first message parameter; the meaning is
specific to the message.
REARAM mp2 ) ,. The second message parameter; the meaning
is specific to the message.
RetumValue..
TRUE if the function was successful, or FALSE if an error
occurred.
Notes..
WinpostMsg places the message in the target window's
message queue and returns immediately (in contrast, Win-
SendMsg calls the target window procedure directly, and
does not return until this procedure has terminated). Accord-
ingly, WinpostMsg does not return the result of the message
processing, but only an error code indicating whether the
message was successfully posted to the queue.
RelatedFunctions..
WinsendMsg (Figure 4.8)
• Figure 1211..
The WinpostMs8 Presentation Manager function
Exploiting Multitasking and Interprocess Communication
605.
After Close has set Abortprint to TRUE to end the print routine, it
does 7iof directly proceed to terminate the application. Rather, it first
waits until PrintThread has successfully ended (it cannot assume that
PrintThread ends immediately). To make sure that PrintThread has
ended, it again calls Dossemwait, this time passing a timeout value of
-1L, which causes Dossemwait not to return until the semaphore has
been cleared. The call to Dossemwait is as follows:
Note,therefore,thatDossemwaitcanbeusednotonlytotestthevalue
of a semaphore, but also to cause the program to pause until the
semaphore is clear. Also, if you set the timeout parameter to a value
greaterthan0,thefunctionwillwaituntileitherthesemaphorehasbe-
come clear or the specified timeout period has elapsed.
You should make one final change in the text editor program to im-
plementtheprintroutine.Notethattheusercanalsoterminatethepro-
gram by selecting the Exit item from the File submenu, as well as
through the Close item of the system menu. The routine that handles
theExitcommandinthepriorversionoftheexampleprogram(listedin
Figure 8.38, in the ID_EXIT case of the function Command) directly
calls the Quit function, which immediately aborts the program. Since
this tactic would bypass the test for an active print thread, the routine
should instead pass control to the code that handles the WM_CLOSE
message, as follows:
case ID EXIT:
WinsendMsg
(hwnd,
" CLOSE,
OL,
OL) ,.
return FALSE,.
•606 Programmer's Guide to the OS/2 Presentation Manager
Using Messages
Semaphores and shared memory are traditional forms of inter-
process communication available to all OS/2 protected mode
programs. Presentation Manager programs can also use messages as a
form of communication among separate threads. To be able to send and
receive messages, each thread must create at least one window; the
threads can then exchange messages using the standard Presentation
ManagerfunctionsWinsendMsgandWinpostMsg.Notethatmessage
identifiers are not limited to the predefined messages that have been
described in this book, but can also be programmer-defined messages
thatarerecognizedonlybythethreadsinvolvedintheexchange.
Thefollowingarethespecificstepsyoucanusetoestablishmessage
communication between the main program thread and a new thread
begun by calling DoscreateThread:
#define WM PRIVATE 00
#define "-PRIVATE=01
#define WM PRIVATE 02
Wincreatewindow
Purpose..
Creates a new window.
Prototype..
HWND APIENTRY Wincreatewindow
(Hum hwndparent, The handle of the parent
window; the value
HWND DESKTOP indicates
the desktop window and
creates a top-level window; the
value HWND_OBJECT creates
an object window (which has
no parent).
PSZ pszclass, Address of a string containing
the name of the window class.
PSZ pszNane, Address of the window text, or
other class-specific data.
ULONG flstyle, The window style.
SHORT x, The horizontal window
position relative to the origin
of the parent window.
SHORT y, The vertical window position
relative to the origin of the
parent window.
SHORT cx, The window width.
SHORT cy, The window height.
Hum hwndowner, Handle of the owner window.
HWND hwndlnsertBehind, Handle of the sibling window
behind which the specified
window is placed; the value
HWND_TOP places the
window on top of all siblings,
and HWND_BOTTOM places
it on the bottom.
USHORT id, The window identifier.
• Figure 12.12..
The Wincreate:Window Presentation Manager function
Exploiting Multitasking and Interprocess Communication 609 .
Return Value ..
The handle of the newly created window, or the value NULL
if an error occurred.
Related Functions ..
Wincreatestdwindow (Figure 2.5)
• Figure 12.12..
Tie Wincreatewindow Presentation Manager function ( continued)
611.
.T
counter while working with the Presentation Manager.
If a term has a special meaning within the context of
OS/2 or the Presentation Manager, this definition is
given rather than the general significance of the word. Note also that
OS/2 is a new and rapidly evolving operating system; you may there-
fore discover inconsistencies in the terminology from one source to
another, as well as general changes over time in the usage of these tech-
nical terms.
boot disk The disk drive that contains the code used to initialize
the computer and load the operating system when the system is first
reset or powered on.
Clip To eliminate data written to the screen or other device that falls
outside of a given boundary.
Code page Atable used to define a character set used by the system.
compatibility box The os/2 screen group for running real mode
MS-DOS programs.
drag To press a mouse button and hold the button down while
moving the mouse.
Family API A subset of the os/2 Apl functions that can be called
by dual-mode programs when they are running in real mode.
icon A fixed-size graphic image that you can create and display
within a Presentation Manager application; an application window is
represented by an icon when it is minimized.
modal Describes a dialog box that does not allow the user to switch
the focus to another window owned by the same application, until the
dialog box is dismissed. A sysfeffl 7ttod¢J dialog box disallows the user
from switching the focus to any other window in the system.
£oa::::e¥isnpTa°y¥d.Awfnd°Wwithinwhichoneormorechi|dwin_
Path The fun specification of the location and name of a disk ffle, in-
cluding the drive, directory, and file name.
Pixel Picture element; smallest unit on the screen that can be control-
led(tumedonoroff,orassignedacolororintensity).
Point To place the hot spot of the mouse pointer on a given item or
within a given area.
Poll To test for the occurrence of a specific event; for example, an in-
efficient program might repeatedly poll for the arrival of a character
rather than blocking.
scroll bar A control window used to scron textual data within a win-
dow.Ahorizontalscroubaristypicauylocatedalongtheloweredgeofits
parentandscroustexthorizontally;averticalscroubaristypicallylocated
alongtherightedgeofitsparentandscroustextverticany.
Server The process that owns a queue and receives the queue messages.
time Slice The period of time that the scheduler allows a thread to
run before it grants CPU time to another thread of equal priority.
title bar A control window typically located along the top edge of
its parent; the title bar contains a text title and is used for moving the
parent window with the mouse.
.T
the Presentation Manager and OS/2 functions that have
been described in the book. The synopsis of each func-
tion provides a short statement of the function's pur-
pose, the function prototype, and a reference to the figure in the book
that fully describes the function. Note that the inside book covers list
these same functions according to the types of services they provide.
Note also that the functions described in this book are a subset of the
full set of services offered by OS/2 and the Presentation Manager; see
the technical documentation cited in the Bibliography for information
on functions not covered in the book.
• DosAllocseg
Purpose..
Allocates a memory segment.
Prototype..
USHORT APIENTRY DosAllocseg
(USHORT ussize,
PSEL psel,
USHORT fAIloc) ,.
Figure..
9.1
• DoscreateThread
Purpose..
Starts a new thread of execution within the current process.
Prototype..
USHORT APIENTRY DoscreateThread
(VOID PASCAL FAR *pfnFunction (VOID) ,
PTID ptidThread,
PBYTE pbThrdstack) ,.
• 632 Programmer's Guide to the os/2Presentation
Manager
Figure..
12.1
• DosExit
Purpose..
Terminates either a single thread or an entire process.
Prototype..
VOID APIENTRY DosExit
`,, (USHORT fTerminate,
USHORT usExitcode) ,.
Figure..
12.5
• DosGetResource
Purpose..
Loads the specified resource segment into memory.
Prototype..
USHORT APIENTRY DosGetResource
(HMODUI.E hmod,
USHORT idType,
USHORT idNane,
PSEL psel) '.
Figure..
10.26
• DosGetseg
Purpose..
Secures access to a shared memory segment for the current
process.
SelectedpresentationManagerFunctions 633 .
Prototype..
USHORT APIENTRY DosGetseg
(SEL sel) '.
Figure..
9.7
• Dossemclear
Puxpose..
Clears the specified semaphore.
Prototype..
USHORT APIENTRY Dossemclear
(HSEM hsem) ,.
Figure..
12.7
• Dossemset
Purpose..
Sets the specified semaphore.
Prototype..
USHORT APIENTRY Dossemset
(HSEM hsem) ,.
Figure..
12.6
• Dossemwait
Purpose..
Waits, if necessary, for the specified semaphore to be cleared,
or until the given timeout has elapsed.
• 634 Programmer'sGuide tothe os/2Presentation
Manager
Prototype..
USHORT APIENTRY Dossemwait
(HSEM hsen,
LONG ITimeout) ,.
Figure..
Figure 12.8
• Dossizeseg
Purpose..
Obtains the size in bytes of a specified memory segment.
Prototype..
USHORT APIENTRY Dossizeseg
(SEL selpuLONG pulsize) ,.
Figure..
10.27
• GpicharstringAt
Purpose..
Draws a line of text at a specified starting position.
Prototype..
LONG APIENTRY GpicharstringAt
(HPS hps,
PPOINTL pptlstart,
LONG cchstring,
PCH pchstring) ,.
Figure..
3.28
SelectedpresentationManagerFunctions 635 .
• GpicreateLogFont
Purpose..
Creates a logical definition of a font.
Prototype..
BOOL APIENTRY GpicreateLogFont
(HPS hps,
PSTR8 pchNane,
LONG lcid,
PFATTRS pfat) ,.
Figure..
3.26
• GpiDeleteBitmap
Purpose..
Frees a bitmap.
Prototype..
BO0L APIENTRY GpiDeleteBitmap
(HBIT"ZP hbm) ,.
Figure..
10.23
• GpiErase
Purpose..
Erases the display device associated with the specified
presentation space using the default system background
color (CLR BACKGROUND).
Prototype..
BOOL APIENTRY GpiErase
(HPS hps) ,.
• 636 Plogrammer's Guidetothe os/2Presentation
Manager
Figure..
10.12
• GpiLine
Purpose..
Draws a straight line from the current graphics position to
the specified endpoint, and resets the current graphics posi-
tion to this endpoint.
Prototype..
LONG APIENTRY GpiLine
(HPS hps,
PPOINTL pptl) ,.
Figure..
11.23
• GpiLoadBitmap
Purpose..
Loads a bitmap from a resource segment into memory.
Prototype..
HBI"AP APIENTRY GpiLoadBitmap
(HPS hps,
USHORT module,
USHORT idBitmap,
LONG Iwidth,
LONG IHeight) ,.
Figure..
10.21
• GpiLoadFonts
Purpose..
Loads one or more fonts from a font file.
Selected Presentation Manager Functions 637.
Prototype..
Boor. APIENTRY GpiLoadFonts
(RE hab,
PSZ pszFilename) ,.
Figure..
3.18
• GpiMOve
Purpose..
Sets the current graphics position.
Prototype..
BOOL APIENTRY GpiMove
(HPS hps,
PPOINTL pptl) ,.
Figure..
11.22
• GpiQueryFonts
Purpose..
Returns information on one or more of the fonts that are cur-
rently available.
Prototype..
LONG APIENTRY GpiQueryFonts
(HPS hps'
ULONG floptions,
PSZ pszFacename,
PLONG pcFonts,
LONG cbMetrics
PFONTMETRICS pfmMetrics) ,.
Figure..
3.20
• 638 Programmer's Guide tothe os/2Presentation
Manager
• GpisetBackcolor
Purpose..
Sets the background color generated by graphics functions
such as GpicharstringAt.
Prototype..
BO0L APIENTRY GpisetBackcolor
(HPS hps'
LONG IColor) ,.
Figure..
9.9
• GpisetBackMix
Purpose..
Specifies the way the background color generated by
graphics functions (such as GpicharstringAt) is combined
with the existing color within the presentation space.
Prototype..
BOOL APIENTRY GpisetBackMix
(HPS hps,
LONG IMi"ode) ,.
Figure..
9.8
• Gpisetcharset
Purpose..
Setsthecurrentcharactersetusedfordisplayingtextualdata
within the specified presentation space.
Selected Presentation Manager Functions 639.
Prototype..
BOOL APIENTRY Gpisetcharset
(HPS hps'
I.ONG lcid) ,.
Figure..
3.27
• Gpisetcolor
Purpose..
SetstheforegroundcolorusedbyGp€.functionssuchasGpi-
CharstringAt.
Prototype..
BOOL APIENTRY Gpisetcolor
(HPS hps'
LONG IColor) ,.
Figure..
3.29
• WinAlarm
Purpose..
Sounds the computer speaker.
Prototype..
BOOL APIENTRY WinAlarm
(HWND hwndDesktop,
USHORT rgfType) ,.
Figure..
6.9
• 640 Programmer's Guide to the os/2Presentation
Manager
• WinAllocMem
Purpose..
Allocates a block of memory from a Presentation Manager
heap.
Prototype..
NPBYTE APIENTRY WinAllocMem
(HHEAI hHeap,
USHORT cb) ,.
Figure..
3.7
• WinBeginpaint
Purpose..
Obtains a handle to a presentation space that is associated
with the specified window.
Prototype..
IIPS APIENTRY WinBeginpaint
(HIND hwnd,
HPS hps,
PRECTL prclpaint) ,.
Figure..
2.20
• Wincloseclipbrd
Purpose..
Closes the clipboard, previously opened through Winopen-
Clipbrd.
SelectedpresentationManagerFunctions 641 .
Prototype..
BOOL APIENTRY Wincloseclipbrd
(HAB hab) ,.
Figure..
9.4
• Wincreatecursor
Puxpose..
Creates a cursor within the specified window.
Prototype..
BOOL APIENTRY Wincreatecursor
(HIND hwnd,
SHORT x,
SHORT y,
SHORT cx,
SHORT cy,
USHORT fs,
PRECTL prclclip) ,.
Figure..
5.3
• WincreateHeap
Purpose..
Creates and initializes a heap for dynamically anocating
blocks of memory.
Prototype..
HHEAP APIENTRY WincreateHeap
(USHORT selHeapBase,
USHORT cbHeap,
USHORT cbGrow,
USHORT cbMinDed,
• 642 Programmer's Guide to the os/2Presentation
Manager
USHORT cbMaxDed,
USHORT fQptions) ,.
Figure..
Figure 3.4
• WincreateMsgQueue
Purpose..
Establishes a message queue that receives messages sent to
all windows created by the current thread.
Prototype..
HinQ APIENTRY WincreateMsgQueue
(HAB hab,
SHORT cmsg) ,.
Figure..
2.3
• Wincreatestdwindow
Purpose:
Creates a standard window.
Prototype..
HWND APIENTRY Wincreatestdwindow
(HEED hwndparent ,
ULONG flstyle,
PVOID pctlData,
PSZ pszclientclass,
PSZ pszTitle,
ULONG styleclient,
"ODULE hood,
USHORT idResources,
PHWND phwndclient) ,.
SelectedpresentationManagerFunctions 643 .
Figure..
2.5
• Wincreatewindow
Puxpose..
Creates a new window.
Prototype..
HWND APIENTRY Wincreatewindow
(HIND hwndparent ,
PSZ pszclass,
PSZ pszNane,
ULONG flstyle,
SHORT x,
SHORT y,
SHORT cx,
SHORT cy,
IIWND hwndowner ,
HWND hwndlnsertBehind,
USHORT id,
PVOID pctlData,
PVOID ppresparams) ,.
Figure..
12.12
• WinDefDlgproc
Puxpose..
Provides default processing for a message sent to a dialog
procedure.
Prototype..
ULONG APIENTRY WinDefDlgproc
(HIND hwndDlg,
` USHORT msgid,
• 644 Programmer's Guide to the os/2Presentation
Manager
mARAI mpl,
REARAM mp2) ,.
Figure..
8.10
• WinDefwindowproc
Purpose..
Passesamessagetothesystemfordefaultprocessing.
Prototype..
IflESULT APIENTRY WinDefwindowproc
(HIND hwnd,
USHORT msg,
REAEN mpl,
REARAI mp2) ,.
Figure..
2.17
• WinDestroycursor
Purpose..
Destroys the cursor associated with the specified window.
Prototype..
BOOL APIENTRY WinDestroycursor
(HIND hwnd) ,.
Figure..
5.6
• WinDestroyHeap
Purpose..
Destroys a heap previously created by WincreateHeap.
Selected Presentation Manager Functions 645.
Prototype,
HHEAP APIENTRY WinDestroyHeap
(HHEAI hHeap) ,.
Figure..
3.5
• WinDestroyMsgQueue
Purpose..
Destroys the specified message queue.
Prototype..
BOOL APIENTRY WinDestroyMsgQueue
(HMQ hmq) ,.
Figure..
2.14
• WinDestroypointer
Purpose..
Destroys an icon or pointer.
Prototype..
Boot- APIENTRY WinDestroypointer
(HPOINTER hptr) ,.
Figure..
10.10
• WinDestroywindow
Purpose..
Destroys the specified window and all its descendant
windows.
•646 Programmer's Guide to the OS/2 Presentation Manager
Prototype..
BOOL APIENTRY WinDestroywindow
(HEAD hwnd) ,.
Figure,
2.13
• WinDismissDlg
Purpose..
Removes the current dialog box and causes the function
WinDlgBox to return control.
Prototype..
B00L APIENTRY WinDismissDlg
(HIND hwncolg,
USHORT usResult) ,.
Figure..
8.11
• WinDispatchMsg
Purpose..
Causes the system to call a window procedure.
Prototype..
ULONG APIENTRY WinDispatchMsg
(HAB hab,
PQMSG pqusg) ,.
Figure..
2.9
• WinDlgBox
Purpose..
Loads, displays, and processes a dialog box.
Selected Presentation Manager Functions 647 .
Prototype..
USHORT APIENTRY WinDlgBox
(HIND hwncaparent ,
HWND himdoimer ,
PFrm pfhDlgproc,
"ODULE hmod,
USHORT idDlg,
PVOID pcreateparams) ,.
Figure..
8.9
• WinDrawBitmap
Purpose..
Draws a bitmap within the specified presentation space.
Prototype..
BOOL APIENTRY WinDrawBitmap
(HPS hpsDst,
HBITur ham,
PRECTL pwrcsrc,
PPOINTL pptlDst,
LONG clrFore,
LONG clrBack,
USHORT fs) ,.
Figure..
10.22
• WinDrawpointer
Purpose..
Draws an icon.
Prototype..
BOOL APIENTRY WinDrawpointer
(HPS hps,
•648 Programmer's Guide to the OS/2 Presentation Manager
SHORT x,
SHORT y,
HPOINTER hptr,
USHORT fs) ,.
Figure..
10.9
• WinDrawText
Purpose..
Printsatextstringwithinaspecifiedrectangle,usingthecur-
rent font.
Prototype..
SHORT APIENTRY WinDrawText
(HPS hps,
SHORT cchText,
PCH pchText,
PRECTL prcl,
LONG clrFore,
LONG clrBack,
USHORT rgfchd) ,.
Figure..
2.24
• WinEmptyclipbrd
Purpose..
Removes all data blocks from the clipboard, freeing the as-
sociated data handles.
Prototype..
BOOL APIENTRY WinEmptyclipbrd
(RED hab) ,.
Selected Presentation Manager Functions 649 .
Figure..
9.6
• WinEnablewindow
Purpose..
Enables or disables the specified window.
Prototype..
BOOL APIENTRY WinEnablewindow
(HIND hwnd,
BOOL fEnable) ,.
Figure..
4.10
• WinEndpaint
Purpose..
Signalsthesystemthattheupdatingofthewindow(which
occurs typically in response to a WM_PAINT message) is
complete.
Prototype..
BO0L APIENTRY WinEndpaint
(HPS hps) '.
Figure..
2.21
• WinFillRect
Purpose..
Draws a rectangle filled with a specified color.
Prototype..
BOOL APIENTRY WinFillRect
(HPS hps'
•650 Programmer's Guide to the OS/2 Presentation Manager
PRECTL pcrl,
LONG IColor) ,.
Figure..
2.23
• WinFreeMem
Purpose..
FreesamemoryblockfromaheapmanagedbythePresenta-
tion Manager.
Prototype..
NPBYTE AVIENTRY WinFreeMem
(HREAP hHeap,
REBYTE npMen,
USHORT cbMem) ,.
Figure..
3.10
• WinGetKeystate
Purpose..
Determines whether a virtual key or mouse button is cur-
rently pressed or released; also returns the toggle status of
a key.
Prototype..
SHORT APIENTRY WinGetKeystate
(HIND hwndDesktop,
SHORT vkey) ,.
Figure..
11.16
Selected Presentation Manager Functions 651 .
• WinGetLastError
Puxpose..
Returns the system error code set by the last Presentation
Manager function that failed, and resets the system error
code to 0.
Prototype..
EREORID APIENTRY WinGetLastError
(HID hab) '.
Figure..
3.11
• WinGetMsg
Purpose,
Extracts the next message from the message queue belong-
ing to the current thread.
Prototype..
BOOL APIENTRY WinGetMsg
(us hab,
PQMSG pqusg,
HWND hwndFilter,
USHORT msgFilterFirst ,
USHORT msgFilterLast) ,.
Figure..
2.8
• winGetps
Purpose..
Obtains a cache presentation space.
•652 Programmer's Guide to the OS/2 Presentation Manager
Prototype..
HPS APIENTRY WinGetps
(HEAD hund) ,.
Figure..
3.19
• Winlnitialize
Purpose..
Initializes the Presentation Manager system for use by the
current program.
Prototype..
HAB APIENTRY Winlnitialize
(USHORT foptions) ,.
Figure..
2.2
• WinlnvalidateRect
Purpose..
Addsarectangularareatoawindow'supdateregion.
Prototype..
B00L APIENTRY WinlnvalidateRect
(HIND hwnd,
PRECTL prcl,
Boor. f Includechildren) ,.
Figure..
5.8
Selected Presentation Manager Functions
653.
• WinLoadpointer
Purpose..
Loads an icon or mouse pointer into memory from a
resource segment contained in a disk file.
Prototype..
HPOINTER APIENTRY WinLoadpointer
(HIND hwndDesktop,
"ODUI.E hood,
USHORT idres) ,.
Figure..
10.8
• WinLoadstring
Purpose..
Loads a string from a string table resource into a program
buffer.
Prototype:
SHORT APIENTRY WinLoadstring
(HAB hab,
"ODUI.E hood,
USHORT id,
SHORT cc"ax,
PSZ pchBuf fer) ,.
Figure..
10.25
• WinLockHeap
Purpose..
Supplies the far address of the base of the segment contain-
ing the specified heap.
®654 Programmer's Guide to the OS/2 Presentation Manager
Prototype..
PVOID APIENTRY WinLockHeap
(HREAP hHeap) ,.
Figure..
3.6
• WinMapwindowpoints
Purpose..
Maps the coordinates of one or more points from the coor-
dinate space relative to one window into the coordinate
space relative to another window.
Prototype..
BcOL APIENTRY WinMapwindowpoints
(HIND hwncITrom,
HWND hundTo,
PPOINTL pptl,
SHORT cxpt) r.
Figure..
11.4
• WinMessageBox
Purpose..
Displays a message box window.
Prototype..
USHORT APIENTRY WinMessageBox
(HIND hwndparent ,
Hue hundormer,
PSZ pszText,
PSZ pszcaption,
USHORT idwindow,
USHORT flstyle) ,.
Selected Presentation Manager Functions 655.
Figure..
3.14
• Winopenclipbrd
Puxpose..
Opens the clipboard for the current thread, to provide this
thread exclusive access to the clipboard.
Prototype..
BOOL APIENTRY Winopenclipbrd
(RED hab) ,.
Figure:
9.2
• WinpostMsg
Purpose..
Posts a message to the message queue belonging to the
specified window.
Prototype..
BOOL APIENTRY WinpostMsg
(Hum hwnd,
USHORT msg,
REAEN mpl,
reJ-mp2) ,.
Figure..
12.11
• WinQueryclipbrdData
Purpose..
Returns a handle to the block of data in the clipboard that
has the requested format.
•656 Programmer's Guide to the OS/2 Presentation Manager
Prototype..
ULONG APIENTRY WinQueryclipbrdData .,
(RE hab,
USHORT fmt) ,.
Figure..
9.5
• WinQueryFocus
Puxpose..
Obtains the handle of the focus window.
Prototype..
HWND APIENTRY WinQueryFocus
(HEED hwndDesktop,
BOOL fLock) ,.
Figure..
5.10
• WinQueryMsgpos
Purpose,
Obtains the position of the mouse pointer at the time the last
message extracted from the message queue was posted. The
position is given in screen coordinates.
Prototype..
BOOL APIENTRY WinQueryMsgpos
(HRE hab,
PPOINTL pptl) '.
Figure..
11.3
SelectedpresentationManagerFunctions 657 .
• WinQuerypointerpos
Purpose..
Obtains the current position of the mouse pointer in screen
coordinates.
Prototype..
BOOL APIENTRY WinQuerypointerpos
(HWND hwndDesktop,
PPOINTL pptl) '.
Figure..
11.2
• WinQuerysyspointer
Purpose..
Returns the handle to the requested system pointer or icon.
Prototype..
HPOINTER APIENTRY WinQuerysyspointer
(HWND hwndDesktop,
SHORT iptr,
BOOL fLoad) ,.
Figure..
11.7
• WinQuerysysvalue
Puxpose..
Returns the specified system value.
Prototype..
LONG APIENTRY WinQuerysysvalue
(HWND hwndDesktop,
SHORT isysvalue) ,.
• 658 Programmer's Guide to the os/2Presentation
Manager
Figure..
11.1
• WinQuerywindow
Purpose..
Returns the handle of the window that has the selected
relationship to a specified window.
Prototype..
HWND APIENTRY WinQuerywindow
(HIND hwnd,
SHORT cnd,
BOOL fLock) ,.
Figure..
4.6
• WinQuerywindowRect
Purpose..
Returns the coordinates of the specified window.
Prototype..
BOOL APIENTRY WinQuerywindowRect
(HIND hwnd,
PRECTL prclDest) ,.
Figure..
2.22
• WinQuerywindowText
Purpose,
Copies the text associated with a window into a program
buffer.
SelectedpresentationManagerFunctions 659 .
Prototype..
SHORT APIENTRY WinQuerywindowText
(HIND hwnd,
SHORT cchBufferMax ,
PSZ pszBuffer) ,.
Figure..
8.16
• WinRegisterclass
Purpose..
Registers a window class.
Prototype..
BOOL APIENTRY WinRegisterclass
(mD hab,
PSZ pszclassName,
PFNWP pfnwndproc ,
ULONG flstyle,
USHORT cbwindowData) ,.
Figure..
2.4
• WinReleaseps
Purpose..
ReleasesthepresentationspaceobtainedthoughWinGetps.
Prototype..
BOOL APIENTRY WinReleaseps
(HPS hps) ,.
Figure..
3.22
• 660 Programmer'sGuidetothe os/2Presentation
Manager
• Winscrollwindow
Purpose..
Scrolls the contents of a window a specified horizontal and
vertical distance.
Prototype..
SHORT APIENTRY Winscrollwindow
(HEED hwnd,
SHORT ck,
SHORT dy,
PRECTL prclscroll,
PRECTL preclclip,
HRGN hrgnupdate,
PRECTL prclupdate,
USHORT rgfsw) ,.
Figure..
4.14
• WinsendDlgltemMsg
Purpose..
Sends a message to a child control window within a dialog
box; the target control window is specified by its identifier
and the parent window handle (rather than by its own win-
dow handle).
Prototype..
MRESULT APIENTRY WinsendDlgltelhMsg
(HEAD hwndDlg,
USHORT idltem,
USHORT msg,
ueAEun mpl ,
mAIRAM mp2) ,.
Selected Presentation Manager Functions 661.
Figure..
8.25
• WinsendMsg
Purpose..
Sends a message to the specified window.
Prototype:
lmESULT APIENTRY WinsendMsg
(HIND hwnd,
USHORT msg,
REARAI "pl ,
REARAI mp2) ,.
Figure..
4.8
• WinsetclipbrdData
Puxpose..
Places a block of data into the clipboard.
Prototype..
BOOL APIENTRY WinsetclipbrdData
(HJD hab'
ULONG ulData,
USHORT fmt,
USHORT rgfFmtlnfo) ,.
Figure..
9.3
• WinsetFocus
Puxpose..
Assigns the focus to the specified window.
• 662 Programmer's Guide to the os/2Presentation
Manager
Prototype..
BOOL APIENTRY WinsetFocus
(HEED hwndDesktop,
HWND hwndsetFocus) ,.
Figure..
4.3
• Winsetpointer
Purpose..
Sets the mouse pointer that is displayed by the system.
Prototype..
BOOL APIENTRY Winsetpointer
(HIND hwndDesktop,
HPOINTER hptrNew) ,.
Figure..
11.6
• Winsetpointerpos
Purpose..
Sets the position of the mouse pointer.
Prototype..
B00L APIENTRY Winsetpointerpos
(HEAD hwndDesktop,
SHORT x,
SHORT y) '.
Figure..
11.11
SelectedpresentationManagerFunctions 663 .
• WinsetwindowText
Puxpose..
Sets the text associated with a window.
Prototype..
BOOL APIENTRY WinsetwindowText
(HIND hwnd,
PSZ pszText) ,.
Figure..
7.18
• Winshowcursor
Purpose..
Makes visible or hides the cursor associated with the
specified window.
Prototype..
BOOL APIENTRY Winshowcursor
(HIND hwnd,
BOOL f show) ,.
Figure..
5.5
• Winshowpointer
Purpose..
Shows or hides the mouse pointer by changing the pointer
hide level.
Prototype..
BOOL APIENTRY Winshowpointer
(HWND hwndDesktop,
BOOL f show) ,.
®664 Programmer's Guide to the OS/2 Presentation Manager
Figure..
11.10
• WinTerminate
Purpose..
Signals the Presentation Manager that the calling thread has
completed using the services of the Presentation Manager,
and releases all Presentation Manager resources held by this
thread.
Prototype..
BOOL APIENTRY WinTerminate
(HAB hab) ,.
Figure..
2.15
• Winupdatewindow
Purpose..
Causes the system to send a WM_PAINT message to the
specified window by directly calling the window procedure.
Prototype..
B00L APIENTRY Winupdatewindow
(HEED hwnd) ,.
Figure..
4.16
• Winupper
Purpose..
Converts the characters in a string to uppercase.
Selected Presentation Manager Functions 665.
Prototype..
SHORT APIENTRY Winupper
(HLne hab,
USHORT idcp,
USHORT idcc,
PSZ psz) ,.
Figure..
7.20
• WinwindowFromlD
/
Purpose..
Returns the handle belonging to a child window.
Prototype..
HWND APIENTRY WinwindowFromlD
(HEED hwndparent ,
USHORT id) ,.
Figure..
4.5
667.
.T predefinedPresentationManagermessagesthathavebeen
described in this book. The synopsis of each message gives
a brief statement of the purpose of the message and a ref-
erencetothefigureinthebookthatfullydescribesthemessageandthe
parametersthataccompanyit.Notethatthesemessagesfallintooneof
two general categories. The first category consists of messages that are
typicallysentfoaclientordialogwindowproceduretonotify.itofuser
input or other significant events. The second category comprises mes-
sages that are normally sent by a window procedure to windows man-
aged by the system, to control the behavior of these windows or to
obtain services from the system. The messages in the second category
effectively extend the Presentation Manager API accessed through sys-
tern function calls.
The messages summarized here are also listed in the inside covers of
the book, where each message is categorized according to the type of
information it provides or the service it performs. Note that these func-
tions form a subset of the full collection of predefined Presentation
Manager messages; see the technical documentation cited in the Bibli-
ography for information on messages not discussed in this book. See
also the section on Using Messages in Chapter 12 for a description of
programmer-defined messages.
• EM SETTEXTLIMIT
Purpose..
Sent to an edit control of a dialog box to set the maximum
number of characters that can be entered into the control.
Figure..
8.24
• LM DELETEALL
Purpose..
Sent to a list box control window to delete all items in the
list box.
•668 Programmer's Guide to the OS/2 Presentation Manager
Figure..
8.31
• LM_INSERTITEM
Purpose..
Sent to a list box control window to cause it to add an item to
the list.
Figure..
8.32
• LM_QUERYSELECTION
Purpose..
Sent to a list box control window to obtain the index of the
currently selected item.
Figure..
8.28
• LM_QUERYITEMTEXT
Purpose..
Sent to a list box control window to obtain the text for a
specific item within the list box.
Figure..
8.29
• MM_SETITEMATTR
Purpose..
Sent to a menu window to set the attributes of a menu item.
Figure..
7.9
Selected Presentation Manager Messages 669.
• MM _SETITEMTEXT
Purpose..
Sent to a menu control window to specify the text displayed
for a given menu item.
Figure..
7.10
• SBM_SETPOS
Purpose..
Sent to a horizontal or vertical scroll bar window to cause it
to set the position of the scroll bar slider.
Figure..
4.17
• SBM_SETSCROLLBAR
Purpose..
Sent to a horizontal or vertical scroll bar window to cause it
to set the range and position of the scroll bar slider.
Figure..
4.9
• WM __CHAR
Purpose..
Sentbythesystemtothefocuswindow(oractivewindow,if
there is no focus window) to notify it of a keyboard event
(that is, a key pressed or released).
Figure..
6.1
•670 Programmer's Guide to the OS/2 Presentation Manager
• WM_CLOSE
Purpose..
Sent by the system to the client window when the user
selects the Close item from the system menu.
Figure..
12.10
• WM_COMMAND
Purpose..
Sentbyacontrolwindowtoitsownertoreportasignificant
event.
Figure..
7.11
• WM_CONTROL
Puxpose..
Sentbyacontrolwindowtoitsownertoreportasignificant
event.
Figure..
8.18
• WM_CREATE
Purpose..
Sent by the system to a window when it is first created. It al-
lows the window procedure to perform initializations.
Figure..
3.16
Selected Presentation Manager Messages 671.
• WM DESTROY
__
Purpose..
Sent by the system to a window when it is about to be
destroyed.
Figure..
10.11
• WM ERASEBACKGROUND
Purpose..
Sent to the client window so that the client window proce-
dure can either erase the window itself, or have the system
erase the window using the default background color
(CLR BACKGROUND).
Figure..
11.15
• WM HSCROLL
__
Purpose..
Sentbyahorizontalscrollbarwindowtoitsownertoreport
relevant scroll bar events.
Figure..
4.12
• WM INITDLG
Puxpose..
Sent by the system to a dialog window when it is first
created, before it becomes visible.
Figure..
8.19
•672 Programmer's Guide to the OS/2 Presentation Manager
• WM INITMENU
Purpose..
Sent by the system to the client window when a menu item
is about to become active.
Figure..
7.7
• WM_MOUSEMOVE
Purpose..
Sentbythesystemtothewindowbeneaththemousepointer
(ortothemousecapturewindow,if any)eachtimetheposi-
tion of the mouse pointer changes.
Figure..
11.5
• WM PAINT
Purpose..
Sent by the system to a window whenever the entire win-
dow, or any portion of it, needs redrawing.
Figure..
2.19
® WM_QUIT
Purpose..
Posted to the message queue to terminate the application.
Figure..
2.10
Selected Presentation Manager Messages 673.
• WM SETFOCUS
Purpose..
Sent by the system to a window whenever it is about to
receive or lose the input focus.
Figure..
5.1
• WM SIZE
Purpose..
Sent by the system to a window whenever its size changes.
Figure..
3.23
• WM VSCROLL
Purpose..
Sent by a vertical scroll bar window to its owner to report
relevant scroll bar events.
Figure..
4.18
•674
• Bibliography
Mic_ro?oft.O.pe_r.a_tingSystem/2,PresentationManagerReference.
Redmond, WA: Microsoft Corporation,1988.
M:ie_ro,soft. Op_era.ting System/2 Programmer's Tloolhit , Progranmer's
Re/ere71cc. Redmond, WA: Microsoft Corporation, 1988.
Mic:osg£:. Operating System/2 Software Development Kit, Presenta~
tion Manager Specification, Vol. I & 11. Tledrrrond, WA.. Mi.crosoft
Corporation,1987.
Mic_ro??£tLW!ndows. S_of_tware D evelopment Kit , Application Style
Gt4z.dc. Redmond, WA: Microsoft Corporation, 1987.
• Index
LM_QUERYITEMTEXT, 389-390,
HEAPSIZE (1inker definition file
668
command), 74, 94
hot spot (mouse pointer), 512, 541 LM_QUERYSELECTION, 389, 668
local descriptor table,10
.I
.M
icon editor, 498-500, 512-513, 519
icons, 41, 45, 491-512
macros (provided by OS/2), 84-89
designing, 498-500 MAKE (utility), 72
displaying, 502-512 menu command, 484
installing, 500-502 menu mnemonic, 484
identifier. See window identifier menus, 301-335
creating, 301-310
import library,11-12
managing, 311-322
include files. See header files
initializing (Presentation Manager), message-based architecture, 56-57
28, 30-33 message queue, 33-34
Ins key (Insert), 262-264 messages
insert mode, 333-334 for interprocess communication,
606-609
insertion point, 199
interprocess communication, 6-7, getting and dispatching, 49-57
594T609. See ¢Jso multitasking, processing, 58-60
semaphores, threads sending,158-160, 215
.N relocation record,11-12
NAME (hnker definition ffle repeat count (keyboard), 232
command), 73 resource compiler, 302-304
New command, 322-330 resource script, 302-309
resources (OS/2), 301-302, 491-533.
See ¢Jso accelerators, bitmaps,
.0 dialog boxes, icons, menus,
object windows, 606, 608 programmer-defined
Open command, 380-395 resources, strings
overwrite mode, 333-334 Return key. See Enter key
owner (of a window),109,112
.S
.P Save As command, 375-380
parent window, 38, 47L49 Save command, 330-333
Pascal conventions, 31-33 scan code (keyboard), 231
Paste command, 479, 483 screen groups, 3-6
point (mouse), 579 scroll bars,147-197
pointer (mouse), 512 selection (of data)
presentation space, 65-69,115,118 described, 479
privilege levels,10-11 marking, 480483
Program Starter, 20 selector (segment), 7-11
programmer-defined resources, semaphores, 594-605
529-533 session manager, 5-6
proportionally spaced characters, sessions, 3-6
114-115 SBM_SETPOS (message), 173-174,
protected-mode screen groups, 4-6 669
protection fault,10 SBM_SETSCROLLBAR (message),
PROTMODE (1inker definition file 158,161, 669
command), 74 Shift-click (mouse), 580-581
Shift-drag (mouse), 580
•Q stack (for new threads), 588-589
STACKSIZE (linker definition file
queue. See message queue, system command), 74, 94
queue standard window, 3849
strings (stored as resources),
.R 526-529
real mode screen group, 4, 6 styles. Scc window styles
system queue, 227-228
Index 681 .
.Z
/Zp (compiler flag), 72
Selections from
The SYBEX Library
revised to include the latest features of
DOS MS-DOS Version 3.3. Two reference
books jn one, this title has separate sec-
tions for programmer and user. Multi-DOS
The ABC's of DOS 4 partitons, 31/2disk format, batch file call
Alan R. Miller and return feature, and comprehensive
coverage of MS-DOS commands are
250pp. Bef. 583-2
included.
This step-by-step introduction to using
DOS 4 is written especially for beginners.
MS-DOS Power user's Guide,
Filled with simple examples, The ABC's of
DOS 4 covers .the basics of hardware,
Volume I
software, disks, the system editor EDLIN, (Second Edition)
DOS commands, and more. Jonathan Kamjn
482pp. Ref. 473-9
ABC's of MS-DOS A fully revised, expanded edition of our
(Second Edition) best-selling guide to high-performance
Alan R. Miller DOS techniques and utiljtjes--with details
233pp. Bef. 493-3 on Version 3.3. Configuration, I/0, direc-
tory structures, hard disks, F]AM disks,
This handy guide to MS-DOS is all many
batch file programming, the ANsl.SYS
PC users need to manage their computer
device driver, more.
files, organize floppy and hard disks, use
EDLIN, and keep their computers orga-
nized. Additional information is given
MS-DOS Power User's Guide,
about utilities like Sidekick, and there is a Volume 11
DOS command and program summary. Martin Waterhouse/Jonathan Kamin
The second edition is fully updated for 418pp, Bef. 411-9
Version 3.3. A second volume of high-performance
techniques and utilities, with expanded
Mastering DOS coverage of DOS 3.3, and new material
(Second Edition) on video modes, Token-Ping and PC Net-
Judd Robbins work support, micro-mainframe links,
700pp. Ref. 555-7
extended and expanded memory, multi-
"The most useful DOS book." This seven- tasking systems, and more.
Mastering Turbo C
Stan Kelly-Bootle
COMMUNICATIONS
578pp. Bef. 462-3
No prior knowledge of C or structured pro-
gramming is required for this introductory Mastering Crosstalk XVI
course on the Turbo C language and devel- Peter W. Gofton
opment environment by this well-known 187pp. Bef. 388-0
author. A logical progression of tutorials and Becoup the cost of this book in a matter of
useful sample programs build a thorough hours with ready-made routines that
understanding of Turbo C. speed up and automate your on-line data-
base sessions. Tutorials cover every
Systems Programming jn Turbo C aspect of installing, running and customiz-
Michael J. Young ing Crosstalk Xvl.
365pp. Bef. 467-4
An introduction to advanced program-
ming with Borland's Turbo C, and a gold-
mine of ready-made routines for the
system programmer's library: DOS and
HARDWARE
BIOS interfacing, interrupt handling, win-
dows, graphics, expanded memory, The RS-232 Solution
UNIX utilities, and more.
Joe Campbell
194pp. Bef.140-3
Understanding C
A complete how-to guide to trouble-free
Bruce H. Hunter RS-232-C inter facing from scratch. In-
320pp. Bet.123-3 depth coverage of concepts, techniques
A programmer's introduction to C, with and testing devices, and case studies
special attention to implementations for deriving cables for a variety of common
microcomputers--both CP/M and MS- computers, printers and modems.
DOS. Topics include data types, storage
management, pointers, random I/0, func- Mastering Serial
tion libraries, compilers and more. Communications
Peter W. Gofton
Mastering C
289pp. Bef,180-2
Craig Bolon
The software side of communications,
437pp. Bet. 326-0
with details on the IBM PC's serial pro-
This in-depth guide stresses planning,
gramming, the XMODEM and Kermit
testing, efficiency and portabHjty in C
protocols, non-ASCII data transfer,
applications. Topics include data types, interrupt-level programming and more.
storage classes, arrays, pointers, data Sample programs in C, assembly lan-
structures, control statements, I/0 and the
guage and BASIC.
C function library.
Microprocessor lnterfacing
Data Handling Utilities Techniques (Third Edition)
in Microsoft C
Austin Lesea/Rodnay Zaks
Pobert A. Radcliffe/Thomas J. Raab 456pp. Bef. 029-6
519pp. Bef. 444-5
This handbook is for engineers and hob-
A C library for commercial programmers, byists alike, covering every aspect of
with techniques and utilities for data entry, interfacing microprocessors with periph-
eral devices. Topics include assembling a Programmer's Guide
CPU, basic I/0, analog circuitry, and bus to the Amiga
standards. Robert A. Peck
352pp. Bet. 310-4
From Chips to Systems: An A programmer's hands-on tour through
Introduction to Microcomputers the Amiga system--AmigaDOS, Exec,
(Second Edition) Graphics, Intuition, Devices, Sound, Ani-
Rodnay Zaks/Alexander Wolfe mation, and more--packed with in-depth
580pp. Bet . 377-5 information and sample programs (in
The best-selling introduction to microcom-
Amiga C) showing proper use of system
routines.
puter hardware-now fully updated, revised,
and illustrated. Such recent advances as 32-
bit processors and RISC architecture ate
introduced and explalned for the first time in
a beginning text. SPREADSHEETS AND
Mastering Digital Device Control INTEGRATED
William a. Houghton
366pp. Bet . 346-5
SOFTWARE
Complete principles of system design
using single-chip microcontrollers, with The ABC's of 1-2-3
numerous examples. Topics include (Second Edition)
expanding memory and I/0, interfacing Chris Gilbert/Laurie Williams
with multi-chip CPUs, clocks, display
245pp. Bef. 355-4
devices, analog measurements, and
0n/i.ne Toddy recommends it as "an easy
much more.
and comfortable way to get started with
the program." An essential tutorial for
novices, it will remain on your desk as a
HOME COMPUTERS valuable source of ongoing reference and
support. For Belease 2.
Amiga Programmer's Handbook,
Mastering 1-2-3
Volume I (Second Edition)
(Second Edition)
Eugene P. Mortimore
Carolyn Jorgensen
624pp. Bet. 367-8
702pp. Bef. 528-X
The complete reference for Amiga graph-
Get the most from 1-2-3 Belease 2 with
ics programming. System commands
this step-by-step guide emphasizing
and function calls are presented in detail,
advanced. features and practical uses.
organized by funcitonal class: Exec,
Topics include data sharing, macros,
Graphics, Animation, Layers, Intuition
spreadsheet security, expanded memory,
and the Workbench. Includes AmigaDOS
and graphics enhancements.
version 1.2.
PNIEdit
PM/£dl.f is a full-featured version of the text editor presented in this book,
which will allow you to write programs and other text files within a window of
the Presentation Manager. It provides the following features: an online help
facility, plus complete documentation in a ready-to-print file; cut, paste, and
other block operations; search and replace commands; background compiling
or printing of listings; macros; an undo command; word processing facilities;
and many other features.
• A set of dynamic-link library functions, which extend the os/2 Apl and
the standard C library. Functions are provided for both kernel and
Presentation Manager programs.
A set of programmer's utilities for OS/2 and the Presentation Manager,
including programs for designing text mode screens and windows, for
writing and executing macros, for cutting and pasting data between
screen groups, and for saving text and graphics screens in files, plus a
GREP program and other utilities.
• Source code: Complete, commented source code is provided for all func-
tions and utilities.
• Documentation: Thorough documentation for all utilities and functions
is supplied in a ready-to-print file.
ORDERFORM
Copies of the Companion Diskette Set @ $29.50 each
Total Order
NameAddres City/State/ZipAlldisket esarmentpayabletcards;forforeiYoursoftware
e in standard 51/4-inch IBM format. Please send a check for full pay-oMichaelJ.YoungorrequestUPSCOD(nopurchaseordersorbankgnorders,pleasesendaninternationalmoneyorderinU.S.dollars).wil beshippedimmediately.Orderfrom:
Michael J. Young
P.O. Box 5068
Mill Valley, CA 94942
415/383-5354
S]YBF¥isnotaffiliatedwithMichaelJ.Youngandassumesnoresponsibilityforanydefectin
the disk or program.
TO JOIN THE SYBEX MAILING LIST OP OBDEB BOOKS
PLEASE COMPLETE THIS FOF"
_ COMPANY
TOTALAMOuNTPAYABLE
DCHECKENCLOSED DVISA
I MASTEF}CARD I AMEF3lcAN EXPRESS
ACCOUNT NUMBEF3
CUSTOMEB SIGNATUBE
I TECHNICAL PBOGBAMMING
I OTHEB:
OCCUPATION
THE FACTOB THAT WAS MOST IMPOPTANT IN
YOUF} SELECTION: I PF30GRAMMER I TEACHEF3
I COMPREHENSIVENESS I ENGINEEB/TECHNICAL
PACKAGE:
NAME
PACKAGES
I PROFESSIONAL PROGF3AMMER
T|
SYBEX, INC.
2021 CHALLENGEF] DR. #100
ALAMEDA, CALIFOF}NIA USA
94501
e. SEAL
SYBEX Computer Books
are different.
Here is why . . .
At SYBEX, each book is designed with you in mind. Every manuscript is
carefully selected and supervised by our editors, who are themselves
computer experts. We publish the best authors, whose technical expertise
is matched by an ability to write clearly and to communicate effectively,
Programs are thoroughly tested for accuracy by our technical staff. Our
computerized production department goes to great lengths to make
sure that each book is well-designed.
Bitmaps
• MESSAGE GpiLoadBitmap
MANAGEMENT WinDrawBitmap
GpiDeleteBitmap
Message Processing
WinGetMsg Icons and Pointers
WinDispatchMsg WinLoadpointer 10.8
WinDefwindowproc WinDrawpointer 10.9
WinDefDlgproc Winsetpointer 11.6
WinDestroypointer 10.10
Message Queues
WincreateMsgQueue Strings
WinDestroyMsgcfueue WinLoadstring 10.25
Sending Messages
WinsendMsg
WinsendDlgltemMsg
• THREAD
WinpostMsg MANAGEMENT
DoscreateThread
DosExit
• MOUSE
MANAGEMENT
Buttons
• WINDOW
WinGetKeystate
MANAGEMENT
11.16
(scc ¢Jso Control Window Management)
Pointer Shape
WinQuerysyspointer Creation/Destruction
Winsetpointer Wincreatestdwindow
Wincreatewindow
PositionIvisibilityofpbinter WinDestroywindow
WinQuerypointerpos 11.2 WM CREATE
WinQueryMsgpos 11.3 WM INITDLG
Winsetpointerpos 11.11 WM CLOSE
Winshowpointer 11.10 WM_QUIT
WM MOUSEMOVE 11.5 WM DESTROY
Focus Window Miscellaneous
WinQueryFocus WinEnablewindow
WinsetFocus WinlnvalidateRect
WinMapwindowpoints
Information WinsetwindowText
WinQuerywindow Winupdatewindow
WinQuerywindowRect WinwindowFromlD
WinQuerywindowText WM SIZE
:,.-..,.--.
:',;
PROGRAMMER'S GUIDE
T0 THE
PRESEN"TI0N MANAGER
Programmer's Guide to the OS/2 Presentation Manager is a tutorial
Praise for Michael J. Young's
introduction to programming for the Presentation Manager, covering all
MS-DOS Adranced ltogranmingr
you need to know to develop complete, full-featured applications for "A good choice for C and
OS/2's graphic programming interface. It requires no previous
assembly language
experience with either Presentation Manager or Microsoft Windows
programmers...wen written to
programming, but offers a clear, systematic approach to learning and show how to optinrize your
using the essential features of this vast, complex, and often confusing
System.
programs.''
Computer Book Review
Bufld a complete Presentation Manager appHcation, from the ground
up. Part I uses a hands-on programming project-writing a Presentation
Manager text editor-to introduce the basic architecture and essential
features of any Presentation Manager application. Turn here to learn
how to:
• open and write text to an on-screen window
• use memory-management functions to buffer text
• add scrou bars, and scroll data in the program window
• create, display, and manage a cursor
About the Author
• implement a full keyboard interface
Michael J. Young is a software
• design and install menus and accelerator keys engineering consultant and a developer
of programmer's tools and uthities for
• design, manage, and display dialog boxes MS-DOS and OS/2. He is a member
of the ANSI committee on the
standardization of the C language,
Tap the rystem's advanced features to enhance your software. Part 11
and the author of MS-DOS 4dva!#ced
explores a selection of advanced topics, including:
Pro_gra.mmpg,SyFtemsprogramming
in T_u!bo C, Bind Programwier's Guidre
• inter facing with the clipboard fo OS/2, all from SYBEX. He
• defining and using resources: icons, pointers, bitmaps, strings, graduated from Stan ford University,
and currently lives and works in Miu
and programmer-defined types Vaney, Cahifornia.
• adding a mouse interface
• using graphics functions
• using and synchronizing multiple threads of execution
I COMPUTER B00KSHELFCATEGORY |
L OPERATING SYSTEMS: OS/2 ISBN 0-Bt]5aa-5Ei-7 U.S.$26.95