How can I set a new focus when PageDown is pressed?

I've looked for this in the search and got some hints, but not got a solution. I suspect it is pretty simple - I hope so!

I have an application that data entry people Tab through. It consists of small panels with a few checkboxes in each. The Tab button sets the focus from checkbox to checkbox then once it reaches the last checkbox, it sets the focus to the first checkbox in the next panel. This is of course just done through TabOrder.

I'd like the application to set the focus to the first button in the NEXT panel when the PageDown key is pressed. Any ideas?

Some background:

The panel and checkbox names are dynamically set, so I need a generic solution, though the name of the Checkbox DOES indicate which panel it is in: think of them as CheckBoxP1CB1, CheckBoxP1CB2, CheckBoxP2CB1 etc. where P1CB1 means "panel 1 checkbox 1". The PageDown needs to go to the next increment of P from the one with focus currently set.

The application is already rather top-heavy so I'd like to minimise reading of Windows messages as much as possible.

I've tried ApplicationEvents.OnMessage where msg.message = VK_NEXT but I wasn't able to get it working, and it executed about a hundred times a second!

Quick and simple is ideal.

Thanks!
MartinCAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ILECommented:
i dont realy anderstand how u change panels
 it is wery easy to set focus when u know the name of component





var i:integer;
begin
for i:=0 to form1.componentcount-1 do
if (form1.components[i] is tcheckbox) and ((form1.Components[i] as tcheckbox).name='CheckBoxP1CB1') then
(form1.Components[i] as tcheckbox).setfocus;
end;
 

this code will set focus for checkbox1p1cb1

now will be easy for you to do other things

0
Stuart_JohnsonCommented:
Turn KeyPreview on on your form and then test for VK_NEXT in the OnKeyDown event for the form.

Here's a simple example:

---DFM --

object Form1: TForm1
  Left = 379
  Top = 189
  Width = 407
  Height = 227
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = False
  OnKeyDown = FormKeyDown
  PixelsPerInch = 96
  TextHeight = 13
  object Panel1: TPanel
    Left = 9
    Top = 9
    Width = 185
    Height = 88
    TabOrder = 0
    object Button1: TButton
      Left = 66
      Top = 24
      Width = 75
      Height = 25
      Caption = 'Button1'
      TabOrder = 0
    end
  end
  object Panel2: TPanel
    Tag = 1
    Left = 201
    Top = 9
    Width = 185
    Height = 88
    TabOrder = 1
    object CheckBox1: TCheckBox
      Left = 42
      Top = 12
      Width = 97
      Height = 17
      Caption = 'CheckBox1'
      TabOrder = 0
    end
  end
  object Panel3: TPanel
    Tag = 2
    Left = 9
    Top = 102
    Width = 185
    Height = 88
    TabOrder = 2
    object ListBox1: TListBox
      Left = 39
      Top = 6
      Width = 112
      Height = 67
      ItemHeight = 13
      TabOrder = 0
    end
  end
  object Panel4: TPanel
    Tag = 3
    Left = 201
    Top = 102
    Width = 185
    Height = 88
    TabOrder = 3
    object Edit1: TEdit
      Left = 39
      Top = 18
      Width = 121
      Height = 21
      TabOrder = 0
      Text = 'Edit1'
    end
  end
end


-----------------------------

---The unit File---

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    Panel4: TPanel;
    Button1: TButton;
    CheckBox1: TCheckBox;
    ListBox1: TListBox;
    Edit1: TEdit;
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
const
  MaxPanels = 3;

var
  ParentPanel: TPanel;
  Index, Count: Integer;
begin
  if Key = VK_NEXT then
    begin
      ParentPanel := TPanel(TControl(ActiveControl).Parent);
      Index := Succ(ParentPanel.Tag);
      if Index > MaxPanels then
        Index := 0;
      for Count := 0 to pred(ControlCount) do
        if Controls[Count] is TPanel then
          if TPanel(Controls[Count]).Tag = Index then
            begin
              TWinControl(TWinControl(Controls[Count]).Controls[0]).SetFocus;
              Break;
            end;
    end;
end;

end.



I hope this helps.

Stu
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MartinCAuthor Commented:
Stuart:

Thanks for that. "KeyPreview = true" is the key to it all, and one I would have probably not found ... I managed to work out a few things after that. I used a simple check of saving the current object's parent, tabbing, then comparing the new current object's parent to the stored one ... if it's the same, repeat process.

Points!

Incidentally, if you are the Stuart Johnson who used to work at Kariong, I am currently doing your old job ... Warren Booth says hello.

Here's the code I used, for those interested:


procedure TfrmDEntryMain.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  oParent: TWinControl;
  iLoopCheck: integer;
begin
  if key = VK_NEXT then
  begin
    oParent := ActiveControl.Parent;
    iLoopCheck := 0;
    while iLoopCheck < 52 do  // stop after 52 iterations - something is wrong
    begin
      FindNextControl(ActiveControl, true,false,false).SetFocus;
      if ActiveControl.Parent = oParent then // this is still in the same panel
        iLoopCheck := iLoopCheck + 1
      else
      begin
        iLoopCheck := 1001;
      end;
    end; // while < 52
    if (((ActiveControl = pNavpanel) or (ActiveControl.Parent = pNavpanel))
      and (pcBase.ActivePageIndex <= pcBase.PageCount)) then
    begin
      btnNextClick(btnNext);
    end; // if last on page
    FindNextControl(ActiveControl, true,false,false).SetFocus; // one more to next
  end; // if VK_NEXT
end;


... where btnNextClick includes the following code:


procedure TfrmDEntryMain.SetFocusToFirstQ;
var
  iLoopCheck: integer;
begin
  iLoopCheck := 0;
  while iLoopCheck < 52 do  // stop after 52 iterations - something is wrong
  begin
    FindNextControl(ActiveControl, true,false,false).SetFocus;
    if ((ActiveControl.Parent = pNavPanel)
      or (ActiveControl.Parent = pButtons)) then // this is still in the same panel
      iLoopCheck := iLoopCheck + 1
    else
    begin
      iLoopCheck := 1001;
    end;
  end; // while < 52
  FindNextControl(ActiveControl, true,false,false).SetFocus; // one more to next
  FindNextControl(ActiveControl, true,false,false).SetFocus; // one more to next
end;


... it's a bit clumsy but it works.

Martin
0
Stuart_JohnsonCommented:
HAHAHAHA!  Yes, I am the same Stuart Johnson that worked with Warren (although I was at West Gosford, not Kariong).

I must appologise to you up front for having to work on my old stuff :)  Good luck with it!  

Please tell me you're not working on the FSM program :)

Glad to have helped.

Good luck with Future School! (Mwahahahahaha - Evil Laugh)

Stu.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.