Article View: comp.windows.ms.programmer
Article #1994Re: Re^2: Actor specific questions
From: Dave Wells
Date: Wed, 03 Apr 1991 09:02
Date: Wed, 03 Apr 1991 09:02
86 lines
3321 bytes
3321 bytes
From: pcb@basin04.cacs.usl.edu (Peter C. Bahrs)
;And finally, for now, has anyone figured out how to modify the interpreter
;so that when an application does something stupid and the debugger
;comes up, the application will not try to process any more messages?
I wrote:
Not in general. The paint() -> debugger -> paint() -> debugger...
loop can be solved:
[details omitted]
kend@data.UUCP Ken Dickey at Microcosm, Beaverton, OR
|adw@otter.hpl.hp.com (Dave Wells) writes:
|>This seems to allow you to get into the debugger reliably. If you keep
|>hitting "OK" on the debug dialog, however, ACTOR siezes up after a few more
|>repaints - cause unknown.
|In all cases of this type I have seen, code is (recursively) grabbing new
|instances of the Windows drawing context and not giving it up. As there
|are a limited number of these (Windows resource limit), Windows dies.
You're quite right - thanks for pointing this out. Window:WM_PAINT()
provides the BeginPaint/EndPaint pair required by Windows. If paint()
traps to the debugger, closing the debug window abandons the WM_PAINT
message loop, and EndPaint never gets called. What I've done is:
o Add an instance variable "hDc" to my application's WindowClass
descendant.
o Override WM_PAINT() thus:
hDc := Call BeginPaint(hWnd, paintStruct);
/* (hDc flags "doing a WM_PAINT") */
paint(self, hDc);
cleanupPaint(self);
hDc := nil;
^0;
o Add a cleanupPaint method thus:
if hDc then Call EndPaint(hWnd, paintStruct); endif;
o Add lines to the start of SystemClass:abort() thus:
if findFunction(class(ThePort:late),#cleanupPaint)
then /* Now absolutely sure there's a method to call - we don't
want a trap from here! */
cleanupPaint(ThePort:late);
endif;
I'd be interested in any substantially simpler fix.
I've also improved the debugger "recursion" trap within paint():
Def paint(self, hdc | frames, myName, calledFromDebugger)
Redraws self. */
{ /* First, guard against the dreaded "debug recursion": */
if (frames := frames(Bug))
then
myName := asString(findFunction(class(self),#paint));
do (frames,{using(frame)
if subString(frame,0,size(myName)) = myName
then calledFromDebugger := true;
endif;
});
endif;
/* NOTE that although this will prevent infinite debugger invocations,
the paint structure and display context must still be deallocated.
Modify SystemClass:abort() to call self:cleanupPaint() to achieve
this. */
if calledFromDebugger
then
printLine(myName+"() called, but debugger is up.");
else
draw(self);
endif;
}!!
This allows repaints if the debugger has been invoked by the execution of a
message other than WM_PAINT.
Dave Wells
Technical Details
Message-ID:
<72170008@otter.hpl.hp.com>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!sdd.hp.com!hplabs!otter.hpl.hp.com!otter!adwReferences:
<466@data.UUCP>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!sdd.hp.com!hplabs!otter.hpl.hp.com!otter!adw From: adw@otter.hpl.hp.com (Dave Wells) Newsgroups: comp.windows.ms.programmer Subject: Re: Re^2: Actor specific questions Message-ID: <72170008@otter.hpl.hp.com> Date: 3 Apr 91 09:02:08 GMT References: <466@data.UUCP> Organization: Hewlett-Packard Laboratories, Bristol, UK. Lines: 86