[comp.sys.mac.programmer] Remembering window locations

time@tbomb.ice.com (Tim Endres) (01/20/91)

In article <cbaE5X_00WBN44j0tK@andrew.cmu.edu>, es1o+@andrew.cmu.edu (Eric Mitchell Snider) writes:
> I need some advice on how to save window locations (so the window will
> appear where the user left it when they run the program again...) and
> intelligently make them appear.  I have no problems with saving the
> locations of windows.  The problem I'm having is I don't know how to
> check if the window will appear on the screen.  Suppose someone with a
> big monitor drags the window way into the lower right corner.  If
> someone else with a small screen runs the program and it tries to
> display the window, they may not be able to see it...  How can I deal
> with this?  I need to be able to check if the window was saved in a
> valid location.

This is very similar to examples from Apple. Call it in good health.
tim.
----------------

DoCheckWindowRect(windRect, check_size)
Rect		*windRect;
int			check_size;	/* != 0 if you want the size reduced to fit screen. */
{
Rect		wrect, thesect, titlerect, screenrect;
GDHandle	dom_gdev, this_gdev;
long		sect_area, greatest_area;
int			bias, title_on_screen;
int			sect_flag;

	titlerect = *windRect;
	titlerect.bottom = titlerect.top;
	titlerect.top -= 20;

	wrect = *windRect;
	if (wrect.bottom == wrect.top)		/* Catch titlized windows */
		wrect.top--;
	
	if (GLOBAL_VARIABLE(theEnviron).hasColorQD) {
		
		dom_gdev = this_gdev = GetDeviceList();
		greatest_area = 0;
		title_on_screen = 0;
		
		for (; this_gdev != (GDHandle)0; this_gdev=GetNextDevice(this_gdev)) {
			if (TestDeviceAttribute(this_gdev, screenDevice)) {
				if (TestDeviceAttribute(this_gdev, screenActive)) {
					sect_flag = SectRect(&wrect, &(**this_gdev).gdRect, &thesect);
					sect_area = (long)(thesect.right - thesect.left) *
									(long)(thesect.bottom - thesect.top);
					if (sect_area > greatest_area) {
						greatest_area = sect_area;
						dom_gdev = this_gdev;
						}
					
					if (SectRect(&titlerect, &(**this_gdev).gdRect, &thesect)) 
						title_on_screen = 1;
					
					} /* screenActive */
				} /* screenDevice */
			} /* for */
		
		if (dom_gdev = GetMainDevice())
			bias = GetMBarHeight();
		
		screenrect = (**dom_gdev).gdRect;
		
		if (greatest_area == 0) {	/* Not on ANY screen! */
			OffsetRect(windRect, - ( windRect->left - screenrect.left),
								 - ( windRect->top - (screenrect.top + bias)) );
			OffsetRect(windRect, 10, 20);
			}
		else if (! title_on_screen) {
			OffsetRect(windRect, 0,
							- ( windRect->top - (screenrect.top + bias) ) );
			OffsetRect(windRect, 10, 20);
			}
		}
	else {
		bias = GetMBarHeight();
		screenrect = scrnrect;
		if (! SectRect(&wrect, &screenrect, &thesect)) {
			OffsetRect(windRect, - ( windRect->left - screenrect.left),
								 - ( windRect->top - screenrect.top + bias) );
			OffsetRect(windRect, 10, 20);
			}
		else if (! SectRect(&titlerect, &screenrect, &thesect)) {
			OffsetRect(windRect, 0,
							- ( windRect->top - screenrect.top + bias) );
			OffsetRect(windRect, 10, 20);
			}
		
		}
	
	if (check_size) {
		if ((windRect->bottom - windRect->top) > (screenrect.bottom - screenrect.top))
			windRect->bottom = (windRect->top + (screenrect.bottom - screenrect.top)) - bias;
		if ((windRect->right - windRect->left) > (screenrect.right - screenrect.left))
			windRect->right = (windRect->left + (screenrect.right - screenrect.left)) - bias;
		}
	
	}

-------------------------------------------------------------
Tim Endres                |  time@ice.com
ICE Engineering           |  uupsi!ice.com!time
8840 Main Street          |
Whitmore Lake MI. 48189   |  (313) 449 8288

d88-jwa@dront.nada.kth.se (Jon W{tte) (01/20/91)

In article <cbaE5X_00WBN44j0tK@andrew.cmu.edu> es1o+@andrew.cmu.edu (Eric Mitchell Snider) writes:

>locations of windows.  The problem I'm having is I don't know how to
>check if the window will appear on the screen.  Suppose someone with a
>big monitor drags the window way into the lower right corner.  If
>someone else with a small screen runs the program and it tries to

You check that the top left corner is within GetGrayRgn ( ).

Try:

	Rect * * thePos ;
	RgnHandle theFoo ;

/* Read in the saved rect */
	thePos = ( Rect * * ) GetResource ( 'Rect' , 128 ) ;

/* Construct the screen outline minus a little slop in the
   lower right parts */
	theFoo = GetGrayRgn ( ) ;
	HandToHand ( theFoo ) ;
	InsetRgn ( theFoo , 5 , 5 ) ;
	OffsetRgn ( theFoo , -5 , -5 ) ;

/* Check for sanity */
	if ( PtInRgn ( * ( Point * ) * theRect , theFoo ) ) {
		/* Use * * theRect */
	} else {
		/* Use your default - screenBits . bounds maybe.
		   GrayRgn . rgnbBBox covers _all_ screens, and thus
		   is less optimal ;-) */
	}

/* Be nice to memory */
	DisposHandle ( theFoo ) ;
	ReleaseResource ( theRect ) ;

Happy hacking,

							h+

Jon W{tte, Stockholm, Sweden, h+@nada.kth.se
:: This article is fake. If you take it for real, the _REAL_
:: Jon W{tte will sue you for slander. So there ! Nyah ! :-)

Chris.Gehlker@p12.f56.n114.z1.fidonet.org (Chris Gehlker) (01/21/91)

EMS> The problem I'm having is I don't know how to check if the window 
EMS> will appear on the screen. Suppose someone with a big monitor 
EMS> drags the window way into the lower right corner. If someone 
EMS> else with a small screen runs the program and it tries to display 
EMS> the window, they may not be able to see it... How can I deal 
EMS> with this?

That's what GetGrayRgn() is for.
 
--  
Uucp: ...{gatech,ames,rutgers}!ncar!asuvax!stjhmc!56.12!Chris.Gehlker
Internet: Chris.Gehlker@p12.f56.n114.z1.fidonet.org

urlichs@smurf.sub.org (Matthias Urlichs) (01/22/91)

In comp.sys.mac.programmer, article <1991Jan20.092039.13132@nada.kth.se>,
  d88-jwa@dront.nada.kth.se (Jon W{tte) writes:
< 
< You check that the top left corner is within GetGrayRgn ( ).
< 
I think it's nicer to check if the title bar is anywhere in the GrayRgn
(maybe InsetRgn()'ed a few pixels). I often place some windows flush left on
my screen, or a few pixels left to that.

IMHO, the important thing is that the user has some way to get at the title
bar. If I place my window at the lower left corner of the screen so that just
the zoom box is visible, your application should make the window reappear
there.

< 	} else {
< 		/* Use your default - screenBits . bounds maybe.
< 		   GrayRgn . rgnbBBox covers _all_ screens, and thus
< 		   is less optimal ;-) */

Moreover, some weird monitor setups would hide the close box, zoom box, and
resize icon of the window.
That's OK if I want the window to be there, but for a new or auto-sized
window this is definitely not a good idea...

< 	DisposHandle ( theFoo ) ;

Hmm, right now it doesn't seem to matter, but Apple recommends that you use
the region handling calls to manipulate regions.  They may conceivably be
stored somewhere inside a graphics processor.

So, you should use NewRgn and CopyRgn to duplicate a region, and DisposRgn to
destroy one, instead of HandToHand and DisposHandle.

-- 
Matthias Urlichs -- urlichs@smurf.sub.org -- urlichs@smurf.ira.uka.de     /(o\
Humboldtstrasse 7 - 7500 Karlsruhe 1 - FRG -- +49+721+621127(0700-2330)   \o)/

jln@casbah.acns.nwu.edu (John Norstad) (01/23/91)

I did alot of work on saving and restoring windows in Disinfectant 2.0.  I 
tried very hard to follow Apple's guidelines as described in their Human 
Interface Notes as closely as possible.  Much of the code I wrote is 
reusable and is available in the Disinfectant sample source code.  If you 
would like a copy (in MPW C 3.1), you can get it via anonymous FTP to 
ftp.acns.nwu.edu [129.105.113.52], or I can mail you a copy.  See 
especially the routines utl_SaveWindowPos and utl_RestoreWindowPos in 
module utl.c.

John Norstad
Academic Computing and Network Services
Northwestern University
jln@casbah.acns.nwu.edu

egw.weakm@p3.lanl.gov (Eric Wasserman) (01/24/91)

Having windows popup offscreen drives me nuts.  I'm glad to finally see
some discussion about this.  In order to keep my sanity I wrote a stupid
little FKey which moves the front window to (100,100). (Note: it doesn't
even try to be clever so use it with caution.)
--------------cut here -------------------
(This file must be converted with BinHex 4.0)
:#8CADf9j)#Ji+3"'5d9C2cmr2`!!!!!!!!!!!D!d(`!!!!!"!!!!!@)!!!"L!!!
!2J"qYqlrq'FL*Qlrq#mX!!S[#dkk!6"3Mbe!rra`'6L!#8CADf9j)#Ji+3)!!!"
'5d9C2cmr2`!"!5X#a3!!!!!!!%C,49Nr2cmr!!%"+`,&!!!!!!!!!!!!!!!!!!!
!!!!!S[X1!`!!!!!!!!'JrrF!$bPZrqS!!LPZrr`!#L!,CaJ-D`!)!'a[%#"V!*J
J8#m,,``J8%k3!&#2-"41V3!U!!B!'J!3!#!!'!!Q!!B!,J!@!%)!&`##!"N!JNK
YkdDS8@!!!(K)D`!3U5KJ!!"Z,`ZTD5m,U50J!!"L5'X!%+LM,`Xr,!!%2b`!!N*
RU4d!!!"HB!i!!%C,49N!#!!!!!!!!%(krqj1F8jaB!!!!Nj@rra1ZJ!b)SJ[$%k
k!#SS88+RU53JAbe)rra+V[rmCa![,[rm2c`!C$mm!'4#CkNE+&p1ANjeB33!!!!
!)Pp1G3!!!3!!!!&L!!!!BJ!!!$i!CB4%$a!!!!!F!$)!!%C,49N!!!!+!!J!!#!
!!!!!CB-8#dCbEfjd9fPZC'ph1TJ:
------------------------end cut-------------------------

Eric
egw.weakm@p3.lanl.gov

Bruce.Hoult@bbs.actrix.gen.nz (01/28/91)

Eric Wasserman gives a BinHex'd file containing a simple FKEY:
>(This file must be converted with BinHex 4.0)
>:#8CADf9j)#Ji+3"'5d9C2cmr2`!!!!!!!!!!!D!d(`!!!!!"!!!!!@)!!!"L!!!
>!2J"qYqlrq'FL*Qlrq#mX!!S[#dkk!6"3Mbe!rra`'6L!#8CADf9j)#Ji+3)!!!"
>'5d9C2cmr2`!"!5X#a3!!!!!!!%C,49Nr2cmr!!%"+`,&!!!!!!!!!!!!!!!!!!!
>!!!!!S[X1!`!!!!!!!!'JrrF!$bPZrqS!!LPZrr`!#L!,CaJ-D`!)!'a[%#"V!*J
>J8#m,,``J8%k3!&#2-"41V3!U!!B!'J!3!#!!'!!Q!!B!,J!@!%)!&`##!"N!JNK
>YkdDS8@!!!(K)D`!3U5KJ!!"Z,`ZTD5m,U50J!!"L5'X!%+LM,`Xr,!!%2b`!!N*
>RU4d!!!"HB!i!!%C,49N!#!!!!!!!!%(krqj1F8jaB!!!!Nj@rra1ZJ!b)SJ[$%k
>k!#SS88+RU53JAbe)rra+V[rmCa![,[rm2c`!C$mm!'4#CkNE+&p1ANjeB33!!!!
>!)Pp1G3!!!3!!!!&L!!!!BJ!!!$i!CB4%$a!!!!!F!$)!!%C,49N!!!!+!!J!!#!
>!!!!!CB-8#dCbEfjd9fPZC'ph1TJ:


If people have to use ResEdit to install the FKEY, they might as
well just create the resource themselves.  Easy instructions:

1) copy the string 42A7A9244A97670A2F3C006400644267A91B4E75 to your
   clipboard
2) start ResEdit
3) open your system file
4) select "New" from "File" menu
5) type "FKEY"
6) select "New" from "File" menu
7) select "Paste" from "Edit" menu
8) close the window
9) select "Get Info" from "File" menu
10) type 8  (or any number from 5 to 9)
11) Quit, saving changes

:-)
-- 
Bruce.Hoult@bbs.actrix.gen.nz   Twisted pair: +64 4 772 116
BIX: brucehoult                 Last Resort:  PO Box 4145 Wellington, NZ
"And they shall beat their swords into plowshares, for if you hit a man
with a plowshare, he's going to know he's been hit."