FB II Compiler
Handle the Clipboard
I've had more than one complaint from end users stating the following:
1.) Intermittantly, when they attempt to launch my application and have insufficient memory to do so, they get a dialog that reads (to the effect of) "Not enough RAM for FutureBasic II..." (which confuses the heck out of them... )
2.) After dismissing the dialog they immediately crash and burn.
I have not been able to recreate this problem. But this is obviously not the normal dialog presented, which would read, "There is not enough memory to open "name of appl", blah, blah, blah..."
In an effort to dismiss any questions about the reliability of the source code, I created a dummy appl that does nothing but throw up a quit menu item and asked one user to test this from time to time. The word back is that it's happening with the dummy appl too.
First, it sounds like the memory settings for your application are too low. FB apps seem to store the contents of the clipboard in it's own memory so if the user has a 400K PICT on the clipboard, the app will use an extra 400K of memory just to launch. You should be aware of this especially if your program does any copying and pasting of PICTs. Try copying a very large PICT to the clipboard and then see if you can launch. If not, set the memory requirements a bit higher.
Next is the dialog problem (which will hopefully already be solved by raising memory requirements). What the user is seeing is ALRT id 130 which FB puts into all FB apps. Open your application in ResEdit and open ALRT #130. Change the wording to show your apps name instead of FutureBASIC II. Then copy the resource and paste it into your resource file. As long as it's in your resource file, every compile after that will use the one you created. What I've done is shorten the message to "Not enough memory! Try increasing the amount of RAM available to <app name>" then I use this ALRT for any other out of memory alerts that my program might display.
Are you using PG to generate your program? Check out the DLOG and ALRT resources in your built application to see if there are any that you didn't create. There may be one that PG or FB uses by default when it is unable to load the minimum run-time support it needs.
If you're using PG and it's creating this DLOG/ALRT you should be able to find where it invokes it because all of the source code for what PG includes in your appl. is available to you. You should be able to override what PG does by default by specifying what to do when the error occurs via PGShowError.
Yes, this does indeed seem to be the problem. My memory allocations are fine for my code and structures, but the problem is with this clipboard business. Unless I'm totally missing something here, isn't the clipboard a dynamic structure? How can I possiblly predetermine an unknown value?
And how am I supposed to sell/promote a simple FB-built appl that requires an excessive amount of RAM -- just in case I encounter a large clipboard?
Unless there's a work-around for this then all of my FB-built appls are in a sad state. Clipboards these days can be several mbs -- and to rely otherwise is foolish. Heck, even my brother the bus driver uses PhotoShop. I just wish that this rather important information had been documented somewhere in the manuals - in 72 pt. type. <sigh>
What can we do? I've already tried zeroing-out the scrap on entry (my main) to no avail.
It appears (even though it's not documented anywhere) that the clipboard overhead is not allocated using the mini-application shell. A solution, but not really a practical one for me at this point.
Chris, I think it would be in everyone's best interest for you to remove this happenstance from the FB code and and post an update. Unless there's another work-around, the alternative to you changing a few lines of code is that I have to recode everything I've ever created in FB. And not only do I have to recode, but I can't ship any product in the mean time. Then I'll have to break down inventory and repackage, replace inventory with distributors, send updates to my user-base, etc. <sigh>
Staz has thought of it all...
You can bypass these startup routines in FB. You have to write an Initialization code (ICOD) resource for your app. There is a demo of an "ICOD" resource in the technical examples folder that came with FB. Using this you should be able to flush the clipboard before FB does Anything.
Okay, this worked. Whew! Actually I was able to just use the code that was in the ICOD example -- stet -- since I noticed that it did everything *except* load the nasty scrap into my heap. And that's all I wanted.
Just out of curiousity, does anyone know why Andy/Chris elected to include the scrap in the appl heap? I, personally, can not see any benefit in doing so. Is it tied to some other FB-specific directive or structure? I'd rather know now than have something else break down the line.
I can't speak for Andy, but I know why _I_ would have done it. There's a little book called "Human Interface Guidelines". I don't have it in front of me, so I can't give the exact quote, but basically it boils down to "Thou Shalt Not Erase The Scrap (or do anything else) Without Being Told To, Or At Least Telling The User You're Doing It".
In C, you have to deliberately _keep_ the scrap (transfer it from the system scrap to the application scrap) on application launch. With ZBasic being intended in part for use by programming "amateurs", it's only logical to do all the "default" stuff _as_ a default; that's why you don't have to call InitQuickDraw, InitText, MaxApplZone, InitThis, InitThat at the start of every program - it's done for you.
In _certain_ cases, it makes sense to clear the application scrap rather than loading it from the system scrap; very tight memory situations are obviously one of them. (Although I'd suggest checking to see if it's so big that it's a problem first...) But if I copied some text from another application, then launched an FB application into which I intended to _paste_ that text, and it wouldn't let me, I'd be one upset customer!
I agree - it's bad interface to delete the scrap without at least notifying the user of what you are about to do and asking him if you should continue. I've seen programs do that (ask first) when memory is low and the scrap is too large.
Perhaps in my panic I have not made myself entirely clear. It is not my intent to dispose of the scrap without the user's knowledge. The scrap is not the problem. My problem is/was that the standard FB init attempts to load the scrap and doesn't seem to handle the situation failure correctly and I want to bypass this problem. Bypassing this does *not* destroy the scrap contents. As it stands, if my memory partition is not large enough to hold the contents of the scrap, FB throws up a dialog and then after the user attempts to dismiss it, the entire system freezes. And now the user has lost much more than just the scrap.
I question the necessity of FB handling these routines, since, to the best of my knowledge, the os already handles all of the necessary scap tranfers. Well, let me look it up just to be sure.
Okay, from, "More Machintosh Toolbox", Chapter 2, Scrap Manager, page 2-12 -- 2-14:
"The system software allocates space in each application's heap for the scrap and allocates a handle to reference the scrap... If the scrap is too large to fit in the applications' application heap, the system software copies the scrap to the disk and sets the value of the handle to NIL to indicate that the scrap is on disk. The scrap manager keeps track of whether the scrap is in memory or on disk... ...your application seldom needs to know the location of the scrap."
Now questions do arise about available disk space, and looking thru this chapter very quickly, I don't see any mention of it, but I would *assume* that the system has made provisions for this. But the bottom line is that the system is already handling everything.
I'll be perfectly honest in telling you that I did *not* know that the system actually attempted to load the scrap into my heap. I thought it was all maintained in the system heap/clipboard file. But the system approach is fine since it first checks to see if I have enough memory to actually hold the scrap, and if not writes it out. The *favor* that FB is doing for me (which I now believe must be addressing a problem which is no longer a concern), wipes me out and it needs to be looked into by Chris/David/Andy/someone.
Maybe most of you have not encoutered this problem, but I will append that statement with the word "yet" . The clipboard can export an amount equal to one-half of the available memory. Lots of Mac users have lots of memory. Lots of Mac users work in applications capable of generating large clipboard exports. Why risk it? And I'm happy to have found a simple work-around since I *do* value FB. It has been a very dependable DE for me for many, many years.
It seems to me that there's a third alternative besides (1) erasing the system scrap on launch or (2) copying the system scrap to the application scrap on launch. That would be:
(3) Don't do either of these on launch. If the user elects to paste the clipboard into your app, _then_ you can copy the system scrap to the application scrap.
If the HIG suggests otherwise, I confess I don't understand why.