Technical Information Database TI422D.txt Does a Turbo Vision control have the input focus? Category :TVISION Platform :All Product :Pascal All Description: The following program demonstrates how to detect if a control in a Turbo Vision dialog has received the focus. The key is the cmReceivedFocus message, which gets sent to the owner of a control whenever that control is about to receive the focus. Here is sample code showing how to respond to the message: procedure TTrainDialog.HandleEvent(var Event: TEvent); begin if (Event.What = EvBroadCast) and (Event.InfoPtr = MyInputLine) and (Event.Command = cmReceivedFocus) then begin MessageBox('Got cmReceivedFocus Message, nil, mfOkCancel); end; TDialog.HandleEvent(Event); end; The above code sample assumes that an inputline has been inserted into a dialog. Whenever the user TABs to the input line, then the cmReceivedFocus message is sent to the control's owner. Note that its not sent to the control itself, but to the control's owner! Note also that this is a broadcast message. Of course its not enough just to pick up on broadcast cmReceivedFocus messages. You also have to detect which control has just received the focus. To do this, you can use the InfoPtr field of the incoming TEVENT record. This field will contain a pointer to the control that is about to receive the focus. The example code here literally compares the pointer to a second copy of a pointer to that control. If they are equal, then you know that you have the right control. Of course, the above code assumes that you have explicitly saved and declared a pointer to the inputline, as shown in the included example program. Now that you understand how cmReceivedFocus messages work, you might be interested in seeing another way of handling the same problem. This is to override the SetState function which actually generates cmReceivedFocus messages. In the program shown below, the following code fragment will enable and disable the state of a command on the statusline, depending on whether or not the control has the focus. procedure TMyButton.SetState(AState: Word; Enable: Boolean); begin inherited SetState(AState, Enable); if (AState = sfFocused) and (Enable = False) then DisableCommands([cmFoo]); if (AState = sfFocused) and (Enable = True) then EnableCommands([cmFoo]); end; The key to the above code is that it checks for sfFocused messages to find out whether the control is receiving or losing the focus. When running the following program, watch the status line to see which control has the focus. } program DlgFocus; uses App, Dialogs, Drivers, Menus, MsgBox, Validate, Views, Objects; const cmDialogBox = 101; cmTest = 102; cmButton = 103; cmInput = 104; InputLength = 128; TheMessage = 'The Input line just received focus.' + #13#10 + 'Chose OK to set Ok in the Inputline' + #13#10 + 'Chose Cancel to set Cancel in the InputLine'; type PMyButton = ^TMyButton; TMyButton = Object(TButton) procedure SetState(AState: Word; Enable: Boolean); virtual; end; PTrainDialog = ^TTrainDialog; TTrainDialog = Object(TDialog) MyInputLine: PInputLine; constructor Init(Bounds: TRect; ATitle: String); procedure HandleEvent(var Event: TEvent); virtual; end; TMyApp = Object(TApplication) constructor Init; procedure InitStatusLine; virtual; procedure HandleEvent(var Event: TEvent); virtual; procedure DialogBox; end; procedure TMyButton.SetState(AState: Word; Enable: Boolean); begin inherited SetState(AState, Enable); if (AState = sfFocused) and (Enable = False) then DisableCommands([cmButton]); if (AState = sfFocused) and (Enable = True) then EnableCommands([cmButton]); end; constructor TTrainDialog.Init(Bounds: TRect; ATitle: String); var R: TRect; Control: PView; S: String; begin TDialog.Init(Bounds, ATitle); R.Assign(2, 2, 37, 4); Insert(New(PMyButton, Init(R, 'Test', cmTest, bfNormal))); R.Assign(3, 5, 37, 6); MyInputLine := New(PInputLine, Init(R, InputLength)); Insert(MyInputLine); R.Assign(2, 4, 24, 5); Insert(New(PLabel, Init(R, 'Delivery instructions', MyInputLine))); R.Assign(2, 7, 37, 9); Insert(New(PButton, Init(R, 'O~k~', cmOk, bfDefault))); S := '32'; SetData(S); end; procedure TTrainDialog.HandleEvent(var Event: TEvent); var Result: Word; S: String; begin if (Event.What = EvBroadCast) and (Event.InfoPtr = MyInputLine) then case Event.Command of cmReceivedFocus: EnableCommands([cmInput]); cmReleasedFocus: DisableCommands([cmInput]); end; TDialog.HandleEvent(Event); end; constructor TMyApp.Init; begin inherited Init; DisableCommands([cmInput,cmButton]); end; procedure TMyApp.HandleEvent(var Event: TEvent); begin TApplication.HandleEvent(Event); if Event.What = EvCommand then begin case Event.Command of cmDialogBox: DialogBox; else Exit; end; ClearEvent(Event); end; end; procedure TMyApp.InitStatusLine; var R: TRect; begin GetExtent(R); R.A.Y := R.B.Y - 1; StatusLine := New(PStatusLine, Init(R, NewStatusDef(0, $FFFF, NewStatusKey('', kbF10, cmMenu, NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit, NewStatusKey('~Alt-D~ Dialog', kbAltD, cmDialogBox, NewStatusKey('~Alt-F4~ Button Focused?', kbAltF4, cmButton, NewStatusKey('~Alt-F5~ InputLine Focused?', kbAltF5, cmInput, nil))))), nil) )); end; procedure TMyApp.DialogBox; var R: TRect; D: PDialog; begin R.Assign(20,5,60,15); D := New(PTrainDialog, Init(R, 'Hit Tab, watch statusline')); if ValidView(D) <> Nil then DeskTop^.ExecView(D); Dispose(D, Done); end; var A: TMyApp; begin A.Init; A.Run; A.Done; end. Reference: 7/16/98 4:33:44 PM
Last Modified: 01-SEP-99