I've created a set of controls derived from CEdit in order to do
in-place validation (i.e when you tab out of the field rather than when
you complete the form). Mostly (at least 99%), they're working fine,
but I've had a couple of problems with one particular form and, sadly,
intermittently.
Basically, I've over-ridden OnKillFocus() and do my validation there,
saving the validated data for later use. When the "save" button is
clicked, UpdateData(TRUE) is called which (I believe) then calls
DoDataExchange(), where the data is taken from my controls into a set
of variables which are then processed by the over-ridden OnRecordSave
handler and placed in the database.
The problem is, sometimes the data that arrives in the database is the
default value (set to be something stupid as a debugging exercise), not
that which the user has entered. I've therefore written a logging
function to trap the data at every point and, as far as I can tell,
when it doesn't work it's becuase OnKillFocus() is called after
DoDataExchange() (my logging table has an IDENTITY field which is how
I'm getting the order of activity).
Is this really possible? Could the button handler be being called
before OnKillFocus()? If so, is there any way to stop this?
To add further to my confusion, you can't leave the edit control unless
you've typed something in it and you it won't save unless you've
clicked a checkbox first. (in the first case it returns to the control,
in the second to the form). Therefore, you must have left the edit
control for another control before clicking "save".
I'm very confused and any help would be gratefully appreciated.
Paul.
ON_CONTROL_REFLECT_EX(EN_KILLFOCUS, OnKillFocus)
to handle the kill focus event to restore the color.
Mabe this will help you.
--
Kind regards, Michael Buechel
while(!sleep())
sheeps++;
"Paul S. Ganney" <paul....@hey.nhs.uk> schrieb im Newsbeitrag
news:1151934479.6...@a14g2000cwb.googlegroups.com...
The side effect you are seeing is, to me, typical of the kinds of bugs that arise when
using UpdateData indiscriminately.
Generally, I consider EN_KILLFOCUS validation to be about the worst possible approach; I
tend to do real-time validation as characters are typed. But there are special
limitations you must follow when using EN_KILLFOCUS validation; for example, you must not
pop up a dialog box, set the focus to any control, or change the contents of the control
you have just left. Ever. if you need to interact with the user, you must PostMessage a
request so it is done only *after* the entire focus-protocol has completed.
I had a lot of problems because of the focus protocol doing unexpected things, so I don't
use it any longer; in the worst case, all I will do is PostMessage a request to do the
validation, but in no way actually *do* anything in my OnKillFocus handler. Doing things
in the OnKillFocus handler (including UpdateData) will generally lead to disaster.
If you are having sequencing problems, you may have to have your button not actually do
the work it claims to do, but itself do a PostMessage to keep the sequencing in place.
One thing you must never, ever do is reset the focus to a control if it isn't "valid".
This makes it impossible to do something as simple as hit the "cancel" button. This is
one of the many reasons I find kill-focus validation to be very suspect as a user
paradigm. You should assume that focus is *exclusively* controlled by the user, and never
change it yourself for any reason.
What I do when I use kill-focus at all is PostMessage a message requesting validation.
Then, when I get it, I merely notate if things are valid, but I do not take any action as
far as changing focus. Typically, I have a static control whose default is to be
invisible, but which, if it has text, shows yellow text on a red background to indicate
the error, and disables the OK button if the constraints are not met. To do this, I
consolidate all my constraint-checking code in exactly one subroutine that everyone calls,
all the time, whenever there is any change at all. There is one, and only one, place
where validation/enabling/hiding is done. See my essay on dialog control management, and
my essay on a validating edit control.
kill-focus validation does tend to lead to confusing situations, which is why I abandoned
it after a couple years of fighting these problems.
joe
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
many thanks for your comments. Due to the complex nature of the issue
I've probably not described it as well as I could (and I certainly
wasn't going to post that much code). I don't do UpdateData() from
within the OnKillFocus() - I use this merely as a method of getting the
framework to call DoDataExchange() where I upload the data from the
controls into the CRecordset fields. The button is not part of the View
but of the Framework, which I should probably have made clear.
Interestingly, I do some of the things that you say you should never do
and have found ways of implementing them successfully (except in this
one puzzling case that I posted originally).
I would like to thank you for your suggestion to get the button to do a
PostMessage() rather than actually run the code - I'd not thought of
this one and, now you've pointed it out, does seem rather elegant.
Thanks again for taking the time to reply, it's very appreciated.
Paul.
On Mon, 3 Jul 2006 19:33:43 +0200, "Michael Buechel" <mcb at gmx dot at> wrote:
>Hi Paul,
>i've also created a set of in-place validation for edit controls.
>i check the edited values through the PreTranslateMessage
>and change the bg color if failed. I use the
>
>ON_CONTROL_REFLECT_EX(EN_KILLFOCUS, OnKillFocus)
>
>to handle the kill focus event to restore the color.
>
>Mabe this will help you.