Maximizing VFP's IntelliSense with a Shared Management Tool 

This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.

Maximizing VFP's IntelliSense with a Shared Management Tool

Dominic F. X. White

The IntelliSense Manager is both powerful and complex. By employing a customized IntelliSense management tool, you can increase your development productivity through creating and sharing functions located in the Foxcode.DBF. Here, Dominic White demonstrates an example of a custom IntelliSense Manager.

The IntelliSense Manager (ISM) allows you to improve your development productivity by enabling you to store customized commands, functions, and scripts in the FoxCode table. The ISM is easily accessible through the Tools menu, and is relatively painless to use. The FoxCode object enhances your programming by completing text, displaying ToolTips, and running tasks. By adding your own entries into the FoxCode table, you reduce repetitive tasks and increase your programming speed.

IntelliSense Manager overview

In this article, I'll discuss three of the eight possible record types within the FoxCode table. The first record type is the command record. In its simplest form, the command record is an auto-complete tool that's enacted by the space character. For example, you can create a command that would expand "BL" to "Browse Last" by entering data into the FoxCode table as shown here:

Type

Abbrev

Expanded

Case

C

BL

Browse Last

M

When you type "BL" in the command window, the FoxCode object automatically expands the entry to "Browse Last" once the space character is entered. A more advanced form of the command record may incorporate a command handler script to replace written text.

The second record type is the function record. The function record is activated by the "(" character and can be used to display tips and menus that correspond with the position within the function. For example, you can display tips for a program called MyProgram by entering data into the FoxCode table as illustrated here:

Type

Abbrev

Expanded

Tip

Case

F

MyProg

MyProgram

My Tip1,My Tip2

M

Immediately after you enter the "(" character following "MyProg", the FoxCode object replaces the text with the contents of the Expanded field and displays the contents of the Tip field.

The third record type is the script record. Script records contain code that can be used by other records within the FoxCode table. The typical script uses the FoxCode object to display lists with tips much like the list that's displayed after you type "SET" in the command window. The script record can also return values and customized tips. Moreover, you're able to specify the environment in which the script will be executed. I'll go over an example—the dommenu script—in detail later in the article.

The script records contained in the FoxCode database—cmdhandler, funcmenu—use the FoxCode2 table to determine the appropriate list constituents and tip text. You can view the associated FoxCode tables and code in the ...VFPSource\foxcode directory. The script records are referenced in the CMD field by the {} characters surrounding the script's name. With the combination of the text in the Tip and Data fields, the FoxCode object performs the procedures specified by the script in order to return one of the previously mentioned items.

For example, a command combined with a custom script record to return a static list requires two entries in the FoxCode table. Here's an illustration of the entries required for the command record; the code that follows is required in the Data field of the script record.

Type

Abbrev

Expanded

CMD

C

CARB

MyVar =

{myscript}

  LPARAMETER oFoxCode

With oFoxCode
  .ValueType = "L"
  Dimension .items[3,2]
  .items[1,1] = '"Apple"'
  .items[1,2] = "This is an Apple"
  .items[2,1] = '"Orange"'
  .items[2,2] = "This is an Orange"
  .items[3,1] = '"Pear"'
  .items[3,2] = "I don't like pears!"
  Return AllTRIM(.Expanded)
EndWith

After you type "CARB" and press the spacebar, a list will appear following the text from the Expanded field of the command record. If you move down the list, you'll notice the tip to the right that displays the second column of the array defined in MyScript. Although a static list may not be that useful, a dynamic list combined with a Shared IntelliSense Manager (SISM) improves your programming efficiency by providing you with updated list entries and tips that are accessible to other developers.

Introduction to the Shared IntelliSense Manager

In an environment with many utility programs and multiple developers, I found it necessary to expand the capabilities of the incumbent IntelliSense Manager. The shared management tool allows you to direct the FoxCode object to the path of your choice (see Figure 1). By doing so, other developers (so long as they have access to the directory) are able to copy public FoxCode records to their own PC's FoxCode table. Sharing the FoxCode records with other developers reduces duplicity and increases your group's development productivity.

The SISM requires three tables: MenuItems, Custom_Script, and List_Script. The MenuItems table is similar in structure and function to the FoxCode2 table, as it provides list constituent data along with corresponding tip data to the dommenu script. The Custom_Script table is the public equivalent of the FoxCode table and is used to publish available functions. Finally, the List_Script table is used by the SISM to distinguish between single-entry and shared records in the Custom_Script table. All together, the aforementioned tables are the backbone of the SISM.

After you run the program for the first time, a text file containing the default path for the three SISM tables is created (see the following code) in the Home(7) directory. As I previously mentioned, you're able to change the backbone directory by clicking the Change Directory button that's located on the first pane of the SISM form.

  *txt file stores dir info
IF !FILE(HOME(7)+'D_LOCAT.TXT')
  nHandle = FCREATE(HOME(7)+'D_LOCAT.TXT')
  cStr = HOME(7)
  =FWRITE(nHandle,cStr)
  =FCLOSE(nHandle)
ELSE
  nHandle = FOPEN(HOME(7)+'D_LOCAT.TXT')
  nSize = FSEEK(nHandle, 0, 2)
  =FSEEK(nHandle, 0, 0)
  cStr = FREAD(nHandle,nSize)
  =FCLOSE(nHandle) 
ENDIF

After the default path is written and the Custom_Script table is produced, the dommenu script is to the table. The dommenu script (see Listing 1) combines the FoxCode object, GetList procedure, and MenuItems table to return lists and/or tips to the programming environment.

Listing 1. The dommenu script.

  LPARAMETER oFoxcode
LOCAL eRetVal, loFoxCodeLoader, nHandle,;
  nSize, cStr
IF FILE(_CODESENSE)
  IF FILE(HOME(7)+'D_LOCAT.TXT')
    nHandle = FOPEN(HOME(7)+'D_LOCAT.TXT')
    nSize = FSEEK(nHandle, 0, 2)
    =FSEEK(nHandle, 0, 0)
    cStr = FREAD(nHandle,nSize)
    =FCLOSE(nHandle)
  ELSE
    RETURN
  ENDIF 
  SET DELETED ON
  SET PROCEDURE TO (_CODESENSE) ADDITIVE
  loFoxCodeLoader = CreateObject("FoxCodeLoader")
  eRetVal = loFoxCodeLoader.Start(m.oFoxCode)
  loFoxCodeLoader = NULL
  IF ATC(_CODESENSE,SET("PROC"))#0
    RELEASE PROCEDURE (_CODESENSE)
  ENDIF
  RETURN m.eRetVal
ENDIF

DEFINE CLASS FoxCodeLoader as FoxCodeScript
  PROCEDURE Main()
    LOCAL lnParmNum,lcLookupCode,lcItem,lnPos,lnLines,i
    LOCAL aTmpData, aParmData, lcType
    lcItem = THIS.oFoxcode.menuitem
    DIMENSION aTmpData[1]
    DIMENSION aParmData[1,3]
    STORE "" TO aParmData
    lnLines = ALINES(aTmpData,ALLTRIM(THIS.oFoxCode.data))
    FOR i = 1 TO lnLines
      IF ISDIGIT(aTmpData[m.i])
        lnParmNum = ;
          VAL(ALLTRIM(GETWORDNUM(aTmpData[m.i],1,",")))
        lcLookupCode = ;
          ALLTRIM(GETWORDNUM(aTmpData[m.i],2,","))
        lcType = ALLTRIM(GETWORDNUM(aTmpData[m.i],3,","))
        IF !EMPTY(lcLookupCode)
          IF !EMPTY(aParmData)
            DIMENSION aParmData[ALEN(aParmData,1)+1,3]
          ENDIF
          aParmData[ALEN(aParmData,1),1] = lnParmNum
          aParmData[ALEN(aParmData,1),2] = lcLookupCode
          aParmData[ALEN(aParmData,1),3] = lcType
        ENDIF
      ENDIF
    ENDFOR
    lnPos=ASCAN(aParmData,THIS.oFoxCode.paramnum+1,-1,-1,1)
    IF lnPos>0
      IF aParmData[lnPos+2]="T"
        * Display parameter tip
        THIS.GetCmdTip(aParmData[lnPos+1],"F")
      ELSE 
        * Display parameter menu
        IF THIS.GETLIST(aParmData[lnPos+1])
          THIS.oFoxCode.ValueType='L'
          RETURN ALLTRIM( THIS.OFOXCODE.EXPANDED)
        ENDIF
      ENDIF
      RETURN ""
    ENDIF
    THIS.oFoxCode.valuetype='V'
    RETURN THIS.AdjustCase()
  ENDPROC

  PROCEDURE GETLIST( tcKEY )
    LOCAL llRETVAL
    LOCAL ARRAY laTEMP[1]
    *GET MATCHING RECORDS FROM THE MENU LIST
    IF USED('MENUITEMS')
      SELECT('MENUITEMS')
      USE
    ENDIF
    SELECT 0
    SET DELETED ON
    USE cStr+"MENUITEMS"
    STORE 0 TO _TALLY
    SELECT ALLTRIM(MENUITEM),menutip ;
      FROM menuitems ;
      INTO ARRAY laTEMP;
      WHERE ALLTRIM(key) = UPPER(tcKEY);
      ORDER BY KEY2
    *SET THE RET VAL AND CLOSE THE TABLE
    STORE (_TALLY > 0) TO llRETVAL
    USE IN MENUITEMS
    IF llRETVAL
      *POPULATE THE FOXCODE ITEM ARRAY
      DIMENSION THIS.OFOXCODE.ITEMS[_TALLY,2]
      ACOPY( laTEMP, THIS.OFOXCODE.ITEMS )
    ENDIF
    RETURN llRETVAL
  ENDPROC
ENDDEFINE

The code in Listing 1 is similar to the funcmenu2 script. The difference is the GetList procedure, which directs the FoxCode object to the MenuItems table rather than the FoxCode2 table. To do so, the laTemp array is populated with records from the MenuItems table and copied to the oFoxCode.Items array.

Creating a custom function with the SISM

In order to demonstrate the SISM, copy the code from the D_GoIE procedure from the main program into a new program with the same name. Start the SISM and select the Customize pane. After you enter the function's data, the end result should look similar to Figure 2.

The Main Tip is the default display that appears as you move through the function parameters if there are no custom menus or tips in place. For clarity, I recommend including the parameter's type enclosed in brackets—"[ ]"—after each subsequent parameter tip. You may find it necessary to include a custom tip for a specific parameter. I recommend naming the custom tip—in the Edit box—the same as the function along with the number of the parameter. It's important to keep the names exclusive in order to prevent errors within the dommenu script.

After you've entered the tip, select the List box and enter the name of the list in the Edit box using the previously described naming convention, and make sure to set its parameter placement to 2. The Menu Items box correlates menu options and their tips with the selected list in the List box. Although the menu items don't require a specific naming convention, they're values that will be returned by the FoxCode object: Be sure to enter a string as a string.

The next step is to add the function records to your local FoxCode table. To add the records, first select the Management pane (see Figure 3). After you select the function from the combo box, the related functions and scripts—in this case D_GoIE1 and dommenu—appear in the Related Functions and Scripts box. The list will confirm the proper recording of the function's associated tips and/or lists. After clicking the Add button, verify that the records have been added to your local FoxCode table by selecting the Status pane. You should see the D_GoIE function in the Current Custom Functions box.

To test the D_GoIE function, type D_GOIE( in the command window. The FoxCode object will display the custom tip as illustrated in Figure 4.

After you enter the Web address as a string, the FoxCode object will display the custom list along with its corresponding tips (see Figure 5).

Conclusion

The usefulness of the incumbent IntelliSense Manager is limited by its lack of portability and lack of programming ease. A shared IntelliSense management tool, however, eliminates duplicity and increases development productivity by allowing you to share FoxCode table records with other developers. Moreover, the SISM simplifies FoxCode record entry and management by allowing you to create and modify tips and/or lists within a form rather than manually entering records in the FoxCode table.

Download 312WHITE.ZIP

To find out more about FoxTalk and Pinnacle Publishing, visit their Web site at http://www.pinpub.com/

Note: This is not a Microsoft Corporation Web site. Microsoft is not responsible for its content.

This article is reproduced from the December 2003 issue of FoxTalk. Copyright 2001, by Pinnacle Publishing, Inc., unless otherwise noted. All rights are reserved. FoxTalk is an independently produced publication of Pinnacle Publishing, Inc. No part of this article may be used or reproduced in any fashion (except in brief quotations used in critical articles and reviews) without prior consent of Pinnacle Publishing, Inc. To contact Pinnacle Publishing, Inc., please call 1-800-788-1900.

© Microsoft Corporation. All rights reserved.