[comp.sys.mac.programmer] _ModalDialog calls only one filterProc?

mahboud@kinetics.com (Mahboud Zabetian) (07/13/90)

Hi all.

In an application I am writing, I am having some problems with
my ModalDialogs and filterProcs.  I have a feeling that _ModalDlog
is brain damaged.  Please prove me wrong.

Here's the problem:

The program puts up a dialog box (DLOG1).  This dialog box is
handled using _ModalDialog with a filterProc (Filter1).  If a
certain button is pressed, a second dialog box is opened (DLOG2).
This dialog box is also handled using _ModalDialog with a
filterProc (Filter2).

Under certain circumstances, DLOG2 will put up an alert.  When
that alert is dismissed by the user, one would expect both
filterProcs to be called to update their respective windows.
What *does* happen is that Filter2 will get called twice instead!
(The second time, theEvent->message contains a pointer to DLOG1!)
Then when DLOG2 is dismissed, then Filter1 gets called to update 
DLOG1.

It seems that ModalDialog is only handling one filterProc at a time.

See the following source (with minor deletions).

How does one get around this?  Don't tell me not to do this sort of
thing, just 'cause Tech Note #203 says everyone should use the
Window Mgr, rather than the Dialog Mgr.  The Dlg Mgr is there,
and I don't mind it being a little slow if you abuse it, as long
as it functions the way it is supposed to.  Also, I have tried 
making the user items have their own update procedures, but I 
would really rather do it this way if possible.

By the way, in the Finder, the Print menu items both can create
the same situation(i.e. two modal dlogs on top of each other),
but I the second dialogs were made bigger than the first so I
can't tell if they have the same problem.


Thank you....

-mahboud

void
FirstDlog()
{
	DialogPtr	dlog1;
	Str255		string;
	short		itemHit;
	Point		clickPt;

	dlog1 = GetNewDialog(128, nil, -1);
	if (dlog1) {
		SetPort(dlog1);
		do {
			
			ModalDialog(Filter1, &itemHit);
			if (itemHit == 3) {
				SecondDlog();
				SetPort(dlog1);
			}
		} while ((itemHit != ok) && (itemHit != cancel));
		if (itemHit == ok) {
		}
		DisposDialog(dlog1);
	}
}
void
SecondDlog()
{
	DialogPtr	dlog2;
	Str255		string;
	short		itemHit;
	Point		clickPt;

	dlog2 = GetNewDialog(129, nil, -1);
	if (dlog2) {
		SetPort(dlog2);
		do {
			
			ModalDialog(Filter2, &itemHit);
			if (itemHit == 4) {
				Alert(130, nil);
				SetPort(dlog2);
			}
		} while ((itemHit != ok) && (itemHit != cancel));
		if (itemHit == ok) {
		}
		DisposDialog(dlog2);
	}
}
pascal Boolean
Filter1(		DialogPtr		dlog,
				EventRecord		*theEvent,
				short			*itemHit	)
{
	char		key 		= theEvent->message & charCodeMask;
	PenState	penState;
	Boolean		retValue = false;
	long		temp;
	
	*itemHit = 0;
	switch (theEvent->what) {
	case	keyDown:
		break;
	case	updateEvt:
		DebugStr("\pThis is Filter1");
		DebugNum(theEvent->message);
		DebugNum(dlog);
		if (dlog == (DialogPtr) theEvent->message) {
			GetPenState(&penState);
			PenSize(3, 3);
			PenPat(black);
			FrameDItem(dlog, ok, -4, true);
			PaintDItem(dlog, 3);
			SetPenState(&penState);
			retValue = false;
		}
		else {
			retValue = false;
		}
		break;
	default:
		retValue = false;
	}
	return retValue;

}
pascal Boolean
Filter2(		DialogPtr		dlog,
				EventRecord		*theEvent,
				short			*itemHit	)
{
	char		key 		= theEvent->message & charCodeMask;
	PenState	penState;
	Boolean		retValue = false;
	
	*itemHit = 0;
	switch (theEvent->what) {
	case	keyDown:
		break;
	case	updateEvt:
		DebugStr("\pThis is Filter2");
		DebugNum(theEvent->message);
		DebugNum(dlog);
		if (dlog == (DialogPtr) theEvent->message) {
			GetPenState(&penState);
			PenSize(3, 3);
			PenPat(black);
			FrameDItem(dlog, ok, -4, true);
			PaintDItem(dlog, 4);
			SetPenState(&penState);
			retValue = false;
		}
		else {
			retValue = false;
		}
		break;
	default:
		retValue = false;
	}
	return retValue;

}
Standard Disclaimer:  Don't mind me, I'm just babbling.
------------------------------------------------------------------------------
     Mahboud Zabetian	 (415) 945-7194		ag.group@applelink.apple.com
------------------------------------------------------------------------------
Woke up in my clothes again this morning, I don't know exactly where I am....
					--- Sting

dorner@pequod.cso.uiuc.edu (Steve Dorner) (07/16/90)

In article <1541@excelan.COM> ag.group@applelink.apple.com (Mahboud Zabetian) writes:
>I have a feeling that _ModalDlog
>is brain damaged.  Please prove me wrong.

Not me, pal.

>What *does* happen is that Filter2 will get called twice instead!
>(The second time, theEvent->message contains a pointer to DLOG1!)

All events get "sent to" the topmost dialog, and hence to its filter.  If
you want to handle events for other windows, you'll have to add code
to "Filter2" to handle that.

This is how things are documented to work, like it or not.

--
Steve Dorner, U of Illinois Computing Services Office
Internet: s-dorner@uiuc.edu  UUCP: {convex,uunet}!uiucuxc!dorner