Watch, Follow, &
Connect with Us

Welcome, Guest
Guest Settings
Help

Thread: Another TPageControl Question



Permlink Replies: 5 - Last Post: Mar 31, 2017 1:46 PM Last Post By: Remy Lebeau (Te... Threads: [ Previous | Next ]
Alan Jordan

Posts: 221
Registered: 3/2/01
Another TPageControl Question
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 8, 2017 10:09 AM
I have an application that uses multiple forms for input and output. I am using these forms in TPageControl with the following code:
var
Form : TForm;
Sheet : TTabSheet;
procedure MainForm.FormCreate(Sender, TObject);
begin
Sheet:=TTabsheet.Create(PageControl1);
Sheet.PageControl:=PageControl1;
Form:=TKinematicsDataDlg.Create(Application);
Form.BorderStyle:=bsNone;
Form.Parent:=Sheet;
Form.Visible:=true;
PageControl1.ActivePage:=Sheet;
Sheet.Caption:=Form.Caption;
end;
In each form that is shown, which now I am only showing one, I have OnKeyPress and OnMouseUp events that I want to fire. I don't see how to call those events from the MainForm that holds the PageControl.

Also, the only place the MainForm where the OnMouseDown or OnMouseUp fires is when I click in the PageControl area of the form. What am I missing?
Remy Lebeau (Te...


Posts: 8,641
Registered: 12/23/01
Re: Another TPageControl Question
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 8, 2017 11:38 AM   in response to: Alan Jordan in response to: Alan Jordan
Alan wrote:

I have an application that uses multiple forms for input and output.
I am using these forms in TPageControl with the following code:

You really shouldn't embed TForm objects like that. Use TFrame instead.
Either way, I suggest you set the TTabSheet object as the Owner instead
of the TApplication object.

In each form that is shown, which now I am only showing one, I have
OnKeyPress and OnMouseUp events that I want to fire. I don't see how
to call those events from the MainForm that holds the PageControl.

Those events are fired when the user types while the child Form has input
focus, or when the user clicks on a blank area of the child Form's client
area, respectively. Why do you need the MainForm to fire the events? What
are you really trying to accomplish?

--
Remy Lebeau (TeamB)
Alan Jordan

Posts: 221
Registered: 3/2/01
Re: Another TPageControl Question
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 10, 2017 12:15 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Alan wrote:

I have an application that uses multiple forms for input and output.
I am using these forms in TPageControl with the following code:

You really shouldn't embed TForm objects like that. Use TFrame instead.
Either way, I suggest you set the TTabSheet object as the Owner instead
of the TApplication object.
What is wrong with embedding a TForm in a PageControl? I want to use the same form in other code as a form, as well as embed in the PageControl.

In each form that is shown, which now I am only showing one, I have
OnKeyPress and OnMouseUp events that I want to fire. I don't see how
to call those events from the MainForm that holds the PageControl.

Those events are fired when the user types while the child Form has input
focus, or when the user clicks on a blank area of the child Form's client
area, respectively. Why do you need the MainForm to fire the events? What
are you really trying to accomplish?

If I am typing on the embedded form, doesn't it have input focus?

I can fire the embedded form's OnKeyPress with the following code, but I am using Activecontrol property in the form and I get an AV at that point.
Code from TPageControl form:

procedure TCamShaftForm.FormKeyPress(Sender: TObject; var Key: Char);

begin
if (Key=#13) then
begin
Form.OnKeyPress(Sender, Key); // This calls the form's FormKeyPress
end;

In the Embedded FormKeyPress lcode snippit looks like this:
procedure TKinematicsDataDlg.FormKeyPress(Sender: TObject; var Key: Char);
var
Str : String;
i : Integer;
begin
BackSpace:=false; // 02-22-2016 # 1886b
Str:=ActiveControl.Name; // this give an AV


--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 8,641
Registered: 12/23/01
Re: Another TPageControl Question
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 10, 2017 3:15 PM   in response to: Alan Jordan in response to: Alan Jordan
Alan wrote:

What is wrong with embedding a TForm in a PageControl?

They don't always work correctly when embedded.

I want to use the same form in other code as a form, as well
as embed in the PageControl.

A TFrame is best for that. Put all the content on the TFrame, and then you
can embed it as a child of a TTabSheet or blank TForm as needed.

If I am typing on the embedded form, doesn't it have input focus?

Not necessary. Typically only input controls, like TEdit, can have focus
for keyboard input.

I can fire the embedded form's OnKeyPress with the following code, but
I am using Activecontrol property in the form and I get an AV at that
point.

TCamShaftForm is not checking if the Form variable is NULL before calling
its OnKeyPress event handler. And TKinematicsDataDlg is not checking if
its ActiveControl is NULL before accessing its Name.

--
Remy Lebeau (TeamB)
Alan Jordan

Posts: 221
Registered: 3/2/01
Re: Another TPageControl Question
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2017 1:07 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
I wrote a small program of two forms; one with some controls and another with a TPageControl. On the one with the PageControl, I am creating the form with controls and putting it on a page. I have included the listings. Please tell me what is wrong with this approach.

Form with controls:
unit DockTestUnit;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls;

type
TTestForm = class(TForm)
BtnPanel: TPanel;
OpenBtn: TBitBtn;
MainPanel: TPanel;
Edit1: TEdit;
Label1: TLabel;
OpenDialog1: TOpenDialog;
Edit2: TEdit;
Edit3: TEdit;
Label2: TLabel;
procedure OpenBtnClick(Sender: TObject);
procedure FormKeyPress(Sender: TObject; var Key: Char);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;

var
TestForm : TTestForm;
BackSpace : Boolean;

implementation

{$R *.dfm}

procedure TTestForm.FormKeyPress(Sender: TObject; var Key: Char);
var
Str : String;
begin
BackSpace:=false;
Str:=(Sender as TForm).ActiveControl.Name;
Edit3.Text:='Actve Control Name: '+Str;
if (ActiveControl is TEdit) then
begin
if (Key=#13) then
begin
Key:=#0;
PostMessage(Handle,WM_NextDlgCtl,0,0);
end;
end;
end;

procedure TTestForm.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ShowMessage('Got to Embedded Form Mouse Down');
end;

procedure TTestForm.OpenBtnClick(Sender: TObject);
var
OldDir : String;
FN : String;
begin
OldDir:=GetCurrentDir;
OpenDialog1.InitialDir:=OldDir;
if OpenDialog1.Execute then
begin
FN:=OpenDialog1.FileName;
Edit1.Text:=FN;
end;

end;

end.

PageControl Form:
unit TPageControl_with_formsUnit;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.ExtCtrls,
DockTestUnit;

type
TForm1 = class(TForm)
PageControl1: TPageControl;
Panel1: TPanel;
procedure FormCreate(Sender: TObject);
procedure FormKeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1 : TForm1;
Form : TForm;
Sheet : TTabSheet;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin
Sheet:=TTabsheet.Create(PageControl1);
Sheet.PageControl:=PageControl1;
Form:=TTestForm.Create(Application);
Form.Parent:=Sheet;
Form.BorderStyle:=bsNone;
Form.Visible:=true;
PageControl1.ActivePage:=Sheet;
Sheet.Caption:=Form.Caption;
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
Form.OnKeyPress(Sender, Key);
end;

end.

Remy Lebeau (TeamB) wrote:
Alan wrote:

What is wrong with embedding a TForm in a PageControl?

They don't always work correctly when embedded.

I want to use the same form in other code as a form, as well
as embed in the PageControl.

A TFrame is best for that. Put all the content on the TFrame, and then you
can embed it as a child of a TTabSheet or blank TForm as needed.

If I am typing on the embedded form, doesn't it have input focus?

Not necessary. Typically only input controls, like TEdit, can have focus
for keyboard input.

I can fire the embedded form's OnKeyPress with the following code, but
I am using Activecontrol property in the form and I get an AV at that
point.

TCamShaftForm is not checking if the Form variable is NULL before calling
its OnKeyPress event handler. And TKinematicsDataDlg is not checking if
its ActiveControl is NULL before accessing its Name.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 8,641
Registered: 12/23/01
Re: Another TPageControl Question
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2017 1:46 PM   in response to: Alan Jordan in response to: Alan Jordan
Alan wrote:

I wrote a small program of two forms; one with some controls and
another with a TPageControl. On the one with the PageControl, I
am creating the form with controls and putting it on a page.

As I told you earlier, you really should use TFrame instead of TForm for
that purpose.

I have included the listings. Please tell me what is wrong with this
approach.

You are still making the same mistakes I mentioned earlier, all you did this
time was change the variable names.

I also see another issue: TTestForm.FormKeyPress() is retrieving the Name
of Sender.ActiveControl, but Sender is the TForm1 object, not the TTestForm
object. It then proceeds to process Self.ActiveControl instead of Sender.ActiveControl.
But this issue is moot unless you have TForm1.KeyPreview set to true, otherwise
the TForm1.OnKeyPress event won't be triggered in the first place when typing
Enter in a TEdit control.

Based on what you are trying to accomplish, I wouldn't even bother using
TTestForm.FormKeyPress() at all, I would let TForm1.OnKeyPress() handle everything:

unit DockTestUnit;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, 
Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls;
 
type
  TTestForm = class(TForm)
    BtnPanel: TPanel;
    OpenBtn: TBitBtn;
    MainPanel: TPanel;
    Edit1: TEdit;
    Label1: TLabel;
    OpenDialog1: TOpenDialog;
    Edit2: TEdit;
    Edit3: TEdit;
    Label2: TLabel;
    procedure OpenBtnClick(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: 
TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  TestForm: TTestForm;
 
implementation
 
{$R *.dfm}
 
procedure TTestForm.FormMouseDown(Sender: TObject; Button: TMouseButton; 
Shift: TShiftState; X, Y: Integer);
begin
  ShowMessage('Got to Embedded Form Mouse Down');
end;
 
procedure TTestForm.OpenBtnClick(Sender: TObject);
begin
  OpenDialog1.InitialDir := GetCurrentDir;
  if OpenDialog1.Execute then
    Edit1.Text := OpenDialog1.FileName;
end;
 
end.

unit TPageControl_with_formsUnit;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.ExtCtrls, 
DockTestUnit;
 
type
  TForm1 = class(TForm)
    PageControl1: TPageControl;
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.FormCreate(Sender: TObject);
var
  Sheet: TTabSheet;
  Form: TForm;
begin
  Sheet := TTabsheet.Create(PageControl1);
  Sheet.PageControl := PageControl1;
  Form := TTestForm.Create(Sheet);
  Form.Parent := Sheet;
  Form.BorderStyle := bsNone;
  Form.Visible := true;
  PageControl1.ActivePage := Sheet;
  Sheet.Caption := Form.Caption;
end;
 
// aassumes Form1.KeyPreview = True...
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
var
  Ctrl: TControl;
  Frm: TCustomForm;
begin
  Ctrl := Screen.ActiveControl;
  if (Ctrl is TEdit) and (Key = #13) then
  begin
    Key := #0;
    Frm := GetParentForm(Ctrl);
    if Frm <> nil then
      PostMessage(Frm.Handle, WM_NEXTDLGCTL, 0, 0);
  end;
end;
 
end.


--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02