OS2
Volume Number: 4
Issue Number: 12
Column Tag: Progràmmer's Forum
OS/2 Presentation Manager
By Dan Weston, Portland, OR
The Good, the Bad, and the Ugly: OS/2 Presentation Manager for Mac
Programmers
by Dan Weston
Nerdworks, Portland, Oregon
The Presentation Manager (PM) is Microsoft’s and IBM’s answer to the
Macintosh user interface toolbox. Due out in late 1988 with OS/2 version 1.1, PM
provides a set of new operating system functions for application programmers that is
somewhat similar to the functions supplied in the Macintosh ROM. OS/2 programmers
can access these functions to create windows and menus, use the mouse, and do all the
things that Mac programmers have been doing for over four years now. PM is directly
descended from Microsoft Windows, so programmers familiar with Windows will have
little trouble making the switch to PM, although their Windows application source code
must be substantially modified to work with PM.
This article will attempt to explain the main features of PM in terms that
Macintosh programmers should be familiar with. I know that many people in the Mac
community look at OS/2 with deep suspicion, but even if you feel that way, read on,
and you may find that there are things to appreciate in PM.
Events and Messages
The foundation of any Macintosh program is the event loop. The Macintosh
operating system watches the outside world, including the mouse, keyboard, and disk
drives, and signals the application whenever an event occurs. Macintosh programs are
event driven.
In a PM program, messages take the place of events. When mouse and keyboard
events take place, PM tells the application by sending messages to it. This is
conceptually very similar to the Macintosh event loop, but PM has a much richer set of
messages and has made the message architecture more general and extensible so that it
is very easy for applications to create new message types.
Many of the messages have direct anologs in Mac event types, such as mouse
button down and up messages (although there can be up to three mouse buttons),
activation and update messages, and keyboard messages. Macintosh programmers
familiar with event-driven application architecture will not find it too hard to make
the adjustment to a message driven system.
Windows
The main components of a PM program are windows. The system provides many
predefined window types, including frame windows, push buttons, radio buttons,
menus, and title bars. The predefined window types are know as “window classes”.
Each window class defines an object that enclose a set of functionality that is available
to the programmer simply by sending messages to a window with that type.
The messages in a PM system are actually sent to an application’s windows rather
than the application itself. Each window has an associated window procedure that
receives messages from the system and other windows. For example, when the user
presses the mouse button, the system sends a mouse button down message to the window
that is underneath the mouse at the time of the event. The window then processes the
mouse down message as it sees fit. Different types of windows respond differently.
A standard PM window, with title bar, size border, and scroll bars, is actually
made up of several different predefined window types. The most basic is the frame
window. On top of the frame window sits the other windows, such as the title bar
window and the scroll bar windows, that gives the window its distinctive look. The
frame window “owns” the other windows, called control windows, that sit on top of it.
The ownership relationship is important since it allows the control windows to
communicate with the frame window.
For example, the title bar window class responds to a mouse down event by
tracking the mouse and allowing the user to drag an outline of the frame window around
the screen to position it, just like on the Mac. The way this works is that the title bar
window handles all the tracking and the display of the window outline. When the mouse
up message comes to the title bar window, the title bar window sends a message to the
frame window telling it the new position on the screen. The frame window then sends
messages to all the windows that it owns telling them to redraw themselves at the new
position.
Typically, a programmer writing a PM program creates at least one new window
class to make a program. In the terminology of PM, this is the “client window”. A
client window corresponds to the content area of a Macintosh window. The client
window is also owned by the frame window. Its main responsibility is to display data
for the user. So while frame windows and their constituent control windows behave
the same in most programs, it is the client window which gives each application its
visual personality.
The operating system takes care of routing messages to the appropriate window.
An application programmer never sees events that are handled by other windows. For
example, when a normal Mac program gets a mouse down event, it must call
FindWindow to determine what part of the window received the click and branch
accordingly. In a PM program, the application programmer never sees a mouse down
in the title bar or menus because those events are handled by the control windows at
those locations. The application programmer only handles messages directed to those
windows he or she creates, such as the client window mentioned above.
The Window Procedure
Each window has an associated window procedure that processes all messages for
that window. The syntax for a window procedure is consistent for all windows, so all
messages are essentially function calls to the window procedure of the window
receiving the message. A very simple window procedure is shown below.
MRESULT MyWindowProc(hwnd,msg,mp1,mp2)
HWND hwnd;
USHORT msg;
MPARAM mp1;
MPARAM mp2;
{
HPS hps;
RECTL rect;
switch (msg){
case WM_PAINT:
hps = WinBeginPaint(hwnd,NULL,&rect);
WinFillRect(hps,&rect,CLR_WHITE);
WinEndPaint(hps);
return (MRESULT)0L;
default:
break;
}
return WinDefWindowProc(hwnd,msg,mp1,mp2);
}
The window procedure is normally a long switch statement that decodes the
message and responds appropriately. A key feature is that the window procedure calls
WinDefWindowProc, for all messages that it does not handle it. WinDefWindowProc is