/******************************************************************** * * PROJECT: GEOS Programming Frequently Asked Questions * MODULE: The FAQ * FILE: sdkfaq.txt * * AUTHOR: Ed Ballot * * REVISION HISTORY: * Name Date Description * ---- ---- ----------- * EB 9/94 Initial version * EB 12/95 Additional Q & A's * NF 5/8/95 Wrote another FAQ * NF 9/21/96 Combined all FAQs * NF 10/14/96 Combined NF FAQ with ALLFAQ * Put FAQ online * * DESCRIPTION: * This FAQ contains programming questions related to the SDK. * For more general information about the SDK, please see the * Geoworks web site (http://www.geoworks.com/). You may * request more information or order the SDK by calling * 1-800-GEOS-SDK (inside the U.S.), FAXing 510-814-4250, or * sending email to orders@geoworks.com. * *******************************************************************/ These questions and answers are grouped together into categories. To ease searching by category, each category header begins with the string "TOPIC:". This FAQ covers the following topics: ESP Assembly Language Known bugs Clipboard Compiler Controllers Database Library Document/DocumentControl Error Checking, Error Messages File/VMFile Routines Fonts GCN (General Change Notification) List Geode Related Geometry and other HINTS Glue, the linker Generic Objects GOC, the preprocessor Graphics Help, Help Files GEOS.INI, the Initialization file Ink and HWR Mouse, Pen Installation GenInteractionClass (dialog, menu) List Classes Keyboard, Floating Keyboard Libraries Localization, ResEdit Math Memory Blocks/Chunks Messages/Objects VisMonikers NoteShellClass/NoteClass PCMCIA Platform Specific (OmniGo, Zoomer, etc.) Power Printer, Spooler Sample Applications Serial/Stream Sound State Files, Shutdown Swat, the debugger TableClass/JTableClass Text Related and Text Objects Multi-threading Timers Tools Visual Objects Where is it? ===================================================================== TOPIC: ESP Assembly Language --------------------------------------------------------------------- Q. I'm writing a Goc application with a single routine in assembly. I prototype the routine (MyDraw) as follows in myapp.goc: extern void _far _pascal MyDraw( GStateHandle gstate ); mydraw.asm contains the Esp source for MyDraw. Both files compile successfully, but Glue fails, giving the error: file "myapp.goc", line 261: error: MyDraw undefined *** Error code 1 How can I get Glue to link in the routine in the Esp resource? A. Since you declared MyDraw, in myapp.goc, as using the Pascal calling convention, you need do the following in mydraw.asm: 1) Up-case the name of the MyDraw routine to HELLOMDRAW. 2) Bracket the routine with SetGeosConvention before and SetDefaultConvention after to let Esp know that parameters will be passed onto the stack in the same order as Pascal. Here is an example: SetGeosConvention global MYDRAW:far MYDRAW proc far \ arg1:word arg2:MyStruct ...other args, if any... ... body of function ... MYDRAW endp SetDefaultConvention --------------------------------------------------------------------- Q. We have a class definition for FooProcessClass. When the definition is in the .def file, Esp gives a "Class FooProcessClass is multiply defined" error. When we move the declaration into the .asm file, the error goes away. A. The def file is being included by more than one asm file, so you end up with multiple definitions of the class. --------------------------------------------------------------------- Q. "warning: segment not known" I get this warning when compiling my code with Esp. Does this condition impact the generated code ? A. "warning: segment not known" can require an extra byte per call because if the routine is in a local segment, it can use less bytes to make the call if it knows the appropriate place (like the .def file) that declares what segment the routine is in. --------------------------------------------------------------------- ===================================================================== TOPIC: Known bugs --------------------------------------------------------------------- Q. Are there any known errors in the header files? A. In the Beta1.0 release, the following definitions need to be fixed so the C compiler knows that they are hex: graphics.h - line 231: EOREGREC 8000h -> should be 0x8000 math.h - line 248: FORMAT_ID_PREF 8000h -> should be 0x8000 line 251: FORMAT_PARAM_ID 63h -> should be 0x63 line 340: FLOAT_FORMAT_FORMAT_NAME_NOT_FOUND 7fffh -> should be 0x7fff --------------------------------------------------------------------- Q. FileEnum() is not returning the number of files that it finds. I am currently working around it by looking for invalid values in the file information structures as I go through the file array created by FileEnum(). When I see an invalid value (I'm already off the end of the array), I stop processing. A. This is a bug in the C stub for FileEnum(). Here is a better solution to the problem: count = MemGetInfo( memHan, MGIT_SIZE ) / sizeof( FEDosInfo ); where FEDosInfo could be the value you used for the FE_params.FEP_returnSize field before calling FileEnum, and memHan is the memory handle returned by FileEnum. The bug was fixed a long time ago, so this probably won't affect you. --------------------------------------------------------------------- ===================================================================== TOPIC: Clipboard --------------------------------------------------------------------- Q: I am trying to implement drag and drop into my program, and I want to get the name of the transfer item. However, when I use this code to do it, I get a VM_HANDLE_NOT_IN_USE error: TransferBlockID transferID; /* File/Block of item header. */ MemHandle itemMem; /* Mem block for item header. */ ClipboardItemHeader * itemPtr; /* Pointer to item header. */ ClipboardEndQuickTransfer( PasteCommon( CIF_QUICK, textOD, pself->GDI_fileHandle, &itemBlock ) ); transferID = ClipboardGetQuickItemInfo(); itemPtr = VMLock( FileFromTransferBlockID( transferID ), BlockFromTransferBlockID( transferID ), &itemMem ); /* * Add the new item to the map block. */ @call self::MSG_SB_DOCUMENT_ADD_ITEM( itemBlock, itemPtr ); VMUnlock( itemMem ); A: Here is how to do it: ClipboardQuickNotifyFlags retFlags; /* Returned from PasteCommon. */ retFlags = PasteCommon( CIF_QUICK, textOD, pself->GDI_fileHandle, &itemBlock ); transferID = ClipboardGetQuickItemInfo(); itemPtr = VMLock( FileFromTransferBlockID( transferID ), BlockFromTransferBlockID( transferID ), &itemMem ); /* * Add the new item to the map block. */ @call self::MSG_SB_DOCUMENT_ADD_ITEM( itemBlock, itemPtr ); VMUnlock( itemMem ); ClipboardEndQuickTransfer( retFlags ); (The PasteCommon function is in the ClipSamp sample program on the GEOS SDK disk.) The reason this code fragment works is that it is getting the information from the item header BEFORE calling ClipboardEndQuickTransfer, which destroys that header. So, in the previous fragment, we were calling for a VM block that was just freed, and thus we get the error message. --------------------------------------------------------------------- ===================================================================== TOPIC: Compiler --------------------------------------------------------------------- Q: When I compile I get the following warning: Warning file.c 163: Undefined structure '_ClassStruct' Is this a serious warning? A: No. It is a fluke caused by one of the header files. You should ignore it. --------------------------------------------------------------------- Q: I keep getting the compiler error 'resource not found' when I add the line 'resource ui-object' to my .GP file. A: That is because a resource (in GEOS) defines a segment of memory (which contains data or objects) used by your application, not a routine name (nor an object name). These resources are managed by the memory manager and can be moved around in memory or swapped out to storage if they are not being used. In the source code, you define a resource with the @start /@end directives (for example, Hello.goc has the resource AppResource). See section 5.4.3.2 of the Concepts book (Concepts\CCoding.txt) for more information on declaring segment resources and chunks (chunks define smaller sections of segment resources). --------------------------------------------------------------------- Q: When can I use the neverSaved option for declaring a subclass? A: The neverSaved option is only meaningful for ProcessClass because the process class does not have instance data, so it should not (cannot) be saved to state. --------------------------------------------------------------------- Q: BCC complains about an illegal '#' character in my GOC file, but I can't find it. A: If the end of your goc file is immediately after a closing brace, on the same line as the brace rather than on the next line, GOC places a #pragma immediately after the closing brace and then bcc complains about it. You get an error telling you there is an illegal character '#' in the goc file, but of course it is actually in the C file. This is something that should be corrected by GOC, though it is considered "bad form" not to have a newline just before end-of-file. --------------------------------------------------------------------- Q: What parts of Borland C++ do I need to work with Goc (i.e. what is the minimal installation)? A: For Borland C++ 3.1, you need the following: bcc.exe - the Borland C compiler cpp.exe - Borland's C pre-processor rtm.exe - used by bcc dpmi16bi.ovl - used by bcc Include/stddef.h Include/_defs.h For BorlandC 4.0, the default install option for Borland C 4.0 is to leave almost everything on the CD, installing only a few configuration files (about 100KB worth) to the hard drive. --------------------------------------------------------------------- Q: I get the following error when I compile: Must take address of a memory location. Multiple declaration for 'optr' (Line numbers usually off by one.) A: Make sure any TO_APP_TARGET and similar destinations in the object definition are surrounded by parentheses. For example: GCI_output = ( TO_APP_TARGET ); --------------------------------------------------------------------- Q: I get the following error when I compile: "Expression syntax" on a line using MSG_VIS_TEXT_CREATE_TRANSFER_FORMAT A: You are using the 2.0 SDK, and in the PCGEOS\INCLUDE\OBJECTS\VTEXTC.GOH file the message is not defined correctly. The return type of VMBlockhandle is wrong, it should be VMBlockHandle. Feel free to change this, then recompile. It should work then. --------------------------------------------------------------------- ===================================================================== TOPIC: Controllers --------------------------------------------------------------------- Q. I noticed that most controllers have GCI_output = TO_APP_TARGET. What is the difference between focus and target? A. You can set GCI_output to anything you want, but you are right that generally controllers work with the target mechanism. Focus is where input (such as keyboard and mouse) are directed. Focus is set by such actions as placing the mouse pointer over an object and clicking on it or by using the tab key to move the focus from one object to the next. Target in many cases will follow the focus, but only if the object that is gaining the focus has GA_TARGETABLE set. Text objects are good candidates for GA_TARGETABLE; triggers and lists are not (unless you want a controller or something to be able to send a message to the trigger/list). There is a third input flow channel called model, which essentially provides a secondary target hierarchy and is used with documents. These three targeting mechanisms are discussed in the Input chapter of the Concepts book (Concepts\CInput). --------------------------------------------------------------------- Q. I see that we can supply our own visual monikers for the DocumentControl dialog. If we set those attributes to null will it remove them from the dialog? A. No. What you really want to do is turn the features off in the controller. ATTR_GEN_CONTROL_PROHIBIT_UI is an easy way to do this; it stems from GenControlClass, the super class of GenDocumentControlClass. The feature set for GenDocumentControlClass can be found in the GDCFeatures flags record. As an example (in Goc), to use the default intermediate features but to make sure the New feature is turned off set: ATTR_GEN_CONTROL_PROHIBIT_UI = { GDCF_NEW }; You can also make sure that specific features are supported, by using ATTR_GEN_CONTROL_REQUIRE_UI. --------------------------------------------------------------------- Q. How does one implement the Undo function with a VisText object? We are using the GenEditControl and setting the VTF_ALLOW_UNDO feature, however we receive an error stating the context must be set up before issuing undo messages. A. The context is a number to allow for multiple undo's, which you must set manually (so that you can have a different context for each text object). What you can do is send MSG_GEN_PROCESS_UNDO_SET_CONTEXT sometime before the application starts tracking undo-able things. One place to send this message is in MSG_GEN_PROCESS_OPEN_APPLICATION. Here's an example: dword oldContext; oldContext = @call MyProcess::MSG_GEN_PROCESS_UNDO_SET_CONTEXT( 1 ); --------------------------------------------------------------------- Q. When I implement SpellControl, the spell checker is always inactive (not enabled). A. You need to tell your DocumentControl object to notify the SpellControl object when there is text available. This is accomplished in the instance data GDCI_enableDisableList. The following example illustrates how to setup and use GDCI_enableDisableList. @object GenDocumentControlClass MyDocControl = { GDCI_enableDisableList = EnableDisableList; } @chunk optr EnableDisableList[] = { @MySpellControl }; @object SpellControlClass MySpellControl = { } --------------------------------------------------------------------- Q: I am trying to use the SpellChecker in my program, but when I test it I just get a little box with a disabled button. Am I doing something wrong? A: The spell checker is disabled in the GEOS EC and NC versions because Geoworks did not license the checker for the SDK versions of GEOS. It is only available in the full GEOS version that is not part of the GEOS SDK. Also, the SpellControl is one of those that is not to be put in a GenInteraction. It should be a direct child of the Edit menu: @object GenInteractionClass MyEditMenu = { GI_comp = @MySpellControl; ... } /* MyEditMenu */ @object SpellControlClass MySpellControl = { GI_visMoniker = "Check Spelling"; GI_states = @default | GS_ENABLED; /* Must enable. */ GCI_output = ( TO_APP_TARGET ); /* Go to text object. */ } /* MySpellControl */ --------------------------------------------------------------------- Q: Why aren't the triggers in the Find/Replace controller enabled, even after I type some text in the Find field? A: In the SearchReplaceControl you need to have the following attribute: ATTR_SEARCH_CONTROL_INTERACT_ONLY_WITH_TARGETED_TEXT_OBJECTS; This will make the triggers become enabled at the appropriate time. Here is a sample SearchReplaceControl object: @object GenInteractionClass MyEditMenu = { GI_comp = @MySearchReplaceControl; ... } /* MyEditMenu */ @object SearchReplaceControlClass MySearchReplaceControl = { GI_visMoniker = "Find and Replace"; GI_states = @default & ~GS_ENABLED; GII_visibility = GIV_DIALOG; ATTR_SEARCH_CONTROL_INTERACT_ONLY_WITH_TARGETED_TEXT_OBJECTS; ATTR_GEN_DESTINATION_CLASS = { (ClassStruct*)&MyTextClass }; } /* MySearchReplaceControl */ This example is for text objects, which is generally what the Find/Replace is used on. You should only have to make minor modifications to make this work with other kinds of objects. --------------------------------------------------------------------- Q: I have a PointSizeControl object that works to set the size of a VisText object. I am trying to have the point size saved when the program exits and then load that point size when the program starts. I have the size information saved to the GEOS.INI file, and that seems to be working fine. However, when the program starts, it does all the message sending, but the point size control is set to 8 point, instead of whatever it's supposed to be. A: The problem here is that the PointSizeControl has this field: GCI_output = ( TO_APP_TARGET ); If your text object does not have the target when the MSG_PSC_SET_POINT_SIZE is sent then that size change will be ignored completely. To remedy this, set the GCI_output to the text object, like this: GCI_output = @MyTextObject; If you can't do this (eg., because the text object is duplicated by the document control) then make sure the text object receives the MSG_META_GRAB_TARGET_EXCL message before you send the MSG_PSC_SET_POINT_SIZE message. --------------------------------------------------------------------- Q: I recently changed my program from multiple-document interface to single-document interface. When I open a document, everything works fine. When I close that document and open a second one, the Undo no longer works. What gives? (I'm using a text object for the document.) A: For some reason or another the text object is being told to not send undo messages to the EditControl. To fix this, in your MSG_META_DOC_OUTPUT_ATTACH_UI_TO_DOCUMENT method (or wherever is appropriate for your program), send the message @send textObj::MSG_VIS_TEXT_SET_FEATURES( VTF_ALLOW_UNDO, 0 ); This will make the text object turn on it's undo support. --------------------------------------------------------------------- Q: I can't get the font and size controllers to work with a GenText I have in a small app I'm working on. The GenText is just a display text, so it's GI_attrs is set GA_READ_ONLY. A: Remove the GA_READ_ONLY. This makes the FontControl and PointSizeControl disabled. --------------------------------------------------------------------- ===================================================================== TOPIC: Database Library --------------------------------------------------------------------- Q. I'm having trouble retrieving the data that I have placed into the default record when I create the database. When I am retrieving the data later, each piece of data has had its last two bytes stomped on, usually with two bytes containing 0xCC. Each item has the format: typedef struct { unsigned short size; char data[1]; } DBField; where size is the size of the data, and data is the address of the first byte of the data. A. You are not allocating the correct size for the items. The size needs to include the word of data that gives the size of the db item. (In other words, add sizeof( word ) to the db item size.) For problems like this, you can gather more information by using the various LMem related EC flags in Swat ('help ec' in Swat for more information). Those flags will enable various extra internal error checking and may well give more insight as to what's happening. --------------------------------------------------------------------- Q. Is it safe to assume that a call to DBFree will not result in moving of any locked item blocks or items ? A. Yes, it is safe. In fact, any calls to MemFree, LMemFree, etc. are safe. The only way a locked block (and therefore a locked DBItem) can be moved is by explicitly resizing the block. For DB item blocks, this would mean calling DBAlloc. --------------------------------------------------------------------- Q. MSG_INK_SAVE_TO_DB_ITEM is documented as: "Return: AX.BP - DB group/item written to (VM Chain)" -------- Does that mean that it could create a chain of VM blocks instead of a single db-item ? A. This syntax was derived from the fact that DB Groups are stored in multiple VM blocks. This is to allow growing populations of DB items within the group to expand over 64K (though I think the primary reasoning is to allow blocks within the group to stay around the optimal 2-6K size without restricting the total sizes of all the items to 6K). Because of this methodology, the creation of a new DB Item can cause the creation of a new VM block. This will probably not happen until the previous items in the group take up more than 4-6K. In any case, I'm sure it can't create more than one additional block at a time. If you've only got a few ink items in the group, it won't create multiple blocks in the chain. --------------------------------------------------------------------- ===================================================================== TOPIC: Document/DocumentControl --------------------------------------------------------------------- Q. Exactly which regular attributes and extended attributes does the document control take into account? Is there a way that I can look at a file's extended attributes with the debugger? It seems the only other way would be to programmatically request each one to get the settings. Then, if I don't know which ones the doc control is looking for I will have to set all of them for each file I create. A. There's FEA_FILE_ATTR (FA_RDONLY), FEA_PROTOCOL, FEA_TOKEN, FEA_CREATOR, FEA_FLAGS (public/template stuff), FEA_USER_NOTES (for display in the file open box), FEA_PASSWORD (all 0 if no password), and FEA_RELEASE (just sets it). (It also does FEA_DISK and FEA_FILE_ID, but those aren't settable.) The file token is what is needed to see the thing in a file-open box. The creator token is needed if you double-click the file. The FEA_FILE_TYPE is needed by the VM system. the protocol is needed once the file is opened and should match the protocol bound into the document group object. --------------------------------------------------------------------- Q. In the document control, the "Find..." button does nothing. What is it supposed to do? If it really is supposed to do nothing in that context, shouldn't it be NOT_ENABLED? A. The "Find" button is managed by a SearchReplaceControl object. It's enabled, because the user ought to be able to search for text within the documents listed -- it's only ~GS_ENABLED when the File Selector shows no files. It does nothing, because the application needs to handle the searching itself. See the sample application DocUI, which is in the SDK_Omni sample app tree, for an example of using MSG_SEARCH. --------------------------------------------------------------------- Q. When implementing the "Find" trigger in the DocumentControl's FileSelector, it always crashes. What's going on? A. There is a bug in the handler for MSG_SEARCH which requires that an object be at the chunk 002ch in the object resource that contains the DocumentControl object. The workaround is to manipulate the objects so that an object actually does exist in that chunk. You can use the "objwalk" command in Swat (for the handle use that of the DocumentControl object) to assist in determining where objects are located in the resource. --------------------------------------------------------------------- Q. The "Note" button does nothing the first time it is hit. The second time, it says "Unable to create the note. The document may be a template, or it may be in use." A. The support for the "Note" trigger isn't completely automatic. You have to add a NoteShellClass object to the app. Also, your application is responsible for saving the NoteShell's data into the VM file. Here's what you should do: In your *.goc file: =================== 1. Include the Geos header file that defines NoteShellClass. @include 2. Create a new subclass of NoteShellClass. 3. Create an object of your new subclass of NoteShellClass. 4. Make it a child of the GenApplication object. 5. Add it to the following GCN lists: MGCNLT_ACTIVE_LIST (same as DocumentControl) GAGCNLT_STARTUP_LOAD_OPTIONS 6. Intercept MSG_GEN_DISPLAY_CLOSE for your subclass of NoteShellClass: @method YourNoteShellClass, MSG_GEN_DISPLAY_CLOSE { /* * First, save away the NoteShell data into a VM file. */ /* * Now, close the NoteShell */ @send self::MSG_NOTE_SHELL_CLOSE_DISPLAY(); } In your *.gp file: ================== 1. Add "library notes" to load the notes library 2. Export your new subclass of NoteShellClass --------------------------------------------------------------------- Q. HINT_APPLICATION_QUIT_ON_IACP_ALLOW_FILE_ACCESS isn't working. My application is running with a document open. I then use Transfer to try to restore an earlier version of the data file, I get the message "Restore Error. Can't access the data in memory. Close the application for which you are restoring data and try again." If I try restoring a second time, the error message is not given. It properly restores the old data file. A. DocumentControl automatically handles IACP file access requests, so don't use HINT_APPLICATION_QUIT_ON_IACP_ALLOW_FILE_ACCESS. The problem with this hint is that it causes the application to shutdown, but the document gets closed near the end of the shutdown procedure. Because the application shutdown process is asynchronous, the document will most likely not be closed by the time Transfer receives feedback that the application is shutting down. NOTE: If your application stores datafile-specific information (such as a data cache), you will still have problems, because the datafile could be altered by the Transfer application, leaving your stored information incorrect. In this case, you should reset the information during MSG_GEN_DOCUMENT_CLOSE_FILE or MSG_GEN_DOCUMENT_REOPEN_FILE. --------------------------------------------------------------------- Q: In my text editor, if I have two documents opened and I use the Window menu to switch between them, the document display will draw twice, and the name in the primary's title bar will be "No Document" instead of the file's name. A: Remove the GDCF_NAME_ON_PRIMARY flag in the GenDocumentControl. To do this, simply add the following line to your GenDocumentControlClass object: GDCI_features = @default & ~GDCF_NAME_ON_PRIMARY; The document name will still be on the primary's title bar, but it won't do the "No Document" thing and the display will stop drawing twice after the first time you switch to that document. --------------------------------------------------------------------- Q: I am setting up my application using the single-document interface and I get this error in Swat: OBJ_BLOCK_DUPLICATE_NOT_DISCARDED when I try to open a file. A: In the procedural model you must take out the GDGI_genDisplay instance from the GenDocumentGroup object definition. If this field is non-null the GenDocumentGroup will automatically try to duplicate the display object resource. You don't want this to happen under the SDI mode. --------------------------------------------------------------------- Q: I have a GenDocument in my program and in one of the message handlers (MSG_GEN_DOCUMENT_DETACH_UI_FROM_DOCUMENT) uses the @send @visChildren::MSG_SOME_MESSAGE_TO_THE_CHILD(); ^ ^ ^ ^ shortcut. But for some reason, the message never seems to reach the children of the GenDocument. Am I misunderstanding something? A: There's something fishy in Denmark when it comes to GenDocuments. You add objects to it as children, and remove them as children, but they really aren't it's children. If you use Swat and do a pobj on the GenDocument object, you will see it's GI_comp field is NULL, even after children have been added to it. Here is what I do in my programs: optr textOD, ourText; pself = ObjDerefGen( oself ); if ( pself->MYDI_textHandle == NullHandle ) { return( FALSE ); /* No error since if text handle is null * then there's nothing to do. */ } else { textOD = GeodeGetOptrNS( @MyText ); ourText = ConstructOptr( pself->MYDI_textHandle, OptrToChunk( textOD ) ); /* Do something with child object. */ return( FALSE ); /* No error */ } I use GeodeGetOptrNS because my programs are always broken into multiple source files, and thus you need to use GeodeGetOptrNS. I added an instance field to the GenDocument subclass that holds the MemHandle of the text object. You get this when you duplicate the text object resource. So, everytime you want to be able to send messages to the text object, or add and remove it, just create the optr to it. --------------------------------------------------------------------- ===================================================================== TOPIC: Error Checking, Error Messages --------------------------------------------------------------------- Q. What's the difference between the EC and NC versions (and how do tools such as PCS automatically handle these)? A. See "The Error-Checking Version" in section 6.5 of Concepts Vol. 1 in the documentation for information on this topic. --------------------------------------------------------------------- Q. My app works in GEOS NC, but causes a fatal error in GEOS EC. Swat says that the app is bombing out just as it launches because backtrace shows nothing that is from my app. A. Make sure that only the subclassing of ProcessClass has the option "neverSaved." EC does not take well to other subclassed objects having the neverSaved option set. --------------------------------------------------------------------- Q. I've added some EC code to my app and noticed that whenever I call ECCheckGStateHandle I always get an ILLEGAL_HANDLE. Why is this happening? A. The C stub for ECCheckGStateHandle was using the wrong registers and thus would always have an illegal handle. This error was fixed on August 9, 1996. In the meantime, if you really want to check the validity of a gstate handle, you can write a C stub of your own which simply takes the handle parameter and calls ECCheckGStateHandle from an assembly subroutine. --------------------------------------------------------------------- Q. I would like to know what KR-06 really is? According to the document, it says KR-06 means "breakpoint hit", but I still don't know what that means. A. The routine FatalError was called for some reason, which ends in a breakpoint. Often KR-06 messages are caused by some really random wacky burp in the hardware or software. A reset of the hardware and software will correct the problem. (If something happened to a file on disk, the problem will not go away until the file is replaced.) --------------------------------------------------------------------- ===================================================================== TOPIC: File/VMFile Routines --------------------------------------------------------------------- Q. How to I get error information for FileOpen or any of the FileXxx routines? A. For most FileXxx() routines, you can use ThreadGetError() to get the error of code specifying what went wrong. --------------------------------------------------------------------- Q. My call to FileCreate now gets "Death due to CREATE_BAD_FLAGS" Here's the call fileHan = FileCreate("sample.rec", (FILE_CREATE_TRUNCATE | FCF_NATIVE | FILE_ACCESS_R | FILE_DENY_NONE), FILE_ATTR_NORMAL); A. As stated in the Routines book under FileCreate(), a file cannot be created in read-only mode. You must open it with write access. And, if you open it with write access, you must open it deny-write for others. Try using FILE_ACCESS_RW | FILE_DENY_RW, as shown in the example which accompanies the FileCreate() reference entry. --------------------------------------------------------------------- Q. Given two full directory path strings (including the drive letters), how can I check whether the two refer to different files ? Doing a string compare of the paths will not cover all cases, since it is possible to have two different drive letters mapped to the same drive. A. Call FileGetPathExtAttributes(FEA_MULTIPLE, 2, [FEA_FILE_ID, FEA_DISK]) for each one (from assembly one can call IACPGetDocumentID) and compare the attributes of the files. --------------------------------------------------------------------- Q. If you use FileEnum in a standard path, will it return multiple entries, if those entries have the same file name. A. No -- local versions of files will override remote versions --------------------------------------------------------------------- Q. How can I tell when an error occurs in FileRead()? The docs mention that errors will be set "in the thread's error value." What is that and how do I access it??? A. FileRead will return -1 and you can then use ThreadGetError(). It returns a word with the thread's error value. It should be one of the enum type FileError (file.def) or Error (in file.h). --------------------------------------------------------------------- Q. I am opening a document using VMOpen with the following parameters: mode = VMO_OPEN flags = VMAF_FORCE_READ_ONLY compression = 0 After calling VMOpen, I get "WARNING: FAULTING_IN_VM_BLOCKS" in Swat. Subsequent operations seems to work fine. What does this mean? A. Since you did not pass VMAF_FORCE_DENY_WRITE, the VM manager is bringing the whole file into memory to make sure you get a consistent copy in case another app opens the same doc and writes to it. This requires a lot of system memory, so unless you have a good reason not to, I would suggest adding the flag VMAF_FORCE_DENY_WRITE. --------------------------------------------------------------------- Q. What is the exact meaning of the VM_COMPRESS_HOSED FatalError? A. It signifies a problem in the VM system (or in whatever created the VM file) that has generated a file with a gap in it (i.e. there are bytes in the file that are not covered by a VM block handle that tracks used space or one that tracks free space in the file). --------------------------------------------------------------------- Q. There are two routines which allow one to set map structures for a VM file: DBSetMap and VMSetMapBlock. The first sets a db-item as the map structure, while the second set a VM block as the map. Can the two (map item and map block) exist together in a single VM file? A. Yes, a VM file can have both a map block and a map item. --------------------------------------------------------------------- Q. I have objects spread among different VM blocks. Some of these are Vis objects, and will be connected together via the standard Vis linkage, while other ones will be meta objects, and will contain optrs to some of the Vis objects in their instance data (the Vis objects have optrs to meta objects in their instance data as well). I'm unclear about how much of the object relocation/unrelocation the VM code will do. Will I have to do all the relocation work myself? A. Object relocations are performed whenever the object block is read in from the file. Make sure you call VMPreserveBlocksHandle whenever you call VMAlloc (or VMAttach) for any blocks that will contain objects. Also, make sure your class definitions are set up properly so that object relocations will happen. and, of course, make sure the VMA_OBJECT_ATTRS attributes are set for the file. --------------------------------------------------------------------- Q. I am calling VMPreserveBlocksHandle on a VM file object block. Do I need to VMLock the block manually to send a message to an object within it? A. It is a bad idea to call VMLock directly on an object block. If you just want to send a message to that object, use VMVMBlockToMemBlock to get the memory handle for that block, and then use ObjMessage. If you really need to lock that block, use VMVMBlockToMemBlock, followed by ObjLockObjBlock. --------------------------------------------------------------------- Q. How can I cause a huge array to be written out to disk after I dirty it? A. VMUpdate --------------------------------------------------------------------- Q: I have a text editor and when I try to open the GEOS.INI file an error dialog appears saying I can't open the file. This I understand, but later on the program crashes when I try to exit. A: The problem is in the GenDocument object that is created for the GEOS.INI file. Even though a message appears saying you can't open the file, a GenDocument object was created for it, and unfortunately, it remains in memory, uninitialized, waiting to cause an error later on. To solve this, in your MSG_GEN_DOCUMENT_OPEN handler check for an error returned by the superclass, then remove the GenDocument object. Here is a sample: @method ZTEDocumentClass, MSG_GEN_DOCUMENT_OPEN { word * error; /* Error value from ReadDataFromFile. */ optr ourText; /* Pointer to current text object. */ /* * Check if error occurred during open. * If so, cancel the open. Return error status. * (Don't try to do MSG_GEN_DESTROY, that gives an error.) */ if ( @callsuper() ) { @send self::MSG_GEN_REMOVE( VUM_NOW, 0 ); return( TRUE ); } else { /* * Read in text file by calling read data function. * Prepare necessary parameters first. */ pself = ObjDerefGen( oself ); ourText = ConstructOptr( pself->ZTEDI_textHandle, OptrToChunk( @ZTEText) ); if ( ReadDataFromFile( pself->GDI_fileHandle, ourText, error ) ) { *fileOrError = *error; return( TRUE ); } else { return( FALSE ); } } } /* MSG_GEN_DOCUMENT_OPEN */ --------------------------------------------------------------------- ===================================================================== TOPIC: Fonts --------------------------------------------------------------------- Q. I need to use a fixed size font to display a table. How should I specify that I need a non-proportional font? A. If you're working with a GState and view, GrSetFont() will do the job. If you're working with a text object, then MSG_VIS_TEXT_SET_FONT_ID is in order (or MSG_VIS_TEXT_SET_CHAR_ATTR if you're setting multiple attributes). If trying to find a fixed width font to use, then it depends on whether you need to print or not. No printing: Bison or URW Mono. Printing: URW Mono. If it's on Zoomer, then URW Mono doesn't have hand-tuned bitmaps and might not be desirable for screen display, depending on the pointsize being used. If you wish to find a font dynamically, then GrEnumFonts() can be used to find a list of matching fonts. Finally, depending on the table, you don't necessarily need to restrict yourself to fixed width fonts. You can set tabs (including decimal tabs) in a text object to force things to line up. Or if in a GState/view setup, you can use font metrics information to calculate text sizes and right-justify the entries without too much trouble. Note that the numbers in many (not all) fonts are fixed width. --------------------------------------------------------------------- Q. What fonts are available on the OmniGo? A. Here are the fonts that are on the OmniGo: Point Type Font Outline? Sizes Styles -------------------------------------------------- FID_JSYS no 14 P, B, PI, BI FID_CALENDAR no 8 P FID_LED no 12 P FID_NOTEPAD no 16, 17 P, B, PI, BI FID_DTC_URW_SANS yes 12, 14 P, B, PI, BI FID_BISON yes -- FID_DTC_URW_MONO yes -- Notes: - Type Styles: P = Plain B = Bold PI = Plain Italic BI = Bold Italic - LED font used only on the HP-12C calculator app. - Sans font is also useful for printing and has two screen bitmaps (12 & 14). It's used primarily for Book Reader in ROM, but developers are more than welcome to use it. The screen bitmaps for Sans currently only include Plain and Bold. You can set up Italic, and though it might not look great on screen, it should be readable. - Bison font is for passwords and has only 1 character (*). - Mono font is useful for printing but not for screen display, as it has no screen bitmaps in it. - Obviously, you can display or print an outline font at any point size you want, but if you don't pick a size that has screen bitmaps, it probably won't look good on screen unless it is 18-point or larger (which is pretty large for that screen size). --------------------------------------------------------------------- ===================================================================== TOPIC: GCN (General Change Notification) List --------------------------------------------------------------------- Q. How does one find out all the applications that have a particular document file open? The problem is that IACPConnect() requires a GeodeToken to determine which servers to connect to. A. Well, IACP maintains a registry of all the open docs. Unfortunately, the only way to make use of it is to perform an IACPConnect. The token is easy enough to come by: FileGetPathExtAttributes(FEA_CREATOR, filename, disk). Create an AppLaunchBlock with the document name and a 0 disk handle for the app, and voila. A more reasonable approach would be to get the CREATOR token and do an IACPConnect with no AppLaunchBlock, then send the appropriate recorded message with a DocumentCommonParams for the document as stack data in the recorded message, sending it TO_MODEL to the GenDocumentGroupClass object (likely). --------------------------------------------------------------------- ===================================================================== TOPIC: Geode Related --------------------------------------------------------------------- Q. I got the optr for an application from MSG_GEN_FIELD_GET_TOP_GEN_APPLICATION, and I would like to get the tokenID for that application. How can I get it? A. Ultimately you want to call GeodeGetInfo, which requires a GeodeHandle. You can get the GeodeHandle from MemOwner(OptrToHandle()) --------------------------------------------------------------------- Q. How do I make GeodeFind work? I am using the DOS file name for the application and I double checked to see that the application is on the disk, but its always returns 0. A. Use the geode's permanent name, not the file name. The permanent name is specified in the .gp file in the "name" field. --------------------------------------------------------------------- ===================================================================== TOPIC: Geometry and other HINTS --------------------------------------------------------------------- Q. I have two GenTriggers inside a GenInteraction. I increased the space between the two GenTriggers with HINT_CUSTOM_CHILD_SPACING. I would also like to increase the size of GenInteraction so that there is more space between the GenInteraction border and the GenTrigger borders. How can I make the GenInteraction become larger, or how can I increase the distance between the GenTriggers and the border of the GenInteraction? A. Use HINT_INCLUDE_ENDS_IN_CHILD_SPACING on the GenInteraction. All of this geometry stuff is in Chapter 12 of the Concepts Book. --------------------------------------------------------------------- Q. How do you set the "desired" width for a GenText object? Specifically, I'd like to be able to have a GenText that is roughly 500 pixels wide, but never so wide as to push the GenInteraction it is inside of off of the screen (i.e. forced to shrink on the Casio Z-7000/Tandy Z-PDA). A. This will cover both requirements: HINT_INITIAL_SIZE = { (SST_PIXELS | 500), 0 }, HINT_MAXIMUM_SIZE = { (SST_PERCENT_OF_FIELD_WIDTH | PCT_100), 0 }; --------------------------------------------------------------------- Q. HINT_EXPAND_HEIGHT_TO_FIT_PARENT is getting ignored in my GenInteraction (GIV_POPUP) which has a FileSelector child. A. HINT_EXPAND_{HEIGHT/WIDTH}_TO_FIT_PARENT and HINT_{FIXED/MINIMUM/MAXIMUM/INITIAL}_SIZE don't do anything on windowed objects. You have to use HINT_SIZE_WINDOW... hints. --------------------------------------------------------------------- Q. Every time I use HINT_SIZE_WINDOW_AS_RATIO_OF_(PARENT or FIELD), my window is larger than the screen. My PCT_xx values are far less than 100. I am using them on GenInteractions. A. Make sure to use SWSS_RATIO like this: HINT_SIZE_WINDOW_AS_RATIO_OF_PARENT = { ( SWSS_RATIO | PCT_40 ), ( SWSS_RATIO | PCT_60 ) }; --------------------------------------------------------------------- Q. How can I make a dialog (GenInteraction, GIV_DIALOG) always stay on top of other dialogs in my application? A. Use window layering, which allows you to set the "height" that you want the dialog box to display at. See section 2.6.1.7 (Window Management) of the Objects book for more information. --------------------------------------------------------------------- Q. How can I get the screen width and height on any system? A. There is no specific API to get general system metric information. For your specific request to get the screen width and height, you will need to do use MSG_GEN_GUP_CALL_OBJECT_OF_CLASS to send MSG_VIS_GET_BOUNDS to the GenFieldClass. MSG_VIS_GET_BOUNDS returns the current bounds of an object in a variable of type Rectangle. The GenField object is kind of a backdrop that everything else sits on. (Section 28.4 of the Objects 3 book [Objects\OSysObj.txt] describes the GenFieldClass in more detail.) --------------------------------------------------------------------- Q. How can I make a popup menu not pin-able? A. HINT_INFREQUENTLY_USED --------------------------------------------------------------------- ===================================================================== TOPIC: Glue, the linker --------------------------------------------------------------------- Q. When we try to run our application on the Casio Z-7000, we receive the error: "This application is incompatible with this version of the system software. Error Code: FM-37." How do we get our programs to run on this device? A. Put "platform zoomer" in your .gp file --------------------------------------------------------------------- Q. My application uses the functions memcpy and memset. The string.h file is included in the program, but when recompiling, I get: "Error _memcpy undefined" and "Error _memset undefined". What am I doing wrong? A. You need to add "library ansic" to your .GP file. This will tell Glue to link in the AnsiC library. --------------------------------------------------------------------- Q. Why am I getting this Glue error? BORLAND.C: Line 2466: assert(base == ((genptr)sos - scopeOff)) failed. *** Error code 1 Q. This is caused by having a source file that is too huge. I would suggest splitting the source into multiple files (this can also speed compilation as files that are unchanged between compilation do not need to be recompiled). Some considerations when splitting up source code: * keep all objects that are in the generic tree within the same file (i.e., all objects that are statically connected should be in the same file). If you split up the objects into several source files, you will need to use MSG_GEN_ADD_CHILD to dynamically link them because during compilation time Glue does not create the links between objects if they are in separate source files. * The standard paradigm for multiple files under GOC is to have all object declarations in one file, and routines and method handlers grouped in source files by the object that they support. --------------------------------------------------------------------- Q. When compiling, Glue complains: "Error test.gp 41: resource CommonCode not defined" though the .goc file has: @start CommonCode; [ ... ] @end CommonCode what does the err message mean? A. It means you didn't declare the resources in the .gp file. Add a line something like this: resource COMMONCODE shared --------------------------------------------------------------------- Q. in the *.gp file, there's the "name hello.app" line. What are all the options for the 3 char extension? A. Any suffix is valid. These are the standard ones Geoworks uses: app = application lib = library drvr = driver ifsd = File system driver spui = specific UI kern = kernel --------------------------------------------------------------------- Q. What is the purpose of the "c-api" flag on the "type" line of a .gp file? A. This is needed for libraries and preferences modules that are written in Goc. It tells the kernel to call the library entry point by passing stuff on the stack. --------------------------------------------------------------------- Q: I just added a new source file to my program, and I get this error when my program starts up: OBJ_LOCK_OBJ_BLOCK_BY_WRONG_THREAD A: Make sure the resource in the new file is listed in the .GP file. If it's not, it defaults to 'object' type and can't be run if the objects in the new file are children of objects that are in the 'ui-object' thread. --------------------------------------------------------------------- ===================================================================== TOPIC: Generic Objects --------------------------------------------------------------------- Q. How can I get the directory path for my application? A. The GenApplicationClass has instance data (GAI_appRef) containing the path where the application was launched from. MSG_GEN_APPLICATION_GET_APP_INSTANCE_REFERENCE returns GAI_appRef as a block handle of the structure AppInstanceReference. typedef struct { PathName AIR_fileName; FileLongName AIR_stateFile; DiskHandle AIR_diskHandle; byte AIR_savedDiskData[1]; } AppInstanceReference; --------------------------------------------------------------------- Q. I have a GenInteractionClass object that I wish to display at the bottom of my application's view on the Zoomer (similar to the way the pop-up keyboard works). What HINT/ATTR would allow me to make the bottom of this object align to the bottom of the screen? A. HINT_POSITION_WINDOW_AT_RATIO_OF_PARENT = { SWSS_RATIO|PCT_nn, SWSS_RATIO|PCT_nn }; where 'nn' (from PCT_nn) is a multiple of five from 0 to 100. --------------------------------------------------------------------- Q. I cannot get the GenPrimary to be a floating window (like you can in Ensemble or like Clip & Go. How can I do this? A. On the OmniGo, GenPrimary is forced to be full-screen no matter what. To get around this, you will have to make a GenInteraction (GIV_DIALOG) and use that as the floating window. If you wish to make the GenPrimary hidden so your application is only represented by a floating window, attach (GI_comp) the dialog box to the GenApplication object. In MSG_GEN_PROCESS_OPEN_APPLICATION, send MSG_GEN_INTERACTION_INITIATE to the dialog box (and make the dialog box GIA_NOT_USER_INITIATABLE). --------------------------------------------------------------------- Q. In GenFileSelector, when I set GDCI_selectorType = GFST_ALL_FILES, it doesn't show both DOS and GEOS files. How can I get it to show all files (both DOS and GEOS) A. Subclass GenDocumentControl and override the method MSG_GEN_DOCUMENT_CONTROL_CONFIGURE_FILE_SELECTOR. The prototype for that method is as follows @message MSG_GEN_DOCUMENT_CONTROL_CONFIGURE_FILE_SELECTOR (optr fileSelector, word flags); In this case, the flags are the GenDocumentControlAttrs structure, which is described in the docs as well as the header file. In the override of this method, you can do what it says: configure the file selector - to list all types of files. --------------------------------------------------------------------- Q. When limiting the search in a file selector to a single directory, how does one specify the name of the directory in the .ui file? A. To specify the path of a GenFileSelector, add ATTR_GEN_PATH_DATA. To limit the ability to change directories, you'll have to turn off the FSA_ALLOW_CHANGE_DIRS attribute. --------------------------------------------------------------------- Q. I have an application that writes lots of text to a GenText object by calling MSG_VIS_TEXT_APPEND_PTR. After a while the system crashes and gives the following message: WARNING: FAULTING_IN_VM_BLOCKS Death due to TS_LOCK_TEXT_PTR_INVALID_RETURN_VALUE A. Your text object has gotten larger than 20K. This is because the system only checks to see if a text object has gotten too large when the user is entering text. You should either use a VisLargeText object or monitor the amount of data that you are adding to the GenText and begin removing old text as the GenText fills up. --------------------------------------------------------------------- Q. I have a problem setting ATTR_GEN_TEXT_CHAR_ATTR. Here is a sample of what I am doing: ATTR_GEN_TEXT_CHAR_ATTR = { \ {{{2, 0}}, CA_NULL_ELEMENT}, VTDF_BERKELEY, {0, VTDS_12}, \ 0, {C_BLACK, CF_INDEX, 0, 0}, 0, FWI_MEDIUM, FW_NORMAL, \ 0, SDM_100, {0}, {C_WHITE, CF_INDEX, 0, 0}, SDM_0, {0}, \ {0,0,0,0,0,0,0}}; A. ATTR_GEN_TEXT_CHAR_ATTR should have a chunk handle, so do this: /* Define a chunk to hold the data */ @chunk VisTextCharAttr myTextCharAttr = { {{{2, 0}}, CA_NULL_ELEMENT}, VTDF_BERKELEY, {0, VTDS_12}, \ 0, {C_BLACK, CF_INDEX, 0, 0}, 0, FWI_MEDIUM, FW_NORMAL, \ 0, SDM_100, {0}, {C_WHITE, CF_INDEX, 0, 0}, SDM_0, {0}, \ {0,0,0,0,0,0,0}}; /* in your object, use that chunk */ ATTR_GEN_CHAR_ATTR = @myTextCharAttr; --------------------------------------------------------------------- Q. Is there an easy way to cause the text field of a GenTextClass object to be displayed in reverse video? A. Use HINT_TEXT_WASH_COLOR. If you set the background to black, you will have to change the character attributes so the characters are not black. --------------------------------------------------------------------- Q. Given a GenText object, could I stick a GString into its text somehow? Would weird things happen to the line spacing? A. You can paste a gstring into the GeoWrite text layer. The text library takes care of figuring out the line spacing based on the size of the graphic. GeoWrite uses a subclass of VisText to do this, but Help files created in GeoWrite are displayed using a subclass of GenText. If you use GeoWrite to insert the graphic into the text, then copy the portion of the text which includes the graphic to the clipboard, you could paste it into a GenText. --------------------------------------------------------------------- Q. I have a message handler for MSG_GEN_VALUE_GET_VALUE_TEXT which provides the kind of display string I need. The length of the value field in the display seems to be fixed so that my string is clipped. A. Make sure you do not @callsuper, as that will set the sizing to the width of a WWFixed value. --------------------------------------------------------------------- Q: I added a couple of entries to a menu and now the contents of the menu don't appear when I click on it. I looked that the source code, but I just can't see what's wrong. A: Sometimes when you add items to a menu (or any other object tree) you forget to change all the links. Here's a rough example: @object class object1 = { GI_comp = @object2, @object3; } @object class object2 = { } @object class object3 = { } Now say I want to add an object4 and group it with object3: @object class object1 = { GI_comp = @object2, @object3; } @object class object2 = { } @object class objectgroup = { GI_comp = @object3, @object4; } @object class object3 = { } @object class object4 = { } Now I'm sure you can see something was forgotten, as this is a simple example. I forgot to change the GI_comp field in object1, so it's pointing to the wrong object. It should be like this: @object class object1 = { GI_comp = @object2, @objectgroup; } In a more complex object tree, spotting this error is difficult. --------------------------------------------------------------------- ===================================================================== TOPIC: GOC, the preprocessor --------------------------------------------------------------------- Q. Goc keeps telling me that it can't find stddef.h. I found stddef.h in the Borland C++ include directory, but not in the PCGeos include directory. Is that the right place for it to be? What should I do? A. This problem usually occurs because you move or change BorlandC's root directory, but don't update the turbo.cfg file that contains pointers to the borlandc bin and include directories. First, make sure that \BIN is in your path. Second, check the turbo.cfg file in the borland bin directory. It should have the following lines in it: -IC:\BORLANDC\INCLUDE -IC:\BORLANDC\LIB (if you have the Borland compiler on a drive other than C: or in a directory other than BORLANDC, please read that into the preceding suggestions.) --------------------------------------------------------------------- Q. How should BIOS calls be made in GOC? A. BIOS calls can be dangerous, as the GEOS kernel controls many of them (serial ports, timers, etc.). This will also limit your application to operate only on hardware that provides the necessary BIOS. With that said, you can use in-line assembly code to generate an interrupt. The syntax looks like this: SysLockBIOS(); asm { mov ax, 10 int 21h } SysUnlockBIOS(); Keep in mind that GEOS interrupts will not be processed. Thus your app will not thread or task switch. Try to keep your excursions in BIOS-land to a minimum in number and duration. --------------------------------------------------------------------- Q: I get a warning in the Borland compiler about the variable not being used in the following code: @define DEBUG .. Boolean error; error = FileWrite( .... ); #ifdef DEBUG if ( error ) { ... } #endif A: The problem is that the @define does not necessarily mean that DEBUG is #define'd. You need to do both an @define DEBUG and a #define DEBUG for the code to be compiled properly. --------------------------------------------------------------------- Q: I have the following code fragment in my program and I get a Goc error saying "ifdef is undefined". @chunk optr enableDisableList[] = { @ifdef ZOOMER @MySaveTrigger, @endif @MyOtherObject }; A: The problem there is Goc thinks @ifdef is an object, instead of a directive. To fix it, have the @ifdef and @endif against the left margin, like this: @chunk optr enableDisableList[] = { @ifdef ZOOMER @MySaveTrigger, @endif @MyOtherObject }; --------------------------------------------------------------------- Q: I have the following code fragment in my global.goh and I get a Goc error saying "Open conditional...". @extern object @SomeObject; @ifdef ZOOMER @extern object @AnotherObject; @endif @extern object @MyOtherObject; A: The problem there is Goc doesn't like it when the @ifdef and @endif are not against the left margin. Fix it be bringing the @ifdef and @endif to the very left side of the document. For example: @extern object @SomeObject; @ifdef ZOOMER @extern object @AnotherObject; @endif @extern object @MyOtherObject; --------------------------------------------------------------------- ERROR: realloc: Illegal address (0x0) SOLUTION: This is a problem with the memory system. The only solution I have found is to exit all the applications and reset the system. --------------------------------------------------------------------- Q: The Concepts book mentions the @if and @endif directives, but no @else. Is there one? A: Yes. For whatever reason, the @else didn't make it into the documentation. It is available and works just like a #else only it's used with code that contains @ symbols (just as the @if directive is used with code containing @ symbols). --------------------------------------------------------------------- ERROR: End of file in resource declaration... SOLUTION: Put a semicolon (;) at the end of the @chunk declarations. Strange, but that fixes the error. --------------------------------------------------------------------- ===================================================================== TOPIC: Graphics --------------------------------------------------------------------- Q. To draw a small icon, is it faster to call drawing routines, or use a bitmap? If bitmaps are better, how do I create one? A. It depends on the type of bitmap (simple or huge/complex), the specific Graphics routines you're using, and the dimensions of the graphic. There are other considerations besides speed, too-- large bitmaps generally take up a lot of space compared to gstrings. You could test out your specific case by timing how long it takes to draw, say, 100 copies of the graphic in your app. This should exaggerate any speed difference to where it's readily apparent which one is faster. It would be hard to guess in advance. --------------------------------------------------------------------- Q. Does the OmniGo support gray scale? A. No. --------------------------------------------------------------------- Q. How do I use GrCreateBitmap? A. GrCreateBitmap returns a GState that points to a large bitmap structure (which in turn is stored in a huge array). One then draws using the returned GState, which stores the image in the bitmap. --------------------------------------------------------------------- Q. Please tell me how I could convert vm data from inkclass objects into standard bitmap files (e.g. PCX, BMP, etc.). A. Here's an outline of what you need to do to convert ink data to a standard graphics format. The first step would be to instantiate an ink object, and load it with the ink data you want to convert to a bitmap. To convert the ink data to GEOS bitmap format, create a bitmap with GrCreateBitmap() -- this results in a gstate for drawing into the bitmap. Then have the ink object draw itself by sending it a MSG_VIS_DRAW (you might want to pass DF_EXPOSED and DF_PRINT as the draw flags for MSG_VIS_DRAW) passing the gstate of the bitmap. You finally use an export controller in your application to convert the GEOS bitmap data to one of the supported graphics formats (PCX, BMP, etc.). The impex library is covered in chapter 16 of the Objects book. (I would recommend minimum reading of section 16.1.2, 16.2 - 16.2.1.2, and 16.2.3.) --------------------------------------------------------------------- Q: I want to use the bitmap tools in my paint program. Where are they in the header files? A: The bitmap tool controller is defined in INCLUDE/OBJECTS/ BITMAPC.GOH. The controller class is VisBitmapToolControlClass and this is used just like GrObjToolControlClass. You will have to edit the BITMAPC.GOH file before you can use it. There is a struct defined in it that is also defined in GROBJ.GOH, and if you're using both (which is highly likely), then you should comment out the struct in BITMAPC.GOH called RectDWFixed. It is not used in BITMAPC.GOH anyway. --------------------------------------------------------------------- ===================================================================== TOPIC: Help, Help Files --------------------------------------------------------------------- Q. When I press Fn-F1 to bring up help for my OmniGo application, it doesn't bring up context sensitive help. When I press the "?" icon to bring up help, it is context sensitive, so it brings up help about the current object. What's the difference? A. This is a Geos problem (it will be fixed in the next version of the OmniGo). Anyway, here's what you can do to make Fn-F1 bring up context sensitive help. Intercept MSG_META_BRING_UP_HELP for the GenApplicationClass object and send yourself MSG_GEN_APPLICATION_BRING_UP_HELP. --------------------------------------------------------------------- Q. How can I get rid of (or disable) the contents button of the help dialog (if we decide not to display the contents at all) ? A. On your HelpControl object, add the following: ATTR_GEN_CONTROL_PROHIBIT_UI = HPCF_CONTENTS; If you look in INCLUDE\OBJECTS\HELPCC.H, you will see a data type called HPDFeatures. Mix and match these features with the GenControl attributes ATTR_GEN_CONTROL_PROHIBIT_UI and ATTR_GEN_CONTROL_REQUIRE_UI to change the help controller's UI gadgetry. --------------------------------------------------------------------- Q: I just finished creating a help file for my program, and I generated it and so on. When I start my program and click on the help button in the New/Open box, I get an error message that says: Error in help: Unable to find "dbDCBig" section in help file "texted ". Please note the exact text of this message if it occurs. Error Code: HP-02 What does this mean and how do I fix it? A: What has happened here is the GenDocumentControl has a line like this: ATTR_GEN_HELP_CONTEXT = "dbDCBig"; /* You can't change this.(?) */ What you must do is add a context to your help file with the name dbDCBig. In this context you can put something about how to open and create documents, or at least put in hyperlinks to contexts that discuss those topics. There are other help contexts related to the GenDocumentControl. They are dbDCCopy, dbDCOpen, and dbDCSaveAs. The PrintControl class also has a context, dbPrint, which goes with the main Print dialog. There may be more "secret" contexts like this one that you must add to your help file. To find them, run your program and click on ANY help triggers you see, and note the name of the section in the box if you get the error. --------------------------------------------------------------------- Q: I created a new help file for my program, and when I try to view the help, I get an error message that it can't find the file. I have the two spaces after the name that it seems to want, but it still doesn't find it. A: The two spaces after the name of the help file is coincidental. To name your help files, first, take the name of your program and make it all lowercase letters. Then, pad the name with spaces until you have eight characters. All help file names are in lowercase and are eight letters long. --------------------------------------------------------------------- ===================================================================== TOPIC: GEOS.INI, the Initialization file --------------------------------------------------------------------- Q. I was attempting to use InitFileReadDataBlock for getting the file transfer settings from the ini file. Though the "parameters" key was definitely set under the "fileTransfer" category, I was getting a size of zero and an empty data block (I was getting a successful return from the call). A. You must use the appropriate InitFileRead??? routine for a given INI file item. That is to say that if the item is a string value then you need to use InitFileReadString??? and if the item is an integer value then you would use InitFileReadInteger(). --------------------------------------------------------------------- ===================================================================== TOPIC: Ink and HWR --------------------------------------------------------------------- Q. We're using VisText objects. The text objects appear and are editable via the PC keyboard and the floating keyboard. However, the user can't write any ink in the object for HWR. Clicking and dragging the mouse simply selects text. What attribute needs to be set so that it will also allow pen input (ink->HWR)? A. The general rule is, unless you know for sure what you're doing, set GVI_inkType = GVIT_QUERY_OUTPUT on the view. GVIT_QUERY_OUTPUT, when used with system-provided objects (ink object, text object) will always work. The default for GVI_inkType is GVIT_PRESSES_ARE_NOT_INK. --------------------------------------------------------------------- Q. How do I set the brush size in IDIP_brushsize? I tried 0x0002, but it is not working. A. IDIP_brushsize (part of InkDestinationInfoParams) is a word size parameter, which provides a byte each for the X and Y brush size. To set this correctly to a brush size of 2 (for example), you need to set IDIP_brushsize to 0x0202, rather than 0x0002. --------------------------------------------------------------------- Q. What is happening when ink is entered? A. When the user clicks on an area of the screen that accepts ink input (for example, on a view that has its GVI_inkType field set to GVIT_PRESSES_ARE_INK), the object that is clicked on notifies the system that it should start drawing/collecting ink. Since the system will (in most cases) erase the ink after the user is done, it first saves as much of the screen as is possible (on the Casio Z-7000 and Tandy Z-PDA, the entire screen is saved) and restores it when the user is done entering ink, without requiring any redrawing by the application (this is why you do not get a MSG_META_EXPOSED after the user draws ink.) Ink delivery is one of the rare places in the system where you get a MSG_META_NOTIFY_WITH_DATA_BLOCK without being on any GCN list. There is no GWNT_INK GCN list (at least, no messages are ever sent to it), and so you need not worry about adding yourself to it. In your application, when the user has finished drawing ink in your GenView, the system erases the ink, and sends the ink (via MSG_META_NOTIFY_WITH_DATA_BLOCK) to the view, which sends it to the optr stored in its GVI_content field. Make sure to set the VI_bounds of your ink object. Its default is 0 pixels by 0 pixels, which would not allow the user to enter ink on it. Also, if you the ink object is the only child of the content, you will want to set the IF_ONLY_CHILD_OF_CONTENT flag on the ink object, which will cause the ink object to use some internal optimizations that can speed up ink entry. --------------------------------------------------------------------- ===================================================================== TOPIC: Mouse, Pen --------------------------------------------------------------------- Q. How can I use the Zoomer's fire buttons (and presumably the joystick button) in my application? A. Look at section "Controls" in the Zoomer portion of the documentation. It includes the following: Input from the buttons acts as "keyboard" input, using a custom set of "keys." These keyboard input events will have a character whose top byte has the value CS_CONTROL and whose bottom byte has one of the following VChar ( "virtual character" ) values: VC_JOYSTICK_135 VC_JOYSTICK_90 VC_JOYSTICK_45 VC_JOYSTICK_180 _______________ VC_JOYSTICK_0 VC_JOYSTICK_225 VC_JOYSTICK_270 VC_JOYSTICK_315 VC_FIRE_BUTTON_1 VC_FIRE_BUTTON_2 The VC_JOYSTICK values correspond to the Zoomer directional keys. Note that the Zoomer has just four directional buttons-the 45, 135, 225, and 315 degree values will be passed when the user is pressing two buttons at once. The VC_FIRE_BUTTON values correspond to the two zoomer fire buttons. --------------------------------------------------------------------- Q. How do I detect a mouse click on a text object at a given line, and then get the text for just that line? A. Subclass MSG_META_START_SELECT, and given the mouse position, Use: MSG_VIS_TEXT_GET_TEXT_POSITION_FROM_COORD to map the mouse click to a text position, MSG_VIS_TEXT_GET_LINE_FROM_OFFSET to map from a text offset to a line, and MSG_VIS_TEXT_GET_LINE_INFO to get the number of characters in the line, then you can grab the text using MSG_VIS_TEXT_GET_TEXT_RANGE or one of its brethren. --------------------------------------------------------------------- Q. Why must MRF_PROCESSED be returned for mouse events? A. The MRF_PROCESSED flag is there so the parent window will know whether a child was hit or the window background was hit, as windows can have their own behavior if their background is hit. --------------------------------------------------------------------- Q. The techdocs state that MSG_VIS_RELEASE_MOUSE will typically be called in the handler to MSG_META_END_SELECT; however, in the TicTac sample app, it is called in the handler for MSG_VIS_LOST_GADGET_EXCLUSIVE. Where is the preferred place to call MSG_VIS_RELEASE_MOUSE? A. The MSG_META_END_SELECT handler calls MSG_VIS_RELEASE_GADGET_EXCL, so that ends up sending MSG_VIS_LOST_GADGET_EXCLUSIVE anyway. The latter is preferable (at least in cases where the object grabbing the mouse can get the gadget exclusive), because if the gadget exclusive is lost in some other way (like the application exiting or something unexpected like that), the mouse will still be released. --------------------------------------------------------------------- Q: How do I detect when the user is holding the Control key and clicking the mouse button at the same time? Also, what about the Shift keys? A: When you receive a MSG_META_START_SELECT, you will get a parameter called inputState. The high byte of this word parameter contains data indicating the special mode of the mouse click. For a normal mouse click, the following bits are set: UIFA_SELECT | UIFA_IN For a Control-click (holding Control key while clicking mouse): UIFA_SELECT | UIFA_PREF_A | UIFA_IN For a Shift-click (holding Shift key while clicking mouse): UIFA_SELECT | UIFA_CONSTRAIN | UIFA_PREF_B | UIFA_IN So, to detect when the user is holding down the Control key and clicking the mouse at the same time, do this in your MSG_META_START_SELECT method: if ( GET_UI_FUNCTIONS_ACTIVE( inputState ) & UIFA_PREF_A ) { /* User clicking while pressing Control */ } For detecting when the user is pressing the Shift key and clicking: if ( GET_UI_FUNCTIONS_ACTIVE( inputState ) & UIFA_PREF_B ) { /* User clicking while holding Shift key. */ } --------------------------------------------------------------------- ===================================================================== TOPIC: Installation --------------------------------------------------------------------- Q. On the Casio Z-7000, we are having problems with our installation program because it seems that directories are "invisible" to pcsend until the directory has been "touched" by the user. A. The problem is not that directories are "invisible" but rather that they simply don't exist. This is actually a "problem" with drive mapping. You are using PCSEND on the B: drive and expecting to see all the directories on A: that are mapped properly by GEOS. Since DataLight's ROMDOS doesn't do such mapping through our @dirname.000 files, PCSEND doesn't either. The solution is to create the directory if it does not exist, and then copy the file there. --------------------------------------------------------------------- Q. I keep getting an error similar to "error 2249 in script line 789" What does this mean and how can I fix it? A. I don't know specifically what it means, but it's the very message that always comes up if you try to install the SDK on a machine that is running the original "bad" EMM386.EXE that came with Novell DOS 7, or if the machine doesn't have enough memory to run the installer (minimum is 520k). --------------------------------------------------------------------- Q. I'm getting an error message when trying to install the SDK software on my target machine. The message is: installation script problem - "Error in line 83: code 2247." What should I do? A. Make sure there are no files with filename extensions of .000, .001, .002, etc. in the root directory of the target machine. Try placing the INSTALL.EXE and TARGET.PVL files in a subdirectory on the target (any subdirectory) by changing to that directory and running PCCOM from there. --------------------------------------------------------------------- Q. Is there a way to speed up the installation of the files to my target machine? A. If you're using MS-DOS 6. The Microsoft InterLink Server, a LapLink-like utility, is bundled in the MS-DOS 6 upgrade. You simply run INTERSVR.EXE on the "host" machine, and add "DEVICE = INTERLNK.EXE" to the target machine's CONFIG.SYS. and your host's C: drive is suddenly accessible to the target machine as drive F: (or whatever). You can then transfer, for example, a three MB TARGET.PVL file between the two at 115200 baud in about 7 minutes, instead of the usual 40+ minutes at 19200 baud. If you're using DR DOS 6, there's a utility called FILELINK that might allow faster communication over the serial port on your system. Type FILELINK /? at the DR DOS prompt to see the command line switches available. --------------------------------------------------------------------- Q. How can I install my application/Bindery book to the OmniGo? A. Geoworks has created a freeware installer application that you can find on CompuServe (the Geoworks library at go GEOSDK), America OnLine (the Geoworks Development Files option at keyword GEOSDK), or the Geoworks web site (http://www.geoworks.com) --------------------------------------------------------------------- Q. For testing purposes, how is an application uploaded to the OmniGo? Where in OmniGo is the app stored once it's uploaded? A. The application is stored in the RAM disk. The easiest way to upload the application is: 1. Reboot the OmniGo (shift-on-next keys) to make sure the previous version of your app is not running in the background 2. Run the Transfer application and connect 3. Use PCSend (comes with the SDK; it should be in the PCGEOS\BIN dir) you will need to set the ptty environment variable to have the same baud rate as the OmniGo (either 9600 or 19200). In DOS you can do this with the SET command. For example: C:\PCGEOS\APPL\SDK_C\MYAPP> set ptty=2,9600 will tell PCSend to use com2 at 9600 baud. (there's more information about pcsend, pcget, and pccom in the tools book.) You will need to specify sending the application to the world directory otherwise it will end up in the root Geoworks directory where HomeScreen can't get to it. You specify the directory like this: pcsend myapp.geo /d:world which will send myapp.geo to the World directory on the OmniGo. --------------------------------------------------------------------- ===================================================================== TOPIC: GenInteractionClass (dialog, menu) --------------------------------------------------------------------- Q. What is the best way to make a dialog scrollable when it is too big to fit into a Casio Z-7000 or Tandy Z-PDA screen ? For example, Palm address book UI provides for the address entry fields vertical scrolling if you choose to view all the fields. A. Use a GenContent inside of a GenView. Then GenContent is designed to allow you to have a bunch of Gen objects that could scroll inside of a view. --------------------------------------------------------------------- Q. What routines do I use to put up and take down a notice saying "please wait"? A. I assume that in this case you don't want a thread-blocking routine such as UserDoDialog(). (I.e. you aren't requesting a response from the user, such as through an 'OK' trigger.) You can create a GenInteraction (set GII_visibility = GIV_DIALOG and GII_attrs = @default | GIA_NOT_USER_INITIATABLE) with a GenGlyph child, whose GI_visMoniker is "please wait", and make it a child of the GenApplication. To bring it on-screen, send MSG_GEN_INTERACTION_INITIATE to the GenInteraction. To take it down, you can send IC_DISMISS through MSG_GEN_GUP_INTERACTION_COMMAND. You probably also want to make the dialog modal. --------------------------------------------------------------------- Q. For a GenInteraction type organizational, visibility dialog, there is an EXIT button for the dialog. I would like to replace/extend the action of that button. Can I substitute the EXIT button in the UI with another GenTrigger through a ATTR_GEN_TRIGGER_INTERACTION_COMMAND? If so, what? Or can I subclass a message in the GenInteractionClass to intercept the message that the trigger is sending or something? A. ATTR_GEN_TRIGGER_INTERACTION_COMMAND = {IC_EXIT} only works for triggers that are in a GIV_POPUP GenInteraction (not GIV_DIALOG). Therefore, you should create your own Exit trigger. Use a GenTrigger that sends a message to a destination (this constitutes the additional functionality), and add to it the GA_SIGNAL_INTERACTION_COMPLETE attribute. Put HINT_SEEK_REPLY_BAR on the trigger as well. --------------------------------------------------------------------- Q. How can I reposition a modal dialog box? A. Modal dialog boxes are automatically centered on the screen by the specific UI. This could be overridden using HINT_POSITION_WINDOW_AT_RATIO_OF_PARENT or another _WINDOW_ hint. --------------------------------------------------------------------- Q. I would like to add a button or two to the DatePicker dialog for my own uses. Can I do this without the source code? A. DatePicker is a GenInteractionClass object. You can add children to the DatePicker with MSG_GEN_ADD_CHILD. (Other GenInteraction messages should work on it as well.) --------------------------------------------------------------------- Q. I have a modal dialog with OK and Cancel triggers, but the OK trigger is initially not enabled. The OK trigger only becomes enable if you change one of the default settings. How can I force it to start out enabled? A. Make it a command dialog instead of a properties dialog. --------------------------------------------------------------------- Q. Is there a way to tell when a GenInteraction is dismissed? A. Intercept MSG_GEN_GUP_INTERACTION_COMMAND(cx = IC_DISMISS) --------------------------------------------------------------------- Q: The keyboard shortcuts in my program don't work. For instance, if I try Ctrl-P, I get a beep instead of the Print panel. A: To fix this, just add GA_KBD_SEARCH_PATH to the GI_attrs of your GenPrimary, and menu groups, such as the File menu. This allows GEOS to search those branches of the tree for the keyboard accelerator. --------------------------------------------------------------------- ===================================================================== TOPIC: List Classes --------------------------------------------------------------------- Q. How do I fetch the number of a current item, the one marked with a dot line rectangle, in a non-exclusive dynamic list? None of the GenItemGroupClass messages seem to get it. A. The item marked with a "dot line rectangle" is actually the focus item. You can use a message to get the current focus item, but this is generally a bad idea because the focus may change between message calls. That is, the "dot line rectangle" is only an intermediate state, like when you're dragging the mouse over a menu before selecting one of the items. It's OK for those items to react in some way, but for another object to query and then act is asking for timing trouble. If you need to act when the dot line rectangle moves to another item, the best thing to do is to have the item intercept MSG_META_GAINED_FOCUS_EXCL and send some custom notification message to the object that's interested in the state. --------------------------------------------------------------------- Q. Is it possible to make a GenDynamicList ignore input when a selection is made? I tried setting GI_attrs = @default | GA_INITIATES_INPUT_IGNORE but it didn't seem to work. A. That should work. The ignore only lasts for as long as it takes to make a trip to the list's output object's event queue and back. The exceptions to that rule follow: If the GenDynamicList and the GenDynamicList's output object (destination) are run by different threads, then GA_INITIATES_INPUT_IGNORE won't work. To fix this you need to change the GenDynamicList's destination to be some object which is run by the same thread as the GenDynamicList. If the GenDynamicList is in a System modal box, it will need ATTR_GEN_INTERACTION_ABIDE_BY_INPUT_RESTRICTIONS on it, since modal boxes otherwise ignore input restrictions. --------------------------------------------------------------------- Q. I've noticed that when I subclass GenDynamicListClass and then try to intercept MSG_META_END_SELECT, I don't ever see the message (but I can intercept MSG_META_START_SELECT just fine). Any ideas on this one? A. If you are not calling @callsuper, then you must return MRF_PROCESSED (MouseReturnFlag that says this object had processed the mouse message). If that is not the problem, then you probably need to grab the mouse. --------------------------------------------------------------------- Q. I would like clarification on what MSG_GEN_ITEM_GROUP_SET_MODIFIED_STATE actually does. My impression is that setting this to TRUE would cause the GIGI_applyMsg to get sent out the NEXT time the group gets an apply message. Is this true? Does this cause the STATUS message (if any set) to go out as well (I believe not). A. MSG_GEN_ITEM_GROUP_SET_MODIFIED_STATE: Items are normally marked as "not modified" anytime their state is set, marked "modified" anytime the user interacts with them, and marked "not modified" again on MSG_APPLY. This primitive provides a way to control the modified status outside of these events. Items can be operated on via this message, even if they are not usable, not enabled, or not represented by a GenItem in the GenItemGroup (useful for linked GenItemGroups). --------------------------------------------------------------------- Q. How can I specify number of items to show in scrollable GenDynamicList or Height of GenDynamicList window (thus specify # of items to show indirectly) A. You need to use HINT_INITAL_SIZE like this: HINT_INITIAL_SIZE = { (SST_AVG_CHAR_WIDTHS | DIC_LIST_LENGTH), (SST_LINES_OF_TEXT | 4), 4 } This will specify that the dynamic list show 4 items. --------------------------------------------------------------------- Q. When I set the three GenItemGoups to GIGBT_EXCLUSIVE it starts off with none of the three selected. I can select any (or all) of the three but I can never get one deselected. When they are set GIGBT_NON_EXCLUSIVE it starts off with none selected again. I can select any (or all) of the three and I can unselect them too. How can I make sure one, and only one, is selected? A. What you describe is the correct default behavior. If you want an initial selection, add GIGI_selection = @Choice1Item in your first GenItemGroup. --------------------------------------------------------------------- Q. Are linked GenItemGroups currently supported? I tried without success to use this feature. The documentation states that a selection is exclusive across all the linked groups, but that's no how it worked for me. A. Linked Gen Item groups are supported (use ATTR_GEN_ITEM_GROUP_LINK), but you have to do most of the work yourself. To get them to work, have each linked GenItemGroup send out the same status message (ATTR_GEN_ITEM_GROUP_STATUS_MESSAGE). In the handler for this message, find out what item has been selected and broadcast that selection (with MSG_GEN_ITEM_GROUP_SET_SINGLE_SELECTION) to each item group. Since each Item in all the Item Groups should have a unique identifier, only one item will be selected. --------------------------------------------------------------------- ===================================================================== TOPIC: Keyboard, Floating Keyboard --------------------------------------------------------------------- Q. What key codes are used on the OmniGo for the Next/Prev keys? VC_NEXT and VC_PREVIOUS are the codes for Page Up / Page Dn. A. VC_NEXT_BUTTON and VC_PREV_BUTTON map to Next/Prev keys. --------------------------------------------------------------------- Q. What's the HINT/ATTR/inst-var to avoid bringing up the floating keyboard? A. ATTR_GEN_WINDOW_KBD_OVERRIDE: you can set it in the GenApplication or popup/dialog GenInteraction. The three settings for this attr are: KO_NO_KEYBOARD - no floating keyboard will be made available for any of the children in this window. KO_KEYBOARD_REQUIRED - forces the a floating keyboard to be brought up whenever this window comes on-screen. KO_KEYBOARD_EMBEDDED - means that the application is providing a keyboard, so no floating keyboard is needed. --------------------------------------------------------------------- Q. Whenever a GenText object is displayed that is editable, the PT9000 pops up its soft keyboard. I would like the default to be that the keyboard does NOT appear unless called up by the user via the PT9000 "firm" key that lives on the right side of the screen. How can this be accomplished? I don't want the keyboard completely unusable, just not to pop up unless requested. A. set ATTR_GEN_WINDOW_KBD_OVERRIDE = (KO_NO_KEYBOARD) in the object. The floating keyboard will not automatically pop up, but is still available through the hard icon bar. --------------------------------------------------------------------- Q. I remember hearing earlier about Geoworks desire to allow for new on-screen keyboards for pen based systems. A. Yes, there is support for this. An application needs to supply its own PenInputControl (a child of the application object), put it on MGCNLT_ACTIVE_LIST (GCN list), and add ATTR_GEN_PEN_INPUT_CONTROL_IS_FLOATING_KEYBOARD and HINT_DONT_KEEP_INITIALLY_ONSCREEN to it (all of this can be done statically). GII_visibility should be GIV_DIALOG and GII_attrs = GIA_NOT_USER_INITIATABLE. The optr of the object should be stored in ATTR_GEN_APPLICATION_KBD_OBJ. The app can use ATTR_GEN_PEN_INPUT_CONTROL_CUSTOM_CHAR_TABLE_DATA to specify a app-custom keyboard layout. --------------------------------------------------------------------- ===================================================================== TOPIC: Libraries --------------------------------------------------------------------- Q. How do I use a GEOS library that was loaded dynamically with GeodeUseLibrary() rather than declared in the .GP file during compilation time? A. Accessing library routines is rather confusing until it is explained. Here's a short description. Using Dynamically Loaded Libraries Calling routines from dynamically loaded libraries is quite easy. The basics are all there is to it, so once you learn the basics, you've learned to use libraries. The three main steps are: 1. call GeodeUseLibrary to load the library and get its handle 2. access the library routines 3. release the library with GeodeFreeLibrary. Setup These two lines should be added to your .GOC file: #include @include /* the header file for your library, if it exists */ In your .GP file, add the line: library mylib noload # "mylib" is the name of your library GeodeUseLibrary Pass the (DOS style) name of the library, the major and minor protocol numbers of that library, and a pointer to a GeodeLoadError structure. Calling the library routines ProcGetLibraryEntry ProcCallFixedOrMovable_cdecl or ProcCallFixedOrMovable_pascal To access the routines in the library, you must first get the pointer to the routine using ProcGetLibraryEntryEntry. Then call the routine with one of the two ProcCallFixedOrMovable_...() routines. You can determine the entryNumber (second parameter of ProcGetLibraryEntry) from the "export" lines in the library's .GP file. The first line corresponds to zero, with the values increasing by one for each successive line. If the creator of the library has #defined these values in the library's .H (or .GOH) file, you could include this in your application's source file and use these definitions for the entryNumber parameter. GeodeFreeLibrary If you dynamically load the library, then it is your responsibility to free the library. This is done simply by calling GeodeFreeLibrary(). Example #define MY_LIB_ROUTINE_A 0 #define MY_LIB_ROUTINE_B 1 #define MY_LIB_ROUTINE_C 2 #define MY_LIB_ROUTINE_D 3 #if ERROR_CHECK static char *myLibName = "mylibec.geo"; #else static char *myLibName = "mylib.geo"; #endif GeodeHandle myLibHandle; GeodeLoadError err; dword returnValue; /* First store the current setting of the standard path and then set it * to the system directory, where all the library geodes should be. */ FilePushDir(); FileSetStandardPath(SP_SYSTEM); (myLibHandle = GeodeUseLibrary(myLibName, 0, 0, &err); if(myLibHandle != NullHandle) { returnValue = ProcCallFixedOrMovable_cdecl( ProcGetLibraryEntry(myLibHandle, MY_LIB_ROUTINE_A), /* library routine parameters go here */); } /* Restore the previous standard path setting. */ FilePopDir(); Additional Information GeodeLoadErrors GLE_PROTOCOL_IMPORTER_TOO_RECENT GLE_PROTOCOL_IMPORTER_TOO_OLD GLE_FILE_NOT_FOUND GLE_LIBRARY_NOT_FOUND GLE_FILE_READ_ERROR GLE_NOT_GEOS_FILE GLE_NOT_GEOS_EXECUTABLE_FILE GLE_ATTRIBUTE_MISMATCH GLE_MEMORY_ALLOCATION_ERROR GLE_NOT_MULTI_LAUNCHABLE GLE_LIBRARY_PROTOCOL_ERROR GLE_LIBRARY_LOAD_ERROR GLE_DRIVER_INIT_ERROR GLE_LIBRARY_INIT_ERROR GLE_DISK_TOO_FULL GLE_FIELD_DETACHING GLE_INSUFFICIENT_HEAP_SPACE --------------------------------------------------------------------- ===================================================================== TOPIC: Localization, ResEdit --------------------------------------------------------------------- Q. What must I do to make my application localizable? A. You should read Chapter 8 "Localization" of the Concepts book. This chapter covers many of the concepts and routines needed to make your application easily localizable. In a nutshell, here's what you need to consider: 1. Put localizable strings in @chunks so you can use ResEdit to modify the strings. 2. Use Local...() routines for formatting strings (for date, currency, measurement, etc.) and other string manipulation. 3. Register for notification of changes to user settings. (see following question.) ------------------------------------------------------------------- Q. How can I receive notification of changes in date/time format or other formatting that the user can change? A. Put yourself on the GCNSLT_NOTIFY_INIT_FILE_CHANGE gcnlist and watch for MSG_META_NOTIFY(MANUFACTURER_ID_GEOWORKS,GWNT_INIT_FILE_CHANGE). The parameter "data" will be the InitFileEntry that changed. Here are the possible values of "data": IFE_DATE_TIME_FORMAT IFE_NUMBER_FORMAT IFE_CURRENCY_FORMAT IFE_PUNCTUATION IFE_OWNER_INFO IFE_SYSTEM_SOUND IFE_INK_THICKNESS --------------------------------------------------------------------- Q. How do I generate the .VM file required as input to the Resource Editor? A. There are three ways you can generate the .vm file. 1. PMAKE FULL, which also makes both EC and non-EC geodes 2. PMAKE .vm 3. loc -o .vm /* -2 option for DBCS */ --------------------------------------------------------------------- ===================================================================== TOPIC: Math --------------------------------------------------------------------- Q. How does one display a floating point value in GOC? I tried sprintf(statusString, "f = %f", myFloat), but it evaluates to statusString containing "f = X" (same with %F, %E, %e, %g). A. Use FloatFloatToAscii. The AnsiC lib does not depend on the math library and thus sprintf can't deal with GEOS floats. --------------------------------------------------------------------- Q. How would you convert a DWFixed into a WWFixed in C? A. Here is an example. wwf is a variable of WWFixed and dwf is a variable of type DWFixed. wwf.WWF_frac = dwf_WWF.frac; wwf.WWF_int = (word)dwf_WWF.int; --------------------------------------------------------------------- ===================================================================== TOPIC: Memory Blocks/Chunks --------------------------------------------------------------------- Q. I am having difficulty using far pointers to functions in PCGEOS. For example if a have a function with the prototype: void far _pascal MyFoo(int bogus1, int bogus2); and a function pointer declared as: void (far _pascal * YourFoo)(int, int); the following assignment does not work correctly: YourFoo = MyFoo; A. Since GEOS swaps memory around, your function pointer is actually a virtual pointer. You need to lock down the block that contains the routine (MyFoo) before making the function call. You can do this in one of two ways: YourFoo = MemLockFixedOrMovable(MyFoo); (*YourFoo)(bog1, bog2); MemUnlockFixedOrMovable(MyFoo); or YourFoo = MyFoo; ProcCallFixedOrMovable_pascal(bog2, bog1, YourFoo); /* note that parameters are in reverse order */ --------------------------------------------------------------------- Q. Do chunk arrays have to be in LMem blocks? A. ChunkArrayCreate calls LMemAlloc, so yes, chunk arrays do have to be in LMem blocks. --------------------------------------------------------------------- Q. How big is the RAM disk on the OmniGo? How big is the heap? Don't they both have to add up to 1M? I have a real live OmniGo in my hands, and Transfer says "35Kb used, 373Kb free". This adds up to 408K. Where's the missing 168Kb? A. In the Transfer application, "Memory available" refers to RAM disk space, since available heapspace is an elusive and generally worthless measurement (what with fragmentation, max available block size, etc.) On the OmniGo, the 1 Meg of RAM is divided as follows: Video Memory 32k Heap Space 576k RAM Disk Space 416k Total 1024k As the RAM disk is a FAT file system, a certain percentage of the memory must be allocated to the FAT itself. The system also uses part of the RAM disk for the INI-file, clipboard file, etc. All those use about 8Kb, which leaves 408Kb for general usage. This is why in Transfer, you only see a total available space of 408Kb. --------------------------------------------------------------------- Q. Are ObjChunkFlags also kept with chunks in general LMem blocks (non-obj) ? A. ObjChunkFlags are used only in Object Blocks. Chunks in LMem Blocks do not use these flags. --------------------------------------------------------------------- Q. Is there a way to tell whether a chunk in an LMem block was created statically (defined in a resource), or dynamically at runtime ? A. You can use OCF_IN_RESOURCE for this. BUT, you will first have to set LMF_HAS_FLAGS (LocalMemoryFlags) when you create the block so that the kernel will expect ObjChunkFlags to be in the first chunk. (Esp currently won't create a flags chunk for you, so you'd have to do that yourself, if defining the resource statically, nor is there a way to tell UIC that you want the resource to have flags, except to make it an object resource). The kernel looks only for the LMF_HAS_FLAGS bit to decide whether to treat the first chunk in the block as a flags chunk. --------------------------------------------------------------------- Q. Is it OK to use LMemContract on Object blocks ? A. Yes. An Object Block is a LMem of type LMEM_TYPE_OBJ_BLOCK, so you can use LMem??? routines on it. --------------------------------------------------------------------- Q. I used GrGetBitmap to save the background, but it returns a MemHandle. Where can I find the definition for MemHandle. And how to make use of the information returned by XYSize ? A. GrGetBitmap returns a MemHandle to a newly allocated memory block containing the bitmap. The memory handle is an indirect reference to that memory block. A MemHandle is a very important type in GEOS; you really need to understand it to effectively develop GEOS applications. At a very basic level, a MemHandle is just a 16-bit value used to locate a memory block. Look in chapter 15 of the Concepts manual to get an in-depth discussion of memory management. To access the memory block, use MemLock(). This will restrict the block from being moved around in memory and return a pointer to the beginning of the block/bitmap. When you are finished accessing the block, use MemUnlock to allow the block to be movable again (the pointer to the block will now be invalid). When you have no more use for the memory block, will have to free the block with MemFree(). --------------------------------------------------------------------- Q. Will MemAlloc ever return a block bigger than MemGetInfo(SGIT_LARGEST_FREE_BLOCK)? A. Yes. MemAlloc compacts the heap if there is not a big enough block. --------------------------------------------------------------------- Q. Is it possible that MemAlloc(), MemLock() or MemUnlock() routine moves an object meaning that I have to dereference pself after the call like I do after @send, @call or ObjInstantiate() ? A. MemAlloc() and MemLock() can cause unlocked blocks to move on the global heap, but not locked blocks. If an object is executing code (e.g. one of its handlers was called), then the object's block must be locked on the global heap, so MemLock() and MemAlloc() will not cause the object block to move. So, the answer is, "no." --------------------------------------------------------------------- Q. How does one go about freeing an object block from the process thread when the object block is run by, say, the UI thread? ObjFreeObjBlock crashes when I try to do this. A. Send MSG_META_BLOCK_FREE to an object in that block. --------------------------------------------------------------------- Q. When geos allocates dgroups, where does it put them? A. dgroup is allocated as a fixed memory block, so it is allocated at the bottom end of the heap (if possible). --------------------------------------------------------------------- ===================================================================== TOPIC: Messages/Objects --------------------------------------------------------------------- Q. When I call MSG_SUCH_AND_SUCH, why does it go off into space rather than call the correct source code? A. You more than likely sent it to the wrong object. Make sure that it is being sent to an object that it can handle it. --------------------------------------------------------------------- Q. In Goc I have a primary and one of it's children is defined in a separate file. When I launch the program, that child has no link (GI_link = null). This hoses the program when one of it's siblings tries to find their parent. Is there something special I have to do to make this work? A. Goc will only create links between statically declared objects if they are within the same source file. So, you can either put all of the objects that are in your generic object tree into the same source file, or you can call MSG_GEN_ADD_CHILD to dynamically add the child when you open the application. --------------------------------------------------------------------- Q. I dynamically instantiate the generic objects in an object block owned by the process thread. I would like to display those objects and thus I need to attach them to the entire generic tree. However, the whole generic tree is owned by the ui-thread. Simply attaching these objects to the entire generic creates error "OBJ_LOCK_OBJ_BLOCK_BY_WRONG_THREAD". A. You cannot have normal generic objects under your GenApplication running in a different thread from the GenApplication objects and the objects underneath it. The only places where a thread boundary is allowed is the GenView/Content. In the GenContent, you can set up a limited set of generic objects (basically triggers, list items, GenGadgets, GenGlyphs, and non-scrollable GenTexts). One way (and not the best) of overcoming this is to make the app single threaded, so everything is in the same thread. --------------------------------------------------------------------- Q. When I quit my demo application by sending MSG_META_QUIT to my Process class, the app exits. After returning to GeoManager, however, the system crashes. What did I do? A. You should be sending MSG_META_QUIT to your Application object, not your Process object. --------------------------------------------------------------------- Q. How does one interact with the immediate document (I guess its called the focus) of a multiple document group? A. To send messages along the focus hierarchy, @record the message and then send it using MSG_META_SEND_CLASSED_EVENT (passing the travel option TO_FOCUS). --------------------------------------------------------------------- Q. I am notifying a controller of a change using a notification. I use MSG_META_NOTIFY_WITH_DATA_BLOCK where the block consists of only a handle to a memory block containing strings. The handle to the memory block containing is the same for each notification. I have noticed that after the first notification none of them seem to reach the controllers. I believe notifications are cached and duplicates discarded although I couldn't confirm this with the manual. Is this true? What is the typical way of sending identical notifications to a controller so that the controllers get each one? A. Duplicate status events are ignored. If they are identical, there is no need to send multiple ones. If they are not identical, you should generate unique notifications. By the way, you do not need to use MSG_META_NOTIFY_WITH_DATA_BLOCK directly. The normal way controllers get notifications is by adding themselves to the necessary GCN list. When a change occurs, the object in which the change occurred should then call GCNListSend or send MSG_META_GCN_LIST_SEND. The system will then send the MSG_META_NOTIFY_WITH_DATA_BLOCK to the objects on the GCN list. --------------------------------------------------------------------- Q. I would like to save some data in the state file during system shutdown (like Exit to DOS). What messages and parameters in messages are special so that I can tell GEOS is being shut down instead of application exits normally? I don't want the app to spend time saving data for restoring state when the app exits normally. A. In your application's message handler for MSG_GEN_PROCESS_CLOSE_APPLICATION you can @call MSG_GEN_APPLICATION_GET_STATE to the Application object. Test ApplicationStates for AS_DETACHING. --------------------------------------------------------------------- Q. I am using ObjInstaniate to create objects. Once I no longer need them, how do I destroy them ? A. for gen objects: MSG_GEN_DESTROY. for vis objects: MSG_VIS_DESTROY. if your object is not a Gen or Vis subclass: MSG_META_OBJ_FREE --------------------------------------------------------------------- Q. What is the technical reason for why ObjFreeObjBlock cannot be used on duplicated resources (and ObjFreeDuplicate must be used instead) ? A. ObjFreeObjBlock is a higher-level routine -- it performs various queue-flushing operations, and eventually calls ObjFreeDuplicate (if the block is a duplicate block). Thus you can use ObjFreeObjBlock in place of ObjFreeDuplicate. Another option is to send MSG_META_BLOCK_FREE to an object in the block. --------------------------------------------------------------------- Q: I get a BAD_DS error in Swat, and I think it's related to this code: { ... textOD = GeodeGetOptrNS( @FMVolumePathText ); @send textOD::MSG_VIS_TEXT_REPLACE_ALL_PTR( pathBuffer, LocalStringLength( pathBuffer )); MemFree( pathBufferHandle ); } A: The problem here is that the block you're using to send the string in is being freed before the text object gets a chance to see it. If you change the @send to an @call, the routine will work, since the call will be blocked until the text object is done with the memory block. After the text object is done, then your routine will continue with the next line of code, namely the MemFree. --------------------------------------------------------------------- Q: I get this error in my program: ILLEGAL_HANDLE and it seems to be associated with this line: @send MyPrimary::MSG_META_DO_STUFF( @MyObject ); A: The problem is with multi-source files you can't refer to objects in another source file just by their name. You have to use the function GeodeGetOptrNS to get a valid optr. Here is how to fix that line: optr primary; primary = GeodeGetOptrNS( @MyPrimary ); @send primary::MSG_META_DO_STUFF( GeodeGetOptrNS( @MyObject )); You'll also have to make the program multi-launchable. Take out the "single" in the type line of your .GP file. --------------------------------------------------------------------- ===================================================================== TOPIC: VisMonikers --------------------------------------------------------------------- Q. What is the correct procedure of installing an icon for the OmniGo? A. Check out the sample app in Appl\SDK_Omni\OmniGoUI. The message to look for is MSG_GEN_APPLICATION_INSTALL_TOKEN. --------------------------------------------------------------------- Q. What is the correct size and format (squashed, tiny, etc...) for an OmniGo icon? A. The icon size is tiny and 18x18 pixels. You can see an example of icons in SDK_Omni\OmniGoUI\Art\omnigoui.goh. --------------------------------------------------------------------- Q. In a visual gadget I am calling self::MSG_VIS_CREATE_VIS_MONIKER to create a visual moniker chunk from a char*. I want the object to clear the chunk containing the moniker from memory when it receives MSG_VIS_DESTROY. Where is the best place to do this? A. MSG_META_FINAL_OBJ_FREE is the preferred solution, but it would probably be okay earlier on too. --------------------------------------------------------------------- Q. We have a resource which is 10K. It is a dialog that includes five 64x64 graphic monikers assigned to triggers. Since we were told that resource size over 4K can be a potential problem, I am wondering if we have to split this resource. If so, how can one move a GI_visMoniker into a different resource ? A. A vis moniker or vis moniker list must be in the same resource as the object as only the chunk handle of the moniker or moniker list is stored with the object. A moniker list stores optrs to its monikers, so the vis monikers can be in a different resource from the moniker list (and the object that uses that moniker list). You should be able to put the monikers into the new resource in whatever way you are currently declaring them. --------------------------------------------------------------------- Q. Is there a way to force a fixed space font for moniker text? A. You can set up the visMoniker with a GString that sets the font, however it is easier to set the font in the Object that will be displaying the moniker. You could use MSG_VIS_TEXT_SET_FONT_ID for most text objects. (You could also use MSG_VIS_TEXT_SET_CHAR_ATTR for setting multiple attributes.) --------------------------------------------------------------------- Q. What syntax should I use for MSG_GEN_RELOC_MONIKER_LIST? And do I need to declare the Monikers as @reloc in addition to using MSG_GEN_RELOC_MONIKER_LIST?? A. @send self::MSG_GEN_RELOC_MONIKER_LIST(ConstructOptr( HandleOf(oself),pself->FTI_altMoniker), 0); And no, do not use @reloc. There is some additional complexity if those moniker lists are to be saved to state, because you'll also need to unrelocate at that time. I advise marking them 'ignoreDirty'. Note that you can only relocate once, not each time you set the moniker. --------------------------------------------------------------------- ===================================================================== TOPIC: NoteShellClass/NoteClass --------------------------------------------------------------------- Q. I put a "Note" button in my OmniGo function bar area. I want it to look like all the other Note buttons--its moniker should be "Note#" where '#' is a graphic of a little piece of note paper. How can I display that graphics? A. This has to be done in assembly. There is an example of this in SDK_Omni\DocUI --------------------------------------------------------------------- ===================================================================== TOPIC: PCMCIA --------------------------------------------------------------------- Q. Will I receive notification if my application is using a file that is located on the PCMCIA card and the user closes out the card? A. The PCMCIA library will notify you in this case. It does this by sending MSG_META_REMOVING_DISK to your process object, but only if you're application is using a file that is on the card. We recommend that your application quit (without saving to state) when it finds out that this has happened. Warning: make sure you're not putting your process object on the GCN list that sends out MSG_META_REMOVING_DISK (GCNSLT_REMOVABLE_DISK). Because if you do, then your process object will always receive MSG_META_REMOVING_DISK when a card is removed, not just when you have a file open on the card (plus you'll get the message twice). --------------------------------------------------------------------- Q. I noticed that if I reboot the OmniGo with a PCMCIA card plugged in (even an ordinary serial card), the OmniGo claims that the card I inserted is unreadable or maybe write protected. But if I then powercycle the unit, it does not complain. A. The OmniGo cannot recognize a card if you reboot with a PCMCIA card plugged in. You can't insert a card until after rebooting, and after you've done the pen calibration screen, then turning the unit off. The OmniGo is just not able to recognize any cards until after the pen calibration has completed--that's the way the software was built. --------------------------------------------------------------------- Q. I noticed that the OmniGo draws a lot more current if a PCMCIA card is plugged into its slot, even if no programs are actively using the card. Would it be possible for the OmniGo to power down the PCMCIA port if no one is using it? A. Nope. There are no power buffers to the PCMCIA port. If there is a card in the device, and the device is on, expect a significant power drain. --------------------------------------------------------------------- Q. How can one tell when a PCMCIA SRAM card has been inserted into the Casio Z-7000 or Tandy Z-PDA? A. MSG_NOTIFY_DRIVE_CHANGE will go out on the GCN list, GCNSLT_FILE_SYSTEM, when a valid filesystem card has been inserted. Note that you should also handle MSG_META_REMOVING_DISK received over the same GCN list. If the disk handle is the one you are currently updating, you need to stop the update ASAP and close the file in question, then do a FilePopDir so you are no longer referring to the card. --------------------------------------------------------------------- Q. If my application resides on the internal RAM disk of the Casio Z-7000/Tandy Z-PDA, but uses library is located on a PCMCIA card, what happens if the card is removed while the library is still in use? A. if an on-card library is to be used by a not-on-card application, then either the not-on-card application needs to watch for META_REMOVING_DISK messages on behalf of the library (as Preferences now does) or the library itself has to arrange to be on the GCNSLT_FILE_SYSTEM list (i.e. have an event-driven thread or an object run by the application) that watches for such notifications and forces the client application to shut down. --------------------------------------------------------------------- Q. I know that to have an application 'automatically' show up in the launcher menu, you need to have that app in the World directory. What I don't know is how to get a flash card to alias itself into the World directory. A. On the PCMCIA card, create a directory structures \GEOWORKS\WORLD. GEOS will alias standard directories (WORLD, SYSTEM, USERDATA,...) and files that are under \GEOWORKS so they show up as if they were on the internal drive. The most common directories you might put on a PCMCIA card are: \GEOWORKS\WORLD - for applications \GEOWORKS\SYSTEM - for libraries and drivers \GEOWORKS\DOCUMENT - for documents and application data files \GEOWORKS\USERDATA\HELP - for application help files --------------------------------------------------------------------- ===================================================================== TOPIC: Platform Specific (OmniGo, Zoomer, etc.) --------------------------------------------------------------------- Q. What is the difference between the OmniGo SDK and the GEOS 2.0 SDK? A. In a nutshell, the OmniGo SDK is targeted towards application development for the HP OmniGo 100 device; the Geos 2.0 SDK provides an environment for developing applications for Geos 2.0 based devices (such as Casio Z-7000, IBM School View, and Geoworks Ensemble). The main differences are that the OmniGo SDK provides: - a development environment for writing applications for Geos 2.1 - libraries and documentation specific to the OmniGo 100 - an OmniGo 100 emulation for debugging purposes The Geos 2.0 SDK provides: - a development environment for writing applications for Geos 2.0 - debugging emulators for Casio Z-7000, Sharp PT-9000, Geoworks Ensemble --------------------------------------------------------------------- Q. Can I use the Geos 2.0 SDK to write applications for the OmniGo 100? A. Yes. The Geos 2.0 SDK may be used to write applications for the OmniGo 100. Likewise, the OmniGo SDK may be used to write applications for Geos 2.0 based products. Developers may have some difficulty fully testing the application since the 2.0 SDK does not contain an OmniGo 100 emulator. (See "How can I debug my application on an actual OmniGo device?" in the "Swat, the debugger" topic.) --------------------------------------------------------------------- Q: I tried using the PT9000 emulator software and the screen looks garbled. How do I fix this? A: The PT9000 needs a 640x440 display. Thus, you need to use a VGA or better display to run the PT9000 demo. --------------------------------------------------------------------- Q: When I run the Bullet (PT9000) demo, if I make any changes in the Preferences, it locks up, saying the GEOS.INI file is corrupt. A: The problem is that the GEOS.INI file has garbage in it. To fix this, use the MS-DOS editor, scroll down to the bottom to the end of the file. There should be some strange characters there. Delete those and save the file. The PT9000 emulator should run fine then. --------------------------------------------------------------------- Q: I'm developing an application for the Zoomer platform. I was testing it on the GEOS EC version and it worked fine. But, when I try to run the program from the Zoomer version of GEOS it says "Missing library or component." What's wrong? A: The problem is there are libraries missing from the Zoomer. Here is a list of all the missing libraries on the Zoomer: Bitmap Chart Convert DIB FFile FileStream Game GrObj MSMFile Saver Spell Spline SSheet SSMeta --------------------------------------------------------------------- ===================================================================== TOPIC: Power --------------------------------------------------------------------- Q. How do I access the power management system on the Zoomer. That is, how do I request battery level information? A. The only way to access the Zoomer power management is through an "internal" assembly interface. At this time, that interface is not published in our SDK. Additionally, there is no way to get battery level information on the Zoomer at all, even using the assembly interface. --------------------------------------------------------------------- Q. How can my application detect when the user has turned the power on or off on the OmniGo 100? A. First of all, unless your application is affected by external events (such as serial input) or for some other reason needs to know when the OmniGo powers on or off, you should not worry about power notifications. If your application does require this information, then it can register a notification routine with the power driver. There is only a limited number of vectors available, so your registration is not guaranteed to be successful. During device power down, there is nothing you can do to prevent the powerdown. On powerup, your routine can @send a message to let your application know that unit is powering back on. The notification routine should be small to prevent power on/off from becoming sluggish. Here is how you register for notification: #define DR_POWER_ON_OFF_NOTIFY (26) GeodeHandle powerDriverHandle; DriverPassParams passParams; DriverReturnParams returnParams; powerDriverHandle = GeodeGetDefaultDriver(GDDT_POWER_MANAGEMENT); ... DriverCallEntryPoint (powerDriverHandle, DR_POWER_ON_OFF_NOTIFY, &passParams, &returnParams); In passParams, dx:cx = fptr to call back routine. returnParams will have carry set if you could not register for the notification (because too many routines are already registered). The callback routine must be written in assembly because the ax register will contain either ax = 0 (PNC_POWER_SHUTTING_OFF) or ax = 1 (PNC_POWER_TURNING_ON). --------------------------------------------------------------------- ===================================================================== TOPIC: Printer, Spooler --------------------------------------------------------------------- Q. My application prints text and graphics to the printer. When I print, all of the GEOS objects print fine, but my text is too small, and my graphics don't print at all. A. You are probably using the system font (which is a bitmap font). Bitmap fonts are not scaled, so on a printer with high DPI, the bitmap font is printed very small. To print bitmaps to the printer, you need to use the GrDrawBitmap() functions, not GrDrawImage(). --------------------------------------------------------------------- Q. How is the information settable via MSG_PRINT_CONTROL_SET_TOTAL_PAGE_RANGE used ? Is it only used by the print dialog's page range objects ? A. You surmise correctly. The information is then passed on to the Spool library (when calling SpoolAddJob). --------------------------------------------------------------------- Q. The 'Print...' option in the File menu is always disabled. Is there something I am forgetting to do? A. The PrintControlClass was designed for multiple document interface, so it is not expecting to have a printable object ready at first. For SDI, you will need to either statically set GS_ENABLED or send MSG_GEN_SET_ENABLED to the PrintControlObject. --------------------------------------------------------------------- Q. When the form prints, the boxes, buttons and check-boxes in the form all look the proper size, but the text is very small. It looks okay When I draw text to the screen. What am I doing wrong here? A. The system font is a bitmap font. Bitmap fonts are not scaled, so on a hi-res printer, the font is very small, and on a low-res printer, the font is bigger. You will need to use an outline font (like Roman) for printing. --------------------------------------------------------------------- Q. My bitmaps do not print at all. I think this is because I use the function GrDrawImage instead of GrDrawBitmap, but I have yet to test this theory. A. GrDrawImage doesn't works when printing. You need to use GrDrawBitmap or GrFillBitmap. --------------------------------------------------------------------- Q. When I am drawing to the screen and call the GString command: GSSetAreaMask SDM_VERTICAL GSFillRect ... The vertical line pattern is clearly visible. However, when drawing to the printer, the vertical lines in the pattern are so close that it appears to be a solid color. I tried using GSApplyScale to increase the resolution (the distance between the vertical lines of the pattern) but it does not seem to do anything. Am I missing some command or something? A. The reason this is happening is that the mask is bit oriented, so on a high resolution device (like your printer) the bits are very close together. You should use GSSetAreaPattern (with PT_SYSTEM_HATCH and SH_VERTICAL) so the system will maintain a consistent hatch pattern on all devices. --------------------------------------------------------------------- Q. Is there a way to tell if the user hit cancel in the Print Control Box? Does the spooler send out any sort of notification? A. Not externally, no. But there is the visibility notification, MSG_PRINT_NOTIFY_PRINT_DB, that gets sent out whenever the dialog comes off the screen. --------------------------------------------------------------------- ===================================================================== TOPIC: Sample Applications --------------------------------------------------------------------- Q. Why can't I make GeoFile? A. MAKEFILE and DEPENDS.MK should not have been installed on your host. Delete them from the \GEOFILE directory then "mkmf" and "pmake depend" them normally. Note that you'll get some warnings, but none will stop the successful compilation of GeoFile. --------------------------------------------------------------------- Q. When I try to run a sample application, I get a message: "Could not open "EC SampleApp" because a required system file is missing." Under SWAT it says: "Re-using patient pen. Pen exited." Which file am I missing? A. It's pretty difficult for us to tell from that information. Before starting up EC SampleApp, break to the Swat prompt and type "showcalls -L". This will show all libraries being loaded; hopefully, this will tell you what library you're missing. --------------------------------------------------------------------- Q. The code for calculating the CRC for PCCOM file transfer appears to have a bug. A. That's right. The loop should be for ( ; size > 0; size-- ) not for ( ; size >= 0 ; size-- ) --------------------------------------------------------------------- Q. LEVELS.GOC won't compile. Why not? A. There are two objects that need to have their visMonikers slightly modified (go to line #474 and 479). The pound sign (#) is what is causing the problem. You can do one of two things to allow the compilation to work: 1. Remove the '#' sign from the string (example below). This will allow the 1 character to remain the keyboard navigation key (if you push '1' it will select that trigger). GI_visMoniker = '1', "Child #1"; *change to* GI_visMoniker = '1', "Child 1"; 2. Place a '\' before the '#'. This will allow the pre-processor to handle the # sign, but for some reason, it cannot use the keyboard navigation. GI_visMoniker = '1', "Child #1"; *change to* GI_visMoniker = '1', "Child \#1"; --------------------------------------------------------------------- ===================================================================== TOPIC: Serial/Stream --------------------------------------------------------------------- Q. What is the port number for a PCMCIA serial card? A. On the OmniGo, com1 is the built-in serial port and com4 is the PCMCIA serial port. --------------------------------------------------------------------- Q. Can I use hardware flow control on the OmniGo? A. Yes and no. Yes you can use RTS/CTS, but you cannot use DTR. On the OmniGo, DTR is always high, but when the transceiver isn't powered on, the external DTR pin isn't driven. Since the pin is floating, it will most likely appear as neither HIGH nor LOW. --------------------------------------------------------------------- Q. How do I know if data has been received at a serial port? Is there an explicit message sent? or do I have to poll using SerialQuery()? A. You can set up a message for serial event notification. See the SDK_C\Serial2 sample application. --------------------------------------------------------------------- Q. How can I code for the infrared port on the Zoomer? A. The serial API controls both the physical RS-232C and the IR. You can select which method of communication to use by selecting the com port as follows: Com1 = Serial RS-232C port Com2 = Short Range IR (18 inches) Com3 = Long Range IR (36 inches) Com4 = PCMCIA serial device Note that the long range IR (Com3) uses a *lot* of power while the com port is open, so it is best to send out the data in a burst, then shut down the port. --------------------------------------------------------------------- Q. The Serial driver doesn't seem to work on Zoomer. Is it compatible? A. It is compatible with the Zoomer. Please read the documentation about the "platform" and "publish" gp file directives, which can be found in the Routines book. You need to specify in your .gp file that you are developing geodes that you want to be able to run on the Zoomer. You do that by adding "platform zoomer" to your .gp file and by adding "exempt streamc" to your .gp file. Also, be sure that \PCGEOS\INCLUDE\LDF\ZOOMER.PLT is not marked read-only. --------------------------------------------------------------------- Q. From within our geode running on the Z, will we be able to, triggered by the user, run pccom like the Casio Z-7000/Tandy Z-PDA File Manager does? A. Sure, just DosExec PCCOM.EXE. Actually, you'll want to use the .ini file settings that indicate the correct parameters to pass to PCCOM (for baud, etc.). Category is 'fileTransfer', keys are 'command' and 'parameters'. --------------------------------------------------------------------- Q. What is the difference between raw, rare, and cooked? A. SM_RAW/SM_RARE/SM_COOKED control how the driver treats incoming data. In cooked mode, the driver provides XON/XOFF flow control and limits characters to 7 bits (to deal with errant parity bits masquerading as 8-bit, no-parity data). In rare mode, flow control is still provided, but incoming data are untouched (except for the stripping of XON and XOFF bytes from the input stream). In raw mode, flow control is disabled. --------------------------------------------------------------------- ===================================================================== TOPIC: Sound --------------------------------------------------------------------- Q. If I call UserStandardSound(SST_KEY_CLICK) followed almost immediately by UserStandardSound(SST_WARNING), the latter sound (SST_WARNING) is never heard. This happens on the PC Zoomer emulation. A. This problem is only on the PC. The problem is because the app is requesting to play 2 sounds at the same time, but the PC hardware can only support one. The Casio Z-7000 and Tandy Z-PDA, however, have 3 separate tone generators, so the app could send UserStandardSound() three times before running into problems. If you want to have all the clicks cue up, you need to use a sound stream, instead of calling UserStandardSound(). OR, you need to make the app pause for 1 tick (via TimerSleep) before sending out the SST_WARNING. --------------------------------------------------------------------- ===================================================================== TOPIC: State Files, Shutdown --------------------------------------------------------------------- Q. How can I force my application to shutdown to state? A. On the OmniGo, you can hit FN-F3. --------------------------------------------------------------------- Q. How can I limit the size of my application's state file? A. There are three ways to limit the size of the application's state file. 1. Completely disable the state file for your application. Write a handler for MSG_GEN_PROCESS_CREATE_NEW_STATE_FILE and simply return NullHandle. If your application needs to save some small amount of information between sessions, consider saving it in the ini file instead of to state file. 2. Marking a resource as notDetachable will prevent objects in that resource from saving to state. 3. Marking an object ignoreDirty will prevent that object from saving to state. --------------------------------------------------------------------- Q. What happens when the unit is turned off? It doesn't go through the state file save/restore mechanism, does it? I'm asking because this can't be tested on the emulator. A. When the OmniGo is turned off, processing is suspending, but Applications are not shut down to state. Power-down and -up are basically transparent to applications. On power-up, MSG_NOTIFY_DATE_TIME_CHANGE is sent over the GCNSLT_DATE_TIME GCN. --------------------------------------------------------------------- Q. Is there a way for the user to delete all state files or the state file for a particular app without clearing the RAM disk? A. On the OmniGo, resetting with Shift-ON-NEXT will clear the state files and clipboard. --------------------------------------------------------------------- Q. I have various global variables. How can I save them to the state file when my application shuts down? A. Intercept MSG_GEN_PROCESS_CLOSE_APPLICATION. Have the message handler copy the global variables to a global memory block and return the handle of that block. The system will automatically save this block to the state file. When the application is resumed, MSG_GEN_PROCESS_OPEN_APPLICATION will provide a memory handle of the additional data block that was saved earlier. Your application can then copy this information back to the global variables. --------------------------------------------------------------------- Q. What is the proper way to shut down an application? Is there a message that will shut down the application regardless of what UI objects are active (such as a modal dialog up)? A. Send MSG_META_DETACH to the application object. For the callerID parameter, pass zero. (callerID is useful if you are writing your own handlers for MSG_META_DETACH and want some way to ID the object that sent the message.) Another option: You can send MSG_META_QUIT to the application object. This will cause your application to completely shut down. It will not save a state file. --------------------------------------------------------------------- Q. How can I prevent my application from saving to state, so that it comes up "new" every time. A. Subclass MSG_GEN_PROCESS_CREATE_NEW_STATE_FILE and return NullHandle. --------------------------------------------------------------------- ===================================================================== TOPIC: Swat, the debugger --------------------------------------------------------------------- Q. I just split my application up into multiple source files and moved my code out of the PCGEOS branch so that I am sure to always have a 'clean' installation. Everything seems to work fine with one exception: when Swat is loading my geode or my geode's symbol table, it waits for a while and responds with: Looking for "ff Eapp"... Can't find executable file for "ff Eapp" (version mismatch?) Answer "quit" to exit to the shell Answer "detach" to detach and return to top level Answer "ignore" to ignore this patient Where is it? C:\DEV\PCGEOS\FF/ If I respond with FFEC.GEO, every thing continues fine. How can I make this stop? A. Add the following to your Swat.cfg file (at the end): "5 [your directory name]" where "[your directory name]" is replaced by the path name of your development directory. Note though that this directory must be under the root PCGEOS directory. --------------------------------------------------------------------- Q. I've got a bad pointer and/or handle floating around in my app and I'm trying to use Swat to track it down. A. Look up the documentation of the 'ec' command in Swat (type 'help ec' inside of Swat and/or look at page 109 in the Tools book). The idea is for you to use various ec flag settings to get specific help from the systemitself in 1) locating the bug directly and 2) forcing the bug to manifest itself sooner and/or reliably/ --------------------------------------------------------------------- Q. Swat is giving me an error about RPC. A. If you run Swat with the target machine not in the GEOSEC or GEOSNC directory, you will get a RPC error. On the target machine, change directory to GEOSEC and run pccom. --------------------------------------------------------------------- Q. What is causing this in Swat *** No explanation available *** Interrupt 3: Breakpoint trap Stopped in FatalError, address 2282h:01c8h CheckHandleLegal+30: MOV AX, 12 (000ch) A. Regarding interrupt 3: When you get something like this, a random interrupt in Swat that just kills everything, you can often stop it from happening by invoking PCCOM differently on the target. Add 10 to the interrupt number, turn it into hexadecimal, and make PCCOM ignore that number. For example, you would run PCCOM thus: PCCOM /i:d This would make PCCOM ignore the unwanted mouse-generated interrupt. Using a bus mouse instead of a serial mouse may also take care of it. --------------------------------------------------------------------- Q. Swat is rather daunting to learn. What parts should I learn first? A. My best suggestion for Swat is to check out the Tutorial book. It not only shows the basics of writing an application, but also how to debug one. Other things that are helpful to know: 1) If your application crashes upon launching, then simply running it from Swat may give you a Death due to ... and explanations will tell you what is wrong. 2) backtrace can give you an idea of what objects and methods the problem is in. 3) GENTREE and VISTREE will display the object tree for you 4) PGEN (and most other P... commands) is good for printing out the contents of a generic object. "pgen GI_link" can be used to see what the object is linked to (or what the link value is). 5) SRCWIN will open a window to display any source code (when it is available). 6) SSTEP (and ISTEP) can be quite usefull. You can even step through the kernel if you want to look at assembly. 7) Set break points with BRK and STOP IN 8) Use FRAME to check different methods/routines in the stack frame (show with a backtrace). 9) MWATCH and OBJWATCH are very useful for watching messages --------------------------------------------------------------------- Q. How can you tell who sends a particular message in Swat? Is there any way to see when a given message is put on the queue, rather that when it is delivered (as mwatch and objwatch seem to operate)? I am trying to track down where a particular message is coming from. A. Try 'cbrk ObjMessage ax= bx= si=' --------------------------------------------------------------------- Q. Is there ec code to check to see if the data you are writing into a chunk over writes the chunk boundary? (not ec lmem in Swat, but ec code I can add to the source)? A. You can either call ECCheckBounds, or use the EC_BOUNDS or Assert_fptr macros. They all do the same thing (call ECCheckBounds), which checks chunk boundaries, but only if ECF_LMEM error checking is set. --------------------------------------------------------------------- Q. SWAT works fine in DOS, but it gives me errors when I try to run SWAT in Windows 3.1. I get errors like "Can't contact PC: Call timed out" or "Phar Lap err 10049: Ran out of stack buffers". A. You need to tell Windows the com port's IRQ level (port address will usually set itself correctly, but you might have to set this, too). You can do this in Control Panel. Select Ports, then the port number you are working with, then Advanced... The most common IRQ levels used by com ports are 3,4 and 5. --------------------------------------------------------------------- Q. What flags should I set for the ec command in Swat? A. When developing and testing and app, turning on the various ec flags is an incredibly simply way to force many lurking bugs to reveal themselves. The minimum ec setting you should use are +normal, +segment, +high. These will catch most common mistakes, like unlocking a block of memory and then passing, as a parameter, pointer into that block of memory. +lmemMove and +unlockMove are also good as they cause the block to move around more often, which will reveal bugs such as pointers to unlocked blocks. If you are using VM files, +vmemDiscard is good. --------------------------------------------------------------------- Q. The Swat command-line prompt is normally something like [manager:0] 30 ==>. I can "patient name" to get "manager". But what Swat command do I use to get the thread number "0"? A. sw patient:0 or just :0 --------------------------------------------------------------------- Q. Why won't Swat run under OS/2? A. Because the Phar Lap memory manager used by our SDK doesn't work with OS/2. --------------------------------------------------------------------- Q. How can I debug my application on an actual OmniGo device? A. There is a batch file called ss1 which will start the Swat stub at 9600 baud. You can start the Swat stub in one of two ways: 1. Remove "geos" from the last line of the OmniGo's autoexec.bat file. Rebooting with the new autoexec file will land you at the DOS prompt (which is hidden behind the splash screen). From here you can type "ss1" to launch the Swat stub or "geos" to continue the OmniGo's normal startup. 2. To start the Swat stub during OmniGo startup: 1) Reboot the OmniGo by pressing shift-ON-next keys. 2) Hold down the 'c' key until a dialog box comes up. It will ask "Discard all data?" 3) Press 'n' (to keep data). 4) Wait about three seconds. 5) Hit CTRL-C. This will break out of autoexec.bat. The splash screen is still up (and will be throughout the DOS session). Type 'y' to cancel execution of the autoexec batch process. 6) Type the following: mcb cd geoworks ss1 This will set you in b:\geoworks and run ss1. The only catch is, on boot-up, the power driver will turn off the on-board serial port to save power. To get around this, after you attach with Swat, you need to do the following: 1. Hit CTRL-C to halt Swat 2. type "spawn jpwr" and "continue" 3. when Swat halts in jpwr, type "assign serialPowerStatus 3" and then "continue" This will cause the power driver to leave the serial port on, and therefore you can continue to debug. If you have trouble with the "assign" command, try copying JPWR.SYM to JPWR.GYM in OmniGo\Driver\Power\Jedi. --------------------------------------------------------------------- Q. In Swat I tried to look at the messages going to the CoffeeTable object in table.goc, but Swat said that the patient table had no threads, classes, or objects. Was Swat returning results for a library called table? I did the same actions for chart.goc, and things appeared to work correctly. A. Yes, the patient "table" is a library. You want to use the patient "tablesam" (this name is found in the .gp file). --------------------------------------------------------------------- Q. Swat gave me a "death due to NOT_MEM_HANDLE". But my handle variable is set to 5890h, which looks valid to me. A. Use the phandle command (i.e., "phandle 5890h") to get info about your handle. I am guessing that the handle's block was freed, which phandle will tell you. --------------------------------------------------------------------- Q. How can I run Swat using a Zoomer as my target machine? A. There are other methods, but here's one way to run Swat with a Zoomer as the target machine (in ten easy steps): 1. You may need to perform a full reset on the Zoomer to free space in the RAM disk. You'll need space for your application plus at least 273k. (To do a full reset, press and release the reset button in the battery compartment while holding down both fire buttons. Keep holding down both fire buttons for a few seconds, then release. Then press and release the A button.) 2. Copy \TARGET\ZOOM\LOADER.EXE from the SDK CD to the \PCGEOS\LOADER\ directory on the host machine. 3. Connect the serial cable from your host machine to the Zoomer. Check your baud rate for PCCOM. (If you've reset the Zoomer, it will be at the default 19200. If need be, run Preferences on the Zoomer and change the baud rate for File Transfer mode.) 4. On the Zoomer, run File Manager, tap the Connect menu, tap File Transfer, tap the "Switch to File Transfer Mode" button in the dialog box. 5. On the host machine, CD to the \TARGET\ZOOM directory on the CD and enter the following commands to send the three files to the Zoomer (page Z.12 of the sdk documentation--\ZOOMDOC): PCSEND GEOS.GEO PCSEND LOADER.EXE PCSEND SWAT.EXE 6. Press a fire button on the Zoomer to exit PCCOM. (If it won't exit for some reason, perform a warm reset by pressing the reset button in the battery compartment without holding the fire buttons.) 7. On the Zoomer, run File Manager, go to the \GEOWORKS directory and move GEOS.GEO to the \SYSTEM directory. Here's a step-by-step: A. tap to select the file: GEOS Kernel (GEOS.GEO) B. tap Move in the File menu C. select SYSTEM in the Move dialog box D. tap the Move button 8. When ready to run Swat, tap File Transfer in the Connect menu on the Zoomer. 9. Run Swat on the host machine. 10. Swat will report it can't find hwrrom.lib, palmui.lib, and alarm.app. Enter "ignore" for each of those. --------------------------------------------------------------------- ERROR: CORRUPT_LINKAGE (This happens when I start my program.) SOLUTION: What's wrong is you probably have a VisClass object as a child of a GenClass object. VisClass objects don't have GI_comp fields, thus the generic tree has a "hole" in it where the VisClass object is. To remedy the problem, make sure the VisClass is the only child of the GenClass object. --------------------------------------------------------------------- Q: Sometimes when I detach in Swat, then reattach, I get the 'Geos exited' message and a prompt, but I can't type anything. I then have to end the task in Windows, or reset the machine if I'm running Swat from the DOS prompt. A: The problem here is most likely that you are using software breaks. To solve this, don't do anything with the breaks while you are detached from the target computer. Here's what you shouldn't do: det brk delete 5- att This will cause Swat to lockup. Instead, do this: det att CTRL-C brk delete 5- The other problem is that if you leave Swat doing nothing while it's detached, it will do the garbage collection. This seems to make it do the 'Geos exited' error. If it does the garbage collection while it's attached, that seems to be okay. --------------------------------------------------------------------- Q: I wrote a new program, and later decided to change the name of it to something else. Now when I use Swat and try to send the program to the target computer, Swat tells me it can't find the program. What can I do? A: Search for every instance of the old name and make sure to change it to the new name. This should only be necessary in the .GP file. To simplify things, make the name of the directory, name of the .GP file, and the permanent name in the .GP file all the same. The only name that should be different is the longname in the .GP. --------------------------------------------------------------------- Q: I am trying to run Swat from within Windows 3.1. I get these errors. Phar Lap err 10049: Ran out of stack buffers or Can't contact PC: Call timed out A: Try putting the null modem at COM 1 or COM 2. Windows 3.1 doesn't seem to like when you use COM 3 or COM 4 in a DOS prompt. This will require reconfiguring your I/O cards and their interrupts, but it will let you run Swat under Windows. Note, Windows 95 does not have this problem. --------------------------------------------------------------------- Q: I get a "PC timed out" error when I use Swat, but everything seems to be set up correctly as far as the null modem settings. A: Sometimes it's not always the modem settings that cause a time out with Swat. If you're in the wrong directory on the target machine, Swat will give you a time-out error. This doesn't make sense, but that's how it is. You should be in the GEOS2XEC or ZOOMEREC directory when running PCCOM on the target. --------------------------------------------------------------------- Q: I get an ILLEGAL_RESOURCE error in my program. Why is that? A: If you're using GeodeGetOptrNS, make sure your program is multi-launchable. In other words, take out the "single" in the "type" line of your .GP file. This is just how the function works, and you can't avoid making the program multi-launchable. Another way this error could occur is if you forgot to create a LOCAL.MK file with the LINK_FLAGS line in it. You'll need this with multi-source apps when you use GeodeGetOptrNS. Here is a sample: # Pass flag for (somewhat) unsafe resource fixups for # multi-launchability. LINKFLAGS += -r #include <$(SYSMAKEFILE)> You need that third line so that the system makefile is included during the compile. See also: Multi-Source File Goc Applications --------------------------------------------------------------------- ===================================================================== TOPIC: TableClass/JTableClass --------------------------------------------------------------------- Q. What is the difference between TableClass and JTableClass? A. JTableClass is a subclass of TableClass that contains OmniGo-specific functionality. If you are writing your application for the OmniGo, use JTableClass. --------------------------------------------------------------------- Q. How can my application tell when a cell is being edited? A. You can check TI_privateFlags for TPF_EDIT_CELL_TEXT. --------------------------------------------------------------------- Q. The right side of the table is cut off. This is true not just for the table itself, but also for the scrolling controls in the title bar, which I have no control over. A. The problem is that the table's column widths add up to 240 or more. Change the widths to add up to about 238. You can play with the value to get it how you want it to look; 235 leaves a bit too much room on the right. --------------------------------------------------------------------- Q. How can I monitor when a user changes the selected cell in a Table? A. Unfortunately, there is no default mechanism which will send you MSG_TABLE_SELECT whenever the selection changes. You will have to subclass these messages and have them send you notification whenever the selection changes: MSG_TABLE_CHANGE_ROW_RANGE_SELECTION - initiated by cursor keys MSG_TABLE_SELECT - initiated by pen/pointer selection MSG_TABLE_REDRAW_CURRENT_SELECTION - selection changed by scrolling action MSG_SET_CURRENT_SELECTION - program initiated selection change. --------------------------------------------------------------------- Q. How can I set a default selection row for a table? I have successfully managed to make a single cell be the default selection but never the row. A. Use MSG_TABLE_SELECT(tcl, (TRIT_ROW|TCF_START_SELECT)); "(TRIT_ROW|TCF_START_SELECT)" will tell it to select the entire row. --------------------------------------------------------------------- Q. I have noticed that in a multi-column table on the OmniGo, I can cursor up and down but not left and right. What do I have to do to allow the user to change columns? A. You can make the table scroll horizontally by making the GenView that contains the table scrollable in the horizontal dimension. BUT DON'T DO THIS! It violates the OmniGo UI Specification to have anything wider than the screen. Horizontal scrolling on the OmniGo is strongly discouraged. To make a table show different columns, you'll have to provide UI to allow the user to signal the app that s/he wants to view a different set of columns. --------------------------------------------------------------------- Q. How can I start to edit a table cell from the keyboard (i.e. not doubling-tapping the pen)? A. You can intercept MSG_META_KBD_CHAR at the Table object, and if it's the Enter key, then do the following: Make a local variable of type TableEditCellTextParams structure. Use MSG_TABLE_GET_CURRENT_SELECTION to get the current selected cell, then set the TableEditCellTextParams structure's TECT_cells field with that cell; set the TECT_text to NullHandle, and TECT_length to 0. Then call MSG_TABLE_START_EDIT_CELL_TEXT on yourself, passing in the TableEditCellTextParams structure. --------------------------------------------------------------------- Q. How can I make a Table cell accept ink input? A. Add a line like this to your MSG_TABLE_START_EDIT_CELL_TEXT method: @call MyTableView::MSG_GEN_VIEW_SET_INK_TYPE(GVIT_QUERY_OUTPUT); Then do something similar for MSG_TABLE_STOP_EDIT_CELL_TEXT: @call MyTableView::MSG_GEN_VIEW_SET_INK_TYPE(GVIT_PRESSES_ARE_NOT_INK); Make sure to @callsuper() before each of the above. --------------------------------------------------------------------- ===================================================================== TOPIC: Text Related and Text Objects --------------------------------------------------------------------- Q. I need to use a fixed size font to display a table. How should I specify that I need a non-proportional font ? A. If you are working with a GState and GenView, GrSetFont() will do the job. If you are working with a text object, then MSG_VIS_TEXT_SET_FONT_ID is in order (or MSG_VIS_TEXT_SET_CHAR_ATTR if you are also setting other attributes). If you are trying to find a fixed width font to use, then it depends on whether you needs to print or not. No printing: ------------ Bison URW Mono Printing: --------- URW Mono --------------------------------------------------------------------- Q. Is it possible to change the font to display items in GenDynamicListClass the same way as it is done with MSG_VIS_TEXT_SET_FONT_ID ? Can the font size be changed for GenDynamicListClass ? A. The way to do this is to specify the list entry monikers as GStrings rather than as normal text strings. In the GStrings, include the GR_SET_FONT command. GStrings are described in the graphics chapters of the SDK documentation. One caveat: All the items are constrained to the same height, calculated via HINT_FIXED_SIZE on the list. --------------------------------------------------------------------- Q. What are the similarities and differences between GEOS and DOS character sets? A. GEOS supports almost all roman-based languages. Geos uses mostly ASCII, which defines chars 0 to 127. Some of the control chars have different meanings. Above 127 are from Geos unique chars, that foreign languages (European), typographicals (like dagger and trademark), currency (yen), and math symbols (like infinity). You can find out the specific char codes from Include/char.def file. Geos does not have the IBM PC graphics chars (i.e., lower left corner piece with two lines). And then there is DBCS, in which is piled every character in existence, PLUS the kitchen sink. --------------------------------------------------------------------- Q. In terms of strings, what is the difference between size and length? A. size = # of bytes, length = # of chars They are the same for SBCS, but size = 2*length for DBCS. --------------------------------------------------------------------- Q. How can I get the metric width of a character? A. You can use GrTextWidth (which returns the width in point size) --------------------------------------------------------------------- ===================================================================== TOPIC: Multi-threading --------------------------------------------------------------------- Q. I need to open a dialog containing a text window and a Cancel button to show progress messages and handle user cancellation of an operation. The operation is a single method which also initializes the dialog. It sends status text strings to be displayed in the text window and checks if Cancel has been pressed. To do that, it calls two application messages periodically. However, the dialog does not show up until the operation method, the one that initializes it, returns. Is there any way force the dialog update without its preliminary opening (it works fine if I open it before the user selected to connect)? While the operation method is working, mouse events are not processed, so I can not click on the Cancel button. How do I yield the control to the UI to handle the mouse within this slow operation? A. I believe you can't really easily accomplish what you want in a single method. In fact, what you really want is two different threads working, which implies two different objects in charge. The first thread (probably your process thread) should be doing the connection work and sending notification messages to the progress dialog box. The second thread (probably your UI thread) should run the dialog box and send a cancellation message to the first thread when the Cancel button is hit. The SDK documentation has a section in the GenInteraction chapter of the Objects book that deals with progress interactions. Check out the on-line documentation. The ASCII file you want to look in is on the disc: \TECHDOCS\ASCII\OBJECTS\OGENINT.TXT. Look for section 7.3.2.4, called "Progress Interactions." --------------------------------------------------------------------- Q. We need to run background tasks on the Zoomer. I use ThreadCreate to start background task, but Glue reports: Error MAP1BKG.GP 19: Usage of THREADCREATE requires geos minor protocol 9, but platform files only allow minor protocol 3 A. This is caused by an enhancement in our new kernel. Since Casio Z-7000 and Tandy Z-PDA use the old kernel, it cannot use the additions to thread create. To overcome this, you can call ThreadCreate_Old. To use ThreadCreate_Old, you must provide the prototype for it and at surround the call with push/pop of the si register. Here is an example: extern ThreadHandle _pascal ThreadCreate_Old(word priority, word valueToPass, word (*startRoutine)(word valuePassed), word stackSize, GeodeHandle owner); . . . _asm push si; thread = ThreadCreate_Old(); _asm pop si; --------------------------------------------------------------------- ===================================================================== TOPIC: Timers --------------------------------------------------------------------- Q: How do I set real-time timers using TimerStart? A: TIMER_EVENT_REAL_TIME starts a real-time clock on the device that will send a message at some particular date and time. You pass the date that the event should happen in the "ticks" parameter and the time of day in the "interval" parameter of TimerStart. The date is stored in a compressed format that is word-sized. The year (since 1980) is in the high 7 bits; the month is in the next 4 bits; and the day is in the low 5-bits. The hour is stored in the high byte of "interval" and the minute is stored in the low byte of "interval. For example, if I wanted to have a wakeup notification sent on March 5, 1996 at 8:05am, I would set up the "ticks" and "interval" parameter as follows: ticks = 0x2065; (year = 1996-1980 = 16 = 0x10, 0x10 << 9 = 0x2000 month = 3, 0x03 << 5 = 0x0060 day = 5, 0x05 << 0 = 0x0005) interval = 0x0805; --------------------------------------------------------------------- ===================================================================== TOPIC: Tools --------------------------------------------------------------------- Q. Why can't PCS find my pattern file? A. PCS can't open the pattern file, PCS.PAT in the INCLUDE directory, if its read-only attribute is set. Due to a bug in the installation procedure, many files are installed with the read-only attribute on certain machines. The best thing to do is enter "attrib -r *.* /s" at the DOS prompt from the root of \PCGEOS on the host machine to clear this attribute from all the files. --------------------------------------------------------------------- Q. PMAKE DEPEND cannot find CPP. Why? A. Check your CONFIG.SYS and AUTOEXEC.BAT files for anti-virus programs that might be incompatible with the development tools, like this one: DEVICE=c:\NDW\NAV&.SYS /b This line loads the Norton Anti-Virus program. --------------------------------------------------------------------- Q. When I attempt to use the remote command capabilities of PCCOM, I am having mixed success. I am able to get the target machine to clear, do ls and exit. Whenever I try a command like CD, MD, or delete file, it always says "Path not found." A. All of the commands work. You need to put a '!' after *each* argument. Also, be sure to use DOS file path conventions. --------------------------------------------------------------------- Q. FrameReader complains about missing fonts when I try to read the documentation. A. Add these lines to the WIN.INI file: [FrameReader3.0] FRHome=c:\reader IniFile=reader.ini (not the FrameMaker equivalents). Also, install a PostScript printer driver (to get rid of the other message that FrameReader can't print without an installed printer). --------------------------------------------------------------------- Q. The SDK tools are very slow. Glue will take up to 20 seconds before it starts linking all the object modules. How can I speed things up? A. Our tools use the Phar-Lap DOS extender, which has some problems with EMM386.EXE in MS-DOS 6.X. This problem causes delays before the programs start executing which are proportional to the amount of memory on the machine. To fix this problem, add the following to your autoexec.bat file set DOSX=-MAXV 0 --------------------------------------------------------------------- Q. Interrupt 2: Non-maskable interrupt Stopped in ffc3h:000eh, address ffc3h:000eh BIOS+64574: I keep on getting this when I am attached to Swat. However, if I just type continue at the Swat prompt, everything is fine but each time I hit a trigger, I get the same interrupt. A. You need to mask out interrupt 2. To do this, first add 8 (int2 * 4 bytes) to the interrupt number to be masked (2+8=a), and then pass the result with the /i flag in the call to the Swat stub. --------------------------------------------------------------------- Q. Every PMAKE DEPEND had this warning: WARNING: file "APPNAME.ASM", line xxx: Couldn't find include file APPNAME.RDF A. That's normal; the .RDF (.rdef) file is generated by uic during compile time. --------------------------------------------------------------------- Q: When I run PMake, it starts to compile my code, and in a minute or so it stops and gives me an error, but it doesn't say what error, just "Error". A: You might want to increase the memory available to the compiler. It needs a lot of memory, probably 6Mb or more. Your machine must have 8Mb to use PMake, and if you're running it with a SmartDrv disk cache, you'll probably need even more memory. Under Windows you can create a swap file which will let you run PMake. --------------------------------------------------------------------- ===================================================================== TOPIC: Visual Objects --------------------------------------------------------------------- Q. What is the message to send to a VisContent which will make it repaint itself and its visual children? I am doing a lot of VUM_MANUAL things and want to repaint the content at the end of my routine. The message will be sent by an object running in my application thread. A. Send MSG_VIS_VUP_UPDATE_WIN_GROUP with VUM_NOW (assuming that your VUM_MANUALs have invalidated things). --------------------------------------------------------------------- Q. How and when is the best time for someone to add a VisComp as a child of a GenDocument? I am trying to do it in the MSG_GEN_DOCUMENT_ATTACH_UI_TO_DOCUMENT handler, but at that point the Vis master part of the document object isn't built out. A. You should be able to do it, after passing ATTACH_UI_TO_DOCUMENT to the superclass. MSG_VIS_ADD_CHILD will force it to be built out. --------------------------------------------------------------------- Q. We've got a simple application that has a dialog brought up by GEN_INTERACTION_INITIATE. In that dialog are a GenView and two triggers. In the GenView are a VisContent and a VisText under that. The problem? Even though apparently the text gets added to the VisText object's VTI_text chunk, the text object never displays it. A. VisText doesn't do any geometry handling, so you have to do it yourself. (Presumably there's a good reason you are not using a GenText.) The content and text object will have zero bounds, since nothing has been done. If the content's bounds are zero, nothing will get drawn. You should at least stuff bounds for the text object, the content will follow suit. --------------------------------------------------------------------- Q. I have several vis objects that overlay each other. I want mouse events to get detected only by the top (from the user's viewpoint) object and ignore the rest. How can I do this? A. Clear the VA_DETECTABLE bit from any vis object that aren't eligible to be clicked on. --------------------------------------------------------------------- ===================================================================== TOPIC: Where is it? --------------------------------------------------------------------- Q. Does the SDK include an API for handwriting recognition? Is it in the docs? If so, where? A. Look in Include/hwr.h. --------------------------------------------------------------------- Q. Where's the Serial Driver? How come the Serial sample application doesn't work? A. Download the SERIALC files from the support center. If you don't have CompuServe, you can get the files from AOL. ---------------------------------------------------------------------