IT SOLUTIONS
Your full service technology partner! 
-Collapse +Expand
Paradox
Search Paradox Group:

Advanced
-Collapse +Expand Paradox To/From
To/FromCODEGuides
-Collapse +Expand Paradox Store
PRESTWOODSTORE

Prestwood eMagazine

April Edition
Subscribe now! It's Free!
Enter your email:

   ► KBDesktop Data...Paradox & Ob...P9 Book: Pow...   Print This     
  From the April 2010 Issue of Prestwood eMag
 
Paradox P9 Book: Power Programming:
Power: Chapter 17, Manipulating Objects At Run Time
 
Posted 22 years ago on 3/26/2003 and updated 2/24/2006
Take Away: Chapter 17, "Manipulating Objects At Run Time" from Paradox 9 Power Programming by Mike Prestwood.

KB100212

Objects that you place on forms and reports are UIObjects (user interface objects). Only UIObjects that you place on forms contain events. The form itself is also a UIObject—it has events and responds to events.

Pixels and Twips

A pixel is an abbreviation for picture element. Pixels vary in size depending on your monitor. One physical pixel is one dot on your screen, regardless of resolution. Contrast this with a twip, which is a physical unit where 1,440 twips are equal to one inch, regardless of resolution. Most ObjectPAL properties that manipulate size are in twips, not pixels.

Using the UIObject Variable

ObjectPAL offers tremendous flexibility in manipulating UIObjects during run time. You can either directly refer to a UIObject or attach to it and refer to it with the UIObject variable. For example, assuming a box named box1 is on a form, you can change its color with the following:

method pushButton(var eventInfo Event)
box1.color = Red
endMethod

 

or with

 

method pushButton(var eventInfo Event)
var
ui UIObject
endVar

ui.attach(box1)
ui.color = Red
endMethod

Obviously, in most situations the first single line of code is simpler, but the second technique is a particularly useful technique that you will often use when you do not know the name of the object a routine will be working with.

Moving a Text Box During Run Mode

Enabling the user to move objects around during View Data mode is very useful. In ObjectPAL, you can enable the user to move an object around to reveal something behind it, or you can enable the user to move an object to a new location. The following example shows you how to move an object around. When you let go of the mouse button, the mouseUp event occurs and the code in it snaps the object back to its original position. You could use this technique for many tasks. For example, you could use this technique in a game to reveal answers or offer clues in an educational game.

Step By Step
  1. Create a form with several text boxes on it. Give them various frames and colors (see Figure 17-1).
  2. Figure 1: Setup form

  3. Add lines 3–5 to the Var window of the form.
  4. 1: ;Form :: Var
    2: Var
    3: x,y,x1,y1,w,h SmallInt
    4: ui UIObject
    5: sTargetClass String
    6: endVar

  5. Add line 3 to the Init event of the form.
  6. 1: ;Form :: init
    2: method init(var eventInfo Event)
    3: sTargetClass = ""
    4: endMethod

  7. Add lines 8–10 to the mouseDown event of the form:
  8. 1: ;Form :: mouseDown
    2: method mouseDown(var eventInfo MouseEvent)
    3: if eventInfo.isprefilter() then
    4: ;This code executes for each object on the form
    5:
    6: else
    7: ;This code executes only for the form
    8: eventinfo.getTarget(ui)
    9: ui.getPosition(x1, y1, w, h)
    10: sTargetClass = ui.class
    11: endIf
    12: endMethod

  9. Add lines 3–5 and 11–17 to the mouseMove event of the form:
  10. 1: ;Form :: mouseMove
    2: method mouseMove(var eventInfo MouseEvent)
    3: var
    4: liX, liY LongInt
    5: endVar
    6: if eventInfo.isprefilter() then
    7: ;This code executes for each object on the form
    8:
    9: else
    10: ;This code executes only for the form
    11: if eventinfo.isLeftDown() and
    12: sTargetClass = "Text" then
    13: liX = eventinfo.x()
    14: liY = eventinfo.y()
    15: ui.getPosition(x, y, w, h)
    16: ui.setPosition(x + liX - 400, y + liY - 400, w, h)
    17: endIf
    18: endIf
    19: endMethod

  11. Add line 8 to the mouseUp event of the form:
  12. 1: ;Form :: mouseUp
    2: method mouseUp(var eventInfo MouseEvent)
    3: if eventInfo.isprefilter() then
    4: ;This code executes for each object on the form
    5:
    6: else
    7: ;This code executes only for the form
    8: ui.setPosition(x1,y1,w,h)
    9: endIf
    10: endMethod

  13. Check the syntax, save the form as MOVER.FSL, and run the form. Click and drag any text box you placed on the form to move it. When you let go (mouseUp), the object snaps back to its original location (see Figure 17-2).

Figure 2: MOVER.FSL demonstrates moving objects during run time

Creating UIObjects

ObjectPAL enables you to create objects in run time. To create objects on the fly, you need to use the create() method, and you need to know about things such as points and twips. As stated earlier, a twip is what you use to measure points on the screen. A point has a x value and a y value, both of which are measured in twips. A twip is 1/1,440 of an inch, or 1/20 of a printer’s point. The following two examples use the create() command and a point variable to create and delete a line. The create() method does just what its name implies—creates objects. The type of object, where the object is created, and the dimensions of the object are all specified as part of the parameters for create().

The properties (frame, color, font, and so on) of the object produced by create() default to whatever the object defaults happen to be at the time the object is created. To modify the properties, you must change each individually, after the object has been created. The notation and properties specific to graphs are discussed later in this chapter.

The parameters for create() are as follows:

objectType

Corresponds to the type of object being created. For graphs, this will be ChartTool.

x

The x coordinate (in twips) of the upper-left corner of the object.

y

The y coordinate (in twips) of the upper-left corner of the object.

w

The width (in twips) of the object to be created.

h

The height (in twips) of the object to be created.

container

This is an optional parameter. If present, container must be a UIObject capable of containing the created object. In other words, you cannot place a 1,000 × 1,000 object within a 500 × 500 container.

A Note on Working with Groups

Normal object creation goes from the outside to inside. For example, first the page is created and then you place a box on the page. Within the box, you place a table frame. Obviously, you cannot create the box without first creating the page. Likewise, you cannot create the frame without first creating the box. Unfortunately, groups work the opposite way. You cannot place a group on the page and then place objects within the group. You must first place the two objects and then place a group around these two objects.

Working with Frames

Because frames can vary in thickness, you need to allow for a border on the containing object. As a general rule of thumb, it is a good idea to give 15-twips distance between the inner object and its containing object.

Creating a Line

Suppose that you want to allow the user to create and delete a line. To do this, you use two buttons on a form. One button creates a line, and the other deletes it.

Step By Step

  1. Create a new form and place two buttons on it. Label the buttons Create Line and Delete Line (see Figure 17-3).
  2. Figure 3: Setup form for the example

  3. Add line 3 to the Var window of the page.
  4. 1: ;Page :: Var
    2: Var
    3: ui UIObject
    4: endVar

  5. Add lines 3–6 to the pushButton event of the Create Line button.
  6. 1: ;Button :: pushButton
    2: method pushButton(var eventInfo Event)
    3: const
    4: INCH = 1440
    5: endConst
    6:
    7: ui.create(LineTool, 15, 15, 1.5 * INCH, 2 * INCH, self.container)
    8: ui.visible = True
    9: endMethod

  7. Add line 3 to the pushButton event of the Delete Line button.
  8. 1: ;Button :: pushButton
    2: method pushButton(var eventInfo Event)
    3: ui.delete()
    4: endMethod

  9. Check your syntax, save the form as CreateLine.fsl, switch to View Data mode, and click the Create Line button. After the line is created, click the Delete Line button to remove it (see Figure 17-4).

Figure 4: CreateLine.fsl demonstrates creating and deleting a line

Having Fun with Lines

Now let’s have a little fun with creating lines. This next example randomly creates lines of varying length, position, color, and thickness in a box.

Step By Step

  1. Create a new form and place two buttons, two fields, and a box on it (see Figure 17-5).
  2. Label one button Create Line and the other Delete Line. Change the upper field name to fldLines and label it # of Lines. Change the lower field’s name to fldDelay and label it Delay (see Figure 17-5).
  3. Figure 5: Setup form for the example

  4. Change the name of the page to pge and the box to boxLines.
  5. Alter the open event of the fldLines field as follows:
  6. 1: ;fldLines :: open
    2: method open(var eventInfo Event)
    3: DoDefault
    4: self.value = 100
    5: endMethod

  7. Alter the open event of the fldDelay field as follows:
  8. 1: ;fldDelay :: open
    2: method open(var eventInfo Event)
    3: DoDefault
    4: self.value = 50
    5: endMethod

  9. Alter the pushButton event of the Draw Lines button as follows. (As a programming exercise, try adding various line properties to this routine.)
  10. 1: ;btnDraw :: pushButton
    2: method pushButton(var eventInfo Event)
    3: var
    4: uiLine UIObject
    5: pBox Point
    6: siCounter SmallInt
    7: xTemp, yTemp, wTemp, hTemp LongInt
    8: x, y, w, h LongInt
    9: siFrameSize SmallInt
    10: siColor SmallInt
    11: siThickness SmallInt
    12: endVar

    13: setMouseShape(MouseWait)

    14: ; Get thickness of box’s frame (plus a little for margin).
    15: siFrameSize = boxLines.Frame.Thickness + 15

    16: ; Get coordinates of box.
    17: pBox = boxLines.fullSize
    18: x = pBox.x() - siFrameSize
    19: y = pBox.y() - siFrameSize
    20: w = pBox.x() - siFrameSize
    21: h = pBox.y() - siFrameSize

    22: for siCounter from 1 to fldLines.value
    23: ;Set value for xTemp.
    24: xTemp = 0
    25: while (xTemp <= siFrameSize)
    26: xTemp = smallInt(rand() * x)
    27: endWhile

    28: ;Set value for yTemp.
    29: yTemp = 0
    30: while (yTemp <= siFrameSize)
    31: yTemp = smallInt(rand() * y)
    32: endWhile

    33: ;Set value for wTemp.
    34: wTemp = w
    35: while (xTemp + wTemp) >= w
    36: wTemp = smallInt(rand() * w)
    37: endWhile

    38: ;Set value for hTemp.
    39: hTemp = h
    40: while (yTemp + hTemp) >= h
    41: hTemp = smallInt(rand() * h)
    42: endWhile

    43: try
    44: ; Delay then create line.
    45: sleep(fldDelay.value)
    46: uiLine.create(LineTool, xTemp, yTemp, wTemp, hTemp, boxLines)

    47: ; Set line color.
    48: siColor = (smallInt(rand() * 5))
    49: switch
    50: case siColor = 1 : uiLine.color = Red
    51: case siColor = 2 : uiLine.color = DarkRed
    52: case siColor = 3 : uiLine.color = Blue
    53: case siColor = 4 : uiLine.color = DarkBlue
    54: otherwise : uiLine.color = Black
    55: endSwitch

    56: ; Set line thickness.
    57: siThickness = (smallInt(rand() * 40))
    58: uiLine.Thickness = siThickness

    59: uiLine.visible = True
    60: onFail
    61: beep()
    62: message("Could not create a line")
    63: endTry
    64. endFor

    65: setMouseShape(MouseArrow)
    66: endMethod

  11. Alter the pushButton event of the Clear Lines button as follows:

1: ;btnClear :: pushButton
2: method pushButton(var eventInfo Event)
3: var
4: uiBox UIObject
5: uiLine UIObject
6: arLines Array[] String
7: siCounter SmallInt
8: endVar

9: setMouseShape(MouseWait)
10: DelayScreenUpdates(True)

11: uiBox.attach("BoxLines")
12: uiBox.enumObjectNames(arLines)

13: for siCounter from 1 to arLines.size()
14: if arLines[siCounter] <> "pge.boxLines" then
15: uiLine.attach(arLines[siCounter])
16: uiLine.delete()
17: endIf
18: endFor

19: DelayScreenUpdates(False)
20: setMouseShape(MouseArrow)
21: endmethod

  1. Check your syntax, save the form as CreateLines.fsl, switch to View Data mode, and click the Draw Lines button. After the lines are created, either click the Draw Lines button again or click the Clear Lines button to remove them (see Figure 17-6).

Figure 6: CreateLine.fsl demonstrates creating and deleting a line

Creating a Graph from Scratch

Now that you’ve seen how easy the create() method is, type the following code into the pushButton event of a button:

1: ;Button :: pushButton
2: method pushButton(var eventInfo Event)
3: var
4: ui UIObject ;Declare a UIObject variable.
5: endVar
6:
7: ui.create( ChartTool, 100, 100, 3000, 3000 ) ;Create the graph.
8: ui.tableName = "ORDERS.DB" ;Set graph properties.
9: ui.visible = True ;Display graph.
10: endMethod

The preceding code creates a graph from scratch on a form. ObjectPAL is powerful; it enables you to create all types of objects while the object to which the code is attached is running. You also can alter the properties of graphs already created.

A Simple Example of Manipulating a Graph Property

This next example is similar to the preceding example, but adds the manipulation of the bindType and graphType properties to set the graph type. Following is another example you can type into the pushButton event of a button:

1: ;Button :: pushButton
2: method pushButton(var eventInfo Event)
3: var
4: ui UIObject
5: endVar
6:
7: ui.create( ChartTool, 20, 20, 3000, 3000 )
8: ui.bindType = GraphTabular
9: ui.graphType = Graph2DPie
10: ui.tableName = "Orders.db"
11: ui.visible = True
12: endMethod

Using designModified

Sometimes you need to open another form, alter it, and close it from ObjectPAL. When you do, you are prompted to save the changes to the form; this is a very undesirable feature for a finished application. You could deliver the form and the problem would go away, or you could use the designModified property of the form, as in the following example:

1: f.designModified = False

In essence, you are telling the form that nothing was changed, when in fact it was.

This technique also works with reports. For example, the following code snippet is from our Paradox Workbench commercial utility—the code snippet opens a report and alters it:

1: var
2: r Report ;Declare r as a report variable.
3: ri ReportOpenInfo ;Declare ri as a ReportOpenInfo variable.
4: endVar
5:
6: ri.name = "SOURCE" ;Specify report name.
7: ri.masterTable = "SOURCE.DB" ;Set master table for report.
8: r.open(ri) ;Open report.
9:
10: ;Set the value property of a text object.
11: r.txtTitle.value = "Source Code for " + fldFileName.value
12: r.show()
13: r.designModified = False ;Tell report it has not changed.
14: r.wait()

Dereferencing a UIObject

You can create, move, size, and generally change any property of a UIObject. But how do you reference a UIObject with a variable? As discussed previously, you do so through dot notation and the use of parentheses. Referencing objects without hard-coding their names in the application adds flexibility to your routines.

When you work with several objects on a form, you might want to perform the same actions on each of the objects at different points in the code. One technique that saves many lines of code is to use a variable to reference an object. Remember the following three rules when you use a variable to reference an object:

  • The statement that references an object must include a containership path. In the example that follows, Page refers to the name of the actual page in which the (Y) object resides.
  • The first object in the path must not be a variable.
  • Parentheses must surround the name of the variable..

Following is an example of how these rules are applied:

1: for X from 1 to 10
2: Y = "Box" + strVal(X) ;This evaluates Y = "Box1" for
3: Page.(Y).color = Blue ;the first iteration of the
4: ;for loop
5: endFor

This code changes the color of the objects named Box1 through Box10 to the color blue. Remember that it’s easier to access the objects if you rename them yourself. If the name of the object is the previous name suffixed by a number, such as Box1, you can use code.

Tip: If you need to rename many objects one right after the other, use the Object Tree. By selecting and inspecting each object on the Object Tree, you can quickly rename many objects.

Using Timers to Animate a UIObject

Timers in ObjectPAL offer a powerful way to manipulate your environment. A timer enables you to execute an event every so many milliseconds. To set a timer, use setTimer(), as in the following:

1: setTimer(milliSeconds [,repeat])

For example, on the open event of any object, you can set a timer to trigger every 10 seconds:

1: self.setTimer(10000)

After you set the timer, add the code that you want to execute on the timer event of the object, as in the following example:

1: method timer(var eventInfo TimerEvent)
2: msgInfo("10 second timer", "Press OK")
3: endMethod

You can use timers for a multitude of tasks, such as the following:

  • Executing a set of commands every n milliseconds
  • Checking the system time or date to set scheduled events
  • Looping every n milliseconds for a multitasking looping technique
  • Animating objects by moving and resizing them

Animating a Box Across the Screen

This next example demonstrates how to move an object across the screen. It uses the timer event and the position property to move a box across the screen. When the Box object has reached the other side, it starts over.

Step By Step
  1. Create a new form with a box measuring approximately one-inch by one-inch (see Figure 17-7).
  2. Figure 7: Setup form for the example

  3. Add lines 3 and 4 to the Var window of the box.
  4. 1: ;Box :: Var
    2: Var
    3: posPt Point
    4: x,y LongInt
    5: endVar

  5. Add lines 3–6 to the open event of the box.
  6. 1: ;Box :: open
    2: method open(var eventInfo Event)
    3: self.setTimer(100)
    4: posPt = self.position
    5: x = posPt.x()
    6: y = posPt.y()
    7: endMethod

  7. Add lines 3–7 to the timer event of the box.
  8. 1: ;Box :: timer
    2: method timer(var eventInfo TimerEvent)
    3: x = x + 50
    4: self.position = Point(x, y)
    5: if x > 5800 then
    6: x = 200
    7: endIf
    8: endMethod

  9. Check your syntax and run the form. The pull-down menus still work even though the code is executing (see Figure 17-8).

Figure 8: Demonstration of animating a UIObject

In step 3, line 3 starts the timer so that the code will execute 10 times a second (100/1000 = 10). Line 4 from step 2 declares posPt as a point variable so that you can get the position of the box in line 3. Line 4 in step 2 declares x and y long integers to store the values in lines 5 and 6 of step 3.

Line 3 in step 4 increments x by 50 for use in line 4 to move the box horizontally to the right by 50 twips. Lines 5 and 6 check whether the box has traveled as far to the right as you want. If it has, line 6 repositions it to the left.

You can have a lot of fun animating your forms with timers. As an exercise, add objects to this form. You could even introduce a random moving of objects. Timers have two basic uses: for timed events and for multitasking. Use timers when you need to execute a set of commands repeatedly, or when you need to multitask one task with another.

Looping with a Timer

Suppose that you want to enable a user to continue using his or her computer during a while loop that will take a long time to complete. To do this, you need to return control to Windows 95 or Windows NT. You won’t see function calls in ObjectPAL that are equivalent to WaitMessage in the Windows SDK. How do you handle this situation? Because it’s part of the Windows API, you can call WaitMessage directly. To do this, declare it in a Uses statement and call it. There are, however, two better and easier techniques.

You can use two techniques, depending on how much control you want to give back to Windows. You can insert a sleep() statement in your while loop, which yields to Windows events. Depending on how complicated the while loop is, this might give you enough of a yield. You can add more sleep() statements to your code, or you can recode it to use the built-in timer event.

Set a timer event on a UIObject to fire every x milliseconds. You set x. Then, place one iteration of the while loop on the timer event. The iteration of the loop will process. You can vary how much you do on each timer event; a single iteration is the simplest example. Of course, you’ll remove the while statement because the timer event controls the repetitive processing.

Example of Looping with Timers

Suppose that you want to add three fields to a form that count up while still enabling users to use the form and Windows. You can use this technique to create loops that enable users to continue their work. In this example, you set up three independent loops that use timers and three buttons that control the three loops as a set. The first button starts the looping process. The second button causes the three loops to pause. The third button kills all three loops. To show that these three loops are multitasking, you add a table frame connected to a table. That way, you can add records while the three loops count.

Step By Step
  1. Set your working directory to Paradox’s Samples directory. Create a new form, based on the Customer table, and add three buttons on it. Label the buttons Start Timers, Pause Timers, and Kill Timers. Add three unlabeled undefined fields. Name them Field1, Field2, and Field3. Figure 17-9 shows how the form should look. In this figure, the three undefined fields and font sizes have been enlarged, and most of the columns have been deleted from the table frame.
  2. Figure 9: Setup form for the looping with timers example

  3. Type line 3 in the Var window of the form.
  4. 1: ;Form :: Var
    2: Var
    3: Counter1, Counter2, Counter3 SmallInt
    4: endVar

  5. Type lines 3–5 in the open event of the page.
  6. 1: ;Page :: open
    2: method open(var eventInfo Event)
    3: Counter1 = 0
    4: Counter2 = 0
    5: Counter3 = 0
    6: endMethod

  7. Add lines 3–10 to the timer event of the Field1 field.
  8. 1: ;Field :: timer
    2: method timer(var eventInfo TimerEvent)
    3: if Counter1 < 100 then
    4: Counter1 = Counter1 + 1
    5: self = Counter1
    6: else
    7: Counter1 = 0
    8: self = 0
    9: self.killTimer()
    10: endIf
    11: endMethod

  9. Add lines 3–10 to the timer event of the Field2 field.
  10. 1: ;Field :: timer
    2: method timer(var eventInfo TimerEvent)
    3: if Counter2 < 200 then
    4: Counter2 = Counter2 + 1
    5: self = Counter2
    6: else
    7: Counter2 = 0
    8: self = 0
    9: self.killTimer()
    10: endIf
    11: endMethod

  11. Add lines 3–10 to the timer event of the Field3 field.
  12. 1: ;Field :: timer
    2: method timer(var eventInfo TimerEvent)
    3: if Counter3 < 1000 then
    4: Counter3 = Counter3 + 1
    5: self = Counter3
    6: else
    7: Counter3 = 0
    8: self = 0
    9: self.killTimer()
    10: endIf
    11: endMethod

  13. Add lines 3–5 to the pushButton event of the Start Timers button.
  14. 1: ;Button :: pushButton
    2: method pushButton(var eventInfo Event)
    3: field1.setTimer(1000)
    4: field2.setTimer(250)
    5: field3.setTimer(50)
    6: endMethod

  15. Add lines 3–5 to the pushButton event of the Pause Timers button.
  16. 1: ;Button :: pushButton
    2: method pushButton(var eventInfo Event)
    3: field1.killTimer()
    4: field2.killTimer()
    5: field3.killTimer()
    6: endMethod

  17. Add lines 3–13 to the pushButton event of the Kill Timers button.

1: ;Button :: pushButton
2: method pushButton(var eventInfo Event)
3: field1.killTimer()
4: Counter1 = 0
5: Field1 = 0
6:
7: field2.killTimer()
8: Counter2 = 0
9: Field2 = 0
10:
11: field3.killTimer()
12: Counter3 = 0
13: Field3 = 0
14: endMethod

  1. Check the syntax, save the form as LOOP-T.FSL, and run the form. Click the Start Timers button and let it run a while. All three loops run at different speeds. You can use this effect to prioritize tasks. Click on the Pause Timers button; all three loops pause. When you click the Start Timers button a second time, the loops continue from where they paused. Now, use the table frame. For example, scroll up and down a few records, insert a record, and so on. Click the Kill Timers button to stop and reset all three loops. Figure 17-10 shows how the form should look after you finish this example.

Figure 10: Using timers to create multitasking

In step 2, line 3 declares the three variables used in the three timers.

In step 3, lines 3–5 initialize the variables declared in step 2 line 3 when the form is opened.

Except for the number of times that the timers loop, the three timers are the same. In step 4, line 3, the first loop checks whether the counter variable is less than 100. If it is, line 4 increments it by 1. Line 5 sets the value of self to the value of the counter variable. This shows progress through the loop; normally, you would do something more productive. If the counter variable in line 3 isn’t less than 100, line 7 sets it to 0. Line 8 sets the value of the field to 0 to indicate visually that the loop is over. Line 9 destroys the timer.

In step 7, lines 3–5 on the Start Timer button start the looping process. They dictate which loop has priority—that is, the loop speed. Line 3 sets the first timer to fire once every second and starts it. Line 4 sets the second timer to fire once every quarter second and starts it. Line 5 sets the third timer to fire once every one-twentieth of a second and starts it.

In step 8, lines 3–5 on the Pause Timer button kill the timers but don’t reset the counter variables. This enables the three loops to pause and restart.

In step 9, lines 3–13 kill and reset the timers, counter variables, and field values. Using timers to multitask and pause loops is an important technique. It often will come in handy.

Summary

In this chapter, you learned that ObjectPAL offers tremendous flexibility in manipulating and creating UIObjects during run time. You learned that the form itself is both a display manager and a UIObject—it has events and responds to events. You can create, move, size, and generally change any property of a UIObject. You need to know about things such as points and twips. A point has a x value and a y value, both of which are measured in twips. Most ObjectPAL properties that manipulate size are in twips, not pixels. A twip is what you use to measure points on the screen.

The ObjectPAL language gives you the capability to dereference objects and use timers. You can either directly refer to a UIObject or attach to it and refer to it with the UIObject variable. Referencing objects without hard-coding their names in the application adds flexibility to your routines. Timers in ObjectPAL offer a powerful way to manipulate your environment. Timers have two basic uses: for timed events and for multitasking. Use timers when you need to execute a set of commands repeatedly, or when you need to multitask one task with another.


Comments

0 Comments.
Share a thought or comment...
 
Write a Comment...
...
Sign in...

If you are a member, Sign In. Or, you can Create a Free account now.


Anonymous Post (text-only, no HTML):

Enter your name and security key.

Your Name:
Security key = P1267A1
Enter key:
Article Contributed By Mike Prestwood:

Mike Prestwood is a drummer, an author, and creator of the PrestwoodBoards online community. He is the President & CEO of Prestwood IT Solutions. Prestwood IT provides Coding, Website, and Computer Tech services. Mike has authored 6 computer books and over 1,200 articles. As a drummer, he maintains play-drums.com and has authored 3 drum books. If you have a project you wish to discuss with Mike, you can send him a private message through his PrestwoodBoards home page or call him 9AM to 4PM PST at 916-726-5675 x205.

Visit Profile

 KB Article #100212 Counter
11114
Since 4/2/2008
Go ahead!   Use Us! Call: 916-726-5675  Or visit our new sales site: 
www.prestwood.com


©1995-2025 Prestwood IT Solutions.   [Security & Privacy]