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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Form and Class 1

Status
Not open for further replies.

NasibKalsi

Programmer
Jan 8, 2004
417
CA
Hi all:

is there exist a user defined class local to the form ? As we have user defined methods local to the form.

my best

nasib
 
Not 100% sure what you are looking for, but I believe that you have to subclass the Form class (create a new class and chose Form as "based on")

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania

 
Can you please rephrase that question? I don't understand what you really want to know.

What you might want to know:

1) Creating an SCX based on a form class
If you design a normal form scx you don't define a class, but you can specify from what class you inherit. One way is setting a template form in the options forms tab. Another way is CREATE FORM yournew.scx AS someformclass Of somelibrary.vcx

2) Difference of form and class designer
The form designer compares to the class designer in that way, that you can add methods to the outmost object, which in case of the form designer always is the form, you can't add methods to anything inside the form. If you design a container class in the class designer you can also not add methods to the inner controls, only to the container. This is the reason it's so important to subclass all base classes and use them everywhere to be able to later change anything in these first level subclasses or in further subclasses, as you can't change base classes themselves. You can only add or modify code, when its a class of its own (Well, not just in the natural language meaning, but also).

From that perspective the form designer is just a special designer only for forms. If you design a form class, you also can only add methods to the form class, the only thing you do on top of what the form designer does is you edit a class, which can later be inherited. From that perspective you better don't use the form designer at all, you have the disadvantage of needing to save as class before the form can be inherited and it's more complicated to inherit from some form class other than the base form. You only have the advantage you can easier DO FORM than needing CreateObject() and then Show(), but there is only one line of code saved.

Overall this limitation seems clumsy, but if you'd be able to change code in the inner objects you'd change code of an object instance, not of that class. It also enforces you to think of how to deisgn your classes so you don't need to adapt them to each single use, that would not make much sense, as the class code then would not be a general solution to a problem and that's bad class design. So in fact you shouldn't need to adjust code in every use of a class, the class code should cover all usages of a class.

3) Creating a class from an SCX
You can also save a SCX as class to make a class of the form to build the next generation, but you better overall use form classes from scratch to make easier use of inheriting and being inherited. If you don't like to change code starting forms you can simply take any form class as basis of an SCX, simply save that as SCX unchanged and thereby start your form class the classic DO FORM ways. Better you create a doform procedure that just does CreateObject() and Show().

One more thing: Form classes have no DE, you need them as separate classes and can add them via the DEClass and DEClasslibrary properties of a form class. That's also available in SCX forms and also means you can use the same DE in several forms.

Overall it's not at all hard to do without SCX forms and only have form classes on the one side and you don't gain the ability to change code of inner objects with the class designer, if you think that way.

Bye, Olaf.
 
Nasib,

Do you mean you want to create a user-defined class, and then add that class to a form? So, the form will "own" the class, and the class will be not be visible from other forms?

If that's what you want, then you need the AddObject method. This is a method of the form. You pass it an object name and the name of your user-defined class. You can then use the object name to reference the class's properties and methods.

For example, if your class is called MySearch, and it has a method named FindNow, you can do this:

[tt]THISFORM.AddObject("oSearch", "MySearch")
THISFORM.oSearch.FindNow("Some parameter")[/tt]

Does that answer your question?

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Another guess:

Are user defined Methods of a form saved in some kind of local class?

No. When you define methods of a form, these just are written in the SCX file, there is no secret hidden class file anyway, you add that code to the SCX. If you look into the Methods memo of the record containting form level code, you simply see new userdefined methods defined by PROCEDURE in the same manner as inherited methods, eg:
Code:
PROCEDURE userdefinedmethod
? "userdefined"
ENDPROC
PROCEDURE Init
? "Init"
ENDPROC

So this goes directly into the form scx file. You also see the defined method in Reserved3 memo.

Bye, Olaf.
 
Thank you Vilhelm-Ion, Olaf and Mike for taking the time to reply.

I was expecting in DE when Clicking on Form

Form
New Property && Exists
New Method && Exists
New Class && Does not Exist

I was thinking there may be a way to have 'New Class' as well. I am a bit lazy and wanted functionally related methods in one place for this form.

So I can do
local t_objTest, t_Ans
t_objTest = CreateObject("thisform.clsTest")
t_Ans = t_objTest.Multiply(5,6)

I am using set classlib to ...
and createobject(), etc.

Enjoy

Nasib


 
There is no such thing as a class as a PEM of something, PEMS are only properties, events and methods (and as aside we can't even create events)
A class always is it's own entity and may have a parent class, but it is no part of something other than a library.

You want to prevent the need for SET CLASSLIB? Then use NewObject() or THISFORM.NewObject(). You may also DEFINE CLASS within your main PRG. And within an EXE you finally need no SET CLASSLIB anyway.

It doesn't make sense to have a form specific class definition. If you want your classes easily avaliable do a routine, eg a projecthook, that loads all class locations into a dbf and iterate that with SET CLASSLIB ... ADDITIVE at PJX start and you always have all classes of your project available via CreateObject(). OOP suggest using a class factory. The task to know where a class definition is to be found is the task of that factory.

Besides all that it doesn't make sense to limit the existence of a class to a form, if that is what you also see in that construct. A class only needed in one form is not needed at all.

Bye, Olaf.



 
You may be confused about what a class *is*.

A form in the form designer is actually an instance of a class. Classes (and instances of them) cannot contain other classes. They can contain *instances* of other classes, but not the classes themselves so the entire concept of 'adding a class in a form' doesn't make any sense.

You're on the right path, though. Class design is largely a matter of packaging your code in sensible units, and then at application design time you gather the instances in ways that work together. As Olaf points out you can either drag a class onto a form or use the form's Addobject() method to add instances of your classes. But your classes themselves live elsewhere.
 
The way I used to explain this on my courses was by analogy with a car.

A car is an object. It has certain characteristics ("properties"), such as a colour, size, number of doors, etc. It also has certain things that it knows how to do ("methods"); thus, it knows how to start, drive, change gear, pollute the atmosphere.

A car class is a set of instructions for creating a car object (for "instantiating" the object). The class is a specification, a blueprint. It specifies a default for the properties and methods of the object (but that doesn't prevent you from varying those properties and methods in a specific instance; with a given car, you can paint it, or enlarge it, or soup up its engine).

But the point is that the class is only a set of instructions. It is not an actual car. You can't drive a blueprint.

I hope that makes sense - or does it confuse the issue even further?

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I still wonder about your motivation to want a class defintion as a kind of attribute of a form and the idea that comes to mind is you want to give a class a scope and be able to reuse the same class name with different implementations for each form. But the main main concept for that would be a template class and a specialisation for each form. You can always do the last specialisation step in the instance of the class you put on a form (or any other containing class or instaance), so if you don't use AddObject, but really drag a test class onto your form (its base class just has to be something you can drag into a form, but a custom class is ok, or a container), you can implement code in its methods, that overrides class code, but still can inherit the class code by DODEFAULT() or by not writing anything into the instance you dragged on the form. You can also use THISFORM and references to all the surrounding objects/instances (This.Parent.othertextbox) on the form. It can be good, it can cause too many dependencies, but you surely want objects to not interact on certain levels.

If you think about a unit testing class that will do things very individually depending on which form you test, you actually test the form and don't need a class for this, you define a test as a series of calls and assertions the call results have to fulfill. A test could be based on a test class, but you would define a general template test class with base methods you want to use in any form, eg openform, closeform, things any form has to fulfill and you'd define that template tester class outside of any context and scope, not within a form.

The other thing, which comes to mind is namespaces, but that's about scoping in a different sense. In .NET classes of a certain namespace can easier avoid double names by specifying/referencing other classes of the same namespace, also some properties and methods can have a privacy in this scope of the namespace, only be usable by the family of classes of the same namespace, but in general you can use a class instance everywhere, also in other namespaces. Eg there are car classes in the namespace of a make, and the preamble "car" can also define a namespace for anything car related, but it's not meant for exclusion For example you want to be able to sit in a car, so you want to be able to have a seat object in a car, also if a seat comes from the namespace of furniture and not of cars.

I still don't see, why you would want to define a class in the context of a form. Just for the easier modularization, being able to hand out one SCX and all any user or other developer needs is included in there? That's against a very genral idea of loose coupling. In the final level you want to combine class instances objects to the more complex overall "thing", eg control or form or application, but every single part/class should have a separate concern and very specifically do one job very good, that is reusable.

Waht you want to define is very specifically working fopr a single form only and by that definition not reusable, there is no need for a class in that moment.

Bye, Olaf.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top