community.borland.com

Article #15422: Does a Turbo Vision control have the input focus?

 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