Eszee
Eszee

Reputation: 262

Override the Tab control for a single Object

I found this code to override it for an entire class:

{ Private declarations }
  procedure CMDialogKey(Var Msg: TWMKey) ;
  message CM_DIALOGKEY;

procedure TForm1.CMDialogKey(var Msg: TWMKey);
begin
  if (ActiveControl is TEdit) and (Msg.Charcode = VK_TAB) then
  begin
   //
  end else
    inherited;
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  ShowMessage('Tab is Pressed!');
end;

Which works fine (for the entire class).

Is there some easy to understand code (I'm a starting programmer) that i can use? Or can I change the code above to fit my needs?

Upvotes: 1

Views: 757

Answers (2)

J...
J...

Reputation: 31403

Following on from comments, one way to do what you are asking is to make use of the Tag property that every VCL control has. You could define a constant like :

const MOVE_NEXT = 123; 

Then, in the designer, choose whichever control in the TabSheet is to be the final control that triggers a page change and set its Tag property to 123. Ideally, this is most likely to be the control with the highest TabOrder on the page. You could also do this programmatically, of course.

enter image description here

In your method, then :

procedure TForm1.CMDialogKey(var Msg: TWMKey);
begin
  if (ActiveControl.Tag = MOVE_NEXT) and
     (Msg.Charcode = VK_TAB) and
     (PageControl1.ActivePageIndex < PageControl1.PageCount - 1) then
  begin
    PageControl1.ActivePageIndex := PageControl1.ActivePageIndex + 1;
    Msg.Result := 1;
    // note : it is good practice to set the message result to 1 
    // to indicate that you have handled the message.
  end else
    inherited;
end;

The method above will cause the TAB key to cycle through all of its pages, landing at each control in the TabOrder dictated by the contained controls. The control with Tag property of 123 will trigger the selection of the next tab. As it is written, it will cycle through the page control once and then leave to the next control on the form.

On the next cycle around, of course, the PageControl will remain on its final page and the Tab key will simply cycle through the controls on the final page before moving on. You could have the page control reset to its first page each time, however, by doing something similar with the preceding TabOrder control on the form - for example :

procedure TForm1.CMDialogKey(var Msg: TWMKey);
begin
  if (ActiveControl.Tag = MOVE_NEXT) and
     (Msg.Charcode = VK_TAB) and
     (PageControl1.ActivePageIndex < PageControl1.PageCount - 1) then
  begin
    PageControl1.ActivePageIndex := PageControl1.ActivePageIndex + 1;
    Msg.Result := 1;
    Exit;
  end;

  // define new const MOVE_FIRST = 124 
  if (ActiveControl.Tag = MOVE_FIRST) and (Msg.Charcode = VK_TAB) then
  begin
    PageControl1.ActivePageIndex := 0;
    PageControl1.SetFocus;
    Msg.Result := 1;
    Exit;
  end;

  inherited;
end;

Upvotes: 3

SilverWarior
SilverWarior

Reputation: 8331

While @J... sugestion would work it is not intuitive as you would have to tab through every control on that specific page on PageControll. Try tabing through about 50 components and you will se what I mean. Don't have any form with so many components. Then open a webpage and use TAB key to move between different controlls that web page is made of.

So why not use specific key combination for quickly moving through pages for PageControll like CTRL+TAB which is comonly used in many programs that support multiple tabs (most web browsers) or even working on multiple documents (older versions of Microsoft Word, Curent versions of Microsoft Excel, etc.)

Infact isn't such feature already implemented in Page Controll already?

Upvotes: 2

Related Questions