willcox@urbana.mcd.mot.com (David A Willcox) (05/25/90)
In article <3707@darkstar.ucsc.edu> sirkm@ssyx.ucsc.edu (Greg Anderson) writes: >I believe that the book "XCMD's for HyperCard" by Gary Bond mentions that >XCMDs cannot create global variables. His solution, if I recall, is to >create a new button (from within the XCMD), give it a script that references >the global variable & then do a callback to it. Am I missing something? I don't have any documentation available here at work, but I could swear that there are a pair of callbacks called something like GetGlobal() and SetGlobal() that let you get and set globals from an XCMD. I've used them, and they work. It's the only way I know of to keep some memory around between invocations of an XCMD. (Allocate a handle, convert its address to something ASCII, store it in a global.) David A. Willcox Motorola MCD - Urbana UUCP: ...!uiucuxc!udc!willcox 1101 E. University Ave. INET: willcox@urbana.mcd.mot.com Urbana, IL 61801 FONE: 217-384-8534
sirkm@ssyx.ucsc.edu (Greg Anderson) (05/28/90)
In article <1266@urbana.mcd.mot.com> willcox@urbana.mcd.mot.com (David A Willcox) writes: >In article <3707@darkstar.ucsc.edu> I write: >>I believe that the book "XCMD's for HyperCard" by Gary Bond mentions that >>XCMDs cannot create global variables. > >Am I missing something? I don't have any documentation available here >at work, but I could swear that there are a pair of callbacks called >something like GetGlobal() and SetGlobal() that let you get and set >globals from an XCMD. I've used them, and they work. Yes, GetGlobal and SetGlobal exist and work fine, but in my experience, strange things happen if the global variables do not exist before the XCMD tries to Get or Set them. (Strange things == the next XCMD that gets the variable finds it empty.) The best solution is to declare "Global foo" in some script that is always executed before the XCMD is invoked. ___\ /___ Greg Anderson ___\ /___ \ \ / / Social Sciences Computing \ \ / / \ /\/\ / University of California, Santa Cruz \ /\/\ / \/ \/ sirkm@ssyx.ucsc.edu \/ \/
willcox@urbana.mcd.mot.com (David A Willcox) (05/31/90)
>>In article <3707@darkstar.ucsc.edu> I write: >>>I believe that the book "XCMD's for HyperCard" by Gary Bond mentions that >>>XCMDs cannot create global variables. >> >>Am I missing something? I don't have any documentation available here >>at work, but I could swear that there are a pair of callbacks called >>something like GetGlobal() and SetGlobal() that let you get and set >>globals from an XCMD. I've used them, and they work. >Yes, GetGlobal and SetGlobal exist and work fine, but in my experience, >strange things happen if the global variables do not exist before the >XCMD tries to Get or Set them. (Strange things == the next XCMD that >gets the variable finds it empty.) >The best solution is to declare "Global foo" in some script that is always >executed before the XCMD is invoked. I couldn't believe this since I've used SetGlobal() and GetGlobal() in XCMDs without "global foo" in any script. I went home and tried it, and found that you are absolutely wrong - the "global foo" is not required. Source for my very simple minded example in Think C 3.? is below. BUT THEN... As a last step in checking this out, I tried my example on the old klunker machine at work, and found that it didn't work - the "global foo" was necessary in the script. The difference appears to be that the MAC at work still has HC version 1.0.1, while I have version 1.2.something. My conclusion - If you have a "modern" version of HyperCard, then you can create globals from within an XCMD/XFCN; the "global" in your script is not necessary. If you have an old version of HyperCard, the "global" is necessary. Sounds to me like a bug that has been fixed. David A. Willcox "Just say 'NO' to universal drug testing" Motorola MCD - Urbana UUCP: ...!uiucuxc!udc!willcox 1101 E. University Ave. INET: willcox@urbana.mcd.mot.com Urbana, IL 61801 FONE: 217-384-8534 Sample XCMD: /* * Invoke this as "GetSetGlobal arg". It remembers arg, and * returns the previous value of arg. */ #include <MacTypes.h> #include <HyperXCmd.h> #include <SetUpA4.h> #define nil 0L #define GLOB_NAME "\pDummyGlobal" pascal void main (XCmdBlock *); Handle CopyHand(h) Handle *h; { long len; Handle ret; len = strlen (*h) + 1; ret = NewHandle (len); strcpy (*ret, *h); /* yeah, I should lock them ... */ return (ret); } pascal void main (paramPtr) XCmdBlock *paramPtr; { RememberA0(); SetUpA4(); paramPtr->returnValue = GetGlobal (paramPtr, (StringPtr)GLOB_NAME); SetGlobal (paramPtr, (StringPtr)GLOB_NAME, CopyHand (paramPtr->params[0])); RestoreA4(); }
johner@portia.Stanford.EDU (John Lynch) (06/03/90)
In article <1269@urbana.mcd.mot.com> willcox@urbana.mcd.mot.com (David A Willcox) writes: >My conclusion - If you have a "modern" version of HyperCard, then you >can create globals from within an XCMD/XFCN; the "global" in your >script is not necessary. If you have an old version of HyperCard, the >"global" is necessary. Sounds to me like a bug that has been fixed. > Just a note: You need to declare them in Supercard also. At least, you do if you are going to access them explicitly from Supertalk. In other words, if you create a dummy global just to use from your XCMD, like XXX_My_Global, then only acces it from an XCMD, you are fine, i.e. you get the necessary storage and the XCMD can find it. But if you explicilty use it in Supertalk when it was created from an XCMD, it usually can't find it the first time. In fact, if you acces it within a callback from the XCMD, you often crash. Whoops. Point is, if using Supercard, declare globals you expect to set from an XCMD. John Lynch Trilogy Development Group