Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
*Compatibility Report 5-7* SYS(2018) content different
Message
General information
Forum:
Visual FoxPro
Category:
Other
Miscellaneous
Thread ID:
00697397
Message ID:
00701652
Views:
35
Hi David,

>Peter,
>
>>Just agreed (I get the feeling that you think I just want to do this. But I really don't ;)
>
>I don't have a clue as to what kind of code you have in your UDFs *s*. Since there hadn't been any code posted on that area, I was just giving an example of what I'd consider a bad way of using a UDF for the purpose.

Right now I don't have access to our code. I'll post some example tomorrow or so.

>
>>Yes, but IMO it is not the most friendly way. Sadly, (e.g.) the locking issues with the backend database just tends to work in that direction : Press save after the hard work done, and find all rejected.
>>This is a matter of opinion, and I am not in favor of it.
>
>If some value can't save, (although I strive to use controls that only allow valid entries in the first place like cbo.Type=DropList), focus is set back to the field causing the problem and the user can correct and save again. Nothing is lost unless the user decides to do a Cancel and TableRevert the whole form.

Yeah, I think that is standard attitude nowadays.;) But please, don't call that the most friendly solution.
"Nothing is lost" ? I think all is lost. When data has been typed, and that date (sorted out at the field level) was changed, it has to be reloaded, right ? So the typing was for nothing. It didn't vanish as such, so that's not what I meant.
Further more, it is not just about the visible data on a form, but also about data that needs replacement further down the line. Think about the RI.

>
>>It is not all that much about the "whether" (we don't even use the When !!), but merely about the program behind the user being in control. This is (too) about the highlighting stuff (Walter). And, it's about when to fire what Valids. Small example : click 10 controls further down the line, and all the controls in between should be validated. Validate can mean (the GUI doesn't know that) that the value of a next control changes. Etc. etc. This could even lead to the user clicking a control that becomes disabled down the line, so how could he ever have clicked it ? And then what ? So, "be in control".
>
>Again a lot of this is predicated on your need to do control level valids. I disagree with that style of UI. This is just a difference of opinion.

It comes to the attitude again I'm afraid. I hope you 'll agree that indeed all can be validated right after pressing OK, but, that this just as well could have been done at the control level. It saves typing again.
But I know, we all started to learn that it sure is not convenient to valid at the control level. Think of web-apps ... Or better, having your normal app into a web-app. That's my problem now ...

>
>>... Hence, once you arrive in the GotFocus Event, you can't tell where you are thinking in procedural sequences. Events don't fire, fire in the sequence the user didn't apply, fire recursively ... it one big pile of a mess. That is, when you approach this from the OS angle.
>
>I don't follow what you mean by "OS angle".

I meant (our situation) the OO being on top of all user functions like an OS. It's the highest level of being generic. For fun, look at your own code. Is it really 100 % detached from the biz functions ? if not, could you do it ?
PS: The answer "no need to" doesn't apply. I found it necessary and benefit highly from it (think of the web-app again).

>
>>There is one GotFocus method. So one set of your code. But, tens of instances as subclassed from the controls, run. The point here is a bit of my own fault (I think) by allowing a control to get into focus, but then starting to fire Valids of other controls (see earlier, the controls between where the user was and where he goes to). So, the program itself gives implicitly control to other controls and gives them the focus. This has to be done in order to fire the Valids in the proper way. And ALWAYS you are in the same GotFocus code. Without the CASES, remember ?
>
>I'm glad you got something working, but it really does sound overly complex to me. Why can't you just iterate through the controls based on the TabIndex? The user leaves ControlN and wants to go to ControlM you can iterate for i = ControlN+1 to ControlM-1. This could be done in a FormSubClass.Method() as easily as in a UDF.

Well, as small 3 line loops these things are in there.
And you are right, it *is* complex, in fact, it is the most complex.
The "just loops" won't do with regards to the communication with the biz functions. Remember, all it detached, and both environments have to communicate with eachother. For example, the Valid code isn't part of the OO classes (objects), but part of the biz functions as they should be. So, the leave of a control must communicate with the biz function concerned. At that time, the biz function is on control, which comes to preparing for error messages (if applicable) which have to be dealt with by the OO-part again. In between the user is in control. So he/she decides where to go to, and in the end what event will fire when. This is normal obviously, but at the back the biz functions are running, knowing nothing at all. So in there, it's 100 % objects again, ready for all that may come to them. Well, not "all", and that's what my "OS" is taking care of.

One small example :
Supposed you can look at the biz function as a procedural action (and IMO it is and should be ...), then the user can go through the controls via the taborder. But, he can just as well go back again. Now, thinking of *my* attitude that a user should not depend on the app's behaviour in doing things wrong (read : when something goes wrong it should be the app's fault), a user may enter some invalid data in a control. Moving to the next control implies an error, but, moving to a previous control (so LostFocus goes to an earlier control) should not imply an error, and instead the old (valid) data must be restored in the control. That's just one aspect of how I think a user should interact with a form. It's how I would like it myself being a user.
Now, when I had designed VFP I had just taken care of this (wanted) behaviour, because (IMO) that is always the right behaviour (think of it). But it is not in VFP, so my OS takes care of it. It's the one big layer on top of all, just changing the natural behaviour of VFP. To the benefit of the user that is.

Because all is normal classes, obviously this behaviour can be changed by the change of the one line of code concerned. This is nothing unusual. What is unusual however, is the things I control. Think of it; when this is outside the biz functions, it can be only about showing and entering data, right ? Well, that's what I spend 5 years of my life on. And I am not the only one working overhere. So let's say that I spend 5 years on how the user should browse through a form. Rather ridiculous, right ? well, that's whay it's so hard to explain.


>>This one (Variable not found. without VFP mentioning the variable name) just couldn't be found. It's a runtime "feaure" only. Compare this one with the Public variable being passed as a parameter; in the called program the Public variable is unknown now. It's Fox kernel behaviour, for you the developer a bad thing, but logic anyhow (looking at the kernel). So just don't do it. The "Variable not found." is much more nasty, but in the same area. When a variable is controlsource somewhere, and under the scope of it (say, that Form) something is instantiated that uses that variable to pass as a parameter, within that called function (or whatever) it becomes unknown. It's run time behaviour because in advance you can't tell what is instantiated (users decide for that).
>
>No public memvars helps solve that problem. *s*

It was just the example to make clear what I mean, because that you can easily test.


>
>I also don't use memvars as ControlSources. I only real data (tables/views) or form level properties. This allows my forms to painlessly be instanced more than once.

Yeah ? well, I'd say that an app that draws it's control data directly from the tables, isn't as felxible as could be. Example : I don't want Y/N to display as data, and at the same time I don't want Yes/No in the table field. Now what ? Added to this, the app is multi-lingual. Then what ? there has to be the other layer in between. This layer could be a table, but this is nonsense. So it's just variables fed with the current language, translated from the normal table data, just as that a "Y" is translated to "Yes" (or translated to a checkbox).
Also think of the table data needing to be in the one language only (mixed Yes/Ja/Oui isn't that good you know (just the simple example -> is a checkbox really !)).

>
>It really sounds at the root of all of this is that you have a legacy procedural codebase that you are trying to use in VFP, and that's causing some of these design issues that you are trying to deal with by using the error handler.

Hmm, the error handler ... I almost forget about the subject ...
Well, basically you are right, but not because of it was converted from procedural coding or so. My idea is that the organization's business just IS procedural, and not so much about events (though it *is* about triggers). This too is hard to explain, but I explicitly reasoned this out. It's just the good think. So, biz functions are procedural, and shouldn't be - nor can't - be captured in the real event stuff. However, it *is* about self containing objects. So in fact what happens (should happen IMO) is that the self containing object acts procedural within itself. Think of the user entering a sales order. It's just a sequence to be completed, and the sequence is pre-defined. BTW, you don't hear me say that it couldn't be captured in the normal OO environment (though I really think it can't be done from some technical point of view), and I only say it is better to have it procedural when the user is in the procedural environment anyway.
This sure does not say that the app is running old code or so, and in only says that the sequence a user has to follow is predefined. So, it is "procedural" code that tells that after the order header has been added, now the adding of order lines should (logically) start. This is not in the OO environment, hence this is not in my classes (remember 100 % detached). But, when the program for adding orders is launched (under logic control of the biz app), it's just the normal form being instantiated with the data (and internal sequences) the biz function tells. At that moment the user is in the OO part ...

So in the end you are sort of right, though I like your word "trying" a bit less ;)

>
>>Ha ! and then have a CASE again ? :=)
>
>A block of ON ERROR( nError ) statements really isn't any different than a CASE statement inside the eror handler.

It sure is David. Did you ever think on how the event model works internally ?
It's one big pile of CASE KeyIsPressed DO KeyPress.
Internally, VFP is just procedural code with one pile of CASEs and an idle loop in the middle. This is even more true when VFP is not multi-threaded.
So what is done, is the shift of procedural working towards event-working as how we see it. The same would that be for the ON ERROR I proposed : it shifts towards events (and its methods), whereas now it's all in the one PRG.
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform