Discussion:
New value of checkbox
(too old to reply)
Gian Luca Spadotto
2008-07-04 08:59:21 UTC
Permalink
hi.
I have a problem with VCL.
This is the scenario.

A tedit control and a tcheckbox and a tbutton in a form.

In tedit OnExit event I have some work if the checkbox is clicked and some
else if not
(or if button is clicked or not).

I write my data in tedit control then i click in the checkbox (or button).

In tedit-OnExit time, CheckBox->Checked (or Status) return the old value!

How i can know in tedit/OnExit moment the checkbox new value ?

I tried with the CheckBox->ControlState (and CheckBox1->ControlStyle <<
csClickEvents)
but don't work how I hope.

Thank you;
--
Gian Luca Spadotto
Clayton Arends
2008-07-04 18:33:04 UTC
Permalink
Post by Gian Luca Spadotto
I write my data in tedit control then i click in the checkbox (or button).
In tedit-OnExit time, CheckBox->Checked (or Status) return the old value!
The OnExit event for your edit control happens before the
OnClick/OnMouseDown happens for the button or the check box. You need to
redesign or rethink your approach. If you post what you are trying to do
someone may be able to give you some advice.

Clayton
Gian Luca Spadotto
2008-07-05 07:51:43 UTC
Permalink
Hi Clayton

Thank you for your answer.

I want explain you the question in more detail.

I want write a SPEEDY data entry program.
The program has several forms.

At OnExit time of every data entry Control, i check if the form has the
MINIMAL data to go next step ( the next form).
If the form has the MINIMAL-VERIFIED data, go next step. If not, the program
remain in the same form with an error message.

Every form has a UNCECKED CheckButton with Caption "STOP".

If the user want write MORE the minimal data in the form, he can:
1- First click the STOP Check box (or before minimal data entered) >>
no problem because the program stops
2- Enter the minimal data and then click on CheckBox control ( that is STOP!
I WANT ENTER MORE DATA IN THIS FORM).
Here is the problem: every Edit/OnExit is processed before the CheckBox
OnClick event, so the program CONTINUE to next form even though the user
clicked the STOP CheckBox.

I want bypass the classical manner of verify data: the data verification for
all data, at the same time, after the user clicks a OK button !.


Other way to explain this problem:
I put my data verification line in the OnExit event of a control. In the
same form i put a button with caption "ABORT".
That is: I don't want execute data verification if i click the ABORT button.
Because Edit/OnExit is processed before the Button OnClick event,
i am forced to enter correct data even though the ABORT button is clicked!


--------------------------------------------------------------------------------------------------------------------------------

I tried to solve this problem with
the CheckBox1->ControlState (and CheckBox1->ControlStyle << csClickEvents)

The online help for TControl::ControlState says "Indicates the current state
of a control at runtime......Read ControlState to find out various
conditions that affect the control such as whether it has been clicked or
needs alignment. ControlState reflects transient conditions of an instance
of the control....."

Two possible flags are "csClicked"( The same as csLButtonDown, but only set
if ControlStyle contains csClickEvents, meaning that mouse-down events are
interpreted as clicks) and "csFocusing" (The application is processing
messages intended to give the control focus).

In tedit/OnExit time, if CheckBox1->ControlState returns "csClicked" the
problem is solved: I switch the old value of CheckBox1 and continue!

But CheckBox1->ControlState at tedit/OnExit time returns properly only the
"csFocusing" flag! (why ?)
Only at tCheckBox/OnClick time CheckBox1->ControlState returns "csClicked"!
But it has nosense: I am already in the OnClick event!

OK. I say that CheckBox1->ControlState at tedit/OnExit time returns
properly only the "csFocusing" flag.

When the program runs, i write data in edit control and then i go in the
CheckBox control with the TAB key or with a MOUSE CLICK.

If you tell me the manner i go away from the tedit control i solve my
problem too!

At tedit/OnExit time, if CheckBox1->ControlState returns "csFocusing" and i
go away with the TAB key, i use the old value of CheckBox.
If i go away with MOUSE CLICK , i use the switched old value of CheckBox.

Thanks for your time and sorry for my english.

Gian Luca Spadotto
Post by Gian Luca Spadotto
hi.
I have a problem with VCL.
This is the scenario.
A tedit control and a tcheckbox and a tbutton in a form.
In tedit OnExit event I have some work if the checkbox is clicked and some
else if not
(or if button is clicked or not).
I write my data in tedit control then i click in the checkbox (or button).
In tedit-OnExit time, CheckBox->Checked (or Status) return the old value!
How i can know in tedit/OnExit moment the checkbox new value ?
I tried with the CheckBox->ControlState (and CheckBox1->ControlStyle <<
csClickEvents)
but don't work how I hope.
Thank you;
--
Gian Luca Spadotto
Remy Lebeau (TeamB)
2008-07-06 07:20:25 UTC
Permalink
Post by Gian Luca Spadotto
At OnExit time of every data entry Control, i check if the form
has the MINIMAL data to go next step ( the next form).
If the form has the MINIMAL-VERIFIED data, go next step.
If not, the program remain in the same form with an error message.
Rather than have the OnExit event do the processing immediately, I suggest
you post a custom message to delay the processing until after the UI has a
chance to update itself, ie:

#define WM_CHECKMINDATA (WM_APP + 100)

void __fastcall TForm1::Edit1Exit(TObject *Sender)
{
PostMessage(Handle, WM_CHECKMINDATA, 0, 0);
}

void __fastcall TForm1::WndProc(TMessage &Message)
{
if( Message.Msg == WM_CHECKMINDATA )
{
if( has minimal data for current step )
move to next step
}
else
TForm::WndProc(Message);
}
Post by Gian Luca Spadotto
I want bypass the classical manner of verify data: the data verification
for all data, at the same time, after the user clicks a OK button !.
Why?
Post by Gian Luca Spadotto
I put my data verification line in the OnExit event of a control. In the
same form i put a button with caption "ABORT".
That is: I don't want execute data verification if i click the ABORT button.
If you have separate OK and ABORT buttons, then one can perform validation
and the other can skip it. Why bypass that design?
Post by Gian Luca Spadotto
Because Edit/OnExit is processed before the Button OnClick event,
i am forced to enter correct data even though the ABORT button is clicked!
All the more reason NOT to use the OnExit event for validation. That is not
usually a good idea anyway. If you move the validation to the OK button,
then you don't have to perform validation when clicking on the ABORT button.


Gambit
Gian Luca Spadotto
2008-07-09 20:57:47 UTC
Permalink
Thank you Remy!
I tryed your suggestion as follow, but, as you can see in the following
source code, nothing has changed!
Perhaps i've misunderstood your code ?
This sequence of breakpoints starts when i leave Edit1 to CheckBox1 with a
mouse click.

UNIT1.H--------------------------

class TForm1 : public TForm
{
__published: // IDE-managed Components
TEdit *Edit1;
TCheckBox *CheckBox1;
void __fastcall Edit1Exit(TObject *Sender);
void __fastcall CheckBox1Click(TObject *Sender);
void __fastcall WndProc(TMessage &Message); // <<<<=====!!!!
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;




UNIT1.CPP--------------------------
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#define WM_CHECKMINDATA (WM_APP + 100) // <= !!!!
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Edit1Exit(TObject *Sender)
{

int Test1 = PostMessage(Handle, WM_CHECKMINDATA, 0, 0); // <= !
int aa = 3; // Put a breakpoint on this line!
// first break, Test1=1 -> the function succeeds!
}
//---------------------------------------------------------------------------
void __fastcall TForm1::WndProc(TMessage &Message)
{
if ( Message.Msg == WM_CHECKMINDATA ) // <= !!!!
{
// minimal data ok, MOVE TO THE NEXT STEP IF CheckBox1 NEW VALUE IS
// UNCHECKED!
bool Test2 = CheckBox1->Checked;
int aa = 3; // Put a breakpoint on this line!
// second break, Test2 is the CheckBox1 OLD VALUE
// AGAIN in Test2!
}
else
TForm::WndProc(Message);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::CheckBox1Click(TObject *Sender)
{
bool Test3 = CheckBox1->Checked;
int aa = 3; // Put a breakpoint on this line!
// third break, finally the right new value in
Test3!
}
//---------------------------------------------------------------------------
Post by Remy Lebeau (TeamB)
Post by Gian Luca Spadotto
At OnExit time of every data entry Control, i check if the form
has the MINIMAL data to go next step ( the next form).
If the form has the MINIMAL-VERIFIED data, go next step.
If not, the program remain in the same form with an error message.
Rather than have the OnExit event do the processing immediately, I suggest
you post a custom message to delay the processing until after the UI has a
#define WM_CHECKMINDATA (WM_APP + 100)
void __fastcall TForm1::Edit1Exit(TObject *Sender)
{
PostMessage(Handle, WM_CHECKMINDATA, 0, 0);
}
void __fastcall TForm1::WndProc(TMessage &Message)
{
if( Message.Msg == WM_CHECKMINDATA )
{
if( has minimal data for current step )
move to next step
}
else
TForm::WndProc(Message);
}
Post by Gian Luca Spadotto
I want bypass the classical manner of verify data: the data verification
for all data, at the same time, after the user clicks a OK button !.
Why?
Post by Gian Luca Spadotto
I put my data verification line in the OnExit event of a control. In the
same form i put a button with caption "ABORT".
That is: I don't want execute data verification if i click the ABORT button.
If you have separate OK and ABORT buttons, then one can perform validation
and the other can skip it. Why bypass that design?
Post by Gian Luca Spadotto
Because Edit/OnExit is processed before the Button OnClick event,
i am forced to enter correct data even though the ABORT button is clicked!
All the more reason NOT to use the OnExit event for validation. That is
not usually a good idea anyway. If you move the validation to the OK
button, then you don't have to perform validation when clicking on the
ABORT button.
Gambit
Remy Lebeau (TeamB)
2008-07-09 23:05:06 UTC
Permalink
Post by Gian Luca Spadotto
I tryed your suggestion as follow, but, as you can see
in the following source code, nothing has changed!
Then the WM_CHECKMINDATA message is arriving in the message queue before the
CheckBox messages arrive. You will have to delay it longer, such as via a
timer.

Alternatively, when the TEdit receives focus, set a flag somewhere
indicating the TEdit is the last control entered. When the CheckBox is
focused, see if the flag is set. If so, then you know the user moved from
the TEdit to the CheckBox, and can act accordingly.

I still think you have a fundamentally flawed design in general. You did
not answer my earlier question about why you are abandoning standard
validation practices. You already have OK and ABORT buttons on the form.
That is where you should be doing your validation. NOT when moving from one
control to the next.


Gambit
Gian Luca Spadotto
2008-07-10 21:09:29 UTC
Permalink
OK I try to explain why i like this error check system.

My costumers work with IBM AS400 machine (i'm the programmer) , with big and
green caracters. Mouse is used only to close the Client Access window!
When the users begin to use this working system, they are slow, unable and
often wrong.
Not to make mistakes users need a thousand requests for confirmation
This make the data enter very slow.
After two or three months of work, the practice makes them extremely fast,
safe and mistakes are rare.
User will not ever remove his hands off the keyboard to take the mouse, find
a window control and then click over this.
At this point people ask me "gian luca take away all confirmation from
programs. Make my work as fast as possible. If I will rarely wrong, I fix
myself the mistake."
My accounting program (Italian) is done in this way and is appreciated by my
customers.

A "bad" day my customers ask me the same program but really version windows.

I tried to send an email attachment with the form of my program, but is not
allowed.
I try to explain in words, without figures.

As you can (-'t-) see, there are four GroupBox (steps) : Dati Comuni, Conti,
C/F, IVA.
For each Group, a CheckButton with Caption STOP.

The current Group (Step) has clGradientActiveCaption Color, the others
clBtnFace color.

A ListBox with error list (Txx=Terminal error, Wxx=Warning error).
A Button CHIUDI

Every fields for each group have a OnExit routine that
1- verify the correctness of data
2- if correct, check whether there are sufficient data to move to next
step
3- if correct and sufficient, verify if the group checkbox is Unchecked.
4- if everything is true, the program passes to the next step

I try to explain you the mechanism.
We begin the first step.

The user find "Data Registrazione" alredy set to today date.
The cursor is in "Causale" field.
The user begin with two keystrokes: 02.
Causale= 02 makes it mandatory number and date document. The program show
IMMEDIATLY
and WITHOUT ANY OTHER ACTION, like click a "OK" button, a Terminal message
(this is the reason why the error list is LIVE!
The list shows the errors as the user enters data, not after pressing a OK
Button).
The user continues with number and date document whitout removing hands off
the keyboard .
When done, the program consider to have sufficient and correct data to
continue to step two.
The "Storno" field is a no mandatory field, so is bypassed.
Now, the current Group (Step) with clGradientActiveCaption Color, is
"Conti".
Fields Enabled or Disabled, Visible or invisible in active group "Conti"
depend on the value of "Causale" field.
Let's go back a step backwards.
Rarely the user may want to set the "Storno" field.
I want the user enter number and data document and then click the STOP
CheckBox to say
"don't go to the next step,i want enter more data than minimal sufficient".
As you know, when the user passes from the data document to the checkbox
with a click of mouse, OnExit is processed before updating value of CheckBox
State.
So the program read "check box state=UNcecked" (the old value) and continue
without leaving the user the ability to enter more data in the same Group.

I thought to customize the status of departure of STOP checkboxes of each
group according to the skill of the user.
For example, the user wants the fast data entry (minimal) for the group
"Comuni", so start with UNchecked "Comuni" Stop Checkbox.
That rare time the user wants insert more data, will click on "Comuni" Stop
Checkbox.
Instead the user usually wants to enter all the data for "Comuni" group, so
start with CHECKED "Conti" Stop Checkbox.
When the user wants to go to next step (without errors), will click on
"Comuni" Stop Checkbox to set UNChecked.

with this system, will continue until complete registration over all groups.
the same kind of problem there if I want to close the window with the button
CHIUDI but there are still Terminal errors.

I hope I have answered your question.
Post by Remy Lebeau (TeamB)
Then the WM_CHECKMINDATA message is arriving in the message queue before
the CheckBox messages arrive. You will have to delay it longer, such as
via a timer.
Sorry Gambit, can you show me a little example?
Post by Remy Lebeau (TeamB)
Alternatively, when the TEdit receives focus, set a flag somewhere
indicating the TEdit is the last control entered. When the CheckBox is
focused, see if the flag is set. If so, then you know the user moved from
the TEdit to the CheckBox, and can act accordingly.
Yes Gambit, but i don't know if the user go to the CheckBox with the TAB key
(in this case i don't know if the user wants toggle the CheckBox value)
or with a click of mouse (in this case i know that the user wants toggle the
CheckBox Value).
as I already know that this would solve my problem.
In other words: if i Know if the user leave the TEdit control with TAB key
or with a mouse click, I solve my problem.

Thank you!



Gian Luca Spadotto
Post by Remy Lebeau (TeamB)
Post by Gian Luca Spadotto
I tryed your suggestion as follow, but, as you can see
in the following source code, nothing has changed!
Then the WM_CHECKMINDATA message is arriving in the message queue before
the CheckBox messages arrive. You will have to delay it longer, such as
via a timer.
Alternatively, when the TEdit receives focus, set a flag somewhere
indicating the TEdit is the last control entered. When the CheckBox is
focused, see if the flag is set. If so, then you know the user moved from
the TEdit to the CheckBox, and can act accordingly.
I still think you have a fundamentally flawed design in general. You did
not answer my earlier question about why you are abandoning standard
validation practices. You already have OK and ABORT buttons on the form.
That is where you should be doing your validation. NOT when moving from
one control to the next.
Gambit
Remy Lebeau (TeamB)
2008-07-10 23:41:00 UTC
Permalink
Post by Gian Luca Spadotto
OK I try to explain why i like this error check system.
Validating when exiting a control is not a good idea. What you describe can
be done quite easily when clicking on the OK button to close the window when
finished, without having to validate every control along the way. When
validating fails, you can jump the user back to the offending control so
they can fix it.

You still have not described anything that requires the type of coding you
are attempting.
Post by Gian Luca Spadotto
Every fields for each group have a OnExit routine that
1- verify the correctness of data
2- if correct, check whether there are sufficient data to move to next
step
3- if correct and sufficient, verify if the group checkbox is Unchecked.
4- if everything is true, the program passes to the next step
That is the kind of design you should stop doing. Just let the user, not
the program, decide when to move on to the next step, validating only at
that time and not allow it if validation fails.
Post by Gian Luca Spadotto
The user find "Data Registrazione" alredy set to today date.
The cursor is in "Causale" field.
The user begin with two keystrokes: 02.
Causale= 02 makes it mandatory number and date document. The program show
IMMEDIATLY
and WITHOUT ANY OTHER ACTION, like click a "OK" button, a Terminal message
(this is the reason why the error list is LIVE!
That is bad. If nothing else, just have the user press ENTER to invoke the
OK button. It only takes a fraction of a second on the user's part. They
won't notice any delay. But it will given them a chance to type whatever
they want and not allow the program to switch screens automatically without
warning. What if "02" is not the corrent text the user wants the program to
process? Maybe his/her finger slipped and he/she meant "03" instead. If
your app switches automatically, they have to go back and start over, taking
more time than if they have initiated the switch manually.
Post by Gian Luca Spadotto
The list shows the errors as the user enters data, not after pressing a OK
Button).
If they are still on the same step, then they should be free to make changes
all they want, and validation is only performed when they are ready to move
to the next step.
Post by Gian Luca Spadotto
The user continues with number and date document whitout removing hands
off the keyboard .
What I propose would allow that as well.
Post by Gian Luca Spadotto
When done, the program consider to have sufficient and correct data to
continue to step two.
I don't think that is the program's responsibility to do. It should be the
user's.
Post by Gian Luca Spadotto
Yes Gambit, but i don't know if the user go to the CheckBox with the
TAB key (in this case i don't know if the user wants toggle the CheckBox
value) or with a click of mouse (in this case i know that the user wants
toggle the CheckBox Value).
It won't matter. Focus switching occurs whether the mouse or keyword is
used.
Post by Gian Luca Spadotto
as I already know that this would solve my problem.
The real solution to your problem is to get rid of the checkbox to begin
with. It is making your design more complicated then it needs to be.


Gambit

Remy Lebeau (TeamB)
2008-07-06 07:09:48 UTC
Permalink
Post by Gian Luca Spadotto
I write my data in tedit control then i click in the checkbox (or button).
In tedit-OnExit time, CheckBox->Checked (or Status) return the old value!
That is because the TCheckBox has not actually been clicked yet. The
TEdit's OnExit event is being fired when the TEdit loses input focus, and
thus running your code before focus can move to the TCheckBox, and before it
can process the click messages.
Post by Gian Luca Spadotto
How i can know in tedit/OnExit moment the checkbox new value ?
Given the setup you have described, you can't. You will have to redesign
your code. It would be best not to use the OnExit event at all. But if you
must, then you will have to delay the processing, such as by starting a
short timer or posting a custom message, so your code is called after the
TCheckBox has processed its own messages first.


Gambit
Loading...