home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 June / MacFormat 25.iso / Shareware City / Developers / ICAppSourceKit1.0 / ICWindows.p < prev    next >
Encoding:
Text File  |  1994-11-27  |  20.4 KB  |  775 lines  |  [TEXT/PJMM]

  1. unit ICWindows;
  2.  
  3. interface
  4.  
  5.     uses
  6.         ICWindowGlobals;
  7.  
  8.     function InitICWindows: OSErr;
  9.  
  10.     function WindowsOpen (wt: WindowType; id: integer): OSErr;
  11.     function WindowsClose (wp: WindowPtr): OSErr;
  12.     function WindowsFlushAll: OSErr;    (* close all information windows *)
  13.     function WindowsCloseAll: OSErr;    (* close all information windows *)
  14.  
  15.     procedure WindowsSetTitle (wt: WindowType; title: Str255);
  16.     procedure WindowsIdle;
  17.     procedure WindowActivateDeactivate (window: WindowPtr; activate: boolean);
  18.     procedure WindowItemWhere (window: WindowPtr; er: EventRecord; item: integer);
  19.     procedure WindowsDoKey (er: EventRecord);
  20.     function WindowsEarlyHandleEvent (er: EventRecord): boolean;
  21.     function WindowsEarlyHandleKey (er: EventRecord): boolean;
  22.     procedure WindowsAdjustMenus;
  23.     procedure WindowsDoEditMenu (item: integer);
  24.  
  25.     procedure WindowsRestorePositions;
  26.     procedure WindowsSavePositions;
  27.     procedure WindowsResetPositions;
  28.  
  29.     function GetWindowPtr (wt: WindowType): WindowPtr;
  30.  
  31. implementation
  32.  
  33.     uses
  34.         IconFamilies, 
  35.  
  36.         ICMiscSubs, ICSubs, ICTypes, ICAPI, ICDialogs, ICText, ICGlobals, 
  37.  
  38.         ICTextWhats, ICPopupWhats, ICFontWhats, ICFSSpecWhats, ICFileMapWhat, ICHelperWhat, ICButtonWhat, 
  39.  
  40.         ICDocUtils;
  41.  
  42.  
  43.     function CallWhatOpen (wt: WindowType; item: integer; open: ProcPtr): OSErr;
  44.     inline
  45.         $205F, $4E90;
  46.  
  47.     function CallWhatClose (wt: WindowType; item: integer; close: ProcPtr): OSErr;
  48.     inline
  49.         $205F, $4E90;
  50.  
  51.     function CallWhatFlush (wt: WindowType; item: integer; close: ProcPtr): OSErr;
  52.     inline
  53.         $205F, $4E90;
  54.  
  55.     function CallWhatClick (wt: WindowType; item: integer; er: eventRecord; close: ProcPtr): OSErr;
  56.     inline
  57.         $205F, $4E90;
  58.  
  59.     function CallWhatKey (wt: WindowType; item: integer; er: eventRecord; key: ProcPtr): OSErr;
  60.     inline
  61.         $205F, $4E90;
  62.  
  63.     function CallWhatActivate (wt: WindowType; item: integer; activate: boolean; actproc: ProcPtr): OSErr;
  64.     inline
  65.         $205F, $4E90;
  66.  
  67.     function CallWhatIdle (wt: WindowType; item: integer; idleproc: ProcPtr): OSErr;
  68.     inline
  69.         $205F, $4E90;
  70.  
  71.     function CallWhatCursor (wt: WindowType; item: integer; pt: Point; cursorid: integer; cursorproc: ProcPtr): OSErr;
  72.     inline
  73.         $205F, $4E90;
  74.  
  75.     function TypeToWhat (typ: OSType): integer;
  76.         var
  77.             i: integer;
  78.     begin
  79.         TypeToWhat := 1;
  80.         for i := 1 to whats_max do begin
  81.             if whatinfo[i].typ = typ then begin
  82.                 TypeToWhat := i;
  83.                 leave;
  84.             end;
  85.         end;
  86.     end;
  87.  
  88.     function GetWhatType (wt: WindowType; item: integer): OSType;
  89.         var
  90.             wrp: WhatRecordPtr;
  91.     begin
  92.         wrp := windowinfo[wt].items[item];
  93.         if wrp = nil then begin
  94.             GetWhatType := 'NULL';
  95.         end
  96.         else begin
  97.             GetWhatType := wrp^.typ;
  98.         end;
  99.     end;
  100.  
  101.     function GetWindowPtr (wt: WindowType): WindowPtr;
  102.     begin
  103.         GetWindowPtr := windowinfo[wt].window;
  104.     end;
  105.  
  106.     function OurWindow (wp: WindowPtr): boolean;
  107.     begin
  108.         OurWindow := GetWindowType(wp) <> WT_None;
  109.     end;
  110.  
  111.     function IsWhatWindow (wp: WindowPtr): boolean;
  112.     begin
  113.         IsWhatWindow := GetWindowType(wp) in [WT_Personal, pred(WT_Last)];
  114.     end;
  115.  
  116.     function WhatIdleText (wt: WindowType; item: integer; var cursor: integer): OSErr;
  117.         var
  118.             r: rect;
  119.             pt: Point;
  120.     begin
  121.         GetDItemRect(windowinfo[wt].window, item, r);
  122.         GetMouse(pt);
  123.         if PtInRect(pt, r) then begin
  124.             cursor := iBeamCursor;
  125.         end;
  126.         WhatIdleText := noErr;
  127.     end;
  128.  
  129.     procedure DoWindowIdle (window: WindowPtr);
  130.         var
  131.             selected_item, i: integer;
  132.             what: WhatRecordPtr;
  133.             idleproc: ProcPtr;
  134.             wt: WindowType;
  135.             err: OSErr;
  136.             cursorid: integer;
  137.             r: rect;
  138.             pt: Point;
  139.             cursor: ProcPtr;
  140.             junk: OSErr;
  141.             cursor_set: boolean;
  142.     begin
  143.         SetPort(window);
  144.         wt := GetWindowType(window);
  145.         selected_item := GetSelectedItem(GetWindowType(window));
  146.         if selected_item > 0 then begin
  147.             TextIdle(windowinfo[GetWindowType(window)].items[selected_item]^.data);
  148.         end;
  149.         if (window = FrontWindow) & InForeground then begin
  150.             GetMouse(pt);
  151.             cursor_set := false;
  152.             for i := 1 to item_max do begin
  153.                 what := windowinfo[wt].items[i];
  154.                 if what <> nil then begin
  155.                     GetDItemRect(window, i, r);
  156.                     if PtInRect(pt, r) then begin
  157.                         cursor_set := true;
  158.                         cursorid := whatinfo[TypeToWhat(what^.typ)].cursorid;
  159.                         cursor := whatinfo[TypeToWhat(what^.typ)].cursor;
  160.                         if cursor = nil then begin
  161.                             if cursorid = 0 then begin
  162.                                 InitCursor;
  163.                             end
  164.                             else begin
  165.                                 SetCursor(GetCursor(cursorid)^^);
  166.                             end;
  167.                         end
  168.                         else begin
  169.                             junk := CallWhatCursor(wt, i, pt, cursorid, cursor);
  170.                         end; (* if *)
  171.                     end;
  172.                 end; (* if *)
  173.             end; (* for *)
  174.             if not cursor_set then begin
  175.                 InitCursor;
  176.             end; (* if *)
  177.         end;
  178.     end;
  179.  
  180.     procedure WindowDoKey (window: WindowPtr; er: EventRecord);
  181.         var
  182.             selected_item: integer;
  183.             key: ProcPtr;
  184.     begin
  185.         selected_item := windowinfo[GetWindowType(window)].selected_item;
  186.         if selected_item > 0 then begin
  187.             key := whatinfo[TypeToWhat(GetWhatType(GetWindowType(window), selected_item))].key;
  188.             if key <> nil then begin
  189.                 SetPort(window);
  190.                 DisplayError(acDoThis, CallWhatKey(GetWindowType(window), selected_item, er, key));
  191.             end; (* if *)
  192.         end;
  193.     end;
  194.  
  195.     procedure WindowActivateDeactivate (window: WindowPtr; activate: boolean);
  196.         var
  197.             wt: WindowType;
  198.             item: integer;
  199.             i: integer;
  200.             actproc: ProcPtr;
  201.             what: WhatRecordPtr;
  202.             err: OSErr;
  203.     begin
  204.         wt := GetWindowType(window);
  205.         if wt <> WT_None then begin
  206.             SetPort(window);
  207.             item := GetSelectedItem(wt);
  208.             if item > 0 then begin
  209.                 TextActivate(windowinfo[wt].items[item]^.data, activate);
  210.             end; (* if *)
  211.             for i := 1 to item_max do begin
  212.                 what := windowinfo[wt].items[i];
  213.                 if what <> nil then begin
  214.                     actproc := whatinfo[TypeToWhat(what^.typ)].activate;
  215.                     if actproc <> nil then begin
  216.                         err := CallWhatActivate(wt, i, activate, actproc);
  217.                         if (err <> noErr) and (err <> userCanceledErr) then begin
  218.                             SysBeep(10);
  219.                         end; (* if *)
  220.                     end;
  221.                 end; (* if *)
  222.             end; (* for *)
  223.         end; (* if *)
  224.     end;
  225.  
  226.     procedure WindowItemWhere (window: WindowPtr; er: EventRecord; item: integer);
  227.         var
  228.             click: ProcPtr;
  229.     begin
  230.         case GetWindowType(window) of
  231.             WT_About: 
  232.                 ;
  233.             otherwise begin
  234.                 click := whatinfo[TypeToWhat(GetWhatType(GetWindowType(window), item))].click;
  235.                 if click <> nil then begin
  236.                     SetPort(window);
  237.                     DisplayError(acDoThis, CallWhatClick(GetWindowType(window), item, er, click));
  238.                 end; (* if *)
  239.             end;
  240.         end;
  241.     end;
  242.  
  243.     function WindowEarlyHandleEvent (window: WindowPtr; er: EventRecord): boolean;
  244.     begin
  245.         WindowEarlyHandleEvent := false;
  246.     end;
  247.  
  248.     procedure WindowTab (window: WindowPtr; shift: boolean);
  249.         var
  250.             orgitem, rorgitem, i: integer;
  251.             k: integer;
  252.             dirn: integer;
  253.             h: handle;
  254.             r: rect;
  255.             selitem: integer;
  256.             t: OSType;
  257.     begin
  258.         selitem := -1;
  259.         orgitem := GetSelectedItem(GetWindowType(window));
  260.         rorgitem := orgitem;
  261.         if orgitem <= 0 then begin
  262.             if shift then begin
  263.                 orgitem := 1;
  264.             end
  265.             else begin
  266.                 orgitem := item_max;
  267.             end;
  268.         end;
  269.         dirn := item_max - 2 * ord(shift);
  270.         i := orgitem;
  271.         repeat
  272.             i := (i + dirn) mod item_max + 1;
  273.             t := GetWhatType(GetWindowType(window), i);
  274.             if t = 'TEXT' then begin
  275.                 selitem := i;
  276.                 leave;
  277.             end;
  278.         until (i = orgitem);
  279.         if selitem > 0 then begin
  280.             SelectTextItem(GetWindowType(window), selitem);
  281.             TextSetSelect(windowinfo[GetWindowType(window)].items[selitem]^.data, 0, 32767);
  282.         end;
  283.     end;
  284.  
  285.     function WindowEarlyHandleKey (window: WindowPtr; er: EventRecord): boolean;
  286.         var
  287.             b: boolean;
  288.             ch: integer;
  289.     begin
  290.         b := false;
  291.         ch := BAND(er.message, $FF);
  292.         if ch = 9 then begin
  293.             WindowTab(window, BAND(er.modifiers, shiftKey) <> 0);
  294.             b := true;
  295.         end;
  296.         if not b then begin
  297.         end;
  298.         WindowEarlyHandleKey := b;
  299.     end;
  300.  
  301.     function FlushWindowType (wp: WindowPtr; wt: WindowType): OSErr;
  302.         var
  303.             i: integer;
  304.             first_err, err: OSErr;
  305.             flush: ProcPtr;
  306.             what: WhatRecordPtr;
  307.             portrect: Rect;
  308.     begin
  309.         first_err := noErr;
  310.         SetPort(wp);
  311.         GetWindowRect(wp, portrect);
  312.         windowinfo[wt].position := portrect.topLeft;
  313.         for i := 1 to item_max do begin
  314.             what := windowinfo[wt].items[i];
  315.             if what <> nil then begin
  316.                 flush := whatinfo[TypeToWhat(what^.typ)].flush;
  317.                 if flush <> nil then begin
  318.                     err := CallWhatFlush(wt, i, flush);
  319.                     if first_err = noErr then begin
  320.                         first_err := err;
  321.                     end; (* if *)
  322.                 end;
  323.             end; (* if *)
  324.         end;
  325.         FlushWindowType := first_err;
  326.     end; (* FlushWindowType *)
  327.  
  328.     function DisposeWindowType (wp: WindowPtr; wt: WindowType): OSErr;
  329.         var
  330.             i: integer;
  331.             first_err, err: OSErr;
  332.             close: ProcPtr;
  333.             what: WhatRecordPtr;
  334.     begin
  335.         first_err := noErr;
  336.         SetPort(wp);
  337.         for i := 1 to item_max do begin
  338.             what := windowinfo[wt].items[i];
  339.             if what <> nil then begin
  340.                 close := whatinfo[TypeToWhat(what^.typ)].close;
  341.                 if close <> nil then begin
  342.                     err := CallWhatClose(wt, i, close);
  343.                     if first_err = noErr then begin
  344.                         first_err := err;
  345.                     end; (* if *)
  346.                 end;
  347.                 windowinfo[wt].items[i] := nil;
  348.                 DisposePtr(Ptr(what));
  349.             end; (* if *)
  350.         end;
  351.         windowinfo[wt].window := nil;
  352.         DisposeDialog(wp);
  353.         DisposeWindowType := first_err;
  354.     end; (* DisposeWindowType *)
  355.  
  356.     function CloseWindowType (wp: WindowPtr; wt: WindowType): OSErr;
  357.         var
  358.             err: OSErr;
  359.             err2: OSErr;
  360.             opened: boolean;
  361.     begin
  362.         opened := false;
  363.         err := ICMapErr(ICBegin(GetInstance, icReadWritePerm));
  364.         if err = noErr then begin
  365.             opened := true;
  366.             err := FlushWindowType(wp, wt);
  367.         end; (* if *)
  368.         err2 := DisposeWindowType(wp, wt);
  369.         if err = noErr then begin
  370.             err := err2;
  371.         end; (* if *)
  372.         if opened then begin
  373.             err2 := ICMapErr(ICEnd(GetInstance));
  374.             if err = noErr then begin
  375.                 err := err2;
  376.             end; (* if *)
  377.         end; (* if *)
  378.         CloseWindowType := err;
  379.     end; (* CloseWindowType *)
  380.  
  381.     function WindowsEarlyHandleEvent (er: EventRecord): boolean;
  382.     begin
  383.         WindowsEarlyHandleEvent := false;
  384.         if GetWindowType(FrontWindow) <> WT_None then begin
  385.             WindowsEarlyHandleEvent := WindowEarlyHandleEvent(FrontWindow, er);
  386.         end;
  387.     end;
  388.  
  389.     function WindowsEarlyHandleKey (er: EventRecord): boolean;
  390.     begin
  391.         WindowsEarlyHandleKey := false;
  392.         if GetWindowType(FrontWindow) <> WT_None then begin
  393.             WindowsEarlyHandleKey := WindowEarlyHandleKey(FrontWindow, er);
  394.         end;
  395.     end;
  396.  
  397.     procedure WindowsDoKey (er: EventRecord);
  398.     begin
  399.         if GetWindowType(FrontWindow) <> WT_None then begin
  400.             WindowDoKey(FrontWindow, er);
  401.         end;
  402.     end;
  403.  
  404.     procedure WindowsIdle;
  405.         var
  406.             wt: WindowType;
  407.     begin
  408.         for wt := WT_None to WT_Last do begin
  409.             if windowinfo[wt].window <> nil then begin
  410.                 DoWindowIdle(windowinfo[wt].window);
  411.             end;
  412.         end;
  413.     end;
  414.  
  415.     procedure WindowsSetTitle (wt: WindowType; title: Str255);
  416.     begin
  417.         if windowinfo[wt].window <> nil then begin
  418.             SetWTitle(windowinfo[wt].window, title);
  419.         end; (* if *)
  420.     end; (* WindowsSetTitle *)
  421.  
  422.     procedure WindowsAdjustMenus;
  423.         var
  424.             wt: WindowType;
  425.     begin
  426.         wt := GetWindowType(FrontWindow);
  427.         AdjustTextMenu(wt);
  428.     end;
  429.  
  430.     procedure WindowsDoEditMenu (item: integer);
  431.         var
  432.             wt: WindowType;
  433.     begin
  434.         wt := GetWindowType(FrontWindow);
  435.         if wt <> WT_None then begin
  436.             DoTextMenu(wt, item);
  437.         end; (* if *)
  438.     end;
  439.  
  440.     function ParseWhat (wt: WindowType): OSErr;
  441.         type
  442.             WhatTemplateRecord = record
  443.                     key: str31;
  444.                     typ: OSType;
  445.                     flags: longInt;
  446.                 end;
  447.             WhatTemplateArray = array[1..10] of WhatTemplateRecord;
  448.             WhatTemplateArrayPtr = ^WhatTemplateArray;
  449.             WhatTemplateArrayHandle = ^WhatTemplateArrayPtr;
  450.         var
  451.             what: WhatTemplateArrayHandle;
  452.             i: integer;
  453.             err: OSErr;
  454.     begin
  455.         err := noErr;
  456.         for i := 1 to item_max do begin
  457.             windowinfo[wt].items[i] := nil;
  458.         end;
  459.         what := WhatTemplateArrayHandle(GetResource('WHAT', windowinfo[wt].id));
  460.         if what <> nil then begin
  461.             for i := 1 to GetHandleSize(handle(what)) div SizeOf(WhatTemplateRecord) do begin
  462.                 if what^^[i].typ <> 'NULL' then begin
  463.                     windowinfo[wt].items[i] := WhatRecordPtr(NewPtr(SizeOf(WhatRecord)));
  464.                     err := MemError;
  465.                     if err <> noErr then begin
  466.                         leave;
  467.                     end; (* if *)
  468.                     with windowinfo[wt].items[i]^ do begin
  469.                         key := what^^[i].key;
  470.                         typ := what^^[i].typ;
  471.                         flags := what^^[i].flags;
  472.                     end; (* with *)
  473.                 end; (* if *)
  474.             end; (* for *)
  475.         end; (* if *)
  476.         ParseWhat := err;
  477.     end; (* ParseWhat *)
  478.  
  479.     function PrepWindow (wt: WindowType; id: integer; wp: WindowPtr): OSErr;
  480.         var
  481.             what, i: integer;
  482.             err: OSErr;
  483.             first_err: OSErr;
  484.     begin
  485.         SetPort(wp);
  486.         windowinfo[wt].window := wp;
  487.         windowinfo[wt].id := id;
  488.         windowinfo[wt].selected_item := -1;
  489.         first_err := ParseWhat(wt);
  490.         if first_err = noErr then begin
  491.             for i := 1 to item_max do begin
  492.                 if windowinfo[wt].items[i] <> nil then begin
  493.                     with windowinfo[wt].items[i]^ do begin
  494.                         what := TypeToWhat(typ);
  495.                         if whatinfo[what].open <> nil then begin
  496.                             err := CallWhatOpen(wt, i, whatinfo[what].open);
  497.                             if first_err = noErr then begin
  498.                                 first_err := err;
  499.                             end; (* if *)
  500.                         end;
  501.                     end; (* with *)
  502.                 end;
  503.             end; (* for *)
  504.         end; (* if *)
  505.         if first_err = noErr then begin
  506.             if windowinfo[wt].selected_item = -1 then begin
  507.                 WindowTab(windowinfo[wt].window, false);
  508.             end; (* if *)
  509.         end; (* if *)
  510.         PrepWindow := first_err;
  511.     end; (* PrepWindow *)
  512.  
  513.     function NewWindow (wt: WindowType; id: integer): OSErr;
  514.         var
  515.             wp: WindowPtr;
  516.             junk: OSErr;
  517.             position: Point;
  518.             original_position: Rect;
  519.             err: OSErr;
  520.             err2: OSErr;
  521.     begin
  522.         wp := nil;
  523.         err := ICMapErr(ICBegin(GetInstance, icReadWritePerm));
  524.         if err = noErr then begin
  525.             wp := GetNewDialog(id, nil, POINTER(-1));
  526.             if wp = nil then begin
  527.                 err := memFullErr;
  528.             end; (* if *)
  529.             if err = noErr then begin
  530.                 err := PrepWindow(wt, id, wp);
  531.             end; (* if *)
  532.             if err = noErr then begin
  533.                 position := windowinfo[wt].position;
  534.                 if (position.h <> 0) or (position.v <> 0) then begin
  535.                     GetWindowRect(wp, original_position);
  536.                     MoveWindow(wp, position.h, position.v, false);
  537.                     ShowWindow(wp);            (* because TitleBarOnScreen requires window to be shown *)
  538.                     if not TitleBarOnScreen(wp) then begin
  539.                         MoveWindow(wp, original_position.left, original_position.top, false);
  540.                     end; (* if *)
  541.                 end; (* if *)
  542.                 ShowWindow(wp);
  543.             end;
  544.             err2 := ICMapErr(ICEnd(GetInstance));
  545.             if err = noErr then begin
  546.                 err := err2;
  547.             end; (* if *)
  548.         end; (* if *)
  549.         (* tidy up code *)
  550.         if err <> noErr then begin
  551.             if wp <> nil then begin
  552.                 junk := DisposeWindowType(wp, wt);
  553.             end; (* if *)
  554.         end; (* if *)
  555.         NewWindow := err;
  556.     end; (* NewWindow *)
  557.  
  558.     function WindowsOpen (wt: WindowType; id: integer): OSErr;
  559.     begin
  560.         if windowinfo[wt].window <> nil then begin
  561.             ShowWindow(windowinfo[wt].window);
  562.             SelectWindow(windowinfo[wt].window);
  563.             WindowsOpen := noErr;
  564.         end
  565.         else begin
  566.             WindowsOpen := NewWindow(wt, id);
  567.         end;
  568.     end; (* WindowsOpen *)
  569.  
  570.     function WindowsClose (wp: WindowPtr): OSErr;
  571.         var
  572.             wt: WindowType;
  573.     begin
  574.         WindowsClose := noErr;
  575.         wt := GetWindowType(wp);
  576.         if wt <> WT_None then begin
  577.             WindowsClose := CloseWindowType(wp, wt);
  578.         end; (* if *)
  579.     end; (* WindowsClose *)
  580.  
  581.     type
  582.         pointArray = array[WT_Main..WT_Last] of Point;
  583.  
  584.     procedure WindowsResetPositions;
  585.         var
  586.             wt: WindowType;
  587.             pos: Point;
  588.     begin
  589.         pos.h := 2;
  590.         pos.v := 42;
  591.         for wt := WT_Main to pred(WT_Last) do begin
  592.             windowinfo[wt].position := pos;
  593.             pos.h := pos.h + 20 * ord(screenbits.bounds.right > 512);
  594.             pos.v := pos.v + 10 * ord(screenbits.bounds.bottom >= 400) + 8 * ord(screenbits.bounds.bottom >= 480);
  595.         end; (* for *)
  596.     end;
  597.  
  598.     procedure WindowsRestorePositions;
  599.         var
  600.             err, err2: OSErr;
  601.             key: Str255;
  602.             attr: longint;
  603.             window_positions: pointArray;
  604.             size: longint;
  605.             wt: WindowType;
  606.     begin
  607.         err := ICMapErr(ICBegin(GetInstance, icReadOnlyPerm));
  608.         if err = noErr then begin
  609.             key := StringOf(Ptr(longint(ICcreator)), '•WindowPositions');
  610.             size := sizeof(window_positions);
  611.             err := ICGetPref(GetInstance, key, attr, @window_positions, size);
  612.             if (err = noErr) and (size <> sizeof(window_positions)) then begin
  613.                 err := -1;
  614.             end; (* if *)
  615.             err2 := ICMapErr(ICEnd(GetInstance));
  616.             if err = noErr then begin
  617.                 err := err2;
  618.             end; (* if *)
  619.         end; (* if *)
  620.         if err = noErr then begin
  621.             for wt := WT_Main to WT_Last do begin
  622.                 windowinfo[wt].position := window_positions[wt];
  623.             end; (* for *)
  624.         end
  625.         else begin
  626.             WindowsResetPositions;
  627.         end; (* if *)
  628.     end; (* WindowsRestorePositions *)
  629.  
  630.     procedure WindowsSavePositions;
  631.         var
  632.             err, err2: OSErr;
  633.             wt: WindowType;
  634.             key: Str255;
  635.             window_positions: pointArray;
  636.     begin
  637.         for wt := WT_Main to WT_Last do begin
  638.             window_positions[wt] := windowinfo[wt].position;
  639.         end; (* for *)
  640.         err := ICMapErr(ICBegin(GetInstance, icReadWritePerm));
  641.         if err = noErr then begin
  642.             key := StringOf(Ptr(longint(ICcreator)), '•WindowPositions');
  643.             err := ICSetPref(GetInstance, key, ICattr_no_change, @window_positions, sizeof(window_positions));
  644.             err2 := ICMapErr(ICEnd(GetInstance));
  645.             if err = noErr then begin
  646.                 err := err2;
  647.             end; (* if *)
  648.         end; (* if *)
  649.     end; (* WindowsSavePositions *)
  650.  
  651.     function WindowsFlushAll: OSErr;    (* flush all information windows *)
  652.         var
  653.             wt: WindowType;
  654.             first_err, err: OSErr;
  655.     begin
  656.         first_err := ICMapErr(ICBegin(GetInstance, icReadWritePerm));
  657.         if first_err = noErr then begin
  658.             for wt := WT_Main to WT_Last do begin
  659.                 if windowinfo[wt].window <> nil then begin
  660.                     SetPort(windowinfo[wt].window);
  661.                     err := FlushWindowType(windowinfo[wt].window, wt);
  662.                     if first_err = noErr then begin
  663.                         first_err := err;
  664.                     end; (* if *)
  665.                 end; (* if *)
  666.             end; (* for *)
  667.             err := ICMapErr(ICEnd(GetInstance));
  668.             if first_err = noErr then begin
  669.                 first_err := err;
  670.             end; (* if *)
  671.         end; (* if *)
  672.         WindowsFlushAll := first_err;
  673.     end; (* WindowsFlushAll *)
  674.  
  675.     function WindowsCloseAll: OSErr;    (* close all information windows *)
  676.         var
  677.             wt: WindowType;
  678.             err, first_err: OSErr;
  679.     begin
  680.         first_err := noErr;
  681.         for wt := WT_Personal to WT_Last do begin
  682.             if windowinfo[wt].window <> nil then begin
  683.                 err := CloseWindowType(windowinfo[wt].window, wt);
  684.                 if first_err = noErr then begin
  685.                     first_err := err;
  686.                 end; (* if *)
  687.             end;
  688.         end; (* for *)
  689.         WindowsCloseAll := first_err;
  690.     end; (* WindowsCloseAll *)
  691.  
  692.     procedure InitWhats;
  693.         procedure W (what: integer; xtyp: OSType; xopen, xkey, xclick, xidle, xflush, xclose, xactivate, xcursor: ProcPtr; xcursorid: integer);
  694.         begin
  695.             with whatinfo[what] do begin
  696.                 typ := xtyp;
  697.                 open := xopen;
  698.                 key := xkey;
  699.                 click := xclick;
  700.                 flush := xflush;
  701.                 close := xclose;
  702.                 activate := xactivate;
  703.                 idle := xidle;
  704.                 cursor := xcursor;
  705.                 cursorid := xcursorid;
  706.             end;
  707.         end;
  708.     begin
  709.         W(1, 'NULL', nil, nil, nil, nil, nil, nil, nil, nil, 0);
  710.         W(2, 'TEXT', @WhatOpenText, @WhatKeyText, @WhatClickText, nil, @WhatFlushText, @WhatCloseText, nil, nil, iBeamCursor);
  711.         W(3, 'SPOP', @WhatOpenPopup, nil, @WhatClickPopup, nil, @WhatFlushPopup, @WhatClosePopup, nil, nil, 0);
  712.         W(4, 'FFSP', @WhatOpenFSSpec, nil, @WhatClickFSSpec, nil, @WhatFlushFSSpec, nil, nil, nil, 0);
  713.         W(5, 'FPOP', @WhatOpenFont, nil, @WhatClickFont, nil, @WhatFlushFont, nil, nil, nil, 0);
  714.         W(6, 'FMAP', @WhatOpenFileMap, @WhatKeyFileMap, @WhatClickFileMap, nil, @WhatFlushFileMap, @WhatCloseFileMap, @WhatActivateFileMap, @WhatCursorFileMap, plusCursor);
  715.         W(7, 'FBUT', nil, nil, @WhatClickFileMap, nil, nil, nil, nil, nil, 0);
  716.         W(8, 'HMAP', @WhatOpenHelper, @WhatKeyHelper, @WhatClickHelper, nil, @WhatFlushHelper, @WhatCloseHelper, @WhatActivateHelper, @WhatCursorHelper, plusCursor);
  717.         W(9, 'HBUT', nil, nil, @WhatClickHelper, nil, nil, nil, nil, nil, 0);
  718.         W(10, 'BUTN', @WhatOpenButton, nil, @WhatClickButton, nil, nil, nil, nil, nil, 0);
  719.         W(11, 'FSIZ', nil, nil, @WhatClickFontSize, nil, nil, nil, nil, nil, 0);
  720.     end;
  721.  
  722.     procedure AboutBoxUpdate (dlg: DialogPtr; item: integer);
  723.         var
  724.             r: Rect;
  725.     begin
  726.         GetDItemRect(dlg, item, r);
  727.         case item of
  728.             1: 
  729.                 DrawIcon(128, r, false);
  730.             3: 
  731.                 DisplayStyledString(dlg, item, concat(GetAString(129, item), app_version.shortVersion));
  732.             otherwise
  733.                 DisplayStyledString(dlg, item, GetAString(129, item));
  734.         end; (* case *)
  735.     end; (* AboutBoxUpdate *)
  736.  
  737.     function InitICWindows: OSErr;
  738.         var
  739.             wt: WindowType;
  740.             i: integer;
  741.             pos: Point;
  742.             wp: WindowPtr;
  743.             kind: integer;
  744.             err: OSErr;
  745.     begin
  746.         InitICWindowGlobals;
  747.         InitWhats;
  748.         for wt := WT_None to WT_Last do begin
  749.             windowinfo[wt].window := nil;
  750.             windowinfo[wt].position.h := 0;
  751.             windowinfo[wt].position.v := 0;
  752.         end;
  753.         WindowsResetPositions;
  754.         (* bring the about box up hidden and leave it there *)
  755.         err := noErr;
  756.         wp := GetNewDialog(128, nil, WindowPtr(-1));
  757.         windowinfo[WT_About].window := wp;
  758.         if wp = nil then begin
  759.             err := memFullErr;
  760.         end; (* if *)
  761.         if err = noErr then begin
  762.             err := PrepWindow(WT_About, 128, wp);
  763.         end; (* if *)
  764.         if err = noErr then begin
  765.             for i := 1 to CountDItems(wp) do begin
  766.                 GetDItemKind(wp, i, kind);
  767.                 if band(kind, $7f) = userItem then begin
  768.                     SetDItemHandle(wp, i, @AboutBoxUpdate);
  769.                 end; (* if *)
  770.             end; (* for *)
  771.         end; (* if *)
  772.         InitICWindows := err;
  773.     end; (* InitICWindows *)
  774.  
  775. end.