Paradox Community
Search:

 Welcome |  What is Paradox |  Paradox Folk |  Paradox Solutions |
 Interactive Paradox |  Paradox Programming |  Internet/Intranet Development |
 Support Options |  Classified Ads |  Wish List |  Submissions 


Paradox Programming Articles  |  Beyond Help Articles  |  Tips & Tricks Articles  


Internal Shortcuts
© 2002 JD Adams

The files referenced in this article are available as a download.

Preface

One problem I have seen in companies which have different Paradox applications on different working directories is that routine users, many of which are computer illiterate or barely literate, find it difficult to maneuver around between these applications. Also, sometimes an application has different opening screens for different people. The most common way they have dealt with it is to put different icons on each person's desktop, each opening Paradox to a different location. This is cumbersome, and is annoying to the user since he has to shut down and re-open Paradox to move around. The other option is to teach all users how to change working directories, and which file to open for each application.


Introduction

I have found that it is easy to create a system to put shortcuts to the different applications in each person's Tools menu, customized to the individual. This allows the person to open the Tools menu, pick the application they want, and have Paradox move them there. The database administrator can create different shortcuts to go to each application, or multiple shortcuts to go to different parts of one application.


Components

There are 4 components to this system. One master table, one administration form, one user form, and a repeatable shortcut form (this last form is duplicated for each shortcut). There is an optional fifth component, an Alias form. The master table holds the location of the shortcut and its status. The administration form allows the DBA to add, edit and remove shortcuts, and change their status. The user form is what creates the shortcuts for the user, based on the contents of the master table. The shortcut form will move the user to the desired working directory and open the application. The optional Alias form just makes it easier to select aliases from the administration form. You will need a directory (it is best to keep it separate from other applications) with the alias :UPGRADE:.


Master Table

The master table has the following structure:

Key Field Type Size
* Shortcut A 20
  Path A 100
  File A 12
  Active A 1

You may give this table any name you want; I named it INTSHORT.DB. You may password protect it or not, as you desire; I gave it a Master password of "SELECT", and a read-only password of "shortcut".

The Shortcut field is the name of the shortcut that will be put into the Tools menu. You cannot use any special characters, but use of the ampersand (&) before a letter will make it a hotkey.

The Path field is the directory you wish to move to. It can be either and alias (:alias:), or a long path name (H:\Paradox\Coatsoc9\). I recommend using aliases whenever possible.

The File field holds the name of the shortcut form (minus the '.FSL') to activate. I find it easiest to name all of these the same, using numbers to differentiate between different shortcuts on the same working directory. I use the form name SCUTx.FSL, where the x represents the number of the shortcut (first one made is SCUT1, the second is SCUT2, etc.).

The Active field is just a Y/N field. Any record marked "Y" in this field will have its shortcut added when the user runs the user form; all others will be skipped.

The table should start out with one record, to put the 'Add New Shortcuts' shortcut into the Tools menu, with the path being :UPGRADE:, and the File being 'AddNew'. Always keep this Active field at Y, so it always goes to all users.


Administration Form

I have named this form NEW.FSL. It is linked to IntShort.DB, with a tableframe to show the shortcut names, fields for the Path and File, and a check box for Active. There are 2 buttons; one to add a new shortcut, and one to quit. The 'DONE' button removes all passwords and closes the form. The 'Add New' button gets the information on the new shortcut, verifies it, then puts the shortcut in. The code shown here assumes use of the optional Alias form.
method pushButton(var eventInfo Event)
var
  tc    TCursor
  nam1  String
  path1 String
  frm1  String
  frm   Form
  n1    SmallInt
endvar

nam1 = ""

;  assume that most paradox applications are on a network directory H,
;  under the subdirectory Paradox.

nam1.view("Shortcut:")
if nam1.size() > 20 then
  msginfo("Too long","Max size is 20 characters.")
  return
endif

if msgQuestion("Path","Will the path call for an alias?") = "Yes" then
  enumAliasNames(":priv:alias.db")

  tc.open(":priv:alias.db")
  tc.edit()
  tc.home()
  path1 = "PRIV"
  if tc."DBPath" = "" then      ; remove the blank line generated
    tc.deleteRecord()
  endif
  if tc.locate("DBPath",path1) then   ; remove the Private directory as an option
    tc.deleteRecord()
  endif
  tc.endedit()
  tc.close()

  frm.open(":Upgrade:ALIAS")
  path1 = String(frm.wait())
  try
    frm.close()
  onFail
    errorClear()
  endtry

  path1 = ":" + path1 + ":"
else
  path1 = "H:\\PARADOX\\"
  path1.view("Path:")
  n1 = path1.size()
  if path1.substr(n1,1) <> "\\" then    ; put the backslash at the end of the path
    path1 = path1 + "\\"                ; if not already typed in
  endif
endif

frm1 = "SCUT"
frm1.view("Form:")
if not isFile(path1+frm1+".fsl") then
  msgstop("ERROR",path1+frm1+".fsl  does not exist!")
  if msgQuestion("Verify","Use Anyway?") = "No" then
    return
  endif
endif

if msgQuestion("Verify",nam1 + "\n"+path1+frm1+".fsl") = "No" then
  return
endif

tc.open(":Upgrade:INTSHORT.DB")
if tc.locate("Shortcut",nam1) then  ; check to see if there is already a shortcut by that name
  msginfo("Already exists",
          "This shortcut already exists for the form " + tc."Path" + tc."File" + ".FSL")
  tc.close()
  locate("Shortcut",nam1)
  return
endif
if tc.locate("Path",path1,"File",frm1) then   ; check to see if there is already a shortcut
                                              ; with that path under a different name
  nam1 = tc."Shortcut"
  msginfo("Already exists","This shortcut already exists with the name "+nam1)
  tc.close()
  locate("Shortcut",nam1)
  return
endif

tc.edit()
tc.insertRecord()
tc."Shortcut" = nam1
tc."Path" = path1
tc."File" = frm1
tc."Active" = "Y"
tc.endedit()
tc.close()
locate("Shortcut",nam1)
endMethod
The shortcut can be turned on and off by toggling the Active field. If this field is checked, anyone running the Add New Shortcuts will get this shortcut.


User Form

This form has all of its code embedded in the Open method of the page, and is set to run whenever anyone hits the 'Add New Shortcuts' under the Tools menu (or when manually done when Paradox is installed). I have named the form AddNew.FSL. The code is:
method open(var eventInfo Event)
var
  tc TCursor
  x  LongInt
  n  SmallInt
endvar

addPassword("shortcut")
tc.open(":UPGRADE:INTSHORT.DB")
x = tc.nRecords()
tc.home()

; NOTE: if using v8 or v9 of Paradox, substitute 8.0 or 9.0 for 10.0
; in the setRegistryValue lines below
; this first part just puts a separator line in the menu
if not setRegistryValue("Software\\COREL\\PARADOX\\10.0\\PXDLITE\\Tools",
                        "&ToolsSep",
                        "Separator",
                        regKeyCurrentUser) then
  ErrorShow()
endif

for n from 1 to x
  if tc."Active" = "Y" then
    if not setRegistryValue("Software\\COREL\\PARADOX\\10.0\\PXDLITE\\Tools",
                            tc.Shortcut,
                            tc.Path+tc.File+".FSL",
                            regKeyCurrentUser) then
      ErrorShow()
    endif
  endif
  tc.nextRecord()
endfor
tc.close()

removeAllPasswords()
msginfo("","Done.  Restart Paradox for changes to take effect.")
self.close()

endMethod

Shortcut Form

This form will change the working directory to wherever it is (thus closing any other objects currently open) while remaining open itself. It will then run whatever code you need to start up the desired application. Most commonly it will open a form or run a script, but it can do whatever you want. Because it won't change the working directory until all code in all open methods is done running, we can't put the code to start the application in any open method. Instead, I have the open method of the page set to start a timer for the page, with an interval of 1 millisecond, with the code to run the application in the timer method of the page. This way, 1 millisecond after the working directory is changed, the code runs. I also put a text box on the page, with its Visible property set to false. I put what that shortcut is used for and what it opens there, so I can tell what it is without looking at the code.

In the Open method of the form, I have this code:
method open(var eventInfo Event)
   var
     f       Form
     dynPath DynArray[] String
   endVar

   if eventInfo.isPreFilter() then
     ;// This code executes for each object on the form:
   else
     ;// This code executes only for the form:
     f.attach()
     splitFullFileName(f.getFileName(), dynPath)
     setWorkingDir(dynPath["Drive"] + dynPath["Path"])
   endIf

endmethod
To keep the form open during the change of working directory, in the MenuAction method of the form, I have this code:
method menuAction(var eventInfo MenuEvent)

const
  kKeepFormOpen = UserMenu   ; UserMenu is an ObjectPAL constant.
endConst                     ; Any nonzero value keeps the form open.

   if eventInfo.isPreFilter() then
     ;// This code executes for each object on the form:
     if eventInfo.id() = MenuChangingWork then
       eventInfo.setErrorCode(kKeepFormOpen)
     endIf
   else
     ;// This code executes only for the form:
   endIf

endmethod
In the Open method of the page, I have this code:
method open(var eventInfo Event)
  self.setTimer(1)
endMethod
In the Timer method of the page, this is an example of a common use of this system:
method timer(var eventInfo TimerEvent)
var
  frm   Form
endvar

frm.open("{form name}")
self.close()

endMethod
This last can also add passwords, run scripts, or do whatever else you need on startup.


Example Situation

Suppose a company has 3 Paradox applications. First, an attendance application with 3 parts: one for the workers to input their hours and get their work history, another for the supervisors to review and approve hours, query work histories and other data, and a final part for Human Resources to process payroll and perform administrative functions. Second, a requisition system with 2 parts: one for the employees to submit their requests, and another part for the Purchasing department to process the requests. And third, a product system to allow only production personnel to review and edit production run conditions.

In this case, 6 shortcuts would be needed. They are:

Directory Shortcut Purpose Who gets it
Attendance Attendance Fill in hours given to all employees
Attendance Sup. Attendance Supervisor Functions given only to supervisors
Attendance HR Attendance HR Functions give only to HR department
Requisition Requisition Submit requests give to everybody
Requisition Process Requests Process requisitions give to Purchasing only
Products Formulas and SOCs Control Run conditions give to Production only

You will also have 2 permanent shortcuts: Add New Shortcuts, always set to Active = Y, and Shortcut Maint, which you set to Active = N after you give it to yourself.

You create and place SCUT1, SCUT2 and SCUT3 in the Attendance directory, each one pointing to the correct opening form, SCUT1 and SCUT2 in the Requisition directory, and SCUT1 in the Products directory.

Upon setting up a new computer with Paradox, since it doesn't have any shortcuts there yet, you would open the form :Upgrade:AddNew.FSL; this puts all shortcuts marked with Active = Y in the Tools menu. In this example, that would be Add New Shortcuts, Attendance, and Requisition. IT then takes the computer and has it ready to issue to a new employee.

The DBA gets a call that he is getting a computer ready for the new Human Resources Manager. Since he is both in HR and a Manager, you open Shortcut Maintenance, mark Sup. Attendance and HR Attendance as Active, then close Shortcut Maintenance. When IT lets you know that he has run Add New Shortcuts, you go back into Shortcut Maintenance and unmark those 2. The system is now ready for the default shortcuts again.

Now suppose you make a new system for Complaints, which would be available to everyone. After you finish creating the application on its own working directory, you create and place SCUT1 there, then go in to Shortcut Maintenance and add the shortcut, marking Active = Y. You can then send a quick e-mail to all users letting them know that if they want to get to the Complaint system, all they have to do is open Paradox, go to the Tools menu, and click Add New Shortcuts. Those people who would want it can get it, and those who don't need to won't have their menu cluttered by extra shortcuts.


Summary

By using this, you can get shortcuts to systems placed on each person's computer which are easy for any person to use, and are customizable as needed. If you need to add a shortcut, you can do it from your desk, and then have anybody who needs it get it for themselves. You can activate a shortcut, have it added, then deactivate it quickly so that other people don't get it.

This system works for all 32-bit applications of Paradox. I have found that it is invaluable for dealing with people of a wide range of computer abilities, with applications over a dozen working directories, many with multiple shortcuts.


Discussion of this article


 Feedback |  Paradox Day |  Who Uses Paradox |  I Use Paradox |  Downloads 


 The information provided on this Web site is not in any way sponsored or endorsed by Corel Corporation.
 Paradox is a registered trademark of Corel Corporation.


 Modified: 15 May 2003
 Terms of Use / Legal Disclaimer


 Copyright © 2001- 2003 Paradox Community. All rights reserved. 
 Company and product names are trademarks or registered trademarks of their respective companies. 
 Authors hold the copyrights to their own works. Please contact the author of any article for details.