0

My question title may be a bit misleading; if so, I apologize. I am unsure how better to title it.

I am attempting to add geocoding for address validation to a Delphi 7 form (built with CLX), and I'm running into a bit of a problem with it. The details are:

  • The user is expected to enter the data in the address fields in order - address, city, state, zip code.
  • Immediately upon leaving the zip code field, the address validation is to be called. (User specification.)
  • If the address comes back as not valid, the user is to be given a yes/no selection asking whether to correct the given address. (User specification)
  • If yes, reset focus to appropriate field (address, city, state, zip) as seen in the result from the geocoding api. Otherwise, proceed to next field.

Immediately after exiting the yes/no dialog, the behavior of the mouse seems to be a bit screwy. For one click, it looks as though the previous form (supposedly closed by this point) is instead receiving the focus - an on-click event on that form is capable of changing some of the values on this one (preloading of data), and those values will change if the mouse is clicked. Disabling the on-click event simply means that there is one mouse click that does nothing on the new form, then the click behavior returns to what is expected.

I've seen several things online while researching this; the consensus from these is that my problem is the conjunction of a Message Dialog inside the Zip Code field's OnExit event. (The MouseUp event seems to be getting lost between the two windows if I understand what I've read correctly.)

If I had my own way, I'd be including a manual button-press to run the validation. Given that end-user constraints bind me into a situation where I do not have that option, what is the best way to handle this situation?

Ken White
  • 123,280
  • 14
  • 225
  • 444
user2051521
  • 149
  • 3
  • @KenWhite: that is generally true for VCL, but does it also apply to CLX? – Remy Lebeau Dec 04 '14 at 23:01
  • @Remy: I'm pretty sure the same solution (particularly Sertac's answer) applies, but I don't have any way to test it on CLX. If the poster edits to indicate that they have seen and tried that post's solution and it doesn't work, I'll undo the duplicate close vote. – Ken White Dec 04 '14 at 23:08
  • @KenWhite: Tried that - PostMessage doesn't work for CLX forms, as it requires the handle be a HWND value, which CLX doesn't use. Attempted to get around that by using Self.Dispatch(Msg), best replacement I could find for the PostMessage call, but that method was still producing the same errant behavior. – user2051521 Dec 05 '14 at 01:11
  • 1
    Specifically, look at NGLN's [answer](http://stackoverflow.com/a/7082298) to the linked question, which has an alternative to PostMessage that should work properly in CLX. That answer isn't the accepted one (it doesn't have the green checkmark), but it still should solve the problem you're having. – Ken White Dec 05 '14 at 01:30
  • Is the form on which user is entering the location info a modal form? Can user clicks on previous form while this form is shown? Making this form modal should prevent any other form from recieveing any mouse clicks and not to mention gain focus at any time. – SilverWarior Dec 05 '14 at 08:11
  • As for general way of handling this whole situation I think that your end-user is insisting on a really bad one. Let me try to explain why it is so bad. Imagine an expirienced clerk entering some data into your program. He/she would probably do it by quickly typing the data into fields and cycling thourgh the fields by using TAB key while reading the information that needs to be entered from some paper during that whole time. What this means is that the clerk woud not even see your Message Dialog poping up and thus try to continue typing more information in. It continues... – SilverWarior Dec 05 '14 at 08:48
  • So after the Message Dilaog is shown the clerk could do multiple key presses before even noticing that the data isn't being inputed (on windows this would be acompanied by the ding sound for each key press). And what is worse it is even posible to initiate click events of certain standard buttons with the keyboard aswell (pressing space bar initiates a click on curently focused button, it is posible to enable the aditional shortcuts for standart buttons like pressing O key for OK button or C key for Cancel button, etc.). So user could even close your Message Dialog before even seeing it. ... – SilverWarior Dec 05 '14 at 08:55
  • Not to mention that if you would then programatically change focus to certain filed that clerk could continue inputing the data into that filed. And that would be wrong data in wrong field. So when the clerk would finall look at the screen seing that he is not in the field that he expected to be and that he might have overwriten some correct data in other fields his only reaction would probably be WTF! ... – SilverWarior Dec 05 '14 at 08:58
  • 1
    Therefore I recomend a different approach. Instead of showing the Dialog Message after data verification fails simply change the background color of those fields that have wrong data in them so that the error can be easily seen (bright red is easuily noticable). But don't change focus so you still alow the clerk to continue entering the data in the rest of the fields without interuption. You can play a sound to give the audiotory warning to the user that he entered the wrong data. But finally make sure that user can't leave this form without bein warned again by the wrong data. ... – SilverWarior Dec 05 '14 at 09:04
  • Now you can use Message Dialog in which you requires for user to confirm the entering of wrong data becouse at this time it si more likely that user will be watching the screen. – SilverWarior Dec 05 '14 at 09:05
  • @KenWhite: I'm sorry, but I'm failing to see what you suggest is present. NGLN's answer isn't an alternative to PostMessage, it uses PostMessage to send a WM_LBUTTONUP command to the active control. Attempting to replace the PostMessage call with the ActiveControl.Dispatch method to send the message is showing the same behavior - the first click after closing the message box is effectively ignored. Would you please explain why you believe this would work in the CLX environment? – user2051521 Dec 05 '14 at 16:39
  • @KenWhite: I'm obviously missing something here, and would appreciate help seeing where I'm going wrong. What, exactly, does the 'Screen.ActiveControl will point to' have to do with the issue? It looked to me as though it was just a comment about using the ActiveControl reference. As for setting to the previous control, I'm not sure what you mean - I am setting the focus for the component it's supposed to go to, but if the user wants to click on another component (editing the preloaded data, or closing the form, for example), the attempt fails because it doesn't register that first click. – user2051521 Dec 05 '14 at 17:09
  • I'm not sure what will work in CLX or not. It was really poorly implemented to begin with, and it's been defunct for a decade now. I'll remove my comments and close vote, and let someone who may still have it installed somewhere try to help; I can't test anything to make sure it will work. – Ken White Dec 05 '14 at 17:17

1 Answers1

0

Ideally, you could have the zip field's OnExit event use TThread.Queue() to delay the message dialog until after OnExit has exited first. Alas, TThread.Queue() was not introduced until Delphi 8. So OnExit will have to use an equivalent method, such as posting yourself a custom asynchronous message or starting a short one-time timer, to trigger the delayed action.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770