INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Developer Tools

Integrating FoxSpell with VFP Applications by GriffMG
Posted: 19 Jan 05

FoxSpell is a wholly VFP source code based spelling checker, developed by David Elliot Lewis PHD and available from Hallogram. It may also be available from StrategicEdge, but, at the time of writing, no web site could be found to match that address.

In order to write this FAQ, I've tried not to show the copyrighted code - if you want it, buy it - and restricted myself to showing the activation of the spellchecker by a command button.

The software is currently supplied by e-mail in two zip files:

ACAWORDS.ZIP
FS_VFP.ZIP

The first contains an alternative (larger) dictionary, the second contains the source code, a few forms and a smaller more manageable dictionary.

My first suggestion is to create a folder for the original source code and extract all the files there - including unzipping the smaller dictionary to create the three WORDSn.DBF files.

From here, the docmentation that comes with FoxSpell makes it pretty simple to get your first project up and running... but before you go ahead and do that, here are a few thoughts for you:

For distributing the dictionary files, I would recommend that you use a free table included within your project, call it BINARIES and give it a structure like the one below:

You can create the table by clicking on the 'free tables' branch on the project manager, under the data tab, save the completed table into your project development folder.

CODE

Field   Field Name       Type               Width    Dec  Index   Collate  Nulls
1        NAME            Character          10                             No
2        BINARY          Memo (binary)       4                             No

Browse the new table and append one record to it for each of the dictionary files, replacing the NAME field in each case with the name of the file, and using a FILETOSTR call to replace the BINARY field with the entire contents of the dictionary.

CODE

APPEND BLANK
REPLACE NAME WITH "WORDS1", BINARY WITH FILETOSTR("C:\DEV\MYPROJECT\WORDS1.DBF")

I've been using this approach for a while now to distribute sound files, FBZIP.EXE and other files which I don't need users to know about, but need to be 'resupplied' or 'updated' on demand from time to time.

Having created the table, and made doubly sure that it has been included in the project, I would suggest that you modify your existing projects source code to test for the presence of the three files on loading (placing them somewhere appropriate to your application) and should they not exist extract them from the BINARIES table and create the indexes for them.

Note here that you would be better off NOT using the built-in VFP FILE() function, as it can be confused by finding files of a similar name anywhere in the current 'PATH' setting!

I use a UDF called MyFile() (code below)

CODE

FUNCTION MYFILE
    PARAMETER m.FILENAME
    PRIVATE m.FILENAME,m.FLG
    M.FLG = .F.
    IF !EMPTY(m.FILENAME)
        IF ADIR(TMPDIRFILES,m.FILENAME) > 0
            M.FLG = .T.
        ENDIF
    ENDIF
    RETURN(m.FLG)

This is probably not the most elegant of approaches, but it works for me.

To extract and index the dictionary files, you could use code like that below:

CODE

public m.DOCLOCATION,m.CCAPTION
m.DOCLOCATION = "P:\PROJECTLIST\"
m.CCAPTION = ""

IF !MYFILE(m.DOCLOCATION+"WORDS1.DBF")
    SELECT 0
    USE ("C:\DEV\MYPROJECT\BINARIES")
    LOCATE FOR BINARIES.NAME = "WORDS1"
    STRTOFILE(BINARIES.BINARY,m.DOCLOCATION+"WORDS1.DBF")
    USE
    USE (m.DOCLOCATION+"WORDS1.DBF") EXCLUSIVE
    DELETE TAG ALL
    INDEX ON WORD TAG TEXT
    INDEX ON SOUNDEX(WORD) TAG SOUND
    USE
ENDIF

IF !MYFILE(m.DOCLOCATION+"WORDS2.DBF")
    SELECT 0
    USE ("C:\DEV\MYPROJECT\BINARIES")
    LOCATE FOR BINARIES.NAME = "WORDS2"
    STRTOFILE(BINARIES.BINARY,m.DOCLOCATION+"WORDS2.DBF")
    USE
    USE (m.DOCLOCATION+"WORDS2.DBF") EXCLUSIVE
    DELETE TAG ALL
    INDEX ON WORD TAG TEXT
    INDEX ON SOUNDEX(WORD) TAG SOUND
    USE
ENDIF

IF !MYFILE(m.DOCLOCATION+"WORDS3.DBF")
    SELECT 0
    USE ("C:\DEV\MYPROJECT\BINARIES")
    LOCATE FOR BINARIES.NAME = "WORDS3"
    STRTOFILE(BINARIES.BINARY,m.DOCLOCATION+"WORDS3.DBF")
    USE
    USE (m.DOCLOCATION+"WORDS3.DBF") EXCLUSIVE
    DELETE TAG ALL
    INDEX ON WORD TAG TEXT
    INDEX ON SOUNDEX(WORD) TAG SOUND
    USE
ENDIF

Note in the above example, the reference to C:\DEV\MYPROJECT\BINARIES will need to be changed to point to the original location of your BINARIES.DBF free table.
Also note that m.DOCLOCATION is a public variable holding the path to where you want to store the dictionaries.
By indexing the files after creating them, you save a lot of space in your deliverable executable.

You could/should check for and/or create the folder specified in m.DOCLOCATION before atempting to copy the files there:

CODE

IF !DIRECTORY(m.DOCLOCATION)
    MD (m.DOCLOCATION)
ENDIF

I can't speak for anyone else, but most of the applications I develop support the creation of a number of databases (call them companies, projects, locations or whatever) each
able to exist in complete isolation from one another - i.e. apart from a bit of shared set-up libraries (which can diverge later) there is no cross-linking between databases. This environment, combined with the ability for more than one machine to share a LIST of databases for a given application, provides an opportunity to store the dictionary files in the same place as the list (if you follow me).

Having created the code for extracting the dictionaries, we can look to the rest of the installation.

You need to include just three forms in your project for FoxSpell:

CODE

fs_ad2_d.scx
fs_del.scx
fs_main.scx

And, in practice just one piece of source code:

CODE

fs_spell.prg

I would recommend modifying the three forms slightly, to include your own project icon on each one and to put the following code close to the beginning of the INIT method of FS_MAIN.SCX (just after the 'private' statements works well).

CODE

    IF TYPE("M.cCaption") = "C"
        THISFORM.CAPTION = m.CCAPTION
    ENDIF

This tests for the existence of a (public) variable m.CCAPTION on loading - enabling you to control the forms caption when spell checking (to indicate which field is being checked for example).

The only other modification to the FoxSpell code I would suggest is to the bit opening the dictionaries on loading, this is contained in the FS_SPELL.PRG file and is near the beginning - you can identify the section by the snippet I've included below:

CODE

    * Created dictionary indexes, if missing------------------------------------- *
    * Open/select the dictionaries----------------------------------------------- *
    IF USED("WORDS1")  && If spelling dictionary #1 isn't open, then open it.
        SELECT WORDS1
    ELSE
        SELECT 0
        USE (m.DOCLOCATION+"WORDS1")
    ENDIF
    SET ORDER TO TAG TEXT

    IF USED("WORDS2")  && If spelling dictionary #2 isn't open, then open it.
        SELECT WORDS2
    ELSE
        SELECT 0
        USE (m.DOCLOCATION+"WORDS2")
    ENDIF
    SET ORDER TO TAG TEXT

    IF USED("WORDS3")  && If spelling dictionary #3 isn't open, then open it.
        SELECT WORDS3
    ELSE
        SELECT 0
        USE (m.DOCLOCATION+"WORDS3")
    ENDIF
    SET ORDER TO TAG TEXT
    * --------------------------------------------------------------------------- *

    * If checking a file, then open it------------------------------------------- *

If you replace everything from

CODE

* Created dictionary indexes, if missing------------------------------------- *
 to

CODE

* If checking a file, then open it------------------------------------------- *

With the snippet above you will be relying on the code in your existing application to extract and index the dictionaries and the FS_SPELL.PRG program to find and use them.

Now you are ready to implement a spell check!

Select a form with a text or edit box that has text that needs checking, for the purposes of this exercise we'll assume the field is called COMMENTS.

Add a command button with no caption to the form and find yourself a nice spellcheck bitmap to place on it as a picture - there are dozens available on the internet for free download - then put the following code in the buttons CLICK procedure:

CODE

    PRIVATE m.STRING
    M.STRING = THISFORM.COMMENTS.VALUE
    M.CCAPTION = "Checking Spelling in 'Comments'"
    IF FS_SPELL("",@m.STRING,.T.)
        IF m.STRING <> THISFORM.COMMENTS.VALUE
            THISFORM.COMMENTS.VALUE = m.STRING
            THISFORM.COMMENTS.SETFOCUS
        ENDIF
    ENDIF

This will result in, when the button is clicked, the contents of the forms comments edit box being copied to a variable, a caption being set-up and the spellchecker being invoked.
Should the resultant string differ from the original, it is used to replace the contents of the edit box, and focus set to it (to force any valid or lostfocus events).

Simple as that.

The author provides a bunch of useful features, for importing text files and spell checking whole tables or files, if I use them - I'll try and write another FAQ!


Back to Microsoft: Visual FoxPro FAQ Index
Back to Microsoft: Visual FoxPro Forum

My Archive

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close