lcs@... wrote: > Salut Alain, > > > DIM teH AS ..TEREC > > DIM teH AS @@TEREC > > DIM teH AS HNDL TO TEREC > > With ^^TEREC that makes four possibliities. I do like the > three .., @@, and ^^ because they are compact and easy > read and write and remember (at least once you understand > them -- I still don't understand #). Better, by learning > about ^ you also learn about ^^, ^^^, and so on. (What > comes after HNDL? Will I misspell HNDL as HAND next > week?) > Hi Larry, Actually there are more possibilities than that: You can use a generic handle (the way FBII used to work) teH& teH AS HANDLE teH AS HNDL In those cases you need to use the FB predefined constants to access the pseudo fields whose name, in rare occasions, may differ from the field name defined in the Toolbox structure. This is what Chris' example has shown with TEHandle: top = TEhndl&..teViewRect.Top% If you want to store the rectangle into a variable (be it declared with DIM r.8 or DIM r AS RECT), you have to move the 8 bytes explicitly with a variant of the BLOCKMOVE statement. For instance: r;8 = @teH&..teViewRect.Top% Specifying a type for the handle with one of the five following possibilities: teH AS HANDLE TO TERec teH AS HNDL TO TERec teH AS ^^TERec teH AS ..TERec teH AS @@TERec is like saying that you want to parse or analyze the data pointed to by the handle according to the layout of a given structure. I think of it as a template applied to an area in memory. Now this is another story, since the Toolbox structures are correctly defined by FB^3. They are true records using the field names that you can find in the Apple Headers. This strategy has some advantages and one of them is that the field types are known by FB. Consequently, you can write something like this: r = teH..viewRect which, in essence, is what you want to do in the first place regardless of the number of bytes that need to be moved. Finally, the burden of learning which specific structure must be used in a given case ends up with code simpler to write, to read and to understand. As to the # symbol it is not much harder I guess. Some Toolbox calls need to change the content of variables that are passed in their parameter list. For this to happen the variable that will be altered and more precisely its address in memory must be known. There are circumstances when you have no variable at your disposal to pass onto the Toolbox call (for instance when you calculate an arbitrary location in memory using an offset from a known address). Using the # symbol will tell the Compiler to consider the result of your calculation like if it were the address of a (fake) variable. Another common circumstance is when you pass a record onto a LOCAL FN and you need to send that record to a Toolbox call inside the LOCAL FN. When you pass a record structure onto a LOCAL FN, FB automatically sends its address. Notice that it is not required to explicitly pass the address onto the LOCAL FN with the @ symbol like it was the case in FBII (I think). Therefore the two following syntaxes work the same: FN doSomethingWith ( @theRect ) FN doSomethingWith ( theRect ) The incoming parameter, in your LOCAL FN, will be a 4 bytes address that will be placed into a register (if you have set that preference to on of course). If you attempt to use the incoming parameter "as is" in a Toolbox call you will have a couple of difficulties. First, the Compiler will stop quickly telling you it can't use a register variable with that Toolbox call. But and secondly, setting the registers to off won't solve the problem. In fact, your incoming parameter can be seen as an address that FB has calculated for you. Depending on what you want to achieve, you have then two solutions: Copy the data located at that address into a local structure. Ex: LOCAL FN doSomethingWith (inRectPtr AS ^RECT) DIM localRect AS RECT localRect = inRectPtr CALL InsetRect (localRect, -2,-2) END FN There are two important things to note here: 1 - FB magically knows that you want to assign a variable and it moves the exact amount of bytes in your local structure. I would call it a built-in shorthand for the following regular statement (which also works perfectly BTW): BLOCKMOVE inRectPtr, @localRect, SIZEOF(RECT) or localRect;8 = inRectPtr 2 - You are working on a copy of your rectangle, which means that your original rectangle will be left unchanged once the function has been executed. Force the Toolbox call to use the so to speak calculated address that you have received. Ex: LOCAL FN doSomethingWith (inRectPtr AS ^RECT) CALL InsetRect (#inRectPtr, -2,-2) END FN Since you are working on its address, your original structure will be modified by the function. Now, what if, for some reasons, you don't want to use the # symbol, but still want to alter the original structure? OK, I don't know if it is reliable, but I have discovered that we can pass back a structure to the calling function doing this: LOCAL FN doSomethingWith (inRectPtr AS ^RECT) DIM localRect AS RECT localRect = inRectPtr CALL InsetRect (localRect, -2,-2) END FN = localRect theRect;8 = FN doSomethingWith ( theRect ) Lately, we had an issue with the SetResInfo Toolbox call. As Heather said some other calls may be concerned by the trick, so it is a good thing to keep it in mind. The # symbol can be used to force a nil pointer or a nil handle where a variable is expected and required. Passing a nil address is not the same as passing a variable that is null, and it is like saying there is no variable at all to deal with. > > > It is absolutely unbelievable that we can have both > > legacy code and a new enhanced (IMO) way of writing > > code living almost in harmony within the same IDE. "Un > > v'eritable tour de force" I would say. > > Amen. Indeed it is wonderful. And necessary. > > In an evolving language there will always be a bleeding > edge. In a consensus language, particularly one with a > lot of parttime programmers like me, there must *also* be > areas of stability and upward compatibility; otherwise > precious code capital and intellectual capital will be > bulldozed before it is has paid off. > > That's not all, there should be low-level and high-level > ways of coding. > > It's amazing that Staz n Andy manage all these factors > so well. It can't hurt to cheer them on! > I am close to say that unfortunately you are right. Well, of course I can say such a thing because I have no critical code to maintain and I believe that the compatibility issue has put a break on the initial release of FB^3. Given that one (I for one) can find the new syntax provided by FB far cleaner and far clearer than what it used to be, one can think that this "necessity" was a waste of time and currently we should be speaking about FB^3 & MacOS X or FB^3 & OOP rather than comparing the merits of different syntaxes. Not only that, new features are added to the language with each release. Those are supposed to make the life easier for the programmers and especially novices. Of course, there's no point in discussing compatibility if you are going to use those features. But this stands true if you want to benefit from many enhancements already included in the language, for instance in the mere handling of strings. So from my point of view the question about compatibility would be how can I move smoothly my code to the FB^3 way of doing things rather than can I still program like FBII with FB^3. This is not always easy but I strongly believe this is the way to go. -- Cheers Alain ----------------------------------------------------- FB^3 in Europe: http://euro.futurebasic.com/ FB II Pouch: http://www.pixmix.com/FB/outils.html -----------------------------------------------------