Dec 142017
 
Windows Message Debugger.
File MESDEB.ZIP from The Programmer’s Corner in
Category Windows 3.X Files
Windows Message Debugger.
File Name File Size Zip Size Zip Type
EXAMPLE.MSG 1638 361 deflated
HELLO 398 223 deflated
HELLO.C 5447 1796 deflated
HELLO.EXE 6240 2786 deflated
MESDEBUG 386 135 deflated
MESDEBUG.C 910 437 deflated
MESDEBUG.DOC 12306 4495 deflated
MESDEBUG.OBJ 573 449 deflated
MESDECOD.C 29251 2935 deflated
MESDECOD.EXE 18004 8792 deflated
MESFAST.C 849 448 deflated
MESFAST.EXE 9304 5412 deflated
MESHYPER.C 1349 532 deflated
MESHYPER.OBJ 691 509 deflated

Download File MESDEB.ZIP Here

Contents of the MESDEBUG.DOC file



MESDEBUG -- Free MESssage DEBUGer utility application for Microsoft Windows
written by Bernard de Champlain for "Les Consultants Gnicom inc."

MesDebug is a group of small utilities that permits you to grab messages
processed by your code, thereby permitting you to see what messages the program
processed during the execution. This information can be used in a multitude of
ways, for example you can determine what was the last message that a procedure
processed before a crash, you could examine why a certain message sequence is
not beeing received as expected (or in the expected order) or you could use the
information to better your understanding of the Windows message environment
(you'd be surprised at the number of messages that pass thru you program if you
have'nt looked at it yet !). What these programs do is'nt in any way a
substitute for what Symdeb does and visa-versa, certain bugs are better
resolved with these programs and others are easyer to resolve with Symdeb. But
before I had my second monitor, all I had to debug were my routines, and I was
able to create and maintain a Windows program of over 7000 lines of code with
it. For use with SDK 1.0x (compiled under SDK 1.04).

Before explaining the usage of these routines, I'd like to introduce a
usefull analogy: These routines are to Windows programs what flight recorders
are to planes, and in the same way there are two parts to the procedure first
the recording (done with MesDebug or MesHyper), then the decoding of the
information (done with MesDecod or MesFast).

First you'll need to slightly modify your code to conect the recorder.
The recorders (MesDebug and MesHyper) are composed of four routines:

BOOL OpenDebug(Path)
char *Path;

Used to open the recorder file, Path is the name of the recording file
(with full pathname if necessary). This routine should be called at the
beginning of your program. Returns non zero if sucessfull, zero otherwise. If
the file allready exists it will be overwritten. The recorder file can be on a
Ram Disk, but if the program crashes and you need to reset you'll lose it...

void DebugMsg(msg)
MSG msg;

Used to record msg in the recorder file. This routine could be connected to
the main message loop in WinMain, thereby trapping all messages processed by
your routines except those in dialog boxes called by DialogBox (DialogBox sets
up its own message loop to interrupt your other window procedures) and all
messages processed outside of the main message loop (as when using functions
like CreateWindow(), ShowWindow(), UpdateWindow(), SendMessage() and others).

void DebugMessage(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;

Used to record hWnd, message, wParam and lParam in a MSG format in the
recorder file. This routine could be connected to your dialog box procedures to
permit you to record messages processed in them when called by DialogBox, or it
could be used when you only wish to trap messages processed by certain
procedures (in this case don't include DebugMsg() in the main message loop), or
you could use it if you wish to trap all messages in a procedure (including
those that do not pass thru the main message loop, see DebugMsg()).

void CloseDebug()

Used to close the recorder file. This routine should be called at the
end of your program.

examples:

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
MSG msg;
HWND hWnd;
HMENU hMenu;

OpenDebug("Example.msg"); /* Open recorder file (Example.msg) */
.
.
.
/* Polling messages from event queue */
while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
TranslateMessage((LPMSG)&msg);
DebugMsg(msg);/* Record msg, could be placed before TranslateMessage */
/* if you would want to record untranslated messages. */
DispatchMessage((LPMSG)&msg);
}

CloseDebug(); /* Close recorder file */
return((int)msg.wParam);
}

/* Window Procedure. */
long FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
DebugMessage(hWnd, message, wParam, lParam); /* Record message */

switch (message)
{
.
.
.
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return(0L);
}

/* Dialog box Procedure. */
BOOL FAR PASCAL DlgWndProc(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
DebugMessage(hDlg, message, wParam, lParam); /* Record message */
.
.
.
return(FALSE);
}

If you want to trap all messages you should use DebugMessage() in all the
window (or dialog) procedures (in this case don't include DebugMsg() in the
main message loop, or you'll record certain messages in double). But usually
you could only use DebugMessage() in the procedures you wish to trap (you could
also put the DebugMessage() calls within your switch statment to trap certain
types of messages only), thereby eliminating message recording for messages
that do not interest you. After connecting the recorder to your source code
(usually adding 3 or 4 lines of code), you should link your program to the
object code MesDebug.obj or MesHyper.obj. MesDebug should be used in a program
that will terminate normally (or at least execute the CloseDebug()) and
MesHyper should be used in a program that will crash (MesHyper opens and closes
the recorder file each time it is writen to, and because of this it slows down
your program quite a lot, also in MesHyper the routine CloseDebug() is a dummy
routine used only to preserve interchangeability with MesDebug). Once all this
is finished you run your program in Windows and create the conditions of the
bug (if thats what you want to analyse), then end your program (if you can) or
reset the system. There is an example of the use of MesDebug supplied, HELLO.C
contains the modified source code, of the HELLO sample program (4 lines added),
to trap all messages and HELLO contains the modified link4 statment to link the
program to MesDebug.obj (all other HELLO files remain unchanged). The example
will create the message recorder file "Example.msg" on the default drive/path.

The next part is to analyse the recorder file using either MesDecod or
MesFast. MesDecode provides a 'decoded' view of the messages in a format that
depends on the messages and MesFast simply prints out the values of hWnd,
message, wParam and lParam. Both these programs are DOS level programs. To
execute these programs simply type the program name at the dos prompt followed
by the recorder file name (with full pathname if necessary). There is an
example recorder file supplied named "Example.msg", this is a recording of all
messages processed by the modified HELLO.EXE during a very short session
( Start, About... (with mouse), Ok (with mouse) and Close (with double click)).

examples:

C:\>MESDECODE EXAMPLE.MSG
hWnd=4208, WM_NCCREATE, hCreateWnd=0
hWnd=4208, WM_CREATE
hWnd=4208, WM_NCACTIVATE, Activated
hWnd=4208, WM_ACTIVATE, Enabled, Opened, Alt hWnd=3300
hWnd=4208, WM_SETFOCUS, Old hWnd=0
hWnd=4208, WM_SHOWWINDOW, Shown, Show Window Call
hWnd=4208, WM_NCCALCSIZE
hWnd=4208, WM_NCPAINT
hWnd=4208, WM_GETTEXT, nBytes=80
hWnd=4208, WM_ERASEBKGND
hWnd=4208, WM_MOVE, x=0, y=16
hWnd=4208, WM_SIZE, SIZENORMAL, Width=640, Height=299
hWnd=4208, WM_PAINT
hWnd=4208, WM_NCHITTEST, x=0, y=0
hWnd=4208, WM_NCHITTEST, x=0, y=0
hWnd=4208, WM_NCMOUSEMOVE, x=0, y=0, HTSYSMENU
hWnd=4208, WM_NCHITTEST, x=0, y=0
hWnd=4208, WM_NCLBUTTONDOWN, x=0, y=0, HTSYSMENU
hWnd=4208, WM_SYSCOMMAND, SC_MOUSEMENU, x=0, y=0
hWnd=4208, WM_INITMENU, hMenu=1982
hWnd=4208, WM_INITMENUPOPUP, hMenu=1986, Menu Index=0, System
hWnd=4208, WM_NCHITTEST, x=0, y=0
hWnd=4208, WM_NCMOUSEMOVE, x=0, y=0, HTSYSMENU
hWnd=4208, WM_NCHITTEST, x=0, y=0
hWnd=4208, WM_NCHITTEST, x=0, y=0
hWnd=4208, WM_NCLBUTTONDBLCLK, x=0, y=0, HTSYSMENU
hWnd=4208, WM_SYSCOMMAND, SC_CLOSE, x=0, y=0
hWnd=4208, WM_CLOSE
hWnd=4208, WM_NCACTIVATE, Inactivated
hWnd=4208, WM_GETTEXT, nBytes=80
hWnd=4208, WM_ACTIVATE, Disabled, Iconic, Alt hWnd=3300
hWnd=4208, WM_KILLFOCUS, New hWnd=0
hWnd=4208, WM_ACTIVATEAPP, Disabled, hTask=15233
hWnd=4208, WM_SHOWWINDOW, Hidden, Show Window Call
hWnd=4208, WM_DESTROY
hWnd=4208, WM_NCDESTROY
Conversion Finished

C:\>MESFAST EXAMPLE.MSG
hWnd=4208, message=0x81, wParam=0x0, lParam=0x446710b4
hWnd=4208, message=0x1, wParam=0x0, lParam=0x446710b4
hWnd=4208, message=0x86, wParam=0x1, lParam=0xce4
hWnd=4208, message=0x6, wParam=0x1, lParam=0xce4
hWnd=4208, message=0x7, wParam=0x0, lParam=0x0
hWnd=4208, message=0x18, wParam=0x1, lParam=0x0
.
.
.
hWnd=4208, message=0x6, wParam=0x0, lParam=0x200ce4
hWnd=4208, message=0x8, wParam=0x0, lParam=0x0
hWnd=4208, message=0x1c, wParam=0x0, lParam=0x3b81
hWnd=4208, message=0x18, wParam=0x0, lParam=0x0
hWnd=4208, message=0x2, wParam=0x0, lParam=0x0
hWnd=4208, message=0x82, wParam=0x0, lParam=0x0
Conversion Finished

I suggest that you read the sections of the manual concerning messages to
fully understand the meaning of the messages. Also remember that certain
messages offer peculiar caracteristics like WM_PAINT (that is always at the end
of the message queue and that only comes out when there is nothing else in the
queue), Mouse messages (that are uppdated while in the queue) and others...
You could use DebugMessage() calls with certain fixed values as position
markers within the message recorder file.

Beacause of the nature of these routines (MesDebug & MesHyper) we cannot
be held responsible for anything that could happen during their use, they have
been created as small as possible so they wouldn't interfere with the program
and also to minimise the chances of the program overwriting parts of them
before calling them (which could be bad). I also want to point out that the
MesDebug routines keep the recorder file open between calls and does not use
the reopen convention suggested by MicroSoft (thereby using up one FCB, meaning
that the maximum number of files open is reduced by one as long as the
CloseDebug() call is not executed (or Reset!), also if the recorder file is on
a diskette you should NOT change the diskette before the end of the program).
These routines should not be used in multiple instances of a program or more
than one instance will access the same recorder file. On a lighter note I'd
like to say that none of these programs has ever created any problems on my
hard disk (I write my recorder file on my hard disk for speed) even when used
with programs that crashed (and burned).

These programs were writen while developping a much larger program for
"Les Consultants Gnicom inc." as a utility for debugging Windows programs (at
the time I did'nt have a second monitor for Symdeb), since most of the time all
I needed to know was where the programmed crashed or what message sequence
the code processed, I thought a message grabber was adequate (and it was).
These programs may be freely distributed as long as this notice remains. For
private, noncommercial use only, NOT FOR RESALE. If anyones wants to modify
these programs, please make the new (and improved) versions available to
everyone by uploading to Compuserve and keep me posted...

Les Consultants Gnicom inc.
CAN: 3431 Drummond, S.100, Montral, QC, H3G 1X6, Tel: (514)-844-1031
or (514)-844-1032
USA: 55 Prentiss Street, Watertown, MA, 02172, Tel: (617)-239-8242

[76246,353] on Compuserve for Les Consultants Gnicom or me.

Bernard de Champlain


 December 14, 2017  Add comments

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)