Path: utzoo!utgpu!watmath!att!tut.cis.ohio-state.edu!brutus.cs.uiuc.edu!apple!rutgers!bellcore!wind!sdh
From: sdh@wind.bellcore.com (Stephen D Hawley)
Newsgroups: comp.sys.mac.programmer
Subject: Re: Can anyone answer these Questions?
Message-ID: <17406@bellcore.bellcore.com>
Date: 15 Aug 89 14:54:47 GMT
References: <840@eutrc3.urc.tue.nl>
Sender: news@bellcore.bellcore.com
Reply-To: sdh@wind.UUCP (Stephen D Hawley)
Organization: Bellcore, Morristown, NJ
Lines: 132

In article <840@eutrc3.urc.tue.nl> rcbaem@eutrc3.urc.tue.nl (Ernst Mulder) writes:
Welcome to Mac programming.  I'll try to field these for you.

>1) [Is there a 3K limit to CopyBits?]

Yes, and no.  If you are running on an old mac, there is.  If not, then
there isn't.  If you don't care about old machines, do 1 CopyBits() call.
Otherwise, break up the call into several pieces.

>2) [How do I shrink selection rects?  Is there a high level sol'n?]

Yes.  There is a high level solution:
void
ShrinkWrap(map, r)
BitMap *map;
Rect *r;
{
	/* let r be the current selection rect 
	 * map is the bitmap in question (assuming bilevel)
	 */
	while(NoPixelsInColumn(map, r->left, r->top, r->bottom)) ++r->left;
	while(NoPixelsInColumn(map, r->right, r->top, r->bottom)) --r->right;
	if (r->right > r->left) NastyErrorMessage();
	while(NoPixelsInRow(map, r->top, r->left, r->right)) ++r->top;
	while(NoPixelsInRow(map, r->bottom, r->left, r->right)) --r->bottom;
	if (r->top > r->bottom) NastyErrorMessage();
}

NoPixelsInColumn(map, col, from, to)
BitMap *map;
register short col, from, to;
{
	while(from <= to) {
		if (PixelOn(map, col, from++)) return(0);
	}
	return(1);
}

NoPixelsInRow(map, row, from, to)
BitMap *map;
register short row, from, to;
{
	while(from <= to) {
		if (PixelOn(map, from++, row)) return(0);
	}
	return(1);
}

Writing PixelOn() is left as a task for the astute reader.  Obviously,
this can be done more efficiently, but you should understand what its doing.

>3) What is the best way to update the default button's outline in a
>   dialogbox? (For when a screensaver or so makes it disappear)

Create an item in your dialog box that is a UserItem.  Make the proc for
it draw the outline.  This will get hit by update events.

>4) When the user selects About... I put a dialog on the screen (GetNewDialog)
>   and DisposDialog it after the user clicked the mouse. I remove the 
>   mousedown event from the eventqueue. After the dialog is disposed of
>   my current front window gets a deactivate and an activate events, and
>   even though it's not disasterous, it still doesn't look nice.

If it happens consistently, remove the events from the event queue.  This
isn't a nice thing to do, and may break in future releases of the machine,
but it should work just fine.


>5) [Should I worry about leaving files open]

Leave them open while your program is running.  Otherwise, there is no
good way for any other program to know that they are in use.  By opening
a file, you are making the operating system put a lock on the file so that
you can avoid a critical section problem (and trust me, you want to avoid
them).  If you do not intend to modify the file in any way, go ahead and
close it and forget about it.  If you intend to work with it, leave it open,
but just make sure you close it before you exit.


>6) I use Str2Num (SANE) to read a number typed in a TEItem in a Dialog
>   box. How can I detect the number is valid? (jshgjs) is detected
>   not being a number my SANE, returning a NaN code. (12.23.1) however
>   returns (12.23) and isn't detected as being wrong... Solution?

I would advise writing the code yourself.  There are 2 attitudes, you can
either prevent the wrong characters from ever getting to the dialog box
(which is a royal pain [I know, I just had to do it] and I wouldn't wish
that fate on anyone who hasn't already done it), or you can do the checking
post hoc.

You can do a quick scan through the list to see that everything is hunky
dorey:

char numbers[] = "0123456789-+";

#define OK_NUM(numstr) HunkyDorey(numstr, numbers);

HunkyDorey(ps, vset)
register unsigned char *ps;
register char *vset;
{
	/*
	 * ps is a pascal string.
	 * vset is a c string of chars valid for the language.
	 */
	register short i;

	for (i = *ps++; i > 0; i--, ps++) {
		if (!CInStr(*ps, vset)) return(0);
	}
	return(1);
}

CInStr(c, s)
register char c, *s;
{
	while(c != *s) s++;
	return(c == *s);
}

Again, this could be written more efficiently, but I chose not to do so for
clarity.

Thr ROMs give you quite a powerful set of programming tools, but you shouldn't
feel tied down to them if they don't give you quite what you want.

Good luck.

Steve Hawley
sdh@flash.bellcore.com
"Up is where you hang your hat."
	--Jim Blandy, computer scientist