Borland Online And The Cobb Group Present:


March, 1995 - Vol. 2 No. 3

How validator objects interact with edit controls

In the accompanying article, Extending objectwindows 2.0 - Enabling other controls after data validation we tell you that there are problems with enabling and disabling a control using a validator class. At the core of this problem is the way the standard TEdit class calls the member functions of a corresponding validator object. To help you understand why the validator isn't able to implement this functionality, we'll take a closer look at the step-by-step interaction of a TEdit object and its validator.

TEdit control

In the TEdit-TValidator relationship, the TEdit object controls the action. The validator can take action only when the TEdit object asks it to do so.

When you press a nonsystem key (a combination that doesn't involve the [Alt] key), Windows sends your application a WM_GETDLGCODE message and then a WM_KEYDOWN message. Later, the Windows TranslateMessage function translates the Windows message WM_KEYDOWN to a WM_CHAR message if the key represents a character entry of some kind (and not simply an arrow key press to move the cursor).

First, the TEdit object will respond to the WM_GETDLGCODE message with the EvGetDlgCode( ) message response function. This function analyzes the current data in the edit control (prior to the current keypress). The function then tells Windows whether to send [Tab] keypress messages to the edit control (if the data wasn't valid prior to the keypress) or to the enclosing dialog box for a focus change.

Next, the TEdit object will respond to the WM_KEYDOWN message with its EvKeyDown() message response function. If the user presses [Tab], the EvKeyDown() function immediately calls the TEdit object's IsValid() member function to determine whether to allow the user to change the focus away from the edit control. If the user presses any other key or if the data in the edit control is already valid, the EvKeyDown() function will process the input normally, and the data will appear in the edit control.

Which IsValid( ) function?

By the way, don't confuse the TEdit::IsValid() member function with the TValidator::IsValid() member function. The TEdit::IsValid() member function accepts a boolean parameter for determining whether the corresponding validator should post any appropriate error messages or allow the TEdit object to handle it.

After responding to the WM_KEYDOWN message, the TEdit object responds to the WM_CHAR message that follows, using the EvChar() function. If the user presses [Backspace] instead of pressing [Tab], the EvChar() function will immediately call the base class TStatic::EvChar() function to delete a character in the control. Since removing characters should always be a valid operation for an edit control, the EvChar() function won't bother to call the validator's IsValidInput() function.

If the user presses any other key, the EvChar() function will process the input and then call the validator's IsValidInput() function. This gives the validator a chance to check the data and modify it using the autofill option. If the input character is valid, the EvChar() function leaves it alone and returns. Otherwise, it restores the string to its original state (prior to adding the new character) before returning.

Several other TEdit member functions call TEdit::IsValid(), including

EvGetDlgCode()
EvKeyDown()
EvKillFocus()
CanClose()

However, these functions either receive their messages prior to the time when the new characters reach the edit control (this is the case with EvGetDlgCode) or they don't receive messages for each keypress when the user is entering data into the control.

Since the edit control doesn't call the validator's IsValid() member function after processing each keypress, you won't be able to override that function in a new validator class and enable or disable a control appropriately. Similarly, since the edit control doesn't call the IsValidInput() function when you begin deleting data from the edit control, you can't override that function to perform the enabling and disabling either.

Return to the Borland C++ Developer's Journal index

Subscribe to the Borland C++ Developer's Journal


Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.