Category : Files from Magazines
Archive   : PJ72.ZIP
Filename : WPMAUX.DOC

 
Output of file : WPMAUX.DOC contained in archive : PJ72.ZIP




WINAUX/PMAUX

William S. Hall
3665 Benton Street, #66
Santa Clara, CA 95051

Introduction


Winaux is a Windows program capable of displaying text sent
to it by another window. PMaux is the corresponding version for
presentation manager. Acting as a simple scrolling window, each
performs many of the operations of an auxiliary terminal. They
are particularly useful for analyzing the behavior of Windows or
PM functions and for print-statement debugging.

We begin by describing Winaux. Please read this section even
if you are planning to use PMaux.


Using Winaux

Winaux is very easy to use. When Winaux runs, it leaves a
copy of its Window handle in win.ini. Another program can then
write to Winaux by sending it a message using the call

SendMessage(hWnd, WM_USER, (WORD)len, (LONG)(LPSTR)str);

where hWnd is the window handle (which can be retrieved from
win.ini), str is a string of characters, and len is its length.
In practice, the operation is made simpler by writing a function
which will carry out the operations of retrieving the handle,
calculating the length, and sending the message. This function
can be placed into an include file and used as needed by the
target program.

When Winaux exits, it resets the value of the handle in
win.ini to 0. Hence programs which test for a valid window
handle before attempting the SendMessage call will not risk the
danger of accessing an invalid window.

Only one instance of Winaux is allowed.

The very first time Winaux runs, it will choose a default
position and size on the screen and write these parameters to
win.ini. The user can modify these values to place Winaux as
desired. A typical entry in win.ini is as follows:

[Winaux]
x=100
y=275
cx=540
cy=75
hWnd=4589

This window will be positioned at pixel location (100,275) on the
display and will be 540 pixels wide and 75 high. On an EGA, this
will place the window in the lower right corner.

If you are using Winaux to help you debug a Windows program,
then you will find it useful to experiment with the position and
size and then add Winaux to your load or run line in win.ini. As
you go repeatedly through the compile-program, run-Windows,
test-program, exit-Windows cycle, you will appreciate WINAUX more
if you do not have to bother with running and positioning its
window repeatedly.

Winaux creates a text buffer with as many lines as your
maximized display can show when using the system font.
Similarly, the number of characters per line is computed based on
the maximum width of the display and the size of the system font.

Lines are displayed at the bottom of the window and scroll
upward. The bigger the window the more lines will be visible.
Currently, there are no scroll bars, so once a line number
exceeds the maximum number of lines, it is lost.

Winaux converts newlines to a carriage-return line-feed
pair. A menu option allows you to kill this option. However,
lines are wrapped if they exceed the maximum number of horizontal
characters on a line.

To illustrate the program's application, we have included a
simple Windows template called Smltpl in which an sprintf
statement has been added at the top of the message loop. All
message parameters, and a counter, are printed to a buffer which
is sent by the function auxprt to the Winaux window. Auxprt
itself is defined in the include file auxprt.h.

long FAR PASCAL MainWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
PAINTSTRUCT ps;

/* print messages to Winaux */
sprintf(auxbuf,"hWnd = %4x message = %4x wParam = %4x lParam = %8lx\n",
hWnd, message, wParam, lParam);
auxprt(auxbuf);

........


Near the top of the program is an include statement

#include "auxprt.h"

The file auxprt.h is as follows (as far as Windows is concerned);

char auxbuf[80];
auxprt(char *str)
{
HWND hWnd;
int len = strlen(str);

#if defined(WINAUX)
hWnd = (HWND)GetProfileInt((LPSTR)"Winaux", (LPSTR)"hWnd", 0);
if (IsWindow(hWnd))
SendMessage(hWnd, WM_USER, (WORD)len, (LONG)(LPSTR)str);
#endif

.... /* code for PM */
}

Whenever a message is received, sprintf formats it and hands
it to auxbuf. The function auxbuf reads the Winaux handle,
computes the length of the string, verifies that the handle
received is valid, and sends it to Winaux.

You can watch the messages being displayed by running
Winaux, then Smltpl. The action is especially swift as the mouse
is moved over the Smltpl window. You can also run more than one
instance of the program and see the messages for each.

Although reading the handle from win.ini may seem wasteful,
it is a solid guarantee that the handle retrieved is either valid
(Winaux is running) or NULL (Winaux has exited). Also note the
use of SendMessage rather than PostMessage. Since Winaux will be
retrieving a long pointer to data, SendMessage insures that the
pointer is valid during the time that the data is being
displayed.


Using PMaux

When PMaux runs, it leaves a copy of its window handle in
os2.ini. However, it is more difficult in PM to get the buffer
from the other program over to PMaux since the data segment of
one program is not accessible to another in protected mode. In
this case it is necessary to create a global, sharable buffer in
the program calling PMaux, fill it, and pass the handle and the
buffer length over to PMaux. The following excerpt from auxprt.h
describes the method.

char auxbuf[80];
auxprt(char *str)
{
HWND hWnd;
int len = strlen(str);

... /* code for Windows */

#if defined(PMAUX)
char hbuf[40];
SEL sel;
PCH pchBuf;
int i;

/* get the string representation of the handle for pmaux from OS2.INI */
WinQueryProfileString(hAB, "PMaux", "hWnd", "", hbuf, 40);
/* convert to a handle */
hWnd = (HWND)atol(hbuf);
/* create a shared buffer which can be read by another process */
if (DosAllocSeg(len, &sel, SEG_GETTABLE) == 0) {
/* make a long pointer to the buffer */
pchBuf = MAKEP(sel,0);
/* load it up */
for (i = 0; i < len; i++)
*(pchBuf+i) = *(str+i);
/* send it over */
if (WinIsWindow(hAB, hWnd))
WinSendMsg(hWnd, WM_USER, (MPARAM)len, (MPARAM)sel);
/* free the buffer */
DosFreeSeg(sel);
}
else /* error, ring the bell */
WinAlarm(HWND_DESKTOP, WA_WARNING);
#endif

To illustrate its usage, we have included a Presentation
Manager template Spmtpl especially modified to transmit all
messages received in the message loop to PMaux. The technique is
similar to that used in the corresponding Windows program.

Most of the other features of Winaux are applicable to PMaux
except that the initial placement and size of the window cannot
be modified. This was done partly for simplicity. However, in
PM, one can run PMaux, size and place it one time, and leave it
for the duration of the OS2 session.


Remarks

If you are trying to use Winaux or PMaux with a dynamic link
library, you can still use the techniques described above for
passing the message. However, methods other than sprintf must be
used to format the string since none of the printf family can be
used when the stack segment does not coincide with the data
segment of your program.

Finally, note that both Spmtpl and Smltpl are very useful
templates which can help you in starting your own Windows or PM
program.