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

Procedure (sub-routine) in a Form 2

Status
Not open for further replies.

SitesMasstec

Programmer
Sep 26, 2010
526
Brasil
Hello colleagues!

In a Form a have:
in Object txtRco01, Procedure GotFocus:
MyNumber="01"
(a lot of same more code)

in Object txtRco02, Procedure GotFocus:
MyNumber="02"
(a lot of same more code)

... repetead in 20 objets (till Object txtRco20)


I think I can write just once the code in a sub-routine...
PROCEDURE MYSUBROT
...(a lot of same more code)
RETURN

... and in each object, in GotFocus procedure, put just this:
MyNumber="01"
DO MYSUBROT

If this is possible, where do I have to put the PROCEDURE MYSUBROT code?

Thanks,
SitesMasstec
 
Create a new method in your form, and call it this way:
ThisForm.MyNewMethod

To create a new method, open your form to edit and choose New method from the Form Menu

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania

 
You can even make a seperate MYSUBROT.prg. Or put the PROCEDURE in MAIN.prg
But in that case you cannot refer inside the procedure to THIS or THISFORM. Then you should use the full qualifier like Myform or Myform.MyObject.
 
Learn this once and for all:

In forms you have methods, methods can't contain procedures, as they themselves are procedures. In a PRG you can also only write one procedure AFTER another procedure but not WITHIN.
To have a new method in a form, you create it, name it and just write the inner code. You don't have the lines PROCEDURE Name and ENDPROC inside the form method, you only write the procedure code.
You call a method via THISFORM.Methodname()
To have parameters use LPARAMETERS or PARAMETERS as first line.

If you are in the method editor of the form designer, you can switch between methods with the combobox above the editor, this lists all form methods, also the native ones, also empty ones. The editor´shows only one form method at a time, you don't have all methods in one long editor window. There is no such thing, as there is a list of methods not only on the form level, but also ofor each single element on the form. So you have a tree of objects with the form as the root object, all controls on it as first level items, all controls within containers, pages of pageframes and things like that as second level items etc etc. Each of these has its own list of code attached to it.

You typically don't navigate the tree of form objects, but just double click on a control to get into one of its methods (eg into click of a button), then if you want to edit another method pick one in the combobox. Or you use the properties window to naviaget the form controls and then can pick a method (including your own added) from the methods tab.

The whole structure of this is much more organised as a flat PRG is.

Bye, Olaf.
 
As the others have explained, what you need is a custom method for the form. A method is essentially a subroutine that belongs specifically to the form. A custom method is simply a method that you add yourself, as opposed to one that is built in.

To add a custom method, do this:

1. Open the form in the form designer.

2. From the Form menu, choose New Method.

3. In the resulting dialogue, type a name for your method, and optionally a description (the description will appear in the comment area at the foot of the properties window).

4. IMPORTANT: Click the Add button (before you click Close). If you don't, nothing will be saved.

5. Repeat the above steps to add further custom methods if necessary.

6. Finally, click the Close button.

From now on, you can call the method just like any other method (e.g. THISFORM.MyMethod). Do not use DO.

Hope this helps.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
If all that seems a bit hard, add a button to the form, make it invisible and put the code you need in the click event
for that, pass a parameter for the '01' or '02' bit and you are done.

so in the GotFocus event of each text box event you could put

Code:
thisform.Mynewbutton.Click(right(this.name,2))

and in the click event of the shiny new button (not actually shiny, because it isn't visible) you do this
Code:
parameters MyNumber
private MyNumber

&& (a lot of same more code)

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
The overall problem should rather be solved by making a textbox class with that code in Lostcos. The line MyNumber="01" should rather be replaced by having a new property .MyNumber
I have the feeling this number is just to address the textbox on the form by its name. You don't need the name at all, any of the 20 textboxes refers to itself via THIS.

Really go into OOP. It is not a burden, it is a help!

Bye, Olaf.

 
That's also interesting, Vilhelm-Ion. And it demonstrates that, if the event is triggered "naturally" (by the user clicking on the button, in Griff's example), the parameter won't interfere with the normal code.

But, having said all that, I would still prefer the conventional approach: adding a custom method to the form. It involves only slightly more work than adding, say, an invisible button (or maybe even less), but somehow it seems more natural.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi Mike

Really, that's how I select report outputs as a rule... a few buttons for preview, print, excel, pdf and to clipboard
and then one hidden button taking a parameter to the chosen output, never thought of doing anything else.

I use the button trick on a lot of 'scanning apps' where I have a timer that looks for something then acts accordingly.
Instead of using a method attached to the form - which is great when I'm looking at the code and debugging regularly -
I pop buttons on the form, and label them so when I come back, 2 or more years sometimes, later I can see all the things
that are supposed to be possible and debugging is easier for me. Getting older, developed a lot of applications that
sometimes get no attention for long periods and need as many memory joggers as I can get!


Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Well, the form is a natural place to put in any centralised code you can call from specific buttons, why do an extra button for that? It sticks out in the form? Well, the form itself also sticks out, it IS the main object, it's always there in any form, it's unavoidable.

If you want something you can also copy over including code to another form, then a good concept would be putting a container based "form events" object on the upper left corner of a form, visible =.f. you can add as many methods there as you like and instead of THISFORM.hiddenbutton.click() you call Thisform.cntEvents.method().

I suggest container instead of custom, because in complicated cases you may nest other eventcontainers inside each other at design time, not only via addobject at runtime. So you can build up "libaries" of methods to reuse on several forms.

Adding methods to the form directly obvioulsy is a clean approach with the one con, you only do it in this concrete form, unless you do it in a form class which is inherited by many forms. You can use both concepts to have a balance of a mere inheritance tree with partial "libraries" you compose as in multiple inheritance and polymorphism.

You fix the lack of vfp to do advanced oop concepts by having a secondary hierarchy of event container classes which you can compose in forms, so a form inherits methods of the parent form and from whatever container you take from another inheritance tree of classes you can even nest. It's a bit less ideal, as it's not directly THISFORM.method(), but if you want to bring this to the form level you can make use of a THIS_ACCESS method, redirecting calls to form methods not existing on the form level to the container (or one of the containers). It's not a concept to avoid OOP, though, it's a concept of extending OOP capabilities of VFP and before you go that route, you should rather start with extending your form at least and simply get used to calls stating with THISCFORMdot instead of DO, which even has the advantage of intelllisense showing you the available methods, which DO does not at all.

Bye, Olaf.
 
Olaf said:
a good concept would be putting a container based "form events" object on the upper left corner of a form, visible =.f. you can add as many methods there as you like and instead of THISFORM.hiddenbutton.click() you call Thisform.cntEvents.method().

I used to do something like that for my data forms. After a while, I stopped doing it, because I found it a bit clumsy. But it's still a good approach, and worth considering.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Such concepts always mean you maintain code in several classes you don't edit at once. But that's the nature of OOP. If your modularisation in classes is good, you don't need to switch editing form vs container or control classes, you just define a base behaviour and specialise on the form level. So you still are able to do all form related stuff on the form itself, if only by setting properties.

If you want a flat structure like one PRG file for a form, you will seldeom make use of inheriting anything, you copy & paste code. This is not good for maintenance, even if it feels easier to maintain. It's just a bad habit.

Bye, Olaf.
 
Hello colleagues!

I haven't worked in my main problem yet (sub-routine). I will work on it now, according to your solutions provided above.

But, something I haven't thought about, hint by Olaf, and which I have just applied now and it is a very smart code:
Instead of putting in every object (names terminated with 01,02,03...20) in the Form, for exemple...

[pre]MyNumber="01"
(a lot of same more code)[/pre]

(repetead in 20 objects till Object anyobject20)

... I use now just this:

[pre]MyNumber=RIGHT(this.Name,2)
(a lot of same more code)[/pre]

So, I have not to worry about assigning a value to MyNumber in every object!

Thank you!
SitesMasstec
 
Yes, that's a solution depending on the name. But for what reason do you need this number. If you want to address the other control of each pair of controls with the same number, then you don't need that, if you have a class with two controls in a container. Then the names can always be the same for the two controls.

For example you can have as many text1/text2 textboxes, if you first add a container, CTRL+click into it, add the two textboxes and then copy this container. I'd rather even do a class of this.

In the end you have container1-20 with each text1 und text2. Every text1 box can address text2 as THIS.Parent.Text2 and every text2 can address Text1 as THIS.Parent.Text1. In both cases Parent is the container.

Bye, Olaf.
 
Hello colleagues!

Thank you all that explained about custom method, as well as about using container classes.

Mike explained how to use custom Method straightforward, that I understood at once and worked on it, tested and it's fine. I also share an important item pointed by Mike: the conventional approach has more work but it is easier to understand, mainly if you have to change code in a year or more (as normally happens).

Our talking here helped me a lot.

Thank you very much,
SitesMasstec
 
The more you work with OOP concepts (like custom methods and classes), the easier it becomes and well-designed OOP is a thing of beauty to work with. I have a client application for which I designed the object model nearly 10 years ago. A few times a year, they come back for new functionality. Almost always, while I have to refresh my memory about how things work, making the changes is simple because the interaction of the different classes makes it easy to do so.

While this article won't give you deep knowledge on any of this, it might help you to start rethinking the way you look at VFP:
Tamar
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top