tcam.gif (6094 bytes)   mouse.gif (3933 bytes)

 


TCL FAQ

Call set_drag() to turn off undesired dragging image


Question:
It happens sometimes that an unexpected dragging image will appear when issuing getinput() function call, though there is no set_drag() function call before it. Why? What should I do to avolid it?

Answer:
You can avoid this by calling set_drag(-1) to turn off the dragging handling explicitly, each time before and after the getinput() function call. Note that once a dragging handling is set by set_drag(), it will remain effective until it is explicitly turned off.


Rule for executing TCL programs using RUN command.


Question:
What is the entry point of a TCL program when it is executed by the RUN command? Is it just like C, which must be started from a function called 'main'?

Answer:
The rule to start executing a TCL program is not the same as that for a standard C program. There is no need for a function named 'main' in a TCL program file, since the TCL interpretor always starts the execution from the first function encountered in the program file. The cause of this difference is obvious. The C is a complier language and its compiled modules must be linked with other modules and libraries to form an executable file, and thus the entry point must be determined uniquely by the name of function. Yet, it is not necessary to force the TCL programmer to use a fixed function name for program entry point, since the TCL, being an interpretor, does not have the module-linking problem. Of course, if you are used to writing C program, you might want to name the entry function of your TCL program as main(), as long as you put it at the beginning of the program. Some folks like to make different TCL functions into separate files, and use '#include' directive to include these function modules into the main program file. Care must be taken if you are doing so. A common mistake is that the '#include' directive is placed at the beginning of the program file and thus change the entry point of the program! If you must chain different function modules into the main program file using '#include' directive, put that '#include' at the end of the file.


Precaution on issuing gete(p1) function call.


Question:
Why do I sometimes get different results when issuing gete(p1) to pick object at the same p1 position?

Answer:
Issuing gete() function with a single POINT argument would have the same result as if the operator were picking objects from that given point. However, this is quite misleading for the programmer to think that gete(p1) should return the same result for the same p1 on the same drawing, which is not true. Since gete(p1) would return the same result as if the operator were picking objects from the given point p1, therefore p1 must be within the current view window. The operator can not pick up an object outside of the view window. There must be certain constraints in using this function call. As a matter of fact, the execution of this function call will make the internal graphic driver to seive out objects from the display list by the given target box. So the programmer must be aware of the following facts in using this function: 1. The given target point must be within the current view window, since it will not pick anything which is not in the display list. 2. The size of the target box is determined by the system variable @PICKBOX, not the system variable @APERTURE. 3. The display list will be searched for the objects that are crossed by the target box. The function will return the first object found for the first time call on the same pick point. So the size of the target box will definitely affect the returning result. 4. For successive calls on the same pick point, it will return the next object crossed by the target box from the display list, until the end of the display list is encountered and NULL is returned. 5. The definition of successive calls on the same pick point is quite strict. Not only the same pick point must be given during the successive calls of gete(), there should also be no other UI function calls (including getxxx(), command() and the like), and any other function calls that are relating to the display list (such as regen(), redraw(), newent(), plotent()). Otherwise, it will be reset to search the object from the beginning of the display list. Therefore, if you must do picking from the same point again, you better pick at some different point (a null pickup) first, to avoid being taken as the successive call, and ensure gete(p1) has been reset.


How to return a string from a TCL function?


Question:
How to return a string from a TCL function?

Answer:
All you have to do is NOT to declare the function with any data type, and directly return a string type data within the funtion, like the example below: readstr() { char input[80]; input = gets("\nString: ",40); return input; } This is convenient, but not compatible with Standard C. The incompatibility lies not in the function type declaration but in the way the data returned. In Standard C, a string is a one-dimensional array of character type data, of which the value can not be returned formally. It must be returned by a pointer pointing to the array. However, the TCL may take the one-dimensional character array as a single data type called STRING and therefore, its value can be formally returned by the return statement. Note that the formal way to return an array data in TCL is through the formal argument.


Linetype selection function.


Question:
I want to let the operator choose a linetype directly. What TCL runtime function can be used for it? It seems that the function getltype() is not for that purpose.

Answer:
Yes, you are correct. The function getltype() is not used for linetype selection by the user. It is used for retrieving a LINETYPE data from the system linetype table. So, you can not expect to have a pop-up window for linetype selection. In fact, in current release, there is no such TCL runtime function to support the user linetype selection directly. However, if you need such functionality, the following program fragment will do the job for you: int selltype(int deft) { int curltype; curltype = @CURLTYPE; @CURLTYPE = deft; command("ELTYPE"); deft = @CURLTYPE; @CURLTYPE = curltype; return deft; }


How to do parameter passing to external TCL programs?


Question:
How to pass parameter values to an external TCL application executed via command("RUN ...") function call?

Answer:
Basically, there is no way to pass formal arguments to a TCL application invoked by the RUN command from another mother TCL application. However, this does not mean that you can not pass parameter values to an external TCL application. As a matter of fact, there are many ways for a mother application to pass and to retrieve values to and from a child application: 1. Use system registers: This is the most simple and easiest way to pass values via the system registers. All you have to do is to make a rule on the usage of these system registers between the mother application and the child application. Of course, you must be awared that these system registers are common resource to all TCL applications, and the number of them are also limited. 2. Create user variables: User variables can be created to store additional information with the drawing. They can also be created for the purpose of communicating between applications. For example, the presence of a certain user variable may indicate that a certain TCL application had been executed, and the value may indicate the last status of the execution. There can be a lot of application in this respect. 3. Through external files: If there is a lot of data to pass to the child applications, using an external disk file would be a feasible choice. You may save the data to the disk file in your way and let the child retrieve them in the same way.


How to use "%@0&f" in printf()?


Question:
How to use the format specifier "%@0&f" in printf() ?

Answer:
The format specifier "%@0&f" is not a standard format specifier and is therefore not documented in the TCL Reference Manual. However, it is actually present and used by the system internally. It is used to output a floating point value (double) in a format controlled by the system variable @DISP_POSNO according to the following rules: 1. If @DISP_POSNO is zero, the output will be rounded to the third decimal position after the decimal point. The trailing '0' will also be removed. This is the system default. 2. If @DISP_POSNO is greater than zero, it specifies the number of decimal position after the decimal point to round the value and to output, but the trailing '0' will be retained. 3. If @DISP_POSNO is negative, then its absolute value specifies the number of decimal position after the decimal point to round the value and to output, and the trailing '0' will be removed. Note that the leading space of the conversion result will always be removed. Care should be taken in setting the @DISP_POSNO variable. It will affect the system display of the coordinates, length and angle values. If you must take advantage of this format specifier, be sure to preserve the original setting value of @DISP_POSNO, and restore it back after use.


Message remains after turning off @CMDECHO.


Question:
I have turned off @CMDECHO before calling the command() function, but there are still messages generated during the command execution. Why?

Answer:
Turning off @CMDECHO does not necessarily mean that the system will not echo any input nor issue any message to the command area. There are certain conditions which must be checked: 1. The script must be active and effective at the time a message is to be suppressed. This means that the next input must be taken from the script and should not be a '/' code to switch the system to the man/machine interface. 2. Certain error messages and reports of command result can not be suppressed (especially when the report generation itself is the purpose of the command). All messages other than the above conditions should be suppressed by the specification of @CMDECHO. If there is any message violating the rules, please report us the command name that causes the problem. However, most of the offending cases are found to violate the first rule mentioned above. For example, the expression command("SELECT c p1 p2 ^M"); is issued to select objects by window crossing with two given points. As the last '^M' code is issued to terminate the SELECT operations, the script ends. And thus, the last message generated by SELECT command to report the state of selection can not be suppressed due to the violation of Rule 1. To avoid the problem, you should add one more space or '^M' code to the end of the script, so that the script will not end when the SELECT command terminates and the message is thus suppressed. This additional space or '^M' code will not cause any problem, since they are ineffective to the command(). They won't cause any repetition of commands.


Length limit in executing script using command().


Question:
Is there any length limit in using the command() to execute a command script? If the limit should be exceeded, what should I do?

Answer:
The command() function accepts at most 15 arguments and each argument can have a string of length not exceeding 250 characters. This means that you can have at most 3750 characters in the command script for one time command() function calls, which is quite sufficient to most applications. However, if your application should execeed this limit, you should use the external script file. Let your program generate the script file (SCR file) first, and then issue command("SCRIPT file") to execute the script. The length of each script line is still limited to 250 characters, but the number of script line is unlimited. Note: The script executed by command() will be stopped if it contains "^C" code.

gotop.gif (1250 bytes)
Go to top