TweetFollow Us on Twitter

Window Structures
Volume Number:5
Issue Number:6
Column Tag:abC

Related Info: Window Manager

Window Structures

By Bob Gordon, Minneapolis, MN

Welcome to the second incarnation of the MacTutor intro column. The column is called abC because of its introductory nature (the “abc’s”), and it uses the C language (the “C”). What I propose to do is to continue in the spirit of the previous set of articles, but focus less on C and more on the Mac.

I also will not attempt to present a complete program each time. Since an introduction by its very nature tends to be a bit repetitive, I found the last time that the same code would appear for months at a time. This took up a lot of space in the magazine, and made it difficult to focus on one issue as we were always carrying around a large amount of other code just to make an application work. This means that the articles will tend to be shorter, which will likely make it more possible for me to get them done.

One other point before we start. I found that one of the most useful things in writing for MacTutor is getting mail. Feel free to write; comments are much appreciated; and include your phone number.

Making a Window

One of the first steps in a Mac application is putting a window on the screen, typically in response to a request from the user. This method developed here is done entirely in code (as opposed to using resources). This has some limits, but offers the ability to easily add some features to ease the maintenance of windows.

There are two points: First a window consists of the window stuff and the application specific stuff. From the Mac’s point of view, the window stuff consists of only the frame and does not even include the scroll bars (if any). On the other hand the application probably does not want to be concerned with such things as the scroll bars, zoom boxes, sizing, et cetera.

Second, it is good programming practice to separate the application specific code from the more generic user-interface code. This eases maintenance and debugging and modification. To this end I created a file, shell.c which handles many of the generic properties, helper files (e.g. windowhelp.c) to add the capabilities I wanted, and the file app.c, which actually contains the parts of the application. In the snippets of code that follow, you will notice an occasional call to a function like appxxx(). This is a call in the shell part of the program to the app.c file. It is here, after, for example, preparation has been made for updating a window (appupdate() ), that the application must update the application portion.

windowhelp.h

The windowhelp functions work because the WindowRecord defined in the ToolBox is a fixed length object. What I did is add some additional data structures on the end. This simply makes the object a little longer, but all the toolbox window and QuickDraw functions will work correctly. The advantage of doing this is that I can now keep additional information, which I think should be attached to a window in a safe place where I can always find it, and the application parts of the code need to concern themselves with it.

One might suggest that the WRefCon (a field in the WindowRecord specifically for the application’s own use) field is the proper place for this. This is probably true, but so much of this stuff seemed to either be more part of the window than the application (scroll bars) or likely to be part of any application (knowing whether the contents had changed or not), that it seemed a Good Idea to put it all together in one place. In this way much of the Mac user interface is handled for us each time we start a project. I use the WRefCon field to store the reference to the applications information proper.

Now, I make have no pretenses that this is the optimal way of doing things. In fact, I know there are additions and changes I am going to make, but if we wait to get all that worked out, we’ll never get this written.

A few comments about the fields:

The first four are what I call window margins. I noticed that many applications place various graphic objects around the edges of the window. There are scroll bars to the bottom and right, rulers on the top and tools on the left. Whatever it is, it brings in the edge of the window as far where the application can write. The window margins are sizes, in pixels of the areas reserved by things around the edges. The application can change them (if the user asks to see the rulers, for example).

The next field, cursrt, is the rectangle defined by the window and the margins. I called it cursrt because outside the rectangle the cursor is typically the 11 o’clock arrow, and inside the cursor is whatever the application would like.

The zoomrt is the rectangle to hold the size to zoom to if the user clicks the zoom box. Frankly, I haven’t implemented zooming yet. It may be that we’ll want two rectangles for zooming: one to hold the maximum size and one to hold the small (user set) size.

mouser is a code for the mouse cursor. I made it a char simply because I couldn’t imagine anyone wanting more than 255 cursors and because the built-in cursors are numbered one through four. If you want to add a cursor resource, simply start the numbers at five and everything will work fine. And if you want more cursors or want to use bigger numbers, make it a short.

The changed field simply states whether or not the window contents have changed.

The next field, ckind (contents kind) I used to indicate the kind of window. Currently this is either text or a object drawing. Whether this will stay this way or not I don’t know. Currently I use this in the functions that handle update and activation events to determine what to do.

The last field is a handle to the current TextEdit record. A window may have more than one. This is needed because when a window is activated, the blinking cursor needs to be placed in whichever edit record the user left it in.

As you can see, much of this information falls somewhere between what is strictly application specific and what is part of the window. Much of it, however, the application either need not be concerned with or is needed for almost all applications.

Following the WindowStruct definition are several groups of #defines. The most interesting of these are the WDOC/WGROW/WZOOM. By using these when you define a window (simply add together the ones you want), you can specify whether you want a simple document window to have a grow box or a zoom box. You can also add in the codes for the vertical or horizontal scroll bars.

/* 1 */

/*windowhelp.h */
#include “TextEdit.h”
 
#ifndef WINDOWHELP_H
#define WINDOWHELP_H

/* window add-on structure */

#define WindowStruct struct w_struct
WindowStruct
 {
 WindowRecord  wr; /* the original window record */
 uchar  mtop;    /* margin indents */
 uchar  mleft;
 uchar  mbottom;
 uchar  mright;
 Rect   cursrt;  /* rectangle used for cursor control */
 Rect   zoomrt;  /* rectangle for zoom operation */
 char   mouser;  /* mouse pointer id (cursor shape) */
 char   changed; /*if window contents havebeen changed */
 short  ckind;   /* kind of contents */
 TEHandle curtext; /* handle current te rec for window */
 };
 

#define Woffset  18
#define SBarWidth15

/* these definitions allow easy generation of the four square
 * cornered titled windows. The basic (simplest) window is the
 * WDOC (NoGrowDocProc). To this optionally add WGROW to add a 
 * grow box and/or WZOOM to add a zoom box.
 */
#define WDOC4
#define WGROW    -4
#define WZOOM    8
#define WVBAR    16
#define WHBAR    32

/* specify the content of the window */
#define CDRAW    1
#define CTEXT    2

/* Value in windowKind field of WindowRecord by WindowNew
 * if the window has a grow box. This is used by routines that
 * redraw the window to decide whether to draw the grow box
 * or not 
 */
#define HASGROW  9

#endif

WindowHelp.c

WindowHelp.c consists mainly of two functions, WindowNew() and WindowClose().

WindowNew() opens a window after creating a WindowStruct as shown above (no check for memory yet). Note that it only gets four arguments. The title (which can be a null string in which case the window is named “Untitled”), a percentage (the window is opened as a certain percentage of the monitor size), the windowkind (WDOC/WGROW/WZOOM), and the content kind.

A few other notes: The call to AppPage() is a kludge. It is supposed to return the page size. Currently some numbers are just hard coded in AppPage(). The page size is needed for scrolling. Just put in sizes for an 8.5 by 11 piece of paper (in pixels) or whatever size page you want. The call to AppNew() is where the application does the initialization of its own data for a new window and places a reference to it (typically a handle) in the WRefCon.

WindowClose() closes a window. After checking to see if the window is a desk accessory (and handling that), it calls AppClose() to allow the application to close its own structures. Then is closes the window and frees the memory. It is in here that we would check to see if the window contents had changed (and had not been saved) and ask the user if we were to save the file.

/*2 */


/* windowhelp.c
 * provides some routines to aid in opening and closing 
 * windows
 */
 
#include“abc.h”
#include“Quickdraw.h”
#include“EventMgr.h”
#include“WindowMgr.h”
#include“MenuMgr.h”
#include“windowhelp.h” 
#include“controlhelp.h”
#include“cursorhelp.h”

short w_total = 0; /* counts total number of windows opened*/
short w_count  = 0;
 /* counts number of windows actually open */

WindowNew(title,percentsz,windkind,contkind)
 char *title;
 short  percentsz;
 short  windkind;
 short  contkind;
{
 char   *thetitle;
 Rect   boundsrt;
 WindowRecord  *w;
 WindowStruct  *ws;
 short  width;
 short  depth;
 short  leftedge;
 short  topedge;
 Rect   pagesz;
 short  hasscroll;
 
 hasscroll = windkind & WVBAR + WHBAR; 
 /* mask out scroll bar options */
 windkind &= 8;
 if (title)
 thetitle = title;
 else
 thetitle = “Untitled”;
 SetRect(&boundsrt,screenBits.bounds.left + 4,
 screenBits.bounds.top + 24,
 screenBits.bounds.right - 4,
 screenBits.bounds.bottom - 4);
 width = boundsrt.right - boundsrt.left;
 depth = boundsrt.bottom - boundsrt.top;
 AdjustRect(&boundsrt,
 topedge = 30 + Woffset * w_total,
 leftedge = 30 + Woffset * w_total,
 ((depth * percentsz) / 100) - topedge,
 ((width * percentsz) / 100) - leftedge);
 ws = (WindowStruct *)NewPtr(sizeof (WindowStruct));
 w = (WindowRecord *)NewWindow(ws,&boundsrt,CtoPstr(thetitle),True,
 windkind,(WindowPtr)-1,True,0);
 ws = (WindowStruct *)w;
 switch (windkind)
 {
 case documentProc : 
 case zoomDocProc :
 w->windowKind = HASGROW;
 break;
 };
 if (w->windowKind == HASGROW)  /* set window margins */
 {
 ws->mright = ws->mbottom = SBarWidth;
 AppPage(&pagesz);
 if (hasscroll == WHBAR)
 ScrollNew(w,0,0,pagesz.right,HORZ);
 if (hasscroll == WVBAR)
 ScrollNew(w,0,0,pagesz.bottom,VERT);
 DrawControls(w);
 DrawGrowIcon(w);
 }
 else
 ws->mright = ws->mbottom = 0;
 ws->mtop = ws->mleft = 0;
 ws->changed = FALSE;
 ws->ckind = contkind;
 ws->curtext = NIL;
 SetCursorRect(w); /* set cursor rect for cursor control */
 AppNew(w); /* function to open application structure */
 w_count++;
 w_total++;
 PtoCstr(thetitle);
}

/* WindowClose()
 * Closes the window passed to it. Assumes window was opened 
 * with WindowNew(). If window is a desk accessory, it will 
 *  be closed correctly. If it is an application window, prior 
 *  to the window close there is a call to AppClose() (which 
 * the application must supply) to allow any application 
 * specific closing.
 */
WindowClose(w)
 WindowRecord  *w;
{
 WindowStruct  *ws;
 short  refnum;
 
 if (ws = (WindowStruct *)w)
 if ((refnum = w->windowKind) < 0)
 CloseDeskAcc(refnum);
 else 
 {
 AppClose(w);    /* close app storage, must do before */
   CloseWindow(w); /*    CloseWindow */
   DisposPtr(w);
   w_count--;    /* decrement the window count */
   if (w_count == 0) 
 /* if the number of windows on screen goes to */
   w_total = 0;  
 /*  zero, set total to zero so next time we */
   }    /* open a window it will start at the original */
}/*   window position */

/* AdjustRect
 * adjusts coordinates of a rectangle by four separate 
 * amounts. adjustment is in (towards center) if amounts are 
 * positive and out if amounts are negative);
 */
AdjustRect(rec,t,l,b,r)
 Rect *rec;
 short  t,l,b,r; /* values to adjust rectangle by */
{
 rec->top +=t;
 rec->left += l;
 rec->bottom -= b;
 rec->right -= r;
}

/* RtGlobalToLocal
 * Adjusts a rectangle to local coordinates
 */
RtGlobalToLocal(rt)
 Rect *rt;
{
 Point  *pt;
 
 pt = (Point *)rt;
 GlobalToLocal(pt);
 pt++;
 GlobalToLocal(pt);
}

The last little piece of code illustrates how these functions are called from the shell program.dofile() is part of the code that responds to menus.

/* 3 */

dofile(item)
 short  item;
{
 WindowRecord  *w;
 
 switch(item)
 {
 case iNew: WindowNew(“”,40,WDOC+WGROW+WVBAR,CTEXT);
   break;
 case iClose: WindowClose(FrontWindow());
   break;
 case iQuit : while (w = (WindowRecord *)FrontWindow() )
 {
 WindowClose(w);
 }
   ExitToShell();
   break;
 }
}

I hope this gives you some ideas on how to handle windows. Since it can open as many windows as you want, there should be some check for memory limits. I also hope this is suitably introductory. Again, if you have any questions or comments, please write.

 
AAPL
$104.48
Apple Inc.
+1.49
MSFT
$44.81
Microsoft Corpora
+0.43
GOOG
$542.21
Google Inc.
+9.50

MacTech Search:
Community Search:

Software Updates via MacUpdate

jAlbum Pro 12.2.4 - Organize your digita...
jAlbum Pro has all the features you love in jAlbum, but comes with a commercial license. With jAlbum, you can create gorgeous custom photo galleries for the Web without writing a line of code!... Read more
jAlbum 12.2.4 - Create custom photo gall...
With jAlbum, you can create gorgeous custom photo galleries for the Web without writing a line of code! Beginner-friendly, with pro results Simply drag and drop photos into groups, choose a design... Read more
ExpanDrive 4.1.7 - Access remote files o...
ExpanDrive builds cloud storage in every application, acts just like a USB drive plugged into your Mac. With ExpanDrive, you can securely access any remote file server directly from the Finder or... Read more
OmniOutliner Pro 4.1.3 - Pro version of...
OmniOutliner Pro is a flexible program for creating, collecting, and organizing information. Give your creativity a kick start by using an application that's actually designed to help you think. It'... Read more
Evernote 5.6.2 - Create searchable notes...
Evernote allows you to easily capture information in any environment using whatever device or platform you find most convenient, and makes this information accessible and searchable at anytime, from... Read more
OmniOutliner 4.1.3 - Organize your ideas...
OmniOutliner is a flexible program for creating, collecting, and organizing information. Give your creativity a kick start by using an application that's actually designed to help you think. It's... Read more
BBEdit 11.0 - Powerful text and HTML edi...
BBEdit is the leading professional HTML and text editor for the Mac. Specifically crafted in response to the needs of Web authors and software developers, this award-winning product provides a... Read more
Apple Security Update 2014-005 - For OS...
Apple Security Update is recommended for all users and improves the security of Mac OS X. For information on the security content of this update, please visit this website: http://support.apple.com/... Read more
EyeTV 3.6.6 - Watch and record TV on you...
EyeTV brings a rich TV experience to your Mac. Watch live TV on your Mac. Pause, rewind, and record whenever you want. EyeTV gives you powerful control over what you watch and how you watch it. Put... Read more
RapidWeaver 6.0 - Create template-based...
RapidWeaver is a next-generation Web design application to help you easily create professional-looking Web sites in minutes. No knowledge of complex code is required, RapidWeaver will take care of... Read more

Latest Forum Discussions

See All

Jam Messenger Review
Jam Messenger Review By Jennifer Allen on October 23rd, 2014 Our Rating: :: SIMPLE MESSAGINGiPhone App - Designed for the iPhone, compatible with the iPad Want a very quick way to send push-based messages? Jam Messenger is basic... | Read more »
Felllice (Games)
Felllice 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: EXCLUSIVE PRICE DROP! 50% OFF FOR A LIMITED TIME! EAT EAT EAT AND GROW ! | Read more »
The Arrow Game: by Grazie Media (Games)
The Arrow Game: by Grazie Media 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: Guide a flying arrow through skyscrapers and city streets to hit a distant target. Experience an endless... | Read more »
Worldly (Games)
Worldly 1.2 Device: iOS Universal Category: Games Price: $2.99, Version: 1.2 (iTunes) Description: | Read more »
Money Pro - EASY! Bills, Budgets and Acc...
Money Pro - EASY! Bills, Budgets and Accounts w/ Sync 1.0 Device: iOS Universal Category: Finance Price: $4.99, Version: 1.0 (iTunes) Description: Manage money like a pro. Money Pro is the next generation of Money app (over 2 million... | Read more »
Pro Strategy Football 2014 (Games)
Pro Strategy Football 2014 2014.141001 Device: iOS Universal Category: Games Price: $4.99, Version: 2014.141001 (iTunes) Description: Take the proven strategy of the PSF franchise and add in Casual Play, improved graphics and... | Read more »
Super Glyph Quest (Games)
Super Glyph Quest 1.01 Device: iOS Universal Category: Games Price: $2.99, Version: 1.01 (iTunes) Description: Adventure is back Questers! Combine elemental glyphs together to cast powerful spells and vanquish adorable monsters in... | Read more »
Fighting Fantasy: Caverns of the Snow Wi...
Fighting Fantasy: Caverns of the Snow Witch 1.0 Device: iOS Universal Category: Games Price: $5.99, Version: 1.0 (iTunes) Description: Travel to Northern Allansia’s perilous Icefinger Mountains to defeat the wicked Snow Witch in this... | Read more »
Star Warfare 2: Payback Review
Star Warfare 2: Payback Review By Blake Grundman on October 22nd, 2014 Our Rating: :: ONE-TRICK PONYUniversal App - Designed for iPhone and iPad Unfortunately, it doesn’t take long for Star Warfare 2’s free-firing fun to turn into... | Read more »
TinType by Hipstamatic (Photography)
TinType by Hipstamatic 1.0 Device: iOS iPhone Category: Photography Price: $.99, Version: 1.0 (iTunes) Description: Create hauntingly beautiful, soul capturing portraits with TinType by Hipstamatic. Inspired by daguerreotypes,... | Read more »

Price Scanner via MacPrices.net

WD My Passport Pro Bus-Powered Thunderbolt RA...
WD’s My Passport Pro RAID solution is powered by an integrated Thunderbolt cable for true portability and speeds as high as 233 MB/s. HighlightsOverviewSpecifications Transfer, Back Up And Edit In... Read more
Save with Best Buy’s College Student Deals
Take an additional $50 off all MacBooks and iMacs at Best Buy Online with their College Students Deals Savings, valid through November 1st. Anyone with a valid .EDU email address can take advantage... Read more
iPad Air 2 & iPad mini 3 Best Tablets Yet...
The new iPads turned out to be pretty much everything I’d been hoping for and more than I’d expected.”More” particularly in terms of a drinking-from-a-firehose choice of models and configurations,... Read more
Drafts 4 Reinvents iOS Productivity App
N Richland Hills, Texas based Agile Tortoise has announced the release of Drafts 4 for iPhone and iPad. Drafts is a quick capture note taking app with flexible output actions. Drafts 4 scales from... Read more
AT&T accepting preorders for new iPads fo...
AT&T Wireless is accepting preorders for the new iPad Air 2 and iPad mini 3, cellular models, for $100 off MSRP with a 2-year service agreement: - 16GB iPad Air 2 WiFi + Cellular: $529.99 - 64GB... Read more
Apple offering refurbished Mac Pros for up to...
The Apple Store is offering Apple Certified Refurbished 2013 Mac Pros for up to $600 off the cost of new models. An Apple one-year warranty is included with each Mac Pro, and shipping is free. The... Read more
Select MacBook Airs $100 off MSRP, free shipp...
B&H Photo has 2014 a couple of MacBook Airs on sale for $100 off MSRP. Shipping is free, and B&H charges NY sales tax only. They also include free copies of Parallels Desktop and LoJack for... Read more
13-inch 2.5GHz MacBook Pro on sale for $100 o...
B&H Photo has the 13″ 2.5GHz MacBook Pro on sale for $999.99 including free shipping plus NY sales tax only. Their price is $100 off MSRP. Read more
Strong iPhone, Mac And App Store Sales Drive...
Apple on Monday announced financial results for its fiscal 2014 fourth quarter ended September 27, 2014. The Company posted quarterly revenue of $42.1 billion and quarterly net profit of $8.5 billion... Read more
Apple Posts How-To For OS X Recovery
OS X 10.7 Lion and later include OS X Recovery. This feature includes all of the tools you need to reinstall OS X, repair your disk, and even restore from a Time Machine backup. OS X Recovery... Read more

Jobs Board

Senior Event Manager, *Apple* Retail Market...
…This senior level position is responsible for leading and imagining the Apple Retail Team's global event strategy. Delivering an overarching brand story; in-store, Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Project Manager / Business Analyst, WW *Appl...
…a senior project manager / business analyst to work within our Worldwide Apple Fulfillment Operations and the Business Process Re-engineering team. This role will work Read more
*Apple* Retail - Multiple Positions (US) - A...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Position Opening at *Apple* - Apple (United...
…customers purchase our products, you're the one who helps them get more out of their new Apple technology. Your day in the Apple Store is filled with a range of Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.