From an Input-query to a static form

Peter Kiers
Peter Kiers used Ask the Experts™
on
Dear experts,

I have an application with a treeview on it, and 2 buttons.
One for making a File-node and the other for making a Folder-node.
Both procedures uses an Input Query. Now I don't want to use
an Input Query anymore but 2 static forms:
->NewItem.Pas, Name of de form: NewItemFrm
->NewFolder.pas, Name of de form: NewFolderFrm

Can someone help me to change the procedures FileBtnClick
and FolderBtnClick. All the functions in these procedures
has to remain, accept the Input-query part offcourse.

Greetings, Peter Kiers



NEW:
 
procedure TForm1.FileBtnClick(Sender: TObject);
begin
 NewItemFrm.showModal;
end;
(*---------------------------------------------------*)
procedure TForm1.FolderBtnClick(Sender: TObject);
begin
 NewFolderFrm.showModal;
end;
(*---------------------------------------------------*)
 
OLD:
 
procedure TForm1.FolderBtnClick(Sender: TObject);
var aText: string;
  aParent: TTreeNode;
begin
  aParent := nil;
  if TreeView1.Selected <> nil then
  begin
    if TreeView1.Selected.ImageIndex = 15 then
      aParent := TreeView1.Selected
    else
    begin
      ShowMessage('Select a folder first');
      Exit;
    end;
  end;
  if InputQuery('New Folder', 'New Folder Name:', aText) then
      begin
      if length(trim(aText)) > 0 then  AddItem(aText, 15, aParent)
      else MessageBox(0, 'You must enter a folder name.', 'Error', MB_OK + MB_ICONEXCLAMATION);
  end;
end;
(*---------------------------------------------------*)
procedure TForm1.FileBtnClick(Sender: TObject);
var aText: string;
begin
  aText := '';
  if (TreeView1.Selected <> nil) and (TreeView1.Selected.ImageIndex = 15) then
  begin
     if InputQuery('New Item', 'New Item Name:', aText) then
        begin
        if length(trim(aText)) > 0 then  AddItem(aText, 17, TreeView1.Selected)
        else MessageBox(0, 'You must enter an item name.', 'Error', MB_OK + MB_ICONEXCLAMATION);
     end;  
  end else
    ShowMessage('Select a folder in the treeview first.');
end;
(*---------------------------------------------------*)
procedure TForm1.AddItem(aText: string; aIndex: Integer; aParent: TTreeNode);
var n: TTreeNode;
  data: TItem;
  parentId: integer;
begin
  parentId := 0;
  if (aParent <> nil) and (TItem(aParent.Data) <> nil) then
    parentId := TItem(aParent.Data).ID;
  data := TItem.Create(AdoQuery1, -1, parentId, 0);
  data.NodeText := aText;
  data.ImageIndex := aIndex;
  n := TTreeNode.Create(TreeView1.Items);
  n.Text := data.NodeText;
  n.ImageIndex := data.ImageIndex;
  n.SelectedIndex := data.ImageIndex;
  TreeView1.Items.AddNode(n, aParent, aText, data, naAddChild);
end;

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
developmentguruPresident

Commented:
I have attached the DFM and PAS for a unit called Unit3 with a form called Form3.  This is an example of a generic input form.  You use it like this:

procedure TForm4.FormClick(Sender: TObject);
var
  Val : string;

begin
  Val := Caption;
  if GenericInput('Enter Your Initials', Val) then
    Caption := Val;
end;

All this example does is let you edit another form's caption.  Let me know if you have questions.
---DFM---
object Form3: TForm3
  Left = 0
  Top = 0
  Caption = 'Enter Your Name'
  ClientHeight = 65
  ClientWidth = 426
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poScreenCenter
  PixelsPerInch = 96
  TextHeight = 13
  object btnOK: TButton
    Left = 262
    Top = 35
    Width = 75
    Height = 25
    Caption = 'O&K'
    Default = True
    ModalResult = 1
    TabOrder = 0
  end
  object btnCancel: TButton
    Left = 343
    Top = 35
    Width = 75
    Height = 25
    Cancel = True
    Caption = '&Cancel'
    ModalResult = 2
    TabOrder = 1
  end
  object eInput: TEdit
    Left = 8
    Top = 8
    Width = 410
    Height = 21
    TabOrder = 2
  end
end
 
---PAS---
unit Unit3;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm3 = class(TForm)
    btnOK: TButton;
    btnCancel: TButton;
    eInput: TEdit;
  private
    function GetValue: string;
    procedure SetValue(const Value: string);
    { Private declarations }
  public
    { Public declarations }
    property Value : string read GetValue write SetValue;
  end;
 
var
  Form3: TForm3;
 
function GenericInput(FormCaption : string; var Input : string) : boolean;
 
implementation
 
function GenericInput(FormCaption : string; var Input : string) : boolean;
var
  NewForm : TForm3;
 
begin
  Result := false;
  NewForm := TForm3.Create(nil);
  try
    NewForm.Value := Input;
    NewForm.Caption := FormCaption;
    if NewForm.ShowModal = mrOK then
      begin
        Input := NewForm.Value;
        Result := true;
      end;
  finally
    NewForm.Free;
  end;
end;
 
{$R *.dfm}
 
{ TForm3 }
 
function TForm3.GetValue: string;
begin
  Result := eInput.Text;
end;
 
procedure TForm3.SetValue(const Value: string);
begin
  eInput.Text := Value;
end;
 
end.

Open in new window

Peter KiersOperator

Author

Commented:
What I want is

procedure TForm1.FileBtnClick(Sender: TObject);
begin
 NewItemFrm.showModal;
end;
(*---------------------------------------------------*)
procedure TForm1.FolderBtnClick(Sender: TObject);
begin
 NewFolderFrm.showModal;
end;
(*---------------------------------------------------*)

And after pressing the OK-button of the NewItemFrm
it has to this:

procedure TForm1.FileBtnClick(Sender: TObject);
var aText: string;
begin
  aText := '';
  if (TreeView1.Selected <> nil) and (TreeView1.Selected.ImageIndex = 15) then
  begin
     if InputQuery('New Item', 'New Item Name:', aText) then
        begin
        if length(trim(aText)) > 0 then  AddItem(aText, 17, TreeView1.Selected)
        else MessageBox(0, 'You must enter an item name.', 'Error', MB_OK + MB_ICONEXCLAMATION);
     end;  
  end else
    ShowMessage('Select a folder in the treeview first.');
end;

Accept for the Inputquery offcourse that's why i made a form.
And the same story for the OK-button of the NewFolderFrm.

Greetings, Peter Kiers


Peter KiersOperator

Author

Commented:
In my previous question I have put 4 pictures of how I want it.

http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_24576550.html

Grtz, PK
Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

Geert GOracle dba
Top Expert 2009

Commented:
i would advise you to go with developmentguru's suggestion

what you want poses future problems as to renaming of the form
developmentguru does not have this issue

just a single issue, rename TForm3 to something more generic like

TFormGenericInput

when walking this road, you have the benefit of:
1: possibility of renaming the form type and only having to change it in 1 procedure in the unit itself
2: not having to keep a form instance in a other form
3: use it from any other unit (or form), just add in the uses clause
4: you can even use descendants for modified behaviour

try build yourself a library so you don't have to keep reinventing the wheel
Peter KiersOperator

Author

Commented:
Hi,

I think I haven't explain it very well. Because I don't want to rename any form etc...

I have a Treeview with 2 buttons on the form, one for making a file-node in the treeview
and the other for making a folder-node in the treeview.

In steps:
1. when the user presses the button to make a file-node in the treeview.
2. The form NewItemFrm appears, where the user can enter a name for his file-node
3. But the edit-field must no be empty, so the user must put some text in it, otherise a message appears.
4. Does the user put text in the editbox and press OK of the NewItemFrm the node will be created in the treeview.

Same for the foldern-node.
Peter KiersOperator

Author

Commented:
Can please someone help me with this.
I made this example yesterday anticipating this question when I answered your previous question.
That said, developmentguru's & Geert_Gruwez advice is sound.

// Unit2.DFM
object Form2: TForm2
  Left = 0
  Top = 0
  Caption = 'New Folder'
  ClientHeight = 106
  ClientWidth = 318
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 12
    Top = 20
    Width = 88
    Height = 13
    Caption = 'New Folder Name:'
  end
  object edFolderName: TEdit
    Left = 12
    Top = 39
    Width = 293
    Height = 21
    TabOrder = 0
  end
  object btnOK: TButton
    Left = 72
    Top = 72
    Width = 75
    Height = 25
    Caption = 'OK'
    Default = True
    TabOrder = 1
    OnClick = btnOKClick
  end
  object btnCancel: TButton
    Left = 160
    Top = 73
    Width = 75
    Height = 25
    Caption = 'Cancel'
    TabOrder = 2
  end
end
 
// Unit2.pas
unit Unit2;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm2 = class(TForm)
    Label1: TLabel;
    edFolderName: TEdit;
    btnOK: TButton;
    btnCancel: TButton;
    procedure btnOKClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form2: TForm2;
 
implementation
 
{$R *.dfm}
 
procedure TForm2.btnOKClick(Sender: TObject);
begin
     if edFolderName.Text <> '' then
          ModalResult := mrOk
     else
          MessageDlg('You must enter a folder name.',mtError,[mbOK],0);
end;
 
end.
 
// Call in Unit1.pas
procedure TForm1.FileBtnClick(Sender: TObject);
begin
  if (TreeView1.Selected <> nil) and
     (TreeView1.Selected.ImageIndex = 15) and
     (Form2.ShowModal = mrOk ) then
          AddItem(Form2.edFolderName.Text ,17,TreeView1.Selected);
end;

Open in new window

Peter KiersOperator

Author

Commented:
Your the best. I am gratefull.
500 points are comming your way...

Greetings, Peter Kiers
Geert GOracle dba
Top Expert 2009

Commented:
why doesn't anybody see the use in not using the Form1, Form2, etc ... ?
has anybody ever tried to rename all the forms in an application ?

using developmentguru's code,
only with changing the function GenericInput you can accomplish this, not changing anything in the main form
function GenericInput(FormCaption : string; var Input : string) : boolean;
var
  NewForm : TForm3;
  ok, cancel: Boolean;
begin
  Result := false;
  NewForm := TForm3.Create(Application);
  try
    NewForm.Value := Input;
    NewForm.Caption := FormCaption;
    repeat 
      ok := False;
      case NewForm.ShowModal of
        mrOK: 
        begin
          if Trim(NewForm.Value) <> '' then 
          begin
            Ok := True;
            Input := NewForm.Value;
          end
          else 
            MessageDlg('The input value may not be empty.', mtWarning, [mbOk], 0);
        end;
        mrCancel: Cancel := True;
      end;
    until cancel or ok;
    if ok then     
      Result := true;
  finally
    NewForm.Free;
  end;
end;

Open in new window

I see the value in what is proposed here however it does not address Peter's desire to have the input form stay visible while validation occurs.  I'm sure that there is a way to accomplish this in a generically handled fashion but sometimes a simple problem is best handled by a simple solution.
BTW: Having to rename *all* of the forms in an application has never come up for me. Occasionally I have had to change the name of one or two forms and I can handle it in a few minutes with a search and replace.
Geert GOracle dba
Top Expert 2009

Commented:
i missed the part where the form has to stay visible

>>SteveBay
simple ?? i thought this site was for "expert" advise

i combined all the answers
(again changing nothing to the mainform)

assuming it's used like this:
procedure TForm4.FormClick(Sender: TObject);
var
  Val : string;
begin
  Val := Caption;
  if GenericInput('Enter Your Folder name', Val) then
    Caption := Val;
end;
unit Unit3;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TGenericInputFrm = class(TForm)
    btnOK: TButton;
    btnCancel: TButton;
    eInput: TEdit;
    procedure btnOKClick(Sender: TObject);
  private
    function GetValue: string;
    procedure SetValue(const Value: string);
  public
    function Validate: boolean; virtual;
    property Value : string read GetValue write SetValue;
  end;
 
var
  GenericInputFrm: TGenericInputFrm;
 
function GenericInput(FormCaption : string; var Input : string) : boolean;
 
implementation
 
function GenericInput(FormCaption : string; var Input : string) : boolean;
var
  NewForm : TGenericInputFrm;
  ok, cancel: Boolean;
begin
  Result := false;
  NewForm := TGenericInputFrm.Create(Application);
  try
    NewForm.Value := Input;
    NewForm.Caption := FormCaption;
    if NewForm.ShowModal = mrOk then 
    begin
      Result := True;
      Input := NewForm.Value;
    end;
  finally
    NewForm.Free;
  end;
end;
 
{$R *.dfm}
 
{ TGenericInputFrm }
 
function TGenericInputFrm.GetValue: string;
begin
  Result := Trim(eInput.Text);
end;
 
procedure TGenericInputFrm.SetValue(const Value: string);
begin
  eInput.Text := Value;
end;
 
procedure TGenericInputFrm.btnOKClick(Sender: TObject);
begin
  if Validated then 
    ModalResult := mrOk;
end;
 
function TGenericInputFrm.Validated: boolean;
begin
  Result := Value <> '';
  if not Result then 
    MessageDlg('You must enter a folder name.',mtError,[mbOK],0);
end;
 
end.

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial