TCL FAQ
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.
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.
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.
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.
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; }
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.
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.
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.
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.
Go to top
|
|