Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Incremental Search - question to faq184-3842 3

Status
Not open for further replies.

german12

Programmer
Nov 12, 2001
563
DE
I found this nice code written by Craigsboyd in 2003.
After I changed it a little bit (no randomized filling, but using my own .dbf as source) the program still works well and very fast.

Then I tried to look in the help-file of VFP9 what "DoCreate" (see below in yellow) means, but did not find that expression there.

Question 1:
Can somebody explain the meaning of "DoCreate = .t."for me?
Question 2:
Would the program be shorter today because VFP9 probably came much later?

Thanks for your answer.
Klaus


Code starts with:
Incremental Search - Like Help Index by craigsboyd faq184-3842 Posted: 6 Jul 03 (Edited 18 Feb 05) Slighthaze = NULL It works good in help so why not give your users the same ability for your application? NOTE: There is a small delay when running it since the list of entries is being created randomly. (Cut-n-paste the code below into a prg file and run it from within VFP) PUBLIC oForm oForm = CREATEOBJECT("clssearch") oForm.visible = .t. DEFINE CLASS clssearch AS form Top = 1 Left = 0 Height = 473 Width = 287 [highlight #FCE94F said:
DoCreate = .T.[/highlight]
Caption = "Incremental Search"
WindowState = 0
Name = "clssearch"]

Peace worldwide - it starts here...
 
Hi Klaus

From VFP Hacker's Guide 7

DoCreate

This may be the most mysterious property we've encountered. It's documented only as a reserved word, appears in just about every form we've come across, but can't be accessed at runtime and doesn't seem to do much of anything.

Usage
frmForm.DoCreate = lLogicalValue

Though we've shown the value as accepting either logical value, in practice we've only ever encountered .T.

By now, you may be wondering why you've never run across this property. (We're beginning to wish we hadn't.) It's not hard to miss it. It doesn't appear in either the property sheet or the debugger and you can't refer to it in code either at design-time or runtime.

So where did we find this one? One of the nice things the Class Browser can do for you is provide you a list of what your class or form would look like (more or less) if you wrote it in code instead of using the appropriate designer. When we ask the Browser to show us the code for pretty much any form we create, the opening section includes the line:

DoCreate = .T.
According to one of our sources, this hidden property is for internal use only. When the line is encountered, VFP optimizes form load performance and memory usage. Otherwise, there is a tiny bit more memory used by the form. On Della's machine, a blank form with DoCreate = .T. averages about 16,000 bytes, and one created with DoCreate = .F. averages around 17,400 bytes. The range of bytes that DoCreate buys you appears to be in the neighborhood of 900 to 1500 bytes. That's not substantial enough for us to want to incorporate this into our applications.

hth

MarK

 
It's new to me. Running Craig's code in VFP 9 produces a "property not found" error. The property is not mentioned in the VFP 9 Help, nor does it show up in Intellisense. But it does appear in blue (indicating a key word or reserved word) when you type it in an edit window.

Probably not worth spending any time on it, except perhaps as an interesting curiosity.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
This gets generated every time you use the "view class code" button from the toolbar of the class browser.
You can also safely remove it.

Mike Lewis said:
Running Craig's code in VFP 9 produces a "property not found" error.
I don't know Mike, the code sample of this FAQ works fine for me.

Chriss
 
Notice Klaus,

you only find so much code of forms posted in the PRG format, because that's easier to share in a forum. and even though you could by now offer downloads by hosting them in a cloud drive and tek-tips has the attachment feature, files, even just images posted in forums often are not stored forever and you don't want to be responsible to keep a download available forever to the public in your cloud drive, do you?

Chriss
 
Chris, due to translation difficulties I am afraid that I have not fully understood, what you wanted to explain.
What is clear to me is this:

I do not save such *.prgs in a cloud but save them on my own computer.

So - I understood this a a warning by you, that some programs could disappear because Tek-Tips could delete (oder deletes them occasionally from time to time)

if that is meant, then I have to thank you.

That following sentence confused me, because I can not differentiate who is "you" - is it me, or somebody e.g. this Tek-tips ...or other forum?

I am sure you can destroy my uncertainty.
Regards
Klaus








Peace worldwide - it starts here...
 
No, I don't meant *.prg files, I meant posting prg code as text only, just as craigsboyd did in his FAQ. So you don't need a file at all and therefore don't depend on a file staying permanently available.
I for example frequented a forum about design that was based on phpBB, I think, and that forum hosted pictures used in posts only for 6 months or so. If you visited old threads, you often were missing the pictures that were the core of the discussion. But text, the posts themselves, are never deleted in any forum software. At least I don't know a forum that also deletes threads after a while.

I just wanted to point this out as it's the reason you find such generated code. if you think the code is handcrafted, you'd think there is a reasoning behind this DoCreate=.T. property, but it isn't. It's just generated from the conversion of a form to that code of the form and the main learnings are somewhere inside the clearly handcrafted sections of the code. In that case the text1.interactivechange procedure code. And by the way, this is not what i would use. It works okay as long as the list only has few items, but there is SEEK or LOCATE for finding a record or the first record of sorted records matching a searched string.

The downside of posting a form converted this way is that it's harder for beginners to understand they need to integrate the essential parts into their own form, they usually start a question based on an existing form lacking to implement a feature like this incremental search that's based on a combination of textbox and listbox. The risk is they fail to transfer this and then use this code as given and work out everything in their applications with such code, as they have learned this as the norm for VFP programming, which it isn't.

Chriss
 
Hello Chris,
now I understand what you wanted to say.
I did not knew - and still don't know how to generate the properties and all objects and procedures from a form into a corresponding text file.
(like craigsboyd did).

I would be very interested in that.
For documenting your own programs and for passing on code, this is indeed a space-saving option that is possible without images.

And you're right - there are many options when it comes to programming.
We have the saying "There are many roads to Rome" - and
the danger of believing that there isn't always a better/faster way is of course present once a program is up and running.

That's why this forum is so good, because very different ways of solving a problem are often addressed here - and that's why I like reading here.

I'll try to avoid the interactive change and the interaction between text box and list box in craigsboyd program with using SEEK and LOCATE to achieve the same result.
Then - as a test - I would like to see the difference in performance by using very long listboxes.

I'm sure I have more questions then which of course I'll ask here.

Thank you very much for your very useful explanation.
Klaus

Peace worldwide - it starts here...
 
More verbose instructions than already said:

myself said:
use the "view class code" button from the toolbar of the class browser.

1. Open the class browser from the Tools menu:
classbrowser_m8qoxo.jpg


2. Open a form class or a form:
open_r6z7fl.jpg

Notice: By default, the open dialog is configured to open a class from a class library, but there is a "files of type" combobox at the bottom, you change to form:
filetype_t8in9x.jpg


3. Now as said use the "view class code" button from the toolbar of the class browser: That's here:
viewclasscode_cewbde.jpg


And as a result of that you get a code window showing you "viewcode.prg".

This comes with a warning: Not all such generated code actually works. If your form involves a grid, that's not always working out. So, after saving that prg, you better run and test it. If that misbehaves you have to fix the code until it works. Besides that, you'll see this generates this line "DoCreate=.T." for any form, also any of your own forms, even though they don't show that property in the property window or by intellisense or by AMEMBERS(). And it's optional, as the Hacker guide says it can even be set .F. and the form still is created when you run it.

One more source of information is here: Search for "DoCreate" on this page (with CTRL+F) and you'll also find a reference to a bug and a post about a fix by Calvin Hsia:
bingo-ev.de said:
You can work around this issue by opening all your forms as a table and reorder the form's properties memo field (look for the record that contains DoCreate in its properties memo field). You have to make sure that the BorderStyle line is before the DoCreate line. Calvin Hsia's blog of April 27th, 2007 shows how to do this programmatically.

So this DoCreate property is hidden within a properties memo of an SCX or VCX you see when you use it as a table. That's usually only having properties that are native or user-defined and are in both cases coming up in the properties window, but this one evades this. I guess from the bigger context it is a property from the class the VFP base form class inherits from on the level of the C++ programming language, the TForm class of C++. VFP is programmed in C++ as you may know and not everything in VFP is programmed from scratch. It is not very surprising that forms or windows, which are a very central part of the Windows OS, play a role here and you inherit from that. What I mean is that indeed the C++ TForm class is also just the basis of windows of the OS.

VFP, like any language, inherits from the Windows OS here, that's why you can apply Windows API functions about windows to VFP forms, they are Windows forms or short WinForms, with the signature property (as in signature dish of a famous cook, not meant as electronic cryptographic signature) of the HWnd windows handle.

Okay, and besides all that you now have the directions about how to turn a form or indeed any class into program code. They are not 100% equivalent, though. If you really want to share something it's better done via a GitHub project. But that's another topic. I just hope that helps you to now finally see the point about DoCreate. It's somehow deeply buried related to the roots of VFP forms in Windows, and while it's interesting, it is unimportant and really just there in the FAQ because Craig didn't reduce the generated code to the absolute minimum required to run it. So it seems like it's written by him, planned and important to be there, and has a meaning Craig intended, but it's not.

Chriss

PS: When you have a problem with the click method of one button, it's still the usual basis for a conversation to only post a part of that code to not get distracted from the core problem.
 
Hello Chriss,
Thanks for the detailed description of how the Class Browser can generate program code from the visual development of a form.
I tried it right away - and it worked right away.
I have now also understood the background to the cause of the display of DOCREATE.
It actually has no effect on the program - regardless of whether it is on .t. or .f. or if it is not used at all.
Chriss said:
your warning
This comes with a warning: Not all such generated code actually works. If your form involves a grid, that's not always working out.
I also tried it - in this case, however, the grid was visible in the generated code (see below), but that's ok - because you said ".."not always"

Code:
ADD OBJECT grid1 AS grid WITH ;
		Height = 253, ;
		Left = 408, ;
		RecordSource = "adressen", ;
		RecordSourceType = 0, ;
		Top = 108, ;
		Width = 205, ;
		Name = "Grid1"


I will continue to look into the craigsboyd program (implement search with SEEK and LOCATE) and I'm glad that one can always get help here quickly if things don't go forward.

Klaus

Peace worldwide - it starts here...
 
I said "not always" having in mind simple grids do work. Indeed the only grid that works is one not set to a columncount and having column objects, but generating them at runtime. Any grid with columns added at designtime translates with a code line [tt]ADD OBJECT form1.grid1.columnX.header1 AS header WITH...[/tt] and that fails. Also the ADD Object of text1 textboxes fails. Indeed if you delete those parts of the generated code the grid can work. Because the columncount alone means columns and the default text1 textbox will exist and won't need an extra ADD OBJECT in code.

This gets trickier if you hae code in the text1 boxes.





Chriss
 
Hi Klaus,

Below the code for an optimized ListBox Search. Just click on the form and start typing. The IncrementalSearch property of the listbox is all you need.

Code:
PUBLIC oForm
 
oForm = CREATEOBJECT("clssearch")
oForm.visible = .t.
 
DEFINE CLASS clssearch AS form
 
	Top = 12
	Left = 12
	Height = 474
	Width = 288
	MinWith = This.Width
	Caption = "Incremental Search"
	WindowState = 0
	Name = "clssearch"

 ADD OBJECT list1 AS listbox WITH ;
	Height = 420, ;
	Left = 12, ;
	Sorted = .T., ;
	Top = 12, ;
	Width = 264, ;
	Name = "List1", ;
	Anchor = 15, ;
[highlight #73D216]	IncrementalSearch = .T.
[/highlight]
*!*	 ADD OBJECT text1 AS textbox WITH ;
*!*	  Format = "!K", ;
*!*	  Height = 24, ;
*!*	  Left = 12, ;
*!*	  Top = 12, ;
*!*	  Width = 264, ;
*!*	  Name = "Text1"
 
	PROCEDURE Init
		LOCAL lnI, lnY, nWordLength, sItem, nUpper, nLower
  
		nUpper = 90 &&ASCII
		nLower = 65 &&ASCII
  
		FOR lnI = 1 to 250
			sItem = ""
			nWordLength = INT((35) * RAND()) + 1
   
			FOR lnY = 1 TO nWordLength
				sItem = sItem + CHR(INT((nUpper - nLower + 1) * RAND( )) + nLower)
			ENDFOR
   
		thisform.List1.additem(sItem)

		NEXT   
	ENDPROC
 
*!*	 PROCEDURE Activate
*!*	     thisform.text1.setfocus()
*!*	 endproc

*!*	 PROCEDURE list1.interactivechange
*!*	    thisform.text1.value = this.value
*!*	    thisform.text1.refresh()
*!*	ENDPROC
*!*	  
*!*	 PROCEDURE text1.interactivechange
*!*	  LOCAL nCnt, sSearchFor, nLen
*!*	  sSearchFor = ALLTRIM(this.value)
*!*	  nLen = LEN(sSearchFor)
*!*	  FOR nCnt = 1 TO ThisForm.List1.ListCount
*!*	    IF sSearchFor == LEFT(ALLTRIM(ThisForm.List1.List(nCnt)),nLen)
*!*	     thisform.List1.Selected(nCnt) = .t.
*!*	     thisform.List1.refresh()
*!*	     EXIT &&Found one
*!*	    endif
*!*	  ENDFOR
*!*	ENDPROC

ENDDEFINE

hth

MarK
 
MarK,

I'm quite on your side as I also questioned the value of using a combobox in combomode for what incrementalsearch already offers. But one thing is true, if you don't want to depend on the timing of incremental search you can specify with _incseek and if you want to visually see what you search for, a separation of the input is nice to have. And then you can also find items that don't start with the entereed letters, but have that letter combination anywhere inside them or similar not that straight forward searches.

Chriss
 
Hi Chriss,

if you want to visually see what you search for, a separation of the input is nice to have

Sure.

And then you can also find items that don't start with the entered letters, but have that letter combination anywhere inside them or similar not that straight forward searches.

If that's your wish you would have to write the appropriate code. The code snippet

Code:
IF sSearchFor == LEFT(ALLTRIM(ThisForm.List1.List(nCnt)),nLen)

does not do that

MarK
 
True, but I wasn't talking about Craigs code, just general possibilities arising from a separate entry of the search term into an extra textbox.

Chriss
 
Mark & Chriss
Mark: Thank you for shortening the program that Craig wrote.
For my purposes, this is sufficient for me in any case.

My list box contains the names of stock transactions.
The names of the stocks were transferred to the list using the SQL command Select...DISTINCT.. from a table with more than 1500 transactions since 2014.
Because of the DISTINCT command, the search list is of course much shorter, but it's still larger than the screen - and so an incremental search is ideal.
In this case, of course, when searching, you know what you want to find,(eg. when you look for Microsoft or IBM etc.) and therefore a separate text box for the search is not necessary for me.

There may be cases where you need exactly one input (without typos) want to see.
(Chriss pointed this out).

In my opinion, however, most cases are those in which the first 2 to 3 letters lead you in the correct position in the search list - or at least in the immediate vicinity (sometimes despite a typo).

Thank you both for the great help.

PS: My next question concerns the difference in how results are displayed after clicking in a search list.
At the moment, browse windows open with desired summaries - that would of course also work with grids .... but I'll make a new thread for that by asking for advantage/disadvantage between BROWSE and GRID


Peace worldwide - it starts here...
 
I really have to say thank you to each and every one of you.
I didn't expect to get so many friendly and helpful replies.
It's already convincing me as all the answers suggest trying a GRID rather than a BROWSE.
It's taking me a bit to get used to it, and I know I can always ask questions about the topic here.

Thanks again - sometimes I regret not being able to just spend a round of beers here.
I'll report back when I feel familiar with the GRID object.

Klaus

Peace worldwide - it starts here...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top