Technical Information Database TI363D.txt Using Validators in OWL Applications Category :General Programming Platform :All Product :Pascal All Description: Starting with version 7.0, Borland Pascal introduced Validator objects for Turbo Vision and the Object Windows Library. These objects help guide the user when they are entering data in Edit fields. The purpose of this TI is to introduce the user to the idea of using Validators in OWL applications. Validators are very flexible objects which can play several different roles in your program. A typical validator might ensure that the user can only enter numbers within a certain range into a particular field. Another common use for Validators might be to ensure that users enter stock numbers that begin with two alphanumeric characters, then include a dash followed by four numbers. An example of this type of stock number might look like this: WD-3344. These are only two examples of the many different types of validators you can create for your programs. Validators are extremely easy to use. In most cases you only need to add one line to your code. Suppose you want to add a validator to an edit field which will ensure that the user can only enter numbers between five and eight. First you would initialize your edit field, just as you have always done: AEdit := New(PEdit, InitResource( Self, Cm_NumEdit, 50)); The next step is to initialize the validator. The following line of code turns the trick: AEdit^.SetValidator(New(PRangeValidator, Init(5, 8))); That's all you need to do. Now the only characters the user can enter into the control will have to fall within the specified range. When compiled, the program and resource script included in this Tech Info Sheet help demonstrate many of the primary features of the validator unit. Included in the example are two range validators, four picture validators and one custom validator. The range validators ensure that input falls inside a particular numeric range. One of the picture validators helps guide the user while he enters a date, and another ensures that the user follows a valid format while entering a social security number. The other validators guide the user while he enters a stock number and a special entry that must begin with the letters 'MIKE' followed by a single number. In order to show you how to create your own Validators, we include a descendant of TPxPictureValidator called TSamValidator which gives you an idea of how to control input on a character by character basis. Validators usually work on a letter by letter or field by field basis. That is, they will check a user's input either as he enters each character, or later on, when he exits a field. If you want to check the data only when the user closes an entire screenful of data, then you should examine the TMyEdit object, presented below. In this object, we override the TEdit methods that would normally ensure that a user's input was checked as he leaves a field. As a result, the data is checked only when the user closes the dialog in which the edit fields reside. {************************************************} { } { Turbo Pascal 7.0 for Windows } { Demo program } { Copyright (c) 1992 by Borland International } { } {************************************************} program ValidExp; uses WinTypes, WinProcs, OWindows, ODialogs, Strings, Validate, BWCC; {$R ValidExp} const Cm_Dialog = 101; Cm_NumEdit = 102; Cm_NumEdit2 = 103; Cm_DateEdit = 104; Cm_StockEdit = 105; Cm_SSNEdit = 106; Cm_SamEdit = 107; Cm_MikeEdit = 108; type TMyApplication = object(TApplication) procedure InitMainWindow; virtual; end; type PMyWindow = ^TMyWindow; TMyWindow = object(TWindow) constructor Init(AParent: PWindowsObject; AName: PChar); procedure cmDialog(var Msg: TMessage); virtual cm_First + cm_Dialog; end; PMyEdit = ^TMyEdit; TMyEdit = Object(TEdit) procedure WMKillFocus(var Msg: TMessage); virtual wm_First + wm_KillFocus; procedure WmGetDlgCode(var Msg: TMessage); virtual wm_First + wm_GetDlgCode; end; PMyDialog = ^TMyDialog; TMyDialog = Object(TDialog) constructor Init(AParent: PWindowsObject; AName: PChar); end; PSamValidator = ^TSamValidator; TSamValidator = object(TPxPictureValidator) function IsValid(const S: string): Boolean; virtual; procedure Error; virtual; end; procedure TMyEdit.WMKillFocus(var Msg: TMessage); begin DefWndProc(Msg) end; procedure TMyEdit.WMGetDlgCode(var Msg: TMessage); begin DefWndProc(Msg); end; {--------------------------------------------------} { TMyWindow's method implementations: } {--------------------------------------------------} constructor TMyWindow.Init(AParent: PWindowsObject; AName: PChar); begin TWindow.Init(AParent, AName); Attr.Menu := LoadMenu(HInstance, 'Menu_1'); end; procedure TMyWindow.cmDialog(var Msg: TMessage); var D: PDialog; begin D := New(PMyDialog, Init( Self, 'Dialog_1')); Application^.ExecDialog(D); end; {--------------------------------------------------} { TMyWindow's method implementations: } {--------------------------------------------------} constructor TMyDialog.Init(AParent: PWindowsOBject; AName: PChar); var AEdit: PEdit; MyEdit: PMyEdit; begin TDialog.Init(AParent, AName); AEdit := New(PEdit, InitResource( Self, Cm_NumEdit, 50)); AEdit^.SetValidator(New(PRangeValidator, Init(5, 8))); MyEdit := New(PMyEdit, InitResource( Self, Cm_NumEdit2, 10)); MyEdit^.SetValidator(New(PRangeValidator, Init(1, 10))); AEdit := New(PEdit, InitResource( Self, Cm_DateEdit, 50)); AEdit^.SetValidator(New(PPXPictureValidator, Init('{#[#]}/{#[#]}/{##[##]}', True))); AEdit := New(PEdit, InitResource( Self, Cm_StockEdit, 50)); AEdit^.SetValidator(New(PPXPictureValidator, Init('&#-####', True))); AEdit := New(PEdit, InitResource( Self, Cm_SSNEdit, 50)); AEdit^.SetValidator(New(PPXPictureValidator, Init('###-##-####', True))); AEdit := New(PEdit, InitResource( Self, Cm_SamEdit, 50)); AEdit^.SetValidator(New(PSamValidator, Init('&&', True))); AEdit := New(PEdit, InitResource( Self, Cm_MikeEdit, 50)); AEdit^.SetValidator(New(PPXPictureValidator, Init('Mike#', True))); end; {--------------------------------------------------} { TSamValidator's method implementations: } {--------------------------------------------------} function IsNumber(Chr: Char): Boolean; near; assembler; asm XOR AL,AL MOV Ch,Chr CMP Ch,'0' JB 1 CMP Ch,'9' JA 1 INC AL 1: end; function TSamValidator.IsValid(const S: string): Boolean; var S1,S2: array[0..5] of Char; begin StrPCopy(S2, S); IsValid := False; StrLCopy(S1, S2, 3); if StrIComp(S1, 'Sam') = 0 then IsValid := True else Exit; if IsNumber(S2[4]) then IsValid := True; end; procedure TSamValidator.Error; begin MessageBox(0, 'Enter the word Sam followed by a number. Example: Sam1', nil, mb_IconExclamation + mb_OK); end; {---------------------------------------------------} { TMyApplication's method implementations: } {---------------------------------------------------} procedure TMyApplication.InitMainWindow; begin MainWindow := New(PMyWindow, Init(nil, 'Sample ObjectWindows Program')); end; {--------------------------------------------------} { Main program: } {--------------------------------------------------} var MyApp: TMyApplication; begin MyApp.Init('MyProgram'); MyApp.Run; MyApp.Done; end. MENU_1 MENU BEGIN MENUITEM "E&xit", 24340 MENUITEM "&Dialog", 101 END DIALOG_1 DIALOG 37, 28, 196, 163 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CLASS "BorDlg" CAPTION "Validator Dialog" BEGIN CONTROL "", 102, "EDIT", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 124, 12, 59, 12 CONTROL "", 103, "EDIT", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 123, 29, 59, 12 CONTROL "", 104, "EDIT", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 123, 46, 59, 12 CONTROL "", 105, "EDIT", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 123, 63, 59, 12 CONTROL "", 106, "EDIT", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 123, 80, 59, 12 CONTROL "", 107, "EDIT", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 123, 97, 59, 12 CONTROL "", 108, "EDIT", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 123, 114, 59, 12 CONTROL "Button", 2, "BorBtn", 1 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 53, 138, 32, 20 CONTROL "Button", 1, "BorBtn", 1 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 112, 138, 32, 20 CONTROL "Valid entries are 1-10 (No Tab)", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 19, 12, 101, 10 CONTROL "Enter a date", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 80, 46, 40, 10 CONTROL "Enter Stock Number (AANN-NNNN)", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 11, 63, 110, 10 CONTROL "Enter Social Security Num", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 34, 80, 86, 8 CONTROL "Enter SAM followed by number", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 20, 97, 100, 10 CONTROL "Enter MIKE followed by number", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 17, 114, 103, 10 CONTROL "", 106, "BorShade", 32774 | WS_CHILD | WS_VISIBLE, 6, 7, 184, 125 CONTROL "Valid entries are 5-8 (Tab Ok)", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 19, 29, 96, 10 END Reference: 7/16/98 4:33:42 PM
Last Modified: 01-SEP-99