You are on page 1of 11

Creating an Object:

There are different ways as shown below:


1. ADD OBJECT oThing AS MyClass
2. THIS.ADDOBJECT( 'oThing', 'MyClass', ... )
3. oThing = NEWOBJECT( 'MyClass', 'MyModule', 'MyApp'... )
4. THIS.NEWOBJECT( 'oThing', 'MyClass', 'MyModule', 'MyApp'... )

oThing is the name of the object and MyClass is the name of the class.

Constructor and destructor of a class in VFP


Constructor of a class is the init() method and destructor is destroy() method

Creating an object in the runtime:


First we should difine the class in a prg file and then in the code whenever we
want we can instantiate an object of that class.
define class MyEditBox as EditBox && Custom editbox class
for Grid

BorderStyle = 1

SpecialEffect = 1

Visible = .T.

function DblClick

messagebox("I am in the double click method")

endfunc

enddefine

and then in the code we might have


thisform.grdPbsOwnCodes.columns(i).addObject(objName,MyEditBox")

Customize an event for a runtime created object


Just refer to the previous section and look at the code for DblClick() event.

Events should be declared as function expect init which is a procedure

PROCEDURE Init( nStyle )

IF NOT DeDefault() && Always call back to the parent class


return .F.
ENDIF

IF NOT EMPTY( nStyle )


THIS.Style = nStyle
ENDIF
RETURN

ENDPROC

Passing parameters to init() method of a class


See the previous section

More information on objects and classes:


Refer to the below web site:

a. http://www.spacefold.com/colin/archive/articles/oo_menus/menus.htm

An Example:
define class MyEditBox as EditBox && Custom editbox class for Grid

BorderStyle = 1

SpecialEffect = 1

Visible = .T.

cDataSource = ""

cReturnVal = ""

cText = ""

cFieldName = ""

&&procedure init(cDS, cTxt, cFName)

procedure init(cDS, cFName)

if pcount() = 2

this.cDataSource = alltrim(cDs)

this.cFieldName = alltrim(cFName)

this.cText = alltrim(cDs) + "." + cFName

&&messagebox("1" + this.cText)

&&messagebox(cDs)
endif

endproc

function DblClick

&&messagebox("test")

lcVal = this.cText

&&messagebox("3" + lcVal)

cMemoTxt = ALLTRIM(&lcVal)

&&messagebox(cMemoTxt)

do form frmMemoDisplay WITH this.cFieldName

this.cReturnVal = cMemoTxt

lcField = this.cDataSource + "." + this.cFieldName

&&messagebox(lcField)

replace &lcField with cMemoTxt

endfunc

function getRetVal()

return(this.cReturnVal)

endfunc

enddefine

And we call this one this way:

tcCurName = tableName or cursorName

this.grdPbsOwnCodes.recordSource = tcCurName

lnFieldsNo = afield(arrFieldSpec)

objName = "edtBox"

thisform.grdPbsOwnCodes.columns(i).addObject(objName, "MyEditBox",
tcCurName, arrFieldSpec(i, 1))
Showing content of a memo field in “command window”
If the table has a memo field and we have to be able to see the content of
that memo filed without double clicking on that then we can so such a thing:
Use myTable &&myTable has 2 fields ‘id’ and ‘myMemo’

browse fields id, myMemo=myMemo:50 &&50 is the length that we


can see

we cannot have a number greater than 255

InputBox in VFP 9.0


MESSAGEBOX(INPUTBOX("test","test","Enter Something", 10000))

Clear Events
Issue CLEAR EVENTS to stop event processing. When CLEAR EVENTS is
issued, program execution continues with the line immediately following
READ EVENTS.

Read Events
When READ EVENTS is issued, Visual FoxPro starts event processing

Note that only one READ EVENTS can be active at a time. If a READ EVENTS is
in effect, any subsequent READ EVENTS commands have no effect.

Changing Form To Parent Form or Changing Specification of a


Form
Just go to the directory in which the actual files of the form exist (*.sct and
*.scx) and then open the .scx file as it is a table, so:

Use formName.scx exclu

Then you would see a window. The second record is the data environment(
we can see it by clicking of the ‘Class’ memo field, then the 3rd record is the
form and codes of the methods are stored under method fields and objected
code in ‘ObjCode’. So we can change the value of the ‘Class ‘ field of the 3rd
recode which is a form and for example make it parentform from childform or
vice versa. We also can put the location of that class that we just specified in
‘Class’ field by changing the value of the ‘ClassLoc’ field

Every time cy pressing ‘ctrl+w’ we save and exit from a memo filed window
to the main table (formName.scx)
Random Function
If we want to generate a number between n and m and we n > m then we
should have:
Int(rand() * (n – m + 1) + m)

Parent Form and Child Form

To have a parent form an d a few child forms we should set a few properties
in the parent form and child form.

Parent Form Should be:

a) WindowType property should be “0 – Modeless”

b) AutoCenter property should be “T”

c) Desktop property should be “T”

d) ShowWindow property should be “2 – As Top-Level form”

Child Form Should Be:

a) WindowType property should be “1 – Modal”

b) AutoCenter property should be “T”

c) Desktop property should be “T”

d) ShowWindow property should be “1 – In Top-Level form”

Copy Structure
Select patient

copy structure to patTest

Top in Select Query


select top 1000 * from patient order by pnumber into table patTest
Select Records From A Table And Add Them To a Cursor Or
Table
select top 1000 * from patient order by pnumber into table patTest

Having Clause in Select Query


The HAVING clause without a GROUP BY clause acts like the WHERE
clause. If the HAVING clause contains no aggregate functions, use the
WHERE clause for faster performance.

NewObject()
goApp = newObject("ExcelConvert", "ExcelConvertor") && Create an instance
of ExcelConvertor

first parameter is the real class which we want to have an instace of it and
second parameter is the name of the class library. The relation of class library
and class can be seen in the classes tab in project manager like below

class library->class

So a class is located in a class library and if we don’t specify class library VFP
looks for the specified class in few different places:

 Visual FoxPro base classes.


 Classes in the current program.
 Class libraries opened with SET CLASSLIB.
 Classes in procedure files opened with SET PROCEDURE.
 Classes in the Visual FoxPro program execution chain.
 The OLE registry if SET OLEOBJECT is ON.

CreateObject()
goApp = createObject(("ExcelConvert")

Use CREATEOBJECT( ) to create an object from a class definition or an


application that supports Automation, and assign a reference to the object to
a system variable or array element.

Before you can create an object from a user-defined class, the user-defined
class must first be created with DEFINE CLASS, or it must be available in a
.vcx visual class library opened with SET CLASSLIB.

this.loExcel = CreateObject("Excel.Application")

AddObject()
objName = “myEditBox”

thisform.grdPbsOwnCodes.columns(i).addObject(objName, EditBox")
Here first parameter is the name of the object which will be added and
second parameter is the name of a class which could be one of VFP base
classes (like here) or we could difine a lass for example in a prg file and then
have a:

set procedure to functions, editBoxClass additive

editBoxClass is a prg in which the class has been defined

Error Handling – On() – On Error


*because if pbsOwnCodes or pbsTcodes tables are open there would be an
error when we want to do the copy structure and I wanted my own error
message not the red screen

llErr = .f.

oldErrHandling = on("error")

on error llErr = .t.

this.createPbsOwnCodes()

this.createPbsTCodes()

*back to old error handling system

on error &oldErrHandling

if llErr

goMessage.ok("Failed To Create Data Files... Close All The Data Files


And Try Again", goApp.getAppTitle())

goApp.leaveApp()

return

endif

Using Dll Api

DECLARE INTEGER GetSystemMetrics IN Win32API INTEGER

lnScreenX = GetSystemMetrics(SM_CXSCREEN)

lnScreenY = GetSystemMetrics(SM_CYSCREEN)

lcTitleBarHeight = GetSystemMetrics(SM_CYCAPTION)
lnMenuBarHeight = GetSystemMetrics(SM_CYMENU)

CLEAR DLLs

And in a header fie we should declare those constants:

* GetSystemMetrics() codes

#DEFINE SM_CXSCREEN 0

#DEFINE SM_CYSCREEN 1

#DEFINE SM_CXVSCROLL 2

#DEFINE SM_CYHSCROLL 3

#DEFINE SM_CYCAPTION 4

#DEFINE SM_CXBORDER 5

#DEFINE SM_CYBORDER 6

#DEFINE SM_CXDLGFRAME 7

#DEFINE SM_CYDLGFRAME 8

#DEFINE SM_CYVTHUMB 9

PADC() & STR()


Num = 2

Padc(num,1) works exactly same as alltrim(str(num))

On Error
On error messagebox(‘error’)

Messagebox(this causes my error handler)

lcErrHandler = on(‘error’)

on error messagebox(‘error handler changed’)

Messagebox(this causes my new error handler)

On error &lcErrHandler

Messagebox(this causes my old error handler)


FUNCTION RetryRename(lcFileFrom, lcFileTo)

llTry = .T.

lnTryCount = 1

oldError = ON("ERROR")

ON ERROR llTry = .T. &&you cannot have like thisform.lltry = .T. ,


thisform can’t be there

DO WHILE llTry AND lnTryCount < 30

lnTryCount = lnTryCount + 1

llTry = .F.

goMessage.wmsge("Renaming Files, Please wait...",30,.F.)

RENAME (lcFileFrom) TO (lcFileTo) && triggers ON ERROR, if


delay in network

IF llTry

goSystem.Sleep(1000)

ENDIF

ENDDO

ON ERROR &oldError

IF llTry

glCompleted = .F.

DO OnError WITH ERROR(), MESSAGE(), MESSAGE(1),


PROGRAM(), LINENO() IN Startup && triggered by RENAME

ENDIF

goMessage.wmsge(" ")
ENDFUNC

Event Sequencing
When A Form Getting Loaded:
1. DataEnvironmet.openTables()

2. DataEnvironmet.beforeOpenTables()

3. Form.load()

4. [cursurs].Init() - for each cursor in DataEnvironment

5. DataEnvironment.init()

6. [controls].init() - for all controls in a form

7. Form.init()

8. Form.show()

9. Form.activate()

10.Form.refresh()

11.[object1].when() – for the first object in tab order

12.[object1].gotFocus() – for the first object in tab order

But In MSDN There Is A Slight Difference:


1. Form.init()

2. Form.activate()

3. [object1].when() – for the first object in tab order

4. Form.gotFocus()

5. [object1].gotFocus()

6. [object1].message()

If We Leave An Object And The Next Object Gets The Focus:

Whenever An Object Gets The Focus The Sequence Of The Events


Is As Below:
1. [object(i)].when()
2. [object(i)].gotFocus()

3. [object(i)].message()

And Whenever An Object Loses The Focus The Sequence Would


Be:
1. [object(j)].valid()

2. [object(j)].lostFocus()

If We Move To The Next Text Box From Currently Focused Text Box And
Type Something In The Next Text Box:
1. Text(i).keyPress()

2. Text(i).valid

3. Text(i).lostFocus

4. Text(i+1).when()

5. Text(i+1).gotFocus()

For form first lostfocus() runs then deactivate()

When We Type In A Text Box:


1. Text(i).keyPress()

2. Text(i).interactiveChange()

When We Leave A Form By Calling Realease() Method (Closing The Form):


1. Form.queryUnload()

2. Form.destroy()

3. Form.[command buttons].destroy()

4. Form.[objects].destroy()

5. Form.unload()

6. DataEnvironment.afterCloseTables()

7. DataEnvironment..destroy()

You might also like