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

Which control determined LostFocus of another control

Status
Not open for further replies.

worky24

Programmer
Aug 20, 2003
13
RO
Hello,

This is more a rethorical question, but I have been asked by one of my coworkers and I can't give a satisfactory answer.
So, having a form with some controls on it, is there any method to know which event cause the LostFocus event of a given control?
To be more specific, let say we have a form with a TextBox, two ComboBoxes, and two Command buttons. In the LostFocus method of the TextBox we have some validation code but we don't want this code to execute when user click the "Exit" button.
Also, we want this code to execute if user click on any other controls.
Any suggestions?
Thank you in advance!

worky
 
worky24

One way would be to add a new form property .lCodeRun.

In the .When() event of the other controls, with the exception of the exit button put
Code:
[COLOR=blue]WITH THISFORM
[tab]IF !.lCodeRun
[tab][tab][/color][COLOR=green]&& Validation code here[/color][COLOR=blue]
[tab]ENDI
ENDW[/color]
In the .When() event of the textbox,
Code:
[COLOR=blue]THISFORM.lCodeRun = .F.[/color]
In the .LostFocus() event of the textbox,
Code:
[COLOR=blue]THISFORM.lCodeRun = .T.[/color]
As the .When() events fire before the .LostFocus() events you should find the code works without constantly running the validation routine.

FAQ184-2483 - answering getting answered.​
Chris [pc2]
PDFcommandertm.com
PDFcommandertm.co.uk


 
worky24
One way would be to add a new form property .lCodeRun.
Apologies - I omitted that the property's value should be set to .T. initially to prevent the validation routine from firing should a user not start with focus on the textbox.


If the textbox gets focus first then there's no need for the value to be .T..

FAQ184-2483 - answering getting answered.​
Chris [pc2]
PDFcommandertm.com
PDFcommandertm.co.uk


 
Worky,

Using your example, in the Valid event of the textbox, put in a check to see what action the user has taken to try to exit the text box.

You can use AMOUSEOBJ() to determine which button they clicked on, and LASKEY() to determine the last key pressed.

So, if in your Valid event, you see that they clicked on the Exit button or hit the ESC key, you know they want to leave the textbox without saving the changes, and you take action accordingly.

Mike


Mike Lewis
Edinburgh, Scotland

My Visual Foxpro web site: My Crystal Reports web site:
 
Mike
Mike said:
So, if in your Valid event, you see that they clicked on the Exit button
There appears to a problem with the use of AMOUSEOBJ() in this situation.


Testing your code under VFP 8.0 SPI, and I may well be missing something, the first two rows of the array created by AMOUSEOBJ() return a value of '(Object)', the third and fourth being the x and y coordinates of the mouse at the time of exiting the textbox.

So it appears you need to rely on the third and fourth rows as 'evidence' of where the mouse is positioned.

If a user tabbed out of the textbox and the mouse happened to be positioned over the Exit button, it would appear that the Exit button had been clicked whereas it had not.

Also the Escape key will not force an exit from a textbox unless specifically programmed so to do. [smile]

worky24

If you were to implement the .When() solution, you could place the validation routine in a new form method such as .mValidateTextbox(), and put the following code in the .When() events of the other controls.
Code:
[COLOR=blue]
WITH THISFORM
[tab]IF !.lCodeRun
[tab][tab].mValidateTextbox()
[tab]ENDI
ENDW[/color]

FAQ184-2483 - answering getting answered.​
Chris [pc2]
PDFcommandertm.com
PDFcommandertm.co.uk


 
Chris,

Thanks for that input, especially about AMouseObj(). To be honest, that wasn't the function I intended to suggest, but I couldn't remember which one I had in mind. I feel sure there is a SYS() that returns a reference to object under the mouse, but I couldn't find it in the Help. But, come to think of it, that might not be an ideal solution either, for the reasons you stated.

Your approach looks like a better road to go down (as is so often the case).

Mike


Mike Lewis
Edinburgh, Scotland

My Visual Foxpro web site: My Crystal Reports web site:
 
Hi

1. Add a form property lOk2Quit
Initialise that to .f.

2. In the Exit button
cmdExit.MouseEnterEvent
***********************
ThisForm.lok2quit = .t.

cmdExit.MouseLeaveEvent
***********************
ThisForm.lok2quit = .f.

3. In the LostFocus Event of other controls..

IF ! ThisForm.lok2quit
** myValidation Code of the control
**
IF ! VALID
NODEFAULT
ENDIF
ENDIF

:)

____________________________________________
ramani - (Subramanian.G) :)
 
Hello all!

Thank you very much for your prompt answers. As I told you, I asked this question because of curiosity than a real need - my approach to user interfaces is usually KISS (keep it simply stupid). Anyhow, it's a good thing always to learn something new. So:

ramani,

I'm using VFP6 with SP5, and this version doesn't have MouseEnter and MouseLeave events.
I've used Chris' ideea which works fine but... there are strange thing which happens.
Let me explain:
I've made a form with 2 TextBoxes, and 2 CommandButtons. Text1 must be validated - only accepted value is "X".
The form have a property "lCodeRun", as Chris sugested and a custom method "lText1Validate":

Code:
Form1.lText1Validate is:
[COLOR=blue]
IF thisform.Text1.Value<>'X'
	WAIT WINDOW 'Incorrect value for TEXT1'
	RETURN .F.
ENDIF
RETURN .T.
[/color]

Text1.When() is:

[COLOR=blue]
thisform.lCodeRun=.F.
[/color]

and Text1.LostFocus() is:

[COLOR=blue]
WAIT WINDOW 'LostFocus from Text1' TIME 3
thisform.lCodeRun=.T.
[/color]

Text2.When() and Command1.When() (which is Save button) are the same:

[COLOR=blue]
WAIT WINDOW 'WHEN from TEXT2' TIME 3
WITH thisform
	IF !.lCodeRun
		RETURN .lText1Validate()
	ENDIF
ENDWITH
[/color]

Command2 (which is Exit button) have only Command2.Click() as:

[COLOR=blue]
thisform.Release()
[/color]

The problem is as follows:

Let say that Text1.Value="AAA" (an incorrect value).
When I try to leave Text1 executing click on Text2 or Command1, the focus remain on Text1 and "Incorrect value for TEXT1" is displayed (as expected).
But, when I'm leaving Text1 using TAB, then the methods of Text1 and Text2 are executed in following order:


Text1.LostFocus()
Text2.When()

and NOT in reverse order, as documented!

Am I missing something, or I'm just stupid?

Thank you all again for your kind support!

worky
 
Hi Mike,

As for the SYS() that returns a reference to object under the mouse, it is SYS(1270), respectively SYS(1272).
Very useful sometimes.

Tom
 
worky

As a possible solution to your problem, remove
Code:
[COLOR=blue]THISFORM.lCodeRun = .T.[/color]
from the .LostFocus() event of the textbox you want to validate and place it to be the last line in the method .mValidateTextbox().

Thus once the textbox has been validated, it can't be validated again until that particular textbox receives focus again.

FAQ184-2483 - answering getting answered.​
Chris [pc2]
PDFcommandertm.com
PDFcommandertm.co.uk


 
First of all, thank you again for your answers!

Chris,

indeed, moving that line from Text1.LostFocus() to Form1.lValidateTextBox() solved the problem and everything works as expected.

worky
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top