?
Solved

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

Posted on 2003-03-13
4
Medium Priority
?
318 Views
Last Modified: 2010-04-04
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!
0
Comment
Question by:MartinC
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 3

Expert Comment

by:ILE
ID: 8132569
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
 
LVL 6

Accepted Solution

by:
Stuart_Johnson earned 404 total points
ID: 8132586
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
 

Author Comment

by:MartinC
ID: 8149473
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
 
LVL 6

Expert Comment

by:Stuart_Johnson
ID: 8149482
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

Featured Post

New benefit for Premium Members - Upgrade now!

Ready to get started with anonymous questions today? It's easy! Learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Suggested Courses
Course of the Month10 days, 1 hour left to enroll

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question