Cancel button in Delphi VCL to over-ride default action in program

I have OnExit actions on many window components, as the user works through the screen.

However, if users want to stop processing, and they click on the cancel button or the exit button, the action of that button won't take place until the users get to a field that has no OnExit event (or similar). In this case the users have to keep clicking until they get the required response.

I have worked out a solution that seems to work, which is make the OnExit events indirect, by using a timer event to delay the execution of these OnExit events, which lets the Cancel button get the first action (and therefore lets me set a StopProcessing flag).

Is that the standard approach, or is there a better solution?
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Sinisa VukSoftware architectCommented:
Better solution is to use Forms OnCloseQuery event. If you put on some button Close to close form, then OnCloseQuery is fired up. There you can check for is all done:


procedure Tform1.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
  bOK: Boolean;
  CanClose := True; //enable close
  if not Check4JobDone then
    CanClose := False; //show some message here if want....

Open in new window

....but using TAction on each Button is more useful ...
With Actions use OnUpdate event to disable some of buttons and disable it until some conditions are fulfilled
Geert GOracle dbaCommented:
it's difficult to follow what you mean

is this like an installation process with next, previous, finish and exit ?
when clicking cancel instead of next, there is usually a question
  > Do you want to exit the installation

how the app reacts depends on how it's coded
GrahamDLovellAuthor Commented:

It is not like an installation process. It is more like completing a complicated form, but allowing the user to give up part way through the process.

I set the form up as two parts. The controls for the first part are on a panel. The second part is a TStringGrid on the form itself. Moving from the panel to the Grid involves running some checks that the first part data is complete, and then locating a combobox on the Grid (logically like the standard oncloseQuery, suggested above, but not on the close of the form).

I am mostly just using the tab order to move from one field to the next, but when I click on Cancel it just moves to the next field in the panel. On reflection (and after checking the code again to make sure I wasn't forcing this happen) this seems weird, so I looked further into my problem.

I can now see that part of my problem is in my use of a panel to hold the first set of controls, since putting the Cancel button on the panel avoids that symptom.

I can probably fix that part of the problem by getting rid of the panel (not as elegant, but workable). The TStringGrid issue is more complicated, since some fields are user controlled, and some programmatically controlled. I can use a timer here when moving from one cell to another, if necessary, delaying the action for OnSelectCell.
PMI ACP® Project Management

Prepare for the PMI Agile Certified Practitioner (PMI-ACP)® exam, which formally recognizes your knowledge of agile principles and your skill with agile techniques.

GrahamDLovellAuthor Commented:
OK. Here is my own solution.

The problem was of my own making.

Firstly, I used a panel to assist in handling the navigation. It didn't help, and when I removed it, the navigation improved.

Secondly, my field validation was poorly placed, since I refused to allow the program to exit a field unless it was properly completed. This meant that no other button was allowed to take any action on such a field. When I deferred the validation, it solved that problem.

Thanks to both those who responded. You both made me think about the underlying difficulties.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Geert GOracle dbaCommented:
it looks like the problem was in the code...glad we could help ... a little :)
GrahamDLovellAuthor Commented:
Neither of the expert responses provided an actual solution to my problem, but both helped me to solve it.
Geert GOracle dbaCommented:
ask a blind man to drive your car and then complain it's got a dent

same as asking to help with your code which you didn't share
GrahamDLovellAuthor Commented:
I wasn't aware that I had made a complaint: I was just stating the facts.

I appreciated the help I received.

My request really was of the sort "why is it so difficult to make this functionality work", and I interpreted both of the responses I received as saying "this should be simple."

This sent me back to the code to develop a test case, and in doing this, I found several problems that I had created.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.