adams.e@oxy.edu (Erik Adams) (06/28/89)
Howdy! I'm not new to programming, but I am new to programming the Macintosh. I am having a couple of problems that look like they have very simple solutions, but I just can't see them. 1.) If I move an application window on top of a system window (the control panel, for example), and then move it away, the system window is _not_ updated. Where the application window was is now a white outline in the system window. This seems to occur with all desk accessories. Currently I am not handling updateEvents for any windows, but when I tried putting in BeginUpdate and EndUpdate, the problem was still there. Any ideas? 2.) I can not get a scroll bar in a modal dialog to work. Here is what I am currently doing: I pass to ModalDialog a pointer to a FilterProcedure. The Filterprocedure checks to see where theEvent is. If theEvent is in the scroll bar, I call TrackControl, passing it an ActionProcedure. I get, at various times with various combinations: nothing at all; a scroll bar that highlights correctly but does not change its value; a scroll bar that both hightlights and moves, but only when you mouseDown about 16 pixels to the left; and more system crashes of varying sorts than I care to enumerate. The problem seem to be with my figuring out whether or not theEvent is in the scroll bar, but there appears to be more than just that. I am using LSC 2.01 on a Mac 512ke, using older (pre-6.0) versions of the Finder and System. (Yes I know there are newer versions of LSC, but I can not compile when I use them: everytime I try I get "Out of Memory" messages from LSC). If enough folk want, I will post my source code. I didn't this time because, as I indicated, these look to me like stupid mistakes which someone has probably run into before and will know how to fix. Thank you in advance. Erik Adams adams.e@oxy.edu
tim@hoptoad.uucp (Tim Maroney) (07/01/89)
In article <42687@tiger.oxy.edu> adams.e@oxy.edu (Erik Adams) writes: > 1.) If I move an application window on top of a system >window (the control panel, for example), and then move it away, >the system window is _not_ updated. Where the application window >was is now a white outline in the system window. The only thing I can think of is that you're calling GetOSEvent rather than GetNextEvent or WaitNextEvent. If you call GetNextEvent or WaitNextEvent, SystemEvent is called by the OS to handle (among other things) update events for desk accessory windows. Don't use GetOSEvent, as it is incompatible with MultiFinder. If you *are* using GetNextEvent, I admit bafflement. > 2.) I can not get a scroll bar in a modal dialog to work. >Here is what I am currently doing: I pass to ModalDialog a >pointer to a FilterProcedure. The Filterprocedure checks to see >where theEvent is. If theEvent is in the scroll bar, I call >TrackControl, passing it an ActionProcedure. I get, at various >times with various combinations: nothing at all; a scroll bar >that highlights correctly but does not change its value; a scroll >bar that both hightlights and moves, but only when you mouseDown >about 16 pixels to the left; and more system crashes of varying >sorts than I care to enumerate. The problem seem to be with >my figuring out whether or not theEvent is in the scroll bar, >but there appears to be more than just that. This is a pretty advanced task for a beginning Mac programmer. I think there are probably a few problems. First, the scroll bar should be completely enclosed by a userItem, or declared as a CNTL item. If you don't do this, then you will have updating problems. Second, make sure you understand the difference between local and global coordinates. When you get an event, the where field will be in global coordinates. You need to convert to local coordinates before determining where it falls in your dialog. To do this, you need to be sure the current port is the dialog window, then call GlobalToLocal. Third, it is generally better *not* to do this directly; instead, pass the point to FindWindow and then to FindControl. This should take care of determining whether the mouse click is in the control or not, and if so, in which part. Fourth, you may be having clipping problems; it shouldn't hurt to do a "ClipRect(&dialog->portRect);" before doing anything with the scroll bars. Fifth, it is generally better to have a bunch of different action procedures, one for each part. Here's a tracking routine I use a lot. Obviously, you don't have all the context for this, and this controls both vertical and horizontal scroll bars, but it ought to give you the idea. Note that FindWindow and FindControl have already been called, and the "where" parameter is in local coordinates. void ScrollClick(window, extra, ch, where, part) WindowPtr window; WindowExtra **extra; ControlHandle ch; Point where; short part; { ControlHandle new; ClipRect(&window->portRect); switch (part) { case inUpButton: if (ch == (*extra)->vScroll) TrackControl(ch, where, ScrollVUp); else TrackControl(ch, where, ScrollHUp); break; case inDownButton: if (ch == (*extra)->vScroll) TrackControl(ch, where, ScrollVDown); else TrackControl(ch, where, ScrollHDown); break; case inPageUp: do { if (ch == (*extra)->vScroll) ScrollVPgUp(ch, part); else ScrollHPgUp(ch, part); GetMouse(&where); } while (StillDown() && FindControl(where, window, &new) == part && ch == new); break; case inPageDown: do { if (ch == (*extra)->vScroll) ScrollVPgDn(ch, part); else ScrollHPgDn(ch, part); GetMouse(&where); } while (StillDown() && FindControl(where, window, &new) == part && ch == new); break; case inThumb: if (TrackControl(ch, where, 0)) ScrollThumb(window, ch); break; } } > I am using LSC 2.01 on a Mac 512ke, using older (pre-6.0) >versions of the Finder and System. Get more memory. The Dove upgrades are excellent -- reliable, easy to install, and cheap. A develoment system needs at least one megabyte and preferably at least 2.5 Megs. You also need to use the latest System and Finder and the latest development system. You're dancing with the devil in the pale moonlight if you don't. Hoep this helps! -- Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com Postal: 424 Tehama, SF CA 94103; Phone: (415) 495-2934 "The Diabolonian position is new to the London playgoer of today, but not to lovers of serious literature. From Prometheus to the Wagnerian Siegfried, some enemy of the gods, unterrified champion of those oppressed by them, has always towered among the heroes of the loftiest poetry." - Shaw, "On Diabolonian Ethics"
oster@dewey.soe.berkeley.edu (David Phillip Oster) (07/01/89)
In article <42687@tiger.oxy.edu> adams.e@oxy.edu (Erik Adams) writes: > 1.) If I move an application window on top of a system >window (the control panel, for example), and then move it away, >the system window is _not_ updated. You mousedown handleer should look like this: /* GoMouseDown - dispatch on the mousedown */ private void GoMouseDown(theEvent)EventRecord *theEvent;{ WindowPtr whichWindow; Integer i; i = FindWindow(theEvent->where, &whichWindow); switch(i){ case inMenuBar: GoMenuBar(theEvent); break; case inGoAway: GoAway(theEvent, whichWindow); break; case inGrow: GoGrow(theEvent, whichWindow); break; case inContent: GoContent(theEvent, whichWindow); break; case inSysWindow: SystemClick(theEvent, whichWindow); break; case inDrag: GoDrag(theEvent, whichWindow); break; case inZoomOut: case inZoomIn: GoZoom(theEvent, whichWindow, i); break; } } It is clear that you forgot the "inSysWindow" case. > 2.) I can not get a scroll bar in a modal dialog to work. >Here is what I am currently doing: I pass to ModalDialog a >pointer to a FilterProcedure. The Filterprocedure checks to see >where theEvent is. If theEvent is in the scroll bar, I call >TrackControl, passing it an ActionProcedure. you are basically doing the right thing. The biggest thing you are forgetting is that the filter procedure sees the mouse in global coordinates. Here is how I handle this. (Note: this is a fragment. I stick a pointer to an array of procedure pointers in the refCon of the control, to do the actual work of the scroll bar. All procs but the thumb proc are responsible for doing a SetCtlValue() to set the control to a new value.) /* ModifyFilter - the dialog event filter */ private pascal Boolean ModifyFilter(dp, event, itemp) DialogPtr dp;EventRecord *event;Integer *itemp;{ GrafPtr savePort; Point where; GetPort(&savePort); SetPort(dp); if(event->what == mouseDown){ where = event->where; GlobalToLocal(&where); if(PtInRect(where, &(**GetCIHandle(SLIDER)).contrlRect) && TrackScroll(where)){ event->what = nullEvent; } } SetPort(savePort); return FALSE; } /* ControlProc - return the appropriate Pascal procedure */ ProcPtr ControlProc(theControl, part)ControlHandle theControl;Integer part;{ Integer i; ProcPtr *p; switch(part){ case inUpButton: i = UPPROC; break; case inDownButton: i = DOWNPROC; break; case inPageUp: i = PAGEUPPROC; break; case inPageDown: i = PAGEDOWNPROC; break; case inThumb: i = THUMBPROC; break; } if(NIL == (p = (ProcPtr *) GetCRefCon(theControl))){ return NIL; } return (ProcPtr) p[i]; } /* TrackScroll - track a scroll bar. takes a pointer to a vector of * procedures in the refcon of the scroll bar, and calls the appropriate * one repeatedly, as appropriate. */ Boolean TrackScroll(where)Point where;{ ControlHandle theControl; Integer part, oldVal; ProcPtr ControlProc(); SubrPtr *p; if(0 != (part = FindControl(where, thePort, &theControl)) ){ if(inThumb == part){ oldVal = GetCtlValue(theControl); p = (SubrPtr *) GetCRefCon(theControl); (*p[THUMBINITPROC])(theControl); } if(inThumb == TrackControl(theControl, where, ControlProc(theControl, part))){ p = (SubrPtr *) GetCRefCon(theControl); (*p[THUMBDONEPROC])(theControl, oldVal); } return TRUE; }else return FALSE; } --- David Phillip Oster --When you asked me to live in sin with you Arpa: oster@dewey.soe.berkeley.edu --I didn't know you meant sloth. Uucp: {uwvax,decvax}!ucbvax!oster%dewey.soe.berkeley.edu
tim@hoptoad.uucp (Tim Maroney) (07/04/89)
In article <42687@tiger.oxy.edu> adams.e@oxy.edu (Erik Adams) writes: > 1.) If I move an application window on top of a system >window (the control panel, for example), and then move it away, >the system window is _not_ updated. In article <29911@ucbvax.BERKELEY.EDU> oster@dewey.soe.berkeley.edu.UUCP (David Phillip Oster) writes: >It is clear that you forgot the "inSysWindow" case. Uh, David, how could leaving a clause out of mouse down event handling have anything to do with update events? SystemClick definitely is not in charge of system updates.... My idea was that he was using GetOSEvent, which wouldn't call SystemEvent. However, another possibility I realized later was that he might be passing an invalid event mask, one without the updateMask bit set. This is similar to the error you pointed out recently in that flawed security scheme. A beginner could easily mistake the event type codes for the event mask bit values. This would not only prevent the application from receiving update events, it would prevents them being passed to SystemEvent from inside GetNextEvent. -- Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com Postal: 424 Tehama, SF CA 94103; Phone: (415) 495-2934 "Do what you wanna, do what you will; Just don't mess up your neighbor's thrill. And when you pay the bill, kindly leave a little tip To help the next poor sucker on his one-way trip." - Frank Zappa, "You Are What You Is"