TweetFollow Us on Twitter

True B, Prototyper
Volume Number:4
Issue Number:8
Column Tag:Basic School

True Basic & Prototyper Reviewed

By Dave Kelly, Editorial Board

True Basic 2.01 Run Time Package

I promised you some more information about the new version of True Basic (2.01). The good news is that you can now create double-clickable applications with the runtime package that is included with the price of True Basic ($99.95 retail).This price includes both a commercial and non-commercial license.There is no longer an extra charge for the license for "unlimited commercial" use. The Bad news is that the Developer's Toolkit is not included with the True Basic interpreter yet. UGH! According to True Basic it will be available soon. The Developer’s Toolkit includes all the ROM routines for creating the Macintosh User features we all know and love. As much as I would like the Toolkit to be included with True Basic, they have come a long way. After all, last time I reviewed this the runtime package was priced way out of sight and even the interpreter was overpriced.

You are probably wondering about the runtime package and just what it is. I just received a copy of the runtime package yesterday, but I can pass on to you some information about it. The runtime includes two new libraries of routines, named Bundle and Launch*. Bundle is a “compiled” True Basic program which sets up the signature id of your application. Launch* consists of some routines for getting your application’s name and getting the names of files to be opened or printed by the application that were selected in the finder when the application was run. Two application files are included in the runtime package too. RTP is an application shell program which is that base of all applications that you will create. RTP contains the ENTIRE True Basic interpreter and is used as the shell which will ‘run’ your program after it is attached. The other application is named Binder and is used to combined compiled True Basic programs with the RTP application so that they can now be considered one application. The RTP application (the interpreter) consists of 73K of True Basic standard packages so you should be aware that your programs will always be at least 73K in size. That may be bad news, but at least the application can be created.

True Basic has one of the most extensive sets of library routines available for any language. Some of these routines are very valuable for scientific/engineering applications. True Basic Inc. says that all the original versions of the libraries work with True Basic 2.01 except for the Developer’s Toolkit and the Communications Support package. Both of these have been updated to work with version 2.01. The Developer’s Toolkit, as I mentioned before, contains all the latest Macintosh ROM routine calls. Some of the libraries available include: Business Graphics Toolkit, Scientific Graphics Toolkit, 3D Graphics, Communications Support, Forms Management, Sorting and Searching, Advanced String Library, and Mathematician’s Toolkit. All of these are list price of $69.95 each. They are probably worth it if you think you need the function they perform.

To give you a little feel for the runtime package I have included the following short program which makes use of the launch* library. The program displays the files which were selected in the finder launch of the application.

! Runtime Demo

LIBRARY “launch*”
CALL AppParms(name$,message,nfiles)
PRINT “Current Application name is:”;name$
SELECT CASE message
CASE 0
     PRINT “Files to be opened:”
CASE 1
     PRINT “Files to be printed:”
END SELECT
FOR i=1 to nfiles
    CALL Appfile(i,filename$,””)
    PRINT filename$
    CALL ClrAppFile(i)
NEXT i
if nfiles=0 then print “NONE”
GET KEY k
END

SAMPLE OUTPUT:

So just what’s so great about True Basic? Actually, the main drawback in the previous version was its inability to be a double-clickable application. As a language, it is excellent, especially in support of scientific applications. On the positive side, True Basic has the strongest version of Basic available on the Mac. The reason I say it is the strongest because the structure and functional capabilities of the language are solid and reliable (I haven’t seen any system bombs!) The library routines are very extensive, more extensive than any for MS Basic. Recursion is supported. The 68881 math coprocessor is supported. Color is supported with ability to modify color palettes (July, 1988 MacTutor). Since the runtime package is now made more freely available, you can use True Basic more effectively in real world applications (instead of the class room world that you have without the runtime package).

No Developer’s Toolkit Yet

On the negative side, there are a few areas that could have been cleaned up a bit. The first negative, and my strongest point is that the Developer’s Toolkit is not included with the interpreter. Since I’ve already mentioned this before I won’t dwell on it, but I feel it is a ‘must have’ if you are doing any serious development. Next there are a few compatibility/ user interface issues some of which you can fix yourself. One problem is the small size of the Standard GetFile/SaveFile Dialog windows. This can be fix with a little ResEdit work. The problem is that the window is only wide enough for short file names (like version 1.0 was when Mac 128K came out). Fortunately this is fixable.

While it is true that True Basic will run with Multifinder, True Basic does not know when to update windows when they have been overwritten by other applications or desk accessories and without the Developer’s Toolkit it would be impossible to know that a window needs to be refreshed. True Basic was designed to run in one window which happens to be the size of the screen (any size screen). All graphics commands are automatically scaled to work with whatever size screen (on whatever computer True Basic runs on). Since the main True Basic window is the size of the screen and is not adjustable, it will overlap ALL windows and icons which are running in the background with Multifinder. Since the menus are disabled during True Basic runtime (runtime package), the only way to switch applications is by clicking on the icon in the upper right corner (in the menu bar). The are a few refinements that could be done here to make it more Multifinder compatible.

True Basic for the Macintosh comes with two manuals, the Reference Manual, and the Macintosh™ User’s Guide. The Reference Manual is much improved over the old version included with version 1.0. The True Basic statements are listed alphabetically in the back half of the book (part III), but since there are sometimes several statements on a page you have to read carefully to find what you are looking for. The Macintosh™ User’s Manual is just what it says it is, a user’s manual. The first half of the book tells what each menu of the True Basic application does, then there are some sections telling about a few Macintosh only routines which are included. Included in this is sections on color support, standard GetFile/PutFile stuff, and a few graphics commands for fonts and basic graphics (about like the original MS Basic Toolbox of Graphics commands). The rest of the graphic support (99% of it) is built into the standard True Basic.

Should you buy it? Well, if you do I recommend that you be sure to get the Developer’s Toolkit too. I haven’t seen the Developer’s Toolkit yet (I hope to be able to review it soon!) so I can’t form an opinion yet, but since I expect it to be similar or better than the original ToolBox routines (from version 1.0) I would say that it should turn out to be a pretty decent package. True Basic costs $99.95, so with the Toolkit it will be about $170 for the whole enchilada. If you are an educator you may be able to get really good prices on everything (about half price). I would say that there is a lot of potential for more support for True Basic in the future.

ProtoTyper Creates Shell Program Code

Thank goodness for software developers. At least that’s what I say when I don’t have the time to write my own software and I need to do something right now. The problem is the length of time it takes to develop software. There are a number of you that, like myself, work full time at a job other than programming and then have family and other responsibilities take you away from that great idea for a software package. Time is valuable, especially when the only time you may have is on weekends and a little time each evening.

One solution to my time schedule problem has been to write most of my programs in Basic because it is “quick and dirty”. I can usually see my results during the same weekend or maybe two weekends for a longer program, compared to several weeks working with a full blown Pascal program. That used to be the only solution available to me (except to give it up and not write anything) until recently. It’s been different lately.

PRESENTING PROTOTYPER™

Back at MacWorld Expo in San Francisco I saw Prototyper™ for the first time. Prototyper is one of those truly ingenious ideas whose time has come. If you haven’t yet seen it or read about it yet then keep on reading. If you have heard of Prototyper then I don’t want it said that it wasn’t ever mentioned in MacTutor.

What is Prototyper? Prototyper is a tool which is used to help you to develop the conceptual design of your software and get you started with your software. It is not all things to all people, but it is a unique tool which may be used to save many hours of development time. Prototyper is not a language compiler; it is a code generation program and resource compiler of a sort. Anyone that uses resources such as menus, windows, dialogs, icons, or controls can make use of Prototyper.

Prototyper is not just another substitute for ResEdit. ResEdit is still very useful for what it does, but Prototyper adds another element of user friendliness to the sometimes hostile world of software development. Let’s look at a typical sample Prototyper application. The Prototyper window lists the windows and dialogs that have been defined. Clicking on the menu icon invokes the menu editor. Clicking on the window icon invokes the window/dialog editor. (See fig. 1 previous page)

The Menu editor is similar to other menu editors I have seen before. By clicking in the first column, Menus:, you can select and change the menu to edit. Clicking on an item in the second column lets you edit each item. The current menu is presented in the menu bar so you can see what you actually get. It’s a good thing because the scrolling window is so narrow that longer menu item names can’t be seen. A wider window here or a better way to scroll would be valuable, but is not essential to creating a menu successfully. You may check, disable items, or add command-keys. Icons may be added to menus to add a personal touch. Icons may be read in from any application and modified with the icon editor. The Link button links any item to a defined window or dialog. More on that later. Only one menu can be created. (See fig. 2 below)

The window editor allows you to create almost any kind of window, dialog, or alert and add text, buttons, scroll bars, active or inactive icons, lists, lines, and rectangles. You should decide before hand whether or not you should use a window, dialog or alert as defined in the guidelines in Inside Macintosh. At least once I created a dialog or alert and used it the wrong way and Prototyper bombed! Except for that it was extremely easy to use. (See fig. 3 below)

I created a sample window and sample dialog for this example. The dialog will serve as my About Dialog when the application is created so I have linked the About menu item (in the Menu Editor) to the DIALOG -About Dialog window and set the OK button to close the dialog when pressed. I included some sample buttons and a scroll bar so that you could see how that works. The scroll bars and buttons will move and toggle, but don’t effect anything else. They won’t do anything until they are updated in the Pascal source code. (See fig. 4 below)

There are a few areas that are deficient that SmethersBarnes needs to work on to improve the next version. One deficiency is that you can’t set up hierarchical menus from within Prototyper. That doesn’t mean that you can’t do it yourself. It just means that you won’t have the menu resources for hierarchical menus set up for you. The next version of Prototyper promises hierarchical menus and support for C. The current version supports four different versions of Pascal, LightSpeed™ Turbo™, MPW™, and TML™. I don’t know if that includes the new TML Pascal II which runs under MPW. I’m very pleased with the results of the LightSpeed code. You set up your preferences and dump the code to the appropriate LightSpeed type files. A resource file is also created along with an RMaker source file (except for PICT resources). (See fig. 5)

Prototyper generates a shell for you which incorporates all of the menus and windows which were created in the Menu and Window Editor. It’s too bad that only one menu may be used, but the shell must be able to work with many different application designs. A sample of the LightSpeed Pascal is given on the source code disk for this issue of MacTutor.

I wholeheartedly recommend Prototyper to anyone that would like to write full blown applications, but can’t use Basic for one reason or another and doesn’t want to take a lot of time writing the shell the application. Some of you might not need Prototyper if you already have your own custom application shell, but even then Prototyper is a great way to create the resources. There are things that can and will improve, such as adding hierarchical menus and generation of C source code, but even without some of the enhancements, Prototyper is a major time saver. Improvements will come with time.

unit About_Dialog;

{File name:About_Dialog.Pas }
{Function: Handle a dialog }
{History: 6/13/88 Original by Prototyper. }

interface

  procedure D_About_Dialog;

implementation

  const {item numbers for controls in the Dialog}
    I_OK = 1;
    I_Static_Text = 2;
var 
    ExitDialog : boolean;  {Flag used to exit the Dialog}
  procedure D_About_Dialog;
    var
      GetSelection : DialogPtr;  {Name of dialog}
      {*ExitDialog : Boolean; declared global for filter routine *} {Flag 
to exit dialog}
      tempRect : Rect;          {Temporary tectangle}
      DType : Integer;          {Type of dialog item}
      Index : Integer;          {For looping}
      DItem : Handle;           {Handle to the dialog item}
      CItem, CTempItem : controlhandle;
      sTemp : Str255;     {temp holding}
      itemHit : Integer;        {Get selection}
      temp : Integer;         {temp holding}
      Icon_Handle : Handle;   {Temp handle to read Icon }
      NewMouse : Point;    {Mouse loc,tracking Icon presses}
      InIcon : boolean;       {Flag to say pressed in an Icon}
      ThisEditText : TEHandle;  {Handle to Dialogs TE record}
      TheDialogPtr : DialogPeek;  {Pntr to Dialogs def record}
   
  {This is an update routine for non-controls in the dialog} 
  {This is executed after the dialog is uncovered by an alert} 
  procedure Refresh_Dialog;  {Refresh dialogs non-controls}
    var 
      rTempRect:Rect;    {Temp rectangle used for drawing}
    begin 
  end; 
   
    begin        {Start of dialog handler}
      GetSelection := GetNewDialog(2, nil,  Pointer(-1) );
      ShowWindow(GetSelection);         {Open a dialog box}
      SelectWindow(GetSelection);       {Lets see it}
      SetPort(GetSelection); 
      TheDialogPtr := DialogPeek(GetSelection); 
      ThisEditText := TheDialogPtr^.textH; 
      HLock(Handle(ThisEditText));      {Lock it for safety}
      ThisEditText^^.txSize := 12;      {TE Point size}
      TextSize(12);                     {Window Point size}
      ThisEditText^^.txFont := systemFont; {TE Font ID}
      TextFont(systemFont);             {Window Font ID}
      ThisEditText^^.txFont := 0;       {TE Font ID}
      ThisEditText^^.fontAscent := 12;  {Font ascent}
      ThisEditText^^.lineHeight := 12 + 3 + 1; 
 {Font ascent + descent + leading}
      HUnLock(Handle(ThisEditText));   {UnLock handle}
       
      {Setup initial conditions}      
      ExitDialog:=FALSE;  {Do not exit dialog handle loop yet}      
      repeat          {Start of dialog handle loop}
        ModalDialog(nil, itemHit);  {Wait til item hit}
        GetDItem(GetSelection, itemHit, DType, DItem, tempRect); {Get 
item information}
        CItem := Pointer(DItem);  {Get the control handle}       
        if (ItemHit =I_OK) then  {Handle Button pressed}
          begin
          {?? Code to handle this button goes here}
          ExitDialog:=TRUE;  {Exit dialog when selection made}
          end;               {End for this item selected}
      until ExitDialog;  
       
      {Get results after dialog}
      DisposDialog(GetSelection);   {Flush dialog}
    end;                            {End of procedure}
  end.                             {End of unit}
  
unit  HandleTheMenus;

{File name :HandleTheMenus.Pas}
{Function: Handle all menu selections.}
{  This procedure is called when a menu item is selected.}
{  There is one CASE statement for all Lists.  There is}
{  another CASE for all the commands in each List.}
{History: 6/13/88 Original by Prototyper.   }

interface

uses
  About_Dialog, Sample_Window, InitTheMenus;

  procedure Handle_My_Menu(var doneFlag:boolean; theMenu,theItem:integer; 
var theInput:TEHandle);

implementation

  procedure Handle_My_Menu; {menu selections realtime}
    const
      L_Apple = 201;                    {Menu list}
      C_About_this_Sample = 1;
      L_File = 202;                     {Menu list}
      C_Quit = 1;
      L_Edit = 203;                     {Menu list}
      C_Undo = 1;
      C_Cut = 3;
      C_Copy = 4;
      C_Paste = 5;
      C_Clear = 6;
      C_Select_All = 7;
    var
      DNA:integer;                     {For opening DAs}
      BoolHolder:boolean;              {For SystemEdit result}
      DAName:Str255;                   {For getting DA name}
      SavePort:GrafPtr;   {Save current port when opening DAs}  
    begin                   {Start of procedure}     
        case theMenu of     {Do selected menu list}     
        L_Apple:
          begin
            case theItem of {Handle commands in menu list}
              C_About_this_Sample:
                begin
                  D_About_Dialog; {Call dialog for this}
                end;
              otherwise                 {Handle the DAs}
                begin                   {Start of Otherwise}
                  GetPort(SavePort);    {Save current port}
                  GetItem(AppleMenu, theItem, DAName); {DA}
                  DNA := OpenDeskAcc(DAName); {Open DA }
                  SetPort(SavePort);    {Restore saved port}
                end;                    {End of Otherwise}  
            end;                        {End of item case}
          end;                          {End for this list}
      
        L_File:
          begin
            case theItem of 
              C_Quit:
                begin
                  doneFlag := TRUE;
                end;
              otherwise
                begin
                end;
             
            end;                        {End of item case}
          end;                          {End for this list}
      
        L_Edit:
          begin
            BoolHolder := SystemEdit ( theItem - 1 ); 
 {Do DA editing}
            if not (BoolHolder) then    
 {If not a DA then we get it}
              begin    {Handle by using a Case statment}
              case theItem of  {Handle all commands in list}
                C_Undo:
                  begin
                    {?? ADD IN WHAT THIS COMMAND SHOULD DO}
                  end;
                C_Cut:
                  begin
                    {?? ADD IN WHAT THIS COMMAND SHOULD DO}
                  end;
                C_Copy:
                  begin
                    {?? ADD IN WHAT THIS COMMAND SHOULD DO}
                  end;
                C_Paste:
                  begin
                    {?? ADD IN WHAT THIS COMMAND SHOULD DO}
                  end;
                C_Clear:
                  begin
                    {?? ADD IN WHAT THIS COMMAND SHOULD DO}
                  end;
                C_Select_All:
                  begin
                    {?? ADD IN WHAT THIS COMMAND SHOULD DO}
                  end;
                otherwise  {Send to a DA}
                  begin    {Start of the Othersize}
                  end;     {End of Otherwise}
               
              end;          {End of item case}
              end;          {End of not BoolHolder}
          end;              {End for this list}
      
        otherwise
          begin
          end;      
      end;                  {End for lists}     
      HiliteMenu(0);   {Turn menu selection off}
    end;               {End of procedure Handle_My_Menu}  
end.                   {End of unit}

unit  InitTheMenus;
 
{File name:InitTheMenus.Pas}
{Function: Pull in menu lists from a resource file.}
{    This procedure is called once at program start.}
{    AppleMenu is the handle to the Apple menu, it is also}
{    used in the procedure that handles menu events.}
{ History: 6/13/88 Original by Prototyper.   }

interface
 
  procedure Init_My_Menus;  {Initialize the menus}
 
  var
    AppleMenu:MenuHandle;  {Used to handle DAs}      
 
implementation
 
  procedure Init_My_Menus;    {Initialize the menus}
  const
    Menu1 = 201;                {Menu resource ID}
    Menu2 = 202;                {Menu resource ID}
    Menu3 = 203;                {Menu resource ID}
  var
    tempMenu:MenuHandle;  {Throw away all other menu handles}
      
  begin                  {Start of Init_My_Menus}
    ClearMenuBar;         {Clear any old menu bars}
      
    { APPLE menu, used for About & desk accessories.}
    tempMenu := GetMenu(Menu1);   {Get menu from res file}
    AddResMenu(tempMenu,’DRVR’);  {Add in DAs}
    InsertMenu (tempMenu,0);      {Insert menu into menu bar}
    AppleMenu:=tempMenu;          {Save menu handle for later}
    { This menu is  File  }
    tempMenu := GetMenu(Menu2);    
    InsertMenu (tempMenu,0);            
    { This menu is  Edit  }
    tempMenu := GetMenu(Menu3);         
    InsertMenu (tempMenu,0);            
    DrawMenuBar;       {Draw the menu bar}
end;                  {End of procedure Init_My_Menus}
end.


Set  RUN OPTIONS to use the resource file  Prototyper_Sample.RSRC
RMaker file to use is Prototyper_Sample.R 
The Project should have the following files in it: 
     MacPasLib      LSP This is the Pascal library file
     MacTraps       LSP This is for Mac routines to be called}
     ROM85          LSP This is necessary if you use any Lists}
     ROM85Lib       LSP This is necessary if you use any Lists}
     ListManager    LSP This is necessary if you use any Lists}
     About_Dialog        Modal Dialog
     Sample_Window       Window
     InitTheMenus.Pas    This initializes the Menus.
     HandleTheMenus      Handle the menu selections.
     Prototyper_Sample.Pas    Main program

Program  Prototyper_Sample;
{Program name:Prototyper_Sample.Pas   }
{Function:  This is the main module for this program.  }
{History: 6/13/88 Original by Prototyper.   }

uses
  About_Dialog, Sample_Window, InitTheMenus, HandleTheMenus;

  var                          {Main variables}
    myEvent:EventRecord;        {Event record for all events}
    doneFlag:boolean;           {Exit program flag}
    code:integer;               {Determine event type}
    whichWindow:WindowPtr;      {See which window for event}
    tempRect:Rect;              {Rect for dragging}
    mResult:longint;    {Menu list and item selected values}
    theMenu,theItem:integer;     {Menu list and item selected}
    chCode : integer;            {Key code}
    ch : char;                   {Key pressed in Ascii}
    theInput:TEHandle;         {Used in text edit selections}
 
  begin                           {Start of main body}
 
    MoreMasters;     {This reserves space for more handles}
    InitGraf(@thePort);           {Quickdraw Init}
    InitFonts;                    {Font manager init}
    InitWindows;                  {Window manager init}
    InitMenus;                    {Menu manager init}
    TEInit;                       {Text edit init}
    InitDialogs(nil);             {Dialog manager} 
    FlushEvents(everyEvent, 0);   {Clear out all events}
    InitCursor;                   {Make an arrow cursor}
    doneFlag:=FALSE;            {Do not exit program yet}
      
    Init_My_Menus;              {Initialize menu bar} 
    theInput:=nil; {Init to no text edit selection active}
    Init_Sample_Window;  {Initialize the window routines}
    Open_Sample_Window;  {Open wind routines at program start}
 
    repeat                   {Start of main event loop}
      if (theInput <> nil) then {See if a TE is active}
        TEIdle(theInput);  {Blink cursor if everything ok}
      SystemTask;      {support of desk accessories} 
      if GetNextEvent(everyEvent, myEvent) then 
        begin         {Start handling the event}
        code := FindWindow(myEvent.where, whichWindow); 
        case myEvent.what of    {Decide type of event}
          MouseDown :         {Mouse button pressed}
            begin            {Handle the pressed button}
              if (code = inMenuBar) then
                begin  {Get menu selection and handle it}
                     mResult := MenuSelect(myEvent.Where); 
                     theMenu := HiWord(mResult); 
                     theItem := LoWord(mResult); 
                 Handle_My_Menu(doneFlag,theMenu,theItem, theInput); 

                end;             {End of inMenuBar}
 
              if (code = InDrag) then   {window drag area}
                begin      {Do dragging the window}
                tempRect:= screenbits.bounds; {screen l,t,r,b}
                      SetRect(tempRect,tempRect.Left+10, tempRect.Top+25,tempRect.Right-10,tempRect.Bottom-10); 

                DragWindow(whichWindow, myEvent.where, tempRect); 
                end;            {End of InDrag}
 
              if (code = inGrow) then   {In grow area}
                begin         {Handle the growing}
                tempRect:= whichWindow^.portRect;  
 {Get size and position}
                tempRect.Right := tempRect.Right - tempRect.Left + 1; 
{Adjust to local}
                tempRect.left := tempRect.Right - 18; 
 {Do for width of right edge}
                tempRect.Bottom := tempRect.Bottom - tempRect.Top + 1; 
{Get window height}
                tempRect.top := 0;   {for height of window}
                EraseRect(tempRect);    {Erase old right edge}
                tempRect:= whichWindow^.portRect;  
 {Get window size and position}
                tempRect.Right := tempRect.Right - tempRect.Left + 1; 
{Adjust to local}
                tempRect.left := 0;  {Do width of  window}
                tempRect.Bottom := tempRect.Bottom - tempRect.Top + 1; 
{Get window height}
                tempRect.top := tempRect.Bottom - 18; {Do for height 
of the edge}
                EraseRect(tempRect);  {Erase old bottom edge}
                SetRect(tempRect, 20, 20, 1000, 1000);  {Min Horz size, 
Min Vert size, Max Horz size, Max Vert size}
                mResult := GrowWindow(whichWindow, myEvent.where, tempRect); 
{Grow it}
                SizeWindow(whichWindow, LoWord(mResult), HiWord(mResult), 
TRUE); {Resize to result}
                DrawGrowIcon(whichWindow); {Draw grow Icon again}
                end;   {End of doing the growing}
 
              if (code = inGoAway) then {window goaway area}
                begin   {Handle the goaway button}
                If TrackGoAway(whichWindow,myEvent.where) then 
 {See if mouse released in GoAway box}
                  begin     {Handle the GoAway}
                  Close_Sample_Window(whichWindow,theInput);
 {Close this window}
                  end;       {End of TrackGoAway}
                end;         {End of InGoAway}
 
              if (code = inContent) then {See if in a window}
                begin     {Handle the hit inside a window}
                if (whichWindow <> FrontWindow) then 
                  SelectWindow(whichWindow) 
                else    
                  begin  {Handle the button in the content}
                  SetPort(whichWindow); {Get ready to draw}
                  Do_Sample_Window ( myEvent,theInput ); 
                  end;         {End of else}
                end;           {End of inContent}
 
              if (code = inSysWindow) then {DA?}
                SystemClick(myEvent, whichWindow); 
 
            end;              {End of MouseDown}
 
          KeyDown,AutoKey:    {Handle key inputs}
            begin         {Get the key and handle it}
              with myevent do    {menu command keys}
                begin  
                  chCode := BitAnd(message, CharCodeMask); 
 {Get character}
                  ch := CHR(chCode);    {Change to ASCII}
                  if (Odd(modifiers div CmdKey)) then 
 {See if Command key is down}
                     begin        
                     mResult := MenuKey(ch); {menu selection}
                     theMenu := HiWord(mResult); 
                        theItem := LoWord(mResult); 
                     if (theMenu <> 0) then 
 {See if a list was selected}
                     Handle_My_Menu(doneFlag,theMenu, theItem,theInput); 
{Do the menu selection}
                     if ((ch = ‘x’) or (ch = ‘X’)) and (theInput <> nil) 
then
                      TECut(theInput);  {Handle a TE Cut}
                    if ((ch = ‘c’) or (ch = ‘C’)) and (theInput <> nil) 
then {}
                      TECopy(theInput); {Handle a TE Copy}
                    if ((ch = ‘v’) or (ch = ‘V’)) and (theInput <> nil) 
then
                      TEPaste(theInput); {Handle a Paste}
                   end                                         
 
 else if (theInput <> nil) then 
                    TEKey(ch,theInput);                 
 end;  {End for with}
            end;      {End for KeyDown,AutoKey}
 
          UpDateEvt :   {Update event for a window}
            begin       {Handle the update}
              whichWindow := WindowPtr(myEvent.message); 
 {Get the window the update is for}
              BeginUpdate(whichWindow); 
 {Set the clipping to the update area}
              Update_Sample_Window ( whichWindow ); 
 {Update this window}
              EndUpdate(whichWindow);   
 {Return to normal clipping area}
            end;         {End of UpDateEvt}
 
          DiskEvt :     {Disk inserted event}
            begin       {Handle a disk event}
            {Ck for disk event}  
 {?? ADD CALL TO HANDLE A DISK INSERTED}
            end;         {End of DiskEvt}
            
          ActivateEvt :   {Window activated event}
            begin         {Handle the activation}
              whichWindow := WindowPtr(myevent.message); 
 {Get the window to be activated}
              if odd(myEvent.modifiers) then 
 {Activate and not DeActivate}
                 SelectWindow(whichWindow); 
 {Activate the window by selecting it}
            end;          {End of ActivateEvt} 
          otherwise       
            begin                                              {?? ADDED 
FOR CATCHING OTHER EVENTS}
            end;             {End of otherwise}
        end;                 {End of case}
        end;                 {end of GetNextEvent}
    until doneFlag;          {End of the event loop}
end.                         {End of the program}

unit  Sample_Window;

{File name: Sample_Window.Pas}
{Function: Handle a Window}
{History: 6/13/88 Original by Prototyper. }

interface

  {Initialize us so all our routines can be activated}
  procedure Init_Sample_Window;

  {Close our window}
  procedure Close_Sample_Window(whichWindow:WindowPtr; var theInput:TEHandle);

  {Open our window and draw everything}
  procedure Open_Sample_Window;

  {Update our window, someone uncovered a part of us}
  procedure Update_Sample_Window(whichWindow:WindowPtr);

  {Handle action to our window, like controls}
  procedure Do_Sample_Window(myEvent:EventRecord; var theInput:TEHandle);

implementation

  const
    I_Buttonx1 = 4;                     {Button ID}
    I_Checkbox1 = 6;                    {Checkbox ID}
    I_Checkbox2 = 17;                   {Checkbox ID}
    I_Radio1 = 7;                       {Radio ID}
    I_Radio2 = 18;                      {Radio ID}
    I_Edit_Text = 3;                    {Edit text ID}
    I_Scroll_bar = 5;                   {Scroll bar ID}
  var
    MyWindow:WindowPtr;                 {Window pointer}
    tempRect : Rect;                    {Temporary rectangle}
    Index : Integer;                    {For looping}
    CtrlHandle : controlhandle;         {Control handle}
    sTemp : Str255;           {Get text entered, temp holding}
    R1Control:array[1..2] of ControlHandle; { Radio button }
    TE_I_Edit_Text: TEHandle; {Text Edit field handle}
 
{=================================}
 
  {Initialize us so all our routines can be activated}
  procedure Init_Sample_Window;
 
  begin    {Start of Window initialize routine}
    MyWindow:=nil; {other routines must know not valid yet}
  end;     {End of procedure}

{=================================}
 
  {Close our window}
  procedure Close_Sample_Window;
 
  begin                {Start of Window close routine}
    if (MyWindow <> nil) and (MyWindow = whichWindow) then     
 {Close if this is us}
      begin
      if (theInput = TE_I_Edit_Text) then 
 {See if this Text Edit field handle}
      theInput:= nil;     {Clear the handle used}
      DisposeWindow(MyWindow);  {Clear window and controls}
      MyWindow:=nil;  {notify routines window open}
      end;        {End for if (MyWindow<>nil)}
  end;            {End of procedure}

{=================================}
 
  {Update our window, someone uncovered a part of us}
  procedure UpDate_Sample_Window;
  var
    SavePort : WindowPtr;  {Place to save the last port}
    Pic_Handle: PicHandle; {Pict handle for pict loaded }
    sTemp:Str255;    {Temporary string}

  begin          {Start of Window update routine}
    if (MyWindow <> nil) and (MyWindow = whichWindow) then     
 {Handle an open when already opened}
      begin
      GetPort(SavePort);    {Save the current port}
      SetPort(MyWindow);    {Set the port to my window}
      Pic_Handle := GetPicture(9 ); {Get Picture into memory}
      SetRect(tempRect, 188,141,247,218); 
      if (Pic_Handle <> nil) then   
        DrawPicture ( Pic_Handle , tempRect ); 
 {Draw this picture}
      
      TextFont(systemFont);  {Set the font to draw in}
      {Draw a string of text, Static Text }
      SetRect(tempRect, 252,146,330,184);
      sTemp :=’Read MacTutor!’;
      TextBox(Pointer(ord(@sTemp) + 1), length(sTemp), tempRect, teJustLeft);
      TextFont(applFont); {Set the default application font}
      
      {Update a TE box, Edit Text }
      SetRect(TempRect,46,27,294,129); {left,top,right,bottom}
      InsetRect(TempRect,-2,-2);        {Surround the TE area}
      FrameRect(TempRect);              {Frame this TE area}
      if (TE_I_Edit_Text <> nil) then   
 {Only update if TE area is valid}
        TEUpdate(TempRect,TE_I_Edit_Text); {Update TE area}
      
      DrawControls(MyWindow); {Draw all the controls}
      DrawGrowIcon(MyWindow);  {Draw the Grow box}
      SetPort(SavePort);                {Restore the old port}
    end;              {End for if (MyWindow<>nil)}
  end;                {End of procedure}

{=================================}
 
  {Open our window and draw everything}
  procedure Open_Sample_Window;
  var
    Index : Integer;                    {For looping}
    dataBounds : Rect;                  {For making lists}
    cSize : Point;                      {For making lists}

  begin               {Start of Window open routine}
    if (MyWindow = nil) then      
 {Handle an open when not already opened}
      begin
      MyWindow:= GetNewWindow(1,nil, Pointer(-1)); 
      SelectWindow(MyWindow);   {Bring window to the front}
      SetPort(MyWindow);    {Prepare to write into our window}
      { Make a button, Button }
      CtrlHandle := GetNewControl(I_Buttonx1,MyWindow); 
      { Make a checkbox, Checkbox1 }
      CtrlHandle := GetNewControl(I_Checkbox1,MyWindow); 
      { Make a checkbox, Checkbox2 }
      CtrlHandle := GetNewControl(I_Checkbox2,MyWindow);  
      { Make a radio button, Radio1 }
      R1Control[1] := GetNewControl ( I_Radio1 , MyWindow );
      { Make a radio button, Radio2 }
      R1Control[2] := GetNewControl ( I_Radio2 , MyWindow );
      { Make a scroll bar, Scroll bar }
      CtrlHandle := GetNewControl(I_Scroll_bar,MyWindow); 
      {Open a TE box, Edit Text }
      SetRect(TempRect,46,27,294,129); {left,top,right,bottom}
      InsetRect(TempRect,-2,-2);        {Surround the TE area}
      FrameRect(TempRect);              {Frame this TE area}
      InsetRect(TempRect,2,2);     {Restore the original size}
      TE_I_Edit_Text:= TENew(TempRect,TempRect); 
 {Create the TE area}
      HLock(Handle(TE_I_Edit_Text));    {Lock the handle}
      TE_I_Edit_Text^^.txFont := geneva; {Font}
      TE_I_Edit_Text^^.fontAscent := 12; {Font ascent}
      TE_I_Edit_Text^^.lineHeight := 12 + 3 + 1; 
 {Font ascent + descent + leading}
      HUnLock(Handle(TE_I_Edit_Text));  {UnLock the handle}
      sTemp:= ‘Edit Text’;
      {Default text string}
      TESetText(Pointer(Ord4(@sTemp)+1),length(sTemp), TE_I_Edit_Text); 
{Place default text in the TE area}
      TEActivate(TE_I_Edit_Text); {Make the TE area active}
      TEUpdate(TempRect,TE_I_Edit_Text);
      TextFont(applFont); {Set the default application font}
      UpDate_Sample_Window(MyWindow);   {update draws it}
      end        {End for if (MyWindow<>nil)}
    else
      SelectWindow(MyWindow);   {Already open, so show it}
  end;         {End of procedure}

{=================================}
 
  {Handle action to our window, like controls}
  procedure Do_Sample_Window;
  var
    RefCon:integer; {RefCon for controls}
    code:integer;   {Location of event in window or controls}
    theValue:integer;  {Current value of a control}
    whichWindow:WindowPtr;  {Window pntr where event happened}
    myPt:Point;      {Point where event happened}
    theControl:ControlHandle;  {Handle for a control}

  Procedure Do_A_Button;  {Handle a button being pressed}
  begin
    HiliteControl(theControl, 10);      {Darken the button}
    RefCon := GetCRefCon(theControl);   {get control refcon}
    case RefCon of          {Select correct button}
            I_Buttonx1:       {Button, button}
              begin          {start for this button}
                {??? HANDLE THE BUTTON BEING PRESSED HERE}
              end;            {end for this button}
          
          otherwise     {allow other buttons}
              begin      {start}
              end;        {end of otherwise}
    end;             {end of case}
    HiliteControl(theControl, 0);  {Lighten the button}
  end;   {Handle a button being pressed}

  Procedure Do_A_Checkbox;  {checkbox being pressed}
  var
    Index:integer;    {Index used for radios}

  procedure Clear1RadioGroup;  {clear radios in group 1}
  var
    Index:integer;   {Index used for radios}
  begin              {Start of the clear routine}
    for Index := 1 to 2 do   {Step thru all radios}
      SetCtlValue(R1Control[Index],0);  {Set this to zero}
  end;             {End of the clear routine}

  begin            {Handle a checkbox being pressed}
    RefCon := GetCRefCon(theControl);   {get control refcon}
    theValue := GetCtlValue(theControl); {Get current value}
    theValue := (theValue + 1) mod 2;   {Change value}
    case RefCon of      {Select correct button}
            I_Checkbox1:  {Checkbox1, checkbox}
              begin      {start for this button}
                {??? HANDLE THE CHECKBOX BEING PRESSED HERE}
                SetCtlValue(theControl, theValue); 
 {Set checkbox to new value}
              end;    {end for this checkbox}
          
            I_Checkbox2:     {Checkbox2, checkbox}
              begin         {start for this button}
                {??? HANDLE THE CHECKBOX BEING PRESSED HERE}
                SetCtlValue(theControl, theValue); 
 {Set checkbox to new value}
              end;           {end for this checkbox}
          
            I_Radio1:       {Radio1 , radio button}
               begin       {start for this radio button}
                {??? HANDLE THE RADIO BEING SELECTED HERE}
                Clear1RadioGroup;  {Clear all Radio values}
                SetCtlValue(theControl, 1); {Select Radio}
              end;     {end for this radio button}
          
            I_Radio2:    {Radio2 , radio button}
               begin    {start for this radio button}
                {??? HANDLE THE RADIO BEING SELECTED HERE}
                Clear1RadioGroup;       {Clear all Radio }
                SetCtlValue(theControl, 1); {Select Radio}
              end;       {end for this radio button}
          otherwise {allow other checkboxes and radios}
              begin  {start}
              end;   {end of otherwise}
    end;    {end of case}
  end;      {Handle a checkbox being pressed}

  Procedure Do_A_ScrollBar(code:integer); 
 {Handle a ScrollBar being pressed}

    procedure HandleWScrollBar (code, Start, Stop, Increment, LIncrement 
: integer; theControl : ControlHandle);
    var
      theValue : integer;   {Value of the scrollbar}
      myPt : Point;    {Returned point from track}
  
    begin
      theValue := GetCtlValue(theControl); {Get current state}
      if (code = inUpButton) then   {See if in up/left arrow}
        begin
        theValue := theValue - Increment; 
        if (theValue < Start) then      
          theValue := Start;   {Bump at the start value}
        end;
      
      if (code = inDownButton) then     
 {See if in the down/right arrow}
        begin
        theValue := theValue + Increment; 
        if (theValue > Stop) then       
          theValue := Stop;    {Bump at the stop value}
        end;
      
      if (code = inPageUp) then     
 {See if in the up/left grey area}
        begin
        theValue := theValue - LIncrement; 
 {Subtract the page increment}
        if (theValue < Start) then      
          theValue := Start; {Bump at the Start value}
        end;
      
      if (code = inPageDown) then {down/right grey area}
        begin
        theValue := theValue + LIncrement; {page increment}
        if (theValue > Stop) then  
          theValue := Stop;   {Bump at the Stop value}
        end;
      
      if (code = inThumb) then   {drag box area}
        begin
        code := TrackControl(theControl, myPt, nil); 
 {Let the OS drag it around}
        theValue := GetCtlValue(theControl); 
 {Get current state}
        end;
      SetCtlValue(theControl, theValue); {Set new state}
    end;             {End of handle scroll bar}
  
  begin             {Handle a ScrollBar being pressed}
    RefCon := GetCRefCon(theControl);   {get control refcon}
    case RefCon of   {Select correct scrollbar}
            I_Scroll_bar:   {Scroll bar’, scroll bar}
              begin        {start for this scroll bar}
                HandleWScrollBar(code,1,10,1,10,theControl);   
 {code,Min,Max,Inc,PageInc,handle}
              end;           {end for this scroll bar}
          
          otherwise     
              begin           {start}
              end;             {end of otherwise}
    end;                       {end of case}
  end;      {Handle a ScrollBar being pressed}

  begin                 {Start of Window handler}
    if (MyWindow <> nil) then  
      begin
      code := FindWindow(myEvent.where, whichWindow); 
      if (myEvent.what = MouseDown) and (MyWindow = whichWindow) then 

        begin                  
        myPt := myEvent.where;  {Get mouse position}
        with MyWindow^.portBits.bounds do {Make it relative}
          begin
            myPt.h := myPt.h + left;
            myPt.v := myPt.v + top;
          end;       
        SetRect(tempRect,46,27,294,129); {Position of the TE}
        if PtInRect(myPt,tempRect) then {Check for pressed in the TE 
 Edit Text }
          begin                         
          theInput:= TE_I_Edit_Text;    
          TEClick(myPt, FALSE, TE_I_Edit_Text); 
          end;                          
        
        SetRect(tempRect,188,141,247,218); {Position of Pict}
        if PtInRect(myPt,tempRect) then {mouse in pict?}
          begin
 { do somethng for mouse click in pict}                        
          end;                          
         end;
      if (MyWindow = whichWindow) and (code = inContent) then  
 {for our window}
        begin 
        code := FindControl(myPt, whichWindow, theControl); 
        if (code <> 0) then   {Check type of control}
          code := TrackControl(theControl,myPt, nil); 
        if code = inButton then
          Do_A_Button;                  {Do buttons}
        if code = inCheckBox then
          Do_A_Checkbox;                {Do checkboxes}
        if (code = inUpButton) or (code = inDownButton) or (code = inThumb) 
or  (code = inPageDown) or (code = inPageUp) then
          Do_A_ScrollBar(code);         {Do scrollbars}      
        end;      {End for if (MyWindow=whichWindow)}
      end;        {End for if (MyWindow<>nil)}
  end;            {End of procedure}

{=================================} 
end.   {End of unit}

***************************************
*
* RMaker resource file sources.
* File: Prototyper_Sample.R
* History: 6/13/88 Original by Prototyper.   
* This file contains the sources for all 
* the resources except for Pictures. 
*
***************************************
*

Prototyper_Sample.RSRC
APPL????

*
* This is the definition for the DIALOG.
*
Type DLOG
*
     ,2                                 ;;Resource ID
About Dialog                            ;;Dialog title
50  120  189  427                       ;;Top Left Bottom Right
Visible NoGoAway                        ;;Visible GoAway 
1                                       ;;ProcID, dialog def ID
2                                       ;;Refcon, reference value
2                                       ;;ID of item list

*
* This is the DIALOG or ALERT item list.
*
Type DITL
*
     ,2          ;;Resource ID
2                ;;Number of controls in list

Button  Enabled  ;;Push button
100  102  129  178    ;;Top Left Bottom Right
OK                  ;;message

StaticText          ;;Static text
9  10  93  295       ;;Top Left Bottom Right
Sorry, this program really does nothing.\0D©1988 MacTutor\0D©1986 THINK 
Technologies, Inc. Certain portions of this software are copyrighted 
by THINK Technologies, Inc. ;;message

*
* This is the definition for the WINDOW.
*
Type WIND
*
     ,1               ;;Resource ID
Sample Window         ;;Window title
41  3  305  350       ;;Top Left Bottom Right
Visible  GoAway       ;;Visible GoAway 
0                     ;;ProcID, Window def ID
1                     ;;Refcon, reference value

*
* This is the CONTROL item list.
*
Type CNTL
*
   ,4                   ;;Resource ID
Button                  ;;Title for a Button
142  46  168  129       ;;Top Left Bottom Right
Visible                 ;;Initially visible 
0                       ;;ProcID (Control definition ID)
4                       ;;RefCon (reference value)
0 1 0                   ;;Min Max Value

   ,6                  ;;Resource ID
Checkbox1              ;;Title for a Checkbox
171  47  193  137      ;;Top Left Bottom Right
Visible                ;;Initially visible 
1                      ;;ProcID (Control definition ID)
6                      ;;RefCon (reference value)
0 1 1                  ;;Min Max Value

   ,17                 ;;Resource ID
Checkbox2              ;;Title for a Checkbox
190  47  212  137      ;;Top Left Bottom Right
Visible                ;;Initially visible 
1                      ;;ProcID (Control definition ID)
17                     ;;RefCon (reference value)
0 1 0                  ;;Min Max Value

   ,7                   ;;Resource ID
Radio1                  ;;Title for a RadioButton
217  47  242  139       ;;Top Left Bottom Right
Visible                 ;;Initially visible 
2                       ;;ProcID (Control definition ID)
7                       ;;RefCon (reference value)
0 1 0                  ;;Min Max Value

   ,18                 ;;Resource ID
Radio2                 ;;Title for a RadioButton
216  145  241  237     ;;Top Left Bottom Right
Visible                ;;Initially visible 
2                      ;;ProcID (Control definition ID)
18                     ;;RefCon (reference value)
0 1 1                  ;;Min Max Value

   ,5                  ;;Resource ID
Scroll bar             ;;Title for a Scrollbar
27  293  129  309      ;;Top Left Bottom Right
Visible                ;;Initially visible 
16                     ;;ProcID (Control definition ID)
5                      ;;RefCon (reference value)
1  10  1               ;;Min Max Value

*
* This is the PICTs for the Window list above.
* Move the pictures from the resource data file 
* after this is compiled.
* Type PICT
*

* This Picture is Picture
*  9                       ;;PICT Resource ID

*
* This is the definition for the MENU.
*
Type MENU
*

     ,201                   ;;Resource ID
\14                         ;;APPLE menu title
About this Sample...        ;;item title
(-                          ;;

     ,202                               ;;Resource ID
File                                    ;;menu title
Quit/Q                                  ;;item title

     ,203                               ;;Resource ID
Edit                                    ;;menu title
Undo/Z                                  ;;item title
(-                                      ;;
Cut/X                                   ;;item title
Copy/C                                  ;;item title
Paste/V                                 ;;item title
Clear                                   ;;item title
Select All                              ;;item title

 
AAPL
$101.06
Apple Inc.
+0.10
MSFT
$47.06
Microsoft Corpora
-0.46
GOOG
$587.37
Google Inc.
-8.71

MacTech Search:
Community Search:

Software Updates via MacUpdate

Evernote 5.6.0 - 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
Monosnap 2.2.2 - Versatile screenshot ut...
Monosnap allows you to save screenshots easily, conveniently, and quickly, sharing them with friends and colleagues at once. It's the ideal choice for anyone who is looking for a smart and fast... Read more
Tunnelblick 3.4beta36 - GUI for OpenVPN...
Tunnelblick is a free, open source graphic user interface for OpenVPN on OS X. It provides easy control of OpenVPN client and/or server connections. It comes as a ready-to-use application with all... Read more
SoftRAID 5.0.4 - High-quality RAID manag...
SoftRAID allows you to create and manage disk arrays to increase performance and reliability. SoftRAID's intuitive interface and powerful feature set makes this utility a must have for any Mac OS X... Read more
Audio Hijack Pro 2.11.3 - Record and enh...
Audio Hijack Pro drastically changes the way you use audio on your computer, giving you the freedom to listen to audio when you want and how you want. Record and enhance any audio with Audio Hijack... Read more
Airfoil 4.8.9 - Send audio from any app...
Airfoil allows you to send any audio to AirPort Express units, Apple TVs, and even other Macs and PCs, all in sync! It's your audio - everywhere. With Airfoil you can take audio from any... Read more
WhatRoute 1.13.0 - Geographically trace...
WhatRoute is designed to find the names of all the routers an IP packet passes through on its way from your Mac to a destination host. It also measures the round-trip time from your Mac to the... Read more
Chromium 37.0.2062.122 - Fast and stable...
Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all Internet users to experience the web. FreeSMUG-Free OpenSource Mac User Group build is... Read more
Attachment Tamer 3.1.14b9 - Take control...
Attachment Tamer gives you control over attachment handling in Apple Mail. It fixes the most annoying Apple Mail flaws, ensures compatibility with other email software, and allows you to set up how... Read more
Duplicate Annihilator 5.0 - Find and del...
Duplicate Annihilator takes on the time-consuming task of comparing the images in your iPhoto library using effective algorithms to make sure that no duplicate escapes. Duplicate Annihilator detects... Read more

Latest Forum Discussions

See All

This Week at 148Apps: September 15-19, 2...
Expert App Reviewers   So little time and so very many apps. What’s a poor iPhone/iPad lover to do? Fortunately, 148Apps is here to give you the rundown on the latest and greatest releases. And we even have a tremendous back catalog of reviews; just... | Read more »
Kitty Powers’ Matchmaker – Tips, Tricks,...
Hey There, Kittens: | Read more »
Goblin Sword Review
Goblin Sword Review By Andrew Fisher on September 22nd, 2014 Our Rating: :: RETRO GOODNESSUniversal App - Designed for iPhone and iPad Fun visuals, good music, engaging level design, and lots of content make Goblin Sword an... | Read more »
Major New Update for CSR Racing Adds Fer...
Major New Update for CSR Racing Adds Ferrari and Multiplaye​r Posted by Jessica Fisher on September 22nd, 2014 [ permalink ] | Read more »
Veditor Review
Veditor Review By Jennifer Allen on September 22nd, 2014 Our Rating: :: PIMP YOUR VIDEOUniversal App - Designed for iPhone and iPad Want to add stickers and music to your videos? Veditor can do that easily.   | Read more »
1849′s Nevada Silver DLC is Still Search...
A few months ago, I took a look at 1849 from SomaSim. This Gold Rush-themed city builder for iPad had a fair bit going for it, but lacked in a few crucial areas to make it a true stand-out on the App Store. SomaSim has since added in a sandbox mode... | Read more »
Fruit Ninja Will be Reborn With a Massiv...
Fruit Ninja Will be Reborn With a Massive Update and Origins Animation Series Posted by Jessica Fisher on September 22nd, 2014 [ permalink ] Halfbrick Studios is rebuilding | Read more »
Daniel Tiger’s Grr-ific Feelings Review
Daniel Tiger’s Grr-ific Feelings Review By Amy Solomon on September 22nd, 2014 Our Rating: iPad Only App - Designed for the iPad Daniel Tiger’s Grr-ific Feelings includes activities that allow young children explore different... | Read more »
CloudMagic Updated for iOS 8 – Adds Inte...
CloudMagic Updated for iOS 8 – Adds Interactive Notifications, Share Extension, and More Posted by Jessica Fisher on September 22nd, 2014 [ | Read more »
Starbase Annex (Games)
Starbase Annex 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: "it’s really very clever... a little bit of Hearthstone and a dash of Eclipse" - PocketTactics.com From the creator of Starbase... | Read more »

Price Scanner via MacPrices.net

New iPhones Score Big in SquareTrade Breakabi...
SquareTrade has announced the iPhone 6 and its larger sibling, iPhone 6 Plus, performed impressively in Breakability testing, and each carries the top Breakability Score in their respective category... Read more
10 Million + First Weekend Sales Set New iPho...
Apple has announced it sold over 10 million new iPhone 6 and iPhone 6 Plus models, a new record, just three days after the launch on September 19. iPhone 6 and iPhone 6 Plus are now available in the... Read more
Betty Crocker Launches New Cookbook for iOS
Betty Crocker, a General Mills brand, an established food industry leader, has announced its free digital cookbook app has been refreshed to make cooking with iPhone, iPad and iPod touch even easier... Read more
Apple restocks some refurbished 2014 MacBook...
The Apple Store has restocked some Apple Certified Refurbished 2014 MacBook Airs, with prices starting at $769. An Apple one-year warranty is included with each MacBook, and shipping is free. These... Read more
13-inch 128GB MacBook Air on sale for $949, s...
B&H Photo has the new 2014 13″ 1.4GHz/128GB MacBook Air on sale for $949.99 including free shipping plus NY tax only. Their price is $50 off MSRP. B&H will also include free copies of... Read more
Apple offering free $25 iTunes Gift Card with...
The Apple Store is offering a free $25 iTunes Gift Card with the purchase of a $99 Apple TV for a limited time. Shipping is free. Read more
Apple refurbished iPod touch available for up...
The Apple Store has Apple Certified Refurbished 5th generation iPod touches available starting at $149. Apple’s one-year warranty is included with each model, and shipping is free. Most colors are... Read more
iFixIt Tears Down iPhone 6; Awards Respectabl...
iFixit notes that even the smaller 4.7″ iPhone 6 is a giant among iPhones; so big that Apple couldn’t fit it into the familiar iPhone form factor. In a welcome reversal of a recent trend to more or... Read more
Phone 6 Guide – Tips Book For Both iPhone 6...
iOS Guides has announced its latest eBook: iPhone 6 Guide. Brought to you by the expert team at iOS Guides, and written by best-selling technology author Tom Rudderham, iPhone 6 Guide is packed with... Read more
How to Upgrade iPhone iPad to iOS 8 without D...
PhoneClean, a iPhone cleaner utility offered by iMobie Inc., reveals a solution for upgrading iPhone and iPad to iOS 8 without deleting photos, apps, the new U2 album or anything. Thanks to more than... Read more

Jobs Board

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
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** At the Apple Store, you connect business professionals and entrepreneurs with the tools they need in order to put Apple solutions to work in their Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.