[comp.sys.mac.programmer] Getting usrItem to draw itself during ModalDialog

ra_robert@gsbacd.uchicago.edu (04/03/89)

I'm having a problem getting a usrItem in a dialog to be drawn.  Specifically,
I want to draw a bar graph which gets filled in (like the one you see now when
you copy files from one disk to another in the Finder).  To summarize, I
generate (or try to generate) an update event from my modalDialog's filter by
invaling my usrItem's rect, hoping this will force ModalDialog to handle the
update event, and call my usrItem's draw proc, getting the thing redrawn. 

So this would be my modal Dialog filter:

function theFilt (theDialogPtr: DialogPtr; var theEvent: EventRecord; var
itemHit: integer): BOOLEAN;

  var
   itemBox: rect;
   itemHandle: handle;
   itemType: integer;
   refcon: longint;
   theString: Str255;

 begin

theFilt := FALSE;
refcon := GetWRefCon(theDialogPtr);
GetDItem(theDialogPtr, DialogTwo_BarGraphItem, itemType, itemHandle, itemBox);
{get box containing barGraph}
InvalRect(itemBox);				{inval our barGraph's box,
forcing it to be redrawn}
SetWRefCon(theDialogPtr, refcon + 1);
 end;
 
This doesn't work; updateEvents don't seem to be generated, and the usrItem
doesn't get redrawn.  Why wouldn't this work?  I know I could call my usrItem's
draw proc from within my filter, but I thought this should work too.

Everything else is set up fine (setting ports, passing correct params).

Any info -- emailed or posted -- much appreciated.

Thanks,
 
Robert
------
ra_robert@gsbacd.uchicago.edu
------
generic disclaimer: all my opinions are mine

brecher@well.UUCP (Steve Brecher) (04/05/89)

In article <2580@tank.uchicago.edu>, ra_robert@gsbacd.uchicago.edu writes:

> I'm having a problem getting a usrItem in a dialog to be drawn.  ...  To
> summarize, I generate (or try to generate) an update event from my
> modalDialog's filter by invaling my usrItem's rect...

InvalRect operates on the current grafPort.  There is no assurance that
your dialogUs port is current when your filter is called.  Use SetPort
before calling InvalRect.
-- 

brecher@well.UUCP (Steve Brecher)

tim@hoptoad.uucp (Tim Maroney) (04/07/89)

In article <2580@tank.uchicago.edu>, ra_robert@gsbacd.uchicago.edu writes:
> I'm having a problem getting a usrItem in a dialog to be drawn.  ...  To
> summarize, I generate (or try to generate) an update event from my
> modalDialog's filter by invaling my usrItem's rect...

In article <11235@well.UUCP> brecher@well.UUCP (Steve Brecher) writes:
>InvalRect operates on the current grafPort.  There is no assurance that
>your dialogUs port is current when your filter is called.  Use SetPort
>before calling InvalRect.

True as far as it goes, but there shouldn't even be a need to call
InvalRect.  I've used userItems for years and there's never been any
reason to call InvalRect on the item rectangle, except when the
contents have changed and need to be redrawn (and usually not then; you
can just do a direct redraw, or let utility software like the List
Manager do the direct redrawing).  Your dialog comes up with its whole
portRect invalidated; any user item procedure you have defined BEFORE
the dialog comes up (and bound to user items) will be called
automagically.

I think Robert's real problem is more likely to be that the user item
drawing procedure isn't getting bound to the item before the Dialog
Manager fields the first update event.  Maybe it's not getting bound at
all, or maybe he's binding it at a strange place (like right after
calling DrawDialog).  In my opinion, the proper way to do this is
generally to: GetNewDialog with dialog invisible, call
GetDItem/SetDItem to bind the procedure, call ShowWindow on the dialog,
and the handle the dialog normally (in Robert's case, with a call to
ModalDialog).  There is no need to muck about with filter procedures
with user items, though they are often useful with keyboard events and
sometimes with mouse events.

There is also the possibility that he has bound everything correctly,
but the userItem drawing procedure is incorrect, and so it seems not to
be called even though it is.  This should be easy enough to trap with a
debugger if so.
-- 
Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim
"This signature is not to be quoted." -- Erland Sommarskog

ra_robert@gsbacd.uchicago.edu (04/07/89)

In article <6899@hoptoad.uucp>, tim@hoptoad.uucp (Tim Maroney) writes...
 
>In article <11235@well.UUCP> brecher@well.UUCP (Steve Brecher) writes:
>>InvalRect operates on the current grafPort.  There is no assurance that
>>your dialogUs port is current when your filter is called.  Use SetPort
>>before calling InvalRect.
> 
>True as far as it goes, but there shouldn't even be a need to call
>InvalRect.  I've used userItems for years and there's never been any
>reason to call InvalRect on the item rectangle, except when the
>contents have changed and need to be redrawn


It turns out that Steve was right:  I merely assumed that my FilterProc would
operate on the Modal Dialog, when in fact I needed to SetPort.  Rather
embarrassing, but I guess that's how you learn, right? I shall do 1000 CopyBits
as penance. :-> 

Actually, I was (am) trying to get a usrItem to be redrawn often: sort of a bar
graph, like the one for disk copying in the Finder.  I see now that I can just
call the drawProc directly in my ModalDialog's filter proc.  Likewise, once the
port is set right for the inval, invalRect works fine too.

Thanks to all who helped!  Much appreciated!

Robert
------
ra_robert@gsbacd.uchicago.edu 
------
generic disclaimer: all my opinions are
mine