[comp.sys.apple] 2 more IIGS programming questions

hartkopf@tramp.Colorado.EDU (HARTKOPF JEFFREY M) (06/29/89)

1)
I've been having a problem getting a new desk accessory which needs to use
Standard File (SF) to work.  The problem occurs when, since SF is not
assumed to be loaded, I need to load and start it up.  Here is the TML
Pascal code I use to do it:


{global} var
    NDALoadedSF:    Boolean;    {did I need to load SF, or not}

procedure LoadStandardFile;
var
    MemID:          Integer;      {application ID assigned by Memory Manager}
    ToolsZeroPage:  Handle;       {handle to zero page memory for tools}
    ToolRec:        ToolTable;
    SvToolErrorNum,
    Btn:            Integer;               {button}
begin
    MemID := MMStartUp;                    {initialize Memory Manager}
        ToolsZeroPage := NewHandle(
        1 * 256,                           {allocate 1 page}
        MemID,                             {user ID for memory blocks}
        FixedBank + PageAligned + FixedBlk + Locked,    {attributes}
        ptr(0));                           {start in bank 0}
    ToolRec.NumTools := 12;                {number of tools needed to load}
    ToolRec.Tools[1].TSNum := 23;          {Standard File}
    ToolRec.Tools[1].MinVersion := 0;
    repeat
        LoadTools(ToolRec);                {load tools}
        SvToolErrorNum := ToolErrorNum;
        if SvToolErrorNum <> 0 then        {error in loading tools}
        begin
            Btn := TLMountVolume(100, 40, 'Error loading tools',
                    'Insert System Disk', 'Ok', 'Cancel');
            if Btn <> 1 then
                SysFailMgr(SvToolErrorNum, 'Unable to load tools');
        end;
    until SvToolErrorNum = 0;
    SFStartUp(MemID, LoWord(ToolsZeroPage^) + $700);
end;

procedure DAInit(Code: Integer);
    Dummy: Integer;
begin
    if Code = 0 then        {closing NDA}
    begin
        if NDALoadedSF then
            SFShutDown
    end
    else                    {opening NDA}
    begin
        Dummy := SFStatus;
        if IsToolError then
        begin
            LoadStandardFile;
        end
        else
            NDALoadedSF := true;
        end
        else
            NDALoadedSF := false;
    end;
end;


So far everything works fine:  it loads and starts up SF if it needs to.
The problems occurs in the Finder which doesn't load SF, so my NDA has
to.  When I try to launch any ProDOS 8 program, the system crashes with the
error message "Sorry, system error $0201 occurred while trying to run the
next application."  ProDOS 16 or GS/OS program launching works fine.  If
I remove the SF loading code from the NDA, then everything works great.
I'm sure I'm doing something wrong.  Any suggestions?



2)
In a program I'm writing I need to draw a window (it's a help window) with
a lot of text in it--maybe 8 typed pages.  Now of course not all of this text
can be displayed at once in the window, but whenever the window needs to be
updated (e.g. when it's first drawn, when the user uses the window's scroll bar,
etc.) it takes a long time to redraw because it seems to have to redraw ALL of
the text, even though only a small part of it shows.  I'm using DrawString to
draw the text in the window.  Any suggestions on making it faster, like
a word processor or text editor does?  Thanks a lot.

wombat@claris.claris (Scott Lindsey) (06/29/89)

   From: hartkopf@tramp.Colorado.EDU (HARTKOPF JEFFREY M)
   Newsgroups: comp.sys.apple
   Date: 29 Jun 89 02:06:16 GMT
   Reply-To: hartkopf@tramp.Colorado.EDU (HARTKOPF JEFFREY M)
   Organization: University of Colorado, Boulder

   1)
   I've been having a problem getting a new desk accessory which needs to use
   Standard File (SF) to work.  The problem occurs when, since SF is not
   assumed to be loaded, I need to load and start it up.  

There's a few problems with your code.  First, when you call SFStatus, you
assume that you will get a tool error if StdFile hasn't been loaded & started.
The first half is true.  You get error $0002 if the tool hasn't been loaded.
If, for some reason (say the finder runs a program which loads, uses, then
shuts down StdFile & returns to the finder) it's loaded but not started you'll
get no error but you still won't have an active StdFile.  You need to look
at the value returned by SFStatus in addition to checking the tool error.  Now,
the answer to your real question is that the memory you allocated for StdFile's
direct page is still allocated.  You allocate it, you dispose of it.  Simple
rule.  One more thing regarding NDA's & tools.  I tend to put tool loading &
startup in the Open vector of an NDA (unless the NDA does something with
heartbeat tasks that requires those tools).  Reasoning: if it isn't needed
by the user, why bother to load it & take up memory.  However, I don't shut
down those tools on a close, just on a NDA shutdown call.

Text & windows: you might consider LETextBox or LETextBox2 if you have less
than 32K of text.  You might also calculate where you're drawing text &
compare it to the update region (or even just the bounding rect of the update
region) and quit drawing when you're no longer visible.



--
Scott Lindsey     |"Cold and misty morning. I heard a warning borne in the air
Claris Corp.      |    About an age of power when no one had an hour to spare"
ames!claris!wombat| DISCLAIMER: These are not the opinions of Claris, Apple,
wombat@claris.com |    StyleWare, the author, or anyone else living or dead.

dlyons@Apple.COM (David Lyons) (06/29/89)

In article <9760@boulder.Colorado.EDU> hartkopf@tramp.Colorado.EDU (HARTKOPF JEFFREY M) writes:
>1)
>I've been having a problem getting a new desk accessory which needs to use
>Standard File (SF) to work.  The problem occurs when, since SF is not
>assumed to be loaded, I need to load and start it up.  Here is the TML
>Pascal code I use to do it:
>
>
>    ToolRec.NumTools := 12;                {number of tools needed to load}
>    ToolRec.Tools[1].TSNum := 23;          {Standard File}
>    ToolRec.Tools[1].MinVersion := 0;

It would be really helpful if that "12" was a "1" instead.

>    SFStartUp(MemID, LoWord(ToolsZeroPage^) + $700);

Congratulations!  You've just fed Standard File a direct-page location
$700 bytes *after* the space you allocated for it.  ACK!  Remove the
"+$700" part, and promise to be more careful when you cut and paste
code from another application!

By the way, you must load and use Standard File *when you need it* and
shut it back down again (and Dispose of the handle you allocated) as
soon as you're through (before returning from one of your 4 DA
procedures).  You can screw up the current application if you leave SF
started when the app didn't start it itself.  If the app *did* start it,
just use it and *don't* shut it down, of course.

>In a program I'm writing I need to draw a window (it's a help window) with
>a lot of text in it--maybe 8 typed pages.  Now of course not all of this text
>can be displayed at once in the window, but whenever the window needs to be
>updated (e.g. when it's first drawn, when the user uses the window's scroll bar,
>etc.) it takes a long time to redraw because it seems to have to redraw ALL of
>the text, even though only a small part of it shows.  I'm using DrawString to
>draw the text in the window.  Any suggestions on making it faster, like
>a word processor or text editor does?  Thanks a lot.

You can use GetPortRect to find out which part of the window you're scrolled
to, or you can get the bounding box of the update region.  More details on
request--gotta take off!


 --Dave Lyons, Apple Computer, Inc.          |   DAL Systems
   AppleLink--Apple Edition: DAVE.LYONS      |   P.O. Box 875
   AppleLink--Personal Edition: Dave Lyons   |   Cupertino, CA 95015-0875
   GEnie: D.LYONS2 or DAVE.LYONS         CompuServe: 72177,3233
   Internet/BITNET:  dlyons@apple.com    UUCP:  ...!ames!apple!dlyons

   My opinions are my own, not Apple's.

dlyons@Apple.COM (David Lyons) (06/30/89)

In article <32779@apple.Apple.COM> dlyons@Apple.COM (David Lyons) writes:
[...]
>You can use GetPortRect to find out which part of the window you're scrolled
>to, or you can get the bounding box of the update region.  More details on
>request--gotta take off!

Let me try this once more, not under time pressure this time.

Inside your content-draw routine, BeginUpdate has already been called by the
system, so what you want to do is get the bouding box of the VisRegion (try
GetVisHandle()^^.bBox to get the smallest rectangle that encloses the part of
the window that needs to be updated.

BeginUpdate temporarily replaces the window's VisRegion with the intersection of
the VisRegion and the Update region.  The bounding box of a region is stored in
bytes 2-9 (the 3rd-10th bytes) of the block of memory the region's handle refers
to.

The part about GetPortRect is true, but checking the VisRegion is generally
better, since it often gives you a smaller area to draw (GetPortRect will give
you the part that the window is "scrolled to", but not all of that really needs
to be drawn).


 --Dave Lyons, Apple Computer, Inc.          |   DAL Systems
   AppleLink--Apple Edition: DAVE.LYONS      |   P.O. Box 875
   AppleLink--Personal Edition: Dave Lyons   |   Cupertino, CA 95015-0875
   GEnie: D.LYONS2 or DAVE.LYONS         CompuServe: 72177,3233
   Internet/BITNET:  dlyons@apple.com    UUCP:  ...!ames!apple!dlyons

   My opinions are my own, not Apple's.