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