[comp.sys.mac.programmer] Saving window position question

maryd@suna.CMI.COM (Mary Dimercurio) (07/07/89)

Hi!  I am trying to make my application "MultiFinder friendly."  Tech
note 158 suggests that I should save the positions of the windows that
I have open so that they will go where the user had them last when the
application is launched again.  Unfortunately it doesn't say HOW I can
do this.  How do I get the location of my windows to save (I plan to
save them in a resource)??

 Mary Dimercurio
 (maryd@suna.cmi.com)

mystone@caen.engin.umich.edu (Dean Yu) (07/07/89)

In article <505@suna.CMI.COM> maryd@suna.CMI.COM (Mary Dimercurio) writes:
>
>Hi!  I am trying to make my application "MultiFinder friendly."  Tech
>note 158 suggests that I should save the positions of the windows that
>I have open so that they will go where the user had them last when the
>application is launched again.  Unfortunately it doesn't say HOW I can
>do this.  How do I get the location of my windows to save (I plan to
>save them in a resource)??
>

  It's quite simple.  Say you have a window pointer theWindow.  You can get
the global coordinates of the window by

  windowPeek(theWindow)^.contRgn^^.rgnBBox

  To make life simple, it you might want to declare a type to store your
window rectangles in:

  TYPE	windRec	=  RECORD
		     saveRects: array [1..maxWindows] of Rect;
		   END;
	windRecPtr  =  ^windRec;
	windRecHand =  ^windRecPtr;

  Now you've got a handle you can store in a resource after a trivial type
coercion.
 
_______________________________________________________________________________
Dean Yu                            | E-mail: mystone@{sol,caen}.engin.umich.edu
University of Michigan             | Real-mail: Dean Yu
Computer Aided Engineering Network |            909 Church St
                                   |            Apt C
===================================|            Ann Arbor, MI 48104
                                   | Phone: Given on a need to know basis, and
"I am the Merit Host.  I speak for |        only if you're going to offer me a
 the bitstream."  (In other words, |        job...
 these are my very own opinions;   | 
 my employer wants to have nothing |===========================================
 to do with them, or me.)          |       This space available for rent
-------------------------------------------------------------------------------

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

In article <505@suna.CMI.COM> maryd@suna.CMI.COM (Mary Dimercurio) writes:
>Hi!  I am trying to make my application "MultiFinder friendly."  Tech
>note 158 suggests that I should save the positions of the windows that
>I have open so that they will go where the user had them last when the
>application is launched again.  Unfortunately it doesn't say HOW I can
>do this.  How do I get the location of my windows to save (I plan to
>save them in a resource)??

You can get the size just by looking at the portRect of the window.
The position is almost as easy -- SetPort to the window and then do a
LocalToGlobal on the point (0,0).  These will require a bit more work
if you have been doing SetOrigin calls, which is one of the many
reasons I never use SetOrigin.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com
Postal: 424 Tehama, SF CA 94103; Phone: (415) 495-2934

These are not my opinions, those of my ex-employers, my old schools, my
relatives, my friends, or really any rational person whatsoever.

wdh@well.UUCP (Bill Hofmann) (07/08/89)

In article <7889@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>In article <505@suna.CMI.COM> maryd@suna.CMI.COM (Mary Dimercurio) writes:
>>... How do I get the location of my windows to save (I plan to
>>save them in a resource)??
>
>You can get the size just by looking at the portRect of the window.
>The position is almost as easy -- SetPort to the window and then do a
>LocalToGlobal on the point (0,0).  These will require a bit more work
>if you have been doing SetOrigin calls, which is one of the many
>reasons I never use SetOrigin.

It's actually much easier than that:
{
	Rect	saveWindow;

	...
	SetPort(myWindow);
	saveWindow = myWindow->portRect;
	LocalToGlobal(&(((Point *) &saveWindow)[0]));
	LocalToGlobal(&(((Point *) &saveWindow)[1]));
	...
}
Which does a LocalToGlobal on the topLeft and the botRight of the portRect.
Actually, what you probably *should* do is save the userState and stdState
of the window (assuming it's a zooming window).  You can get those from the
dataHandle in the WindowRecord, and they're already global.  Then, save
a boolean which tells you which state it's in (compare the globalized portRect
with one of them).  Of course, when you open the document, you need to
check that the current state is on one of the current screens. 

-Bill Hofmann

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

In article <12616@well.UUCP> wdh@well.UUCP (Bill Hofmann) writes:
>It's actually much easier than that:
>{
>	Rect	saveWindow;

>	SetPort(myWindow);
>	saveWindow = myWindow->portRect;
>	LocalToGlobal(&(((Point *) &saveWindow)[0]));
>	LocalToGlobal(&(((Point *) &saveWindow)[1]));
>}
>Which does a LocalToGlobal on the topLeft and the botRight of the portRect.

Not to put too fine a point on it, but that is easy only from the
perspective of the software writer, not of the poor schlub who has to
maintain the thing.  Yes, I and many others are well aware that
rectangles are laid out as two points; if I recall correctly, the
standard Pascal definition is a variant record which lets one see
either four integers or two points.  However, this kind of typecasting
and simulation of Pascal variants in C is at best idiosyncratic, and
at word deliberately obscure for purposes of self-congratulation.
It is, in brief, not clearly written.

Much the same could be accomplished this way --

	Point topLeft, bottomRight;
	Rect saveRect;

	SetPort(window);
	SetPt(&topLeft, window->portRect.left, window->portRect.top);
	SetPt(&bottomRight, window->portRect.right, window->portRect.bottom);
	LocalToGlobal(&topLeft);
	LocalToGlobal(&bottomRight);
	SetRect(&saveRect, topLeft.left, topLeft.top, bottomRight.right,
		bottomRight.bottom);

Which I think is considerably more maintainable.  It is slightly less
computationally efficient, but then this is not a frequently performed
operation, and my version still executes in far less time than it takes
a human being to perceive an event.

>Actually, what you probably *should* do is save the userState and stdState
>of the window (assuming it's a zooming window).  You can get those from the
>dataHandle in the WindowRecord, and they're already global.  Then, save
>a boolean which tells you which state it's in (compare the globalized portRect
>with one of them).  Of course, when you open the document, you need to
>check that the current state is on one of the current screens. 

Very good point.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com
Postal: 424 Tehama, SF CA 94103; Phone: (415) 495-2934

"Yet another piece of evidence that it's a Communist society which is being
 presented as good, but which we probably would not want to live in."
	-- Ken Arromdee on rec.arts.startrek, on the Federation's Red Menace

pepke@loligo.cc.fsu.edu (Eric Pepke) (07/28/89)

The saved position and size may no longer be valid when the document is 
opened on a Macintosh with a different configuration of screens, so that
must be checked as well.  How are people out there doing it?  My favorite
way of doing this for a standard document window is

1) Store the desired rectangle of the content region in a variable windowRect.
2) Make a variable barRect such that
      barRect . top = windowRect . top - 13;
      barRect . bottom = windowRect . top - 5;
      barRect . left = windowRect . left + 4;
      barRect . right = windowRect . right - 4;
3) Determine if this intersects GetGrayRgn().

This seems to be consistent with the criteria that DragWindow uses to
determine whether a window position is reasonable or not, or at least it's
close.

Are there any better ways?

Eric Pepke                                     INTERNET: pepke@gw.scri.fsu.edu
Supercomputer Computations Research Institute  MFENET:   pepke@fsu
Florida State University                       SPAN:     scri::pepke
Tallahassee, FL 32306-4052                     BITNET:   pepke@fsu

Disclaimer: My employers seldom even LISTEN to my opinions.
Meta-disclaimer: Any society that needs disclaimers has too many lawyers.

uucibg@sw1e.UUCP (3929]) (07/29/89)

In article <7913@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>In article <12616@well.UUCP> wdh@well.UUCP (Bill Hofmann) writes:
>>It's actually much easier than that:
[a short but somewhat unclear method for saving the size of the current window]
>
>...................  Yes, I and many others are well aware that
>rectangles are laid out as two points; ....
>...................................  However, this kind of typecasting
>.. is, in brief, not clearly written.
>Much the same could be accomplished this way --
>	Point topLeft, bottomRight;
>	Rect saveRect;
>	SetPort(window);
>	SetPt(&topLeft, window->portRect.left, window->portRect.top);
>	SetPt(&bottomRight, window->portRect.right, window->portRect.bottom);
>	LocalToGlobal(&topLeft);
>	LocalToGlobal(&bottomRight);
>	SetRect(&saveRect, topLeft.left, topLeft.top, bottomRight.right,
>		bottomRight.bottom);
...

Why not simply do:

	Rect saveRect;
	...
	SetPort(window);
	saveRect = window->portRect;
	LocalToGlobal(&saveRect.topLeft);
	LocalToGlobal(&saveRect.bottomRight);
	/* Restore the port and go your merry way */

--------------------------------------------------------------------------------
Brian R. Gilstrap    ...!{ bellcore!texbell, uunet }!swbatl!sw1e!uucibg
One Bell Center      +----------------------------------------------------------
Rm 17-G-4            | "Winnie-the-Pooh read the two notices very carefully,
St. Louis, MO 63101  | first from left to right, and afterwards, in case he had
(314) 235-3929       | missed some of it, from right to left."   -- A. A. Milne
--------------------------------------------------------------------------------
Disclaimer:
Me, speak for my company?  You must be joking.  I'm just speaking my mind.