🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.windows.ms.programmer
Article #1994

Re: Re^2: Actor specific questions

#1994
From: Dave Wells
Date: Wed, 03 Apr 1991 09:02
86 lines
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!adw
References: <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