Advisor Answers. January, Visual FoxPro 3.0 and 5.0

Similar documents
Give users a control that makes entering dates as easy as it is in Intuit Quicken.

Designing a Database -- Understanding Relational Design

Advisor Discovery. Use BindEvent() to keep things in synch. BindEvent() Refresher. June, By Tamar E. Granor, technical editor

Q: I've been playing with the Microsoft Internet Transfer Control (inetctls.inet.1) and it would be great if only it worked.

It Might Be Valid, But It's Still Wrong Paul Maskens and Andy Kramek

Advisor Answers. Create Cross-tabs. July, Visual FoxPro 9/8/7

Screenshots Made Easy

Linked Lists. What is a Linked List?

Advisor Answers. Match multiple items in a query. December, 2005 VFP 9/8/7

Taking Advantage of Idle Cycles. Make Your Application Work When the User Isn't. The Idea. The Strategy. December, 2003

Combos and Lists - The Forgotten Controls

This tool lets you specify a new name for each control on a form or class and fixes all code that uses it.

Working with the Registry. The Registry class makes it easy. The Registry Structure. January, By Tamar E. Granor

Formulas Learn how to use Excel to do the math for you by typing formulas into cells.

Working with Tables in Word 2010

their in the new a program such as Excel or Links aren't just document.

Microsoft Access 2016 Intro to Forms and Reports

Using Visual Studio.NET: IntelliSense and Debugging

Manage Your Applications Doug Hennig

This lesson is part 5 of 5 in a series. You can go to Invoice, Part 1: Free Shipping if you'd like to start from the beginning.

Introduction. Using Styles. Word 2010 Styles and Themes. To Select a Style: Page 1

PowerPoint Introduction. Video: Slide Basics. Understanding slides and slide layouts. Slide Basics

In our first lecture on sets and set theory, we introduced a bunch of new symbols and terminology.

Create your first workbook

Tracking changes in Word 2007 Table of Contents

Definition: A data structure is a way of organizing data in a computer so that it can be used efficiently.

A PROGRAM IS A SEQUENCE of instructions that a computer can execute to

Hello, and welcome to another episode of. Getting the Most Out of IBM U2. This is Kenny Brunel, and

Basic Fiction Formatting for Smashwords in OpenOffice L. Leona Davis. Copyright 2012 L. Leona Davis All Rights Reserved

Microsoft Excel 2013 Series and Custom Lists (Level 3)

PowerPoint Slide Basics. Introduction

The Stack, Free Store, and Global Namespace

Organizing your Outlook Inbox

Lesson 1. Importing and Organizing Footage using Premiere Pro CS3- CS5

MICROSOFT WORD 2010 BASICS

A File Open Dialog Box Doug Hennig

BEGINNER PHP Table of Contents

Customizing Access Parameter Queries

Watch the video below to learn more about number formats in Excel. *Video removed from printing pages. Why use number formats?

! Emacs Howto Tutorial!

and I want the subsets with three members, the result would be:

The Crypt Keeper Cemetery Software Online Version Tutorials To print this information, right-click on the contents and choose the 'Print' option.

Introduction. Table Basics. Access 2010 Working with Tables. Video: Working with Tables in Access To Open an Existing Table: Page 1

PROFESSOR: Well, now that we've given you some power to make independent local state and to model objects,

Copyright. For more information, please read the Disclosures and Disclaimers section at the end of this ebook. First PDF Edition, February 2013

M i c r o s o f t E x c e l A d v a n c e d P a r t 3-4. Microsoft Excel Advanced 3-4

Chart For Dummies Excel 2010 Title Link To Cell Value Into

Heads Up Design: Focusing on the drawing area

uilding Your Own Builders with BuilderB Doug Hennig and Yuanitta Morhart

Christmas Stocking Stuffers Doug Hennig

Indispensable tips for Word users

Let's start by taking a look at the object generated by LIST OBJECTS. I used the following code to put a few objects in memory for testing:

Below you'll find some browser and device specific instructions, as well as links to more expansive tutorials if you need them.


Supporting Class / C++ Lecture Notes

How to Improve Your Campaign Conversion Rates

Troubleshooting Maple Worksheets: Common Problems

Copyright 2004, Mighty Computer Services

Earthwork 3D for Dummies Doing a digitized dirt takeoff calculation the swift and easy way

Smart formatting for better compatibility between OpenOffice.org and Microsoft Office

Understanding And Using Custom Queries

How to create an eactivity on the Casio fx9860g

Simply Personnel Screen Designer

Understanding Business Objects, Part 1

The Mother of All TreeViews, Part 2 Doug Hennig

Tutorial: Bryce Instancing Without the Instancing Lab

Taking Control Doug Hennig

REVEL 3.0 Keyboard Accessibility Documentation for Students REVEL 3.0

CS102: Standard I/O. %<flag(s)><width><precision><size>conversion-code

Managing Files & Folders

Windows XP. A Quick Tour of Windows XP Features

REVEL 3.0 Android/Keyboard Accessibility Documentation for Students REVEL 3.0

Microsoft Office Training Skills 2010

Lesson 3 Transcript: Part 1 of 2 - Tools & Scripting

Getting Started with AnyBook

While you can always enter data directly into database tables, you might find it easier to use

You might already know that tables are organized into vertical columns and horizontal rows.

Ad Muncher's New Interface Layout

Excel Basics Rice Digital Media Commons Guide Written for Microsoft Excel 2010 Windows Edition by Eric Miller

SurveyToGo Scripting Best Practices

PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between

Post Experiment Interview Questions

Running Wordstar 6 on Windows 7 Using vdos

MITOCW watch?v=zm5mw5nkzjg

Laboratory 1. Part 1: Introduction to Spreadsheets

Try Thor s Terrific Tools, Part 2

Formal Methods of Software Design, Eric Hehner, segment 1 page 1 out of 5

PowerPoint Instructions

Session V-STON Stonefield Query: The Next Generation of Reporting

MITOCW ocw apr k

Here are all the comments that your Udacity Code Reviewer had about your code...

Browser Cookie Settings

FanBuzz Business-Enterprise-Create A New fan Page

Manually Setup Yahoo Mail Iphone 5 Can't >>>CLICK HERE<<<

Introduction. Opening and Closing Databases. Access 2010 Managing Databases and Objects. Video: Working with Databases in Access 2010

INTRO TO EXCEL 2007 TOPICS COVERED. Department of Technology Enhanced Learning Information Technology Systems Division. What s New in Excel

Text box. Command button. 1. Click the tool for the control you choose to draw in this case, the text box.

FILE ORGANIZATION. GETTING STARTED PAGE 02 Prerequisites What You Will Learn

Lab 7 Macros, Modules, Data Access Pages and Internet Summary Macros: How to Create and Run Modules vs. Macros 1. Jumping to Internet

static CS106L Spring 2009 Handout #21 May 12, 2009 Introduction

Transcription:

January, 1998 Advisor Answers Visual FoxPro 3.0 and 5.0 Q: I would like to create a combo box that functions exactly like the FoxPro help index, that is, when the user types in a value, that value is automatically displayed in the list. If the user just types in the first letter of the entry, that entry is displayed and when the next letter is typed in, the entry that matches those two letters is selected. I have tried creating a text box and list box where the ControlSource of the list is the value of the textbox. The value in the list box is selected, but only after the user has typed in the exact match of the entry. I would like the value to be highlighted when, for example, the user types in the first three letters of the entry. Instead it is only highlighted when the whole word is typed in. What am I missing to make this work? Judith Barer (via CompuServe) A: The kind of behavior you want is called "incremental search." VFP's combos and lists have it natively - typing in a listbox always moves you to the first item that matches what you've typed. (If you don't see this behavior, increase the value of the system variable _DBLCLICK, which controls the amount of time you can wait between keystrokes.) However, the native behavior doesn't show you exactly the characters typed so far, the way Help's Index tab does. You need to combine a textbox with another control to get both the echo and the highlight. This is one of those cases where VFP's ability to subclass its controls and add code to them makes what seems like a difficult task pretty easy. This is a combination you're likely to want to use repeatedly once it works, so start by creating a subclass of VFP's container class. Add a textbox (txtsearchstring) and a listbox (lstdata) to the container, giving them equal width and lining them up vertically. Set the BorderWidth of the container to 0, so the two controls look independent. Figure 1 shows the new container class in the Class Designer.

Figure 1. Incremental Search Container Class - The class contains a textbox and a listbox, which work together to provide the kind of incremental search capability offered by Help's Index tab. By default, string matching in VFP is case-sensitive. Although you'll generally want this control to be case-insensitive, I could imagine some cases where you'd want the default of case-sensitivity. So add a custom property, lcasesensitive, to the container, which determines whether or not it should be case-sensitive. It defaults to.f., meaning that searches should consider "A"="a". Set the Value of the textbox to the empty string, so we start with nothing in the textbox. There are two things a user can do when using this control. He can type into the textbox or he can navigate in the list (using keyboard or mouse). Each calls for a response. When the user types into the textbox (or otherwise edits the data there), we need to search the list to find the first matching item. Add a custom method called Search to the container class and set the textbox's InteractiveChange method to call the Search method: THIS.Parent.Search() The Search method does the hard work, but even that isn't too complicated. Here's the code: * Search the list for the first entry that matches the * user's entry in the textbox. LOCAL csearchstring, coldexact csearchstring = TRIM(THIS.txtSearchString.Value) csearchstring = UPPER(cSearchString) coldexact = SET("EXACT") SET EXACT OFF WITH THIS.lstData LOCAL citem, nindex FOR nindex = 1 TO.ListCount-1

citem =.List[nIndex] citem = UPPER(cItem) IF citem = csearchstring EXIT ELSE citem =.List[nIndex+1] citem = UPPER(cItem) IF citem>csearchstring * As long as items are in order, * as soon as we pass the search string, * we can stop EXIT ENDFOR.ListIndex = nindex ENDWITH SET EXACT &coldexact RETURN There are several things to note in the code. First, the code assumes that the items in the list are sorted. There's no code that forces this to be the case - when you drop the control onto a form, you need to specify the list's RowSource and ensure that it's sorted. Next, unfortunately, VFP's ASCAN() function doesn't work on the built-in property arrays like List, so we're forced to search sequentially. (Actually, we could implement a more complex search algorithm, but I'd only do that if the search speed became an issue.) The good news is that using sequential search makes handling case-sensitivity easier. If lcasesensitive is.f., the search string is converted to upper case at the beginning of the code. The items in the list are converted as they're accessed. The most complicated part of this code is in handling search strings that don't match anything in the list. In testing the Help Index, I found that when there's no entry that matches what's been typed, the list lands on the closest item before the search string. That is, if your search string contains "Elton" and your list has consecutive entries "Ellen" and "Ethel", "Ellen" gets highlighted. So, if the search string doesn't match the current item, we need to check whether the next item is too far. That's what's going on in the ELSE clause. When we leave the loop (whether by finding a match or not), we set the highlight to the current item. Either we found a match, we found that there was no match and stopped before going too far, or we ran out of items to check, in which case we know that even the last item on the list comes before the search string. The other thing a user can do is move the highlight in the list, either with the mouse or the keyboard. In that case, we want the textbox to reflect the current list value. Add

another method to the container called Position and set the list's InteractiveChange method to call it: THIS.Parent.Position() The code for Position is extremely simple: * Update the textbox when the user makes * a change in the list THIS.txtSearchString.Value = ; THIS.lstData.List[ THIS.lstData.ListIndex ] In fact, that code is so simple, you may be tempted to ask why we should even bother to create a custom method for it. Since Search is called from only one place, you might ask the same question about it, too. In both cases, it's because updating one control when the other changes is the responsibility of the container, not the control that changed. In general, when designing classes, it's important to ask who has responsibility for a particular action. One of the goals in a container class like this one is for the textbox and the listbox to know as little as possible about each other. In fact, the way the class is written, either of those controls could be replaced with something different or another control could be added to the container without having to change the code inside the individual controls. All the changes would take place at the container level. Creating the Position and Search methods gives us the most flexibility for future changes. This container control behaves like Help's Index page, except for two things, one of which I think is better behavior. The first issue is that the pointer in the list doesn't move when the user adds a space to the search string. That is, in the example in Figure 2, if the user types a space, the list highlight doesn't move from "Mary" to "Mary Margaret". This is because the search string gets trimmed in Search. Trimming is necessary to do partial string matching. You could keep track of the string length and make sure only blanks typed by the user end up in the search string, but the code to do so is complex and failing to move the pointer on a trailing blank seems fairly unimportant.

Figure 2. Using the incremental search container - The highlight in the list always is on the first entry that matches the text shown in the texbox. However, adding a space in the textbox doesn't move the highlight. I think the second difference is actually an improvement. In Help's Index page, if the user types any characters at all in the listbox, the highlight moves to the first item in the list. In our container, when the user types, the highlight moves to the matching item and the textbox is properly updated. You'll find the class on this month's Companion Resource Disk. There are a number of things you'll probably want to do to improve this class. First is to add some code to make sure that a RowSource for the list has been specified and that the RowSource is ordered. In addition, you may want to set the container's Resize event so that it resizes the contained controls. (See Ask Advisor in the March 1996 issue to learn how to resize the controls in a container.) You can probably think of other enhancements as well. Tamar