Delphi Pages Forums  

Go Back   Delphi Pages Forums > Delphi Forum > General

Lost Password?

Reply
 
Thread Tools Display Modes
  #1  
Old 08-26-2010, 11:48 AM
mesnet mesnet is offline
Junior Member
 
Join Date: Aug 2010
Posts: 5
Default Using a variable name as string.

Hi,

Is it possible to use the name of a variable as string and use it in string operations. Here is a tiny dummy code to explain what I meant:

var
MyInteger:integer;
TheName:string;

begin
MyInteger:=1234;
TheName:=GetName(MyInteger);
end;


Suppose that GetName() is a fuction doing what I want, grabing the name of a variable and assigning it into another string variable in order to use it in further string operations.

How to code such a function.

Thanks in advance.

(I'm Delphi 7 user)
Reply With Quote
  #2  
Old 08-26-2010, 12:13 PM
Norrit Norrit is offline
Moderator
 
Join Date: Aug 2001
Location: Landgraaf
Posts: 7,307
Default

With properties this is possible using the RTTI, but with variables it's not possible...
Reply With Quote
  #3  
Old 08-26-2010, 02:10 PM
mesnet mesnet is offline
Junior Member
 
Join Date: Aug 2010
Posts: 5
Default

Thanks for your response.

Actually, I'm a mechanical engineer and my Delphi knowledge is very limited, just targetting my needs on engineering calculations and some tiny tools. After reading your answer I have read some articles on RTTI in internet but I could not relate it with my needs. Could you please give me a code doing the same thing with my dummy code using RTTI technique? And may be you can give me some link explaining RTTI for dummies like me.

Thanks.
Reply With Quote
  #4  
Old 08-26-2010, 02:42 PM
Norrit Norrit is offline
Moderator
 
Join Date: Aug 2001
Location: Landgraaf
Posts: 7,307
Default

Quick sample:
Code:
unit RttiDemoForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, TypInfo, ActnList, StdCtrls, ComCtrls;

type
  TMyClass = class(TComponent)
  private
    FStringValue: String;
    FIntegerValue: Integer;
  published
    property IntegerValue: Integer read FIntegerValue write FIntegerValue;
    property StringValue: String read FStringValue write FStringValue;
  end;

  TFormRTTI = class(TForm)
    ListViewProperties: TListView;
    ButtonRefresh: TButton;
    ActionList: TActionList;
    ActionRefresh: TAction;
    ComboBoxClasses: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure ActionRefreshExecute(Sender: TObject);
  private
    FTestInteger: Integer;
    FTestString: String;
    FMyClass: TMyClass;
    procedure SetTestInteger(const Value: Integer);
    procedure SetTestString(const Value: String);
  public
    property TestString: String read FTestString write SetTestString;
    property TestInteger: Integer read FTestInteger write SetTestInteger;
  end;

var
  FormRTTI: TFormRTTI;

implementation

{$R *.dfm}

procedure TFormRTTI.ActionRefreshExecute(Sender: TObject);
var
  aclass: TComponent;
  proplist: PPropList; // uses TypInfo
  propinfo: PPropInfo;
  i: Integer;
begin
  New(proplist);
  try
    case ComboBoxClasses.ItemIndex of
      0: aclass := FormRTTI;
      1: aclass := FMyClass;
      else Exit;
    end;

    // list all public and published properties of the class
    GetPropInfos(aclass.ClassInfo(), proplist);

    ListViewProperties.Items.BeginUpdate();
    try
      ListViewProperties.Items.Clear();

      for i := 0 to GetTypeData(aclass.ClassInfo())^.PropCount - 1 do
      begin
        propinfo := proplist^[i];
        with ListViewProperties.Items.Add() do
        begin
          Caption := propinfo^.Name;
          SubItems.Add(VarToStr(GetPropValue(aclass, propinfo)));
        end;
      end;
    finally
      ListViewProperties.Items.EndUpdate();
    end;
  finally
    Dispose(proplist);
  end;
end;

procedure TFormRTTI.FormCreate(Sender: TObject);
begin
  ActionRefresh.Execute();
  FMyClass := TMyClass.Create(Self);
  FMyClass.IntegerValue := 4;
  FMyClass.StringValue := 'some text';
end;

procedure TFormRTTI.SetTestInteger(const Value: Integer);
begin
  FTestInteger := Value;
end;

procedure TFormRTTI.SetTestString(const Value: String);
begin
  FTestString := Value;
end;

end.
Form:
Code:
object FormRTTI: TFormRTTI
  Left = 0
  Top = 0
  Caption = 'RTTI Demo'
  ClientHeight = 294
  ClientWidth = 562
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  DesignSize = (
    562
    294)
  PixelsPerInch = 96
  TextHeight = 13
  object ListViewProperties: TListView
    AlignWithMargins = True
    Left = 3
    Top = 3
    Width = 556
    Height = 249
    Align = alTop
    Anchors = [akLeft, akTop, akRight, akBottom]
    Columns = <
      item
        Caption = 'Property'
        Width = 200
      end
      item
        Caption = 'Value'
        Width = 200
      end>
    GridLines = True
    RowSelect = True
    TabOrder = 0
    ViewStyle = vsReport
    ExplicitLeft = 0
    ExplicitTop = 0
    ExplicitWidth = 562
  end
  object ButtonRefresh: TButton
    Left = 8
    Top = 261
    Width = 75
    Height = 25
    Action = ActionRefresh
    Anchors = [akLeft, akBottom]
    TabOrder = 1
  end
  object ComboBoxClasses: TComboBox
    Left = 112
    Top = 264
    Width = 145
    Height = 21
    Style = csDropDownList
    ItemHeight = 13
    ItemIndex = 0
    TabOrder = 2
    Text = 'TFormRTTI'
    Items.Strings = (
      'TFormRTTI'
      'TMyClass')
  end
  object ActionList: TActionList
    Left = 40
    Top = 56
    object ActionRefresh: TAction
      Caption = 'Refresh'
      OnExecute = ActionRefreshExecute
    end
  end
end
Reply With Quote
  #5  
Old 08-27-2010, 07:19 AM
mesnet mesnet is offline
Junior Member
 
Join Date: Aug 2010
Posts: 5
Default

I'm getting some error messages. Most probably due to my limited knowledge on implementing given external code into a delphi application.

This is one of them:
Error Reading Form
Error reading ListviewProperties.AlignwithMargins:
Property AlignWithMargins does not exist. Ignore the error and continue? NOTE: Ignoring the error may cause components to be deleted or property values to be lost.

Ignore Cancel Ignore All

There is three more same type of errors for
ListviewProperties.ExplicitLeft
ListviewProperties.ExplicitTop
ListviewProperties.ExplicitWidth


I ignored all of them.
Then when I try to run, I get an error in this line:

SubItems.Add(VarToStr(GetPropValue(aclass, propinfo)));

type mismatch: String and PPropinfo.

I'm sorry but I don't know how to handle all of these above and go further.

Could you please comment on?
(or you can say "Learn by yourself" if I'm wasting your time. Because I feel that I will get some more errors after solving the issues up to this point. I mean more questions to you)

Thanks.
Reply With Quote
  #6  
Old 08-27-2010, 08:59 AM
Norrit Norrit is offline
Moderator
 
Join Date: Aug 2001
Location: Landgraaf
Posts: 7,307
Default

Well, this code was made by D2007, so there are a few form properties (like AlignWithMargins) that are different...

Best is to create a new project in D7, and add the following components to your form:

TListView (name=ListViewProperties)
- Add 2 columns
- ViewStyle = vsReport

TActionList (name=ActionList)
- Add a action (name=ActionRefresh)

TButton (name=ButtonRefresh)
- Action=ActionRefresh

TComboBox (name=ComboBoxClasses);
- Style = csDropDownList
- Items
'TFormRTTI'
'TMyClass'

In other words, rebuild my form in D7...
Then implement the events (and make sure TypInfo is in the uses list), the code is nothing more then cut and past in the right places (mostly events)

All your errors come due to the fact that you ignored some errors. The RTTI still has them and when trying to access it'll raise you the exception (since D7 doesn't know it)

Hope it's a bit clear what to do now

And questions are no problem, that's why this is a forum...
Reply With Quote
  #7  
Old 08-27-2010, 10:25 AM
mesnet mesnet is offline
Junior Member
 
Join Date: Aug 2010
Posts: 5
Default

This is my form:
Code:
object TFormRTTI: TTFormRTTI
  Left = 192
  Top = 107
  Width = 640
  Height = 466
  Caption = 'TFormRTTI'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object ButtonRefresh: TButton
    Left = 528
    Top = 400
    Width = 97
    Height = 33
    Action = ActionRefresh
    TabOrder = 0
  end
  object ComboBoxClasses: TComboBox
    Left = 16
    Top = 400
    Width = 209
    Height = 21
    Style = csDropDownList
    ItemHeight = 13
    TabOrder = 1
    Items.Strings = (
      'TFormRTTI'
      'TMyClass')
  end
  object ListView1: TListView
    Left = 8
    Top = 8
    Width = 617
    Height = 385
    Columns = <
      item
      end
      item
      end>
    TabOrder = 2
    ViewStyle = vsReport
  end
  object ActionList: TActionList
    Left = 488
    Top = 400
    object ActionRefresh: TAction
      Caption = 'ActionRefresh'
    end
  end
end
this is initial code that D7 created:

Code:
unit RTTIDemoForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ActnList, ComCtrls;

type
  TTFormRTTI = class(TForm)
    ButtonRefresh: TButton;
    ComboBoxClasses: TComboBox;
    ActionList: TActionList;
    ListView1: TListView;
    ActionRefresh: TAction;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  TFormRTTI: TTFormRTTI;

implementation

{$R *.dfm}

end.
This is the application code:
Code:
program Project1;

uses
  Forms,
  RTTIDemoForm in 'RTTIDemoForm.pas' {TFormRTTI};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TTFormRTTI, TFormRTTI);
  Application.Run;
end.
When I replace the initial code above with the code you gave, I get this error message:

Error in module RTTIDemoForm: Declaration of class TTFormRTTI is missing or incorrect.

Can you comment on this?
Reply With Quote
  #8  
Old 08-27-2010, 10:36 AM
Norrit Norrit is offline
Moderator
 
Join Date: Aug 2001
Location: Landgraaf
Posts: 7,307
Default

You cannot replace the .pas with mine, you'll have to copy the parts manually...
And the ListView1 is not ListView1 in my code ;-)

I have no D7 anymore, so I cannot provide the D7 example...
Reply With Quote
  #9  
Old 08-27-2010, 12:21 PM
mesnet mesnet is offline
Junior Member
 
Join Date: Aug 2010
Posts: 5
Default

This is the final code that I've got by copy-paste operations:
Code:
unit RttiDemoForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,TypInfo, ComCtrls, ActnList, StdCtrls;

type
  TMyClass = class(TComponent)
  private
    FStringValue: String;
    FIntegerValue: Integer;
  published
    property IntegerValue: Integer read FIntegerValue write FIntegerValue;
    property StringValue: String read FStringValue write FStringValue;
  end;

  TFormRTTI = class(TForm)
    ButtonRefresh: TButton;
    ComboBoxClasses: TComboBox;
    ActionList: TActionList;
    ListViewProperties: TListView;
    ActionRefresh: TAction;
    procedure ActionRefreshExecute(Sender: TObject);
    procedure FormCreate(Sender: TObject);

  private
    { Private declarations }
    FTestInteger: Integer;
    FTestString: String;
    FMyClass: TMyClass;
    procedure SetTestInteger(const Value: Integer);
    procedure SetTestString(const Value: String);

  public
    { Public declarations }
    property TestString: String read FTestString write SetTestString;
    property TestInteger: Integer read FTestInteger write SetTestInteger;
  end;

var
  FormRTTI: TFormRTTI;

implementation

{$R *.dfm}

procedure TFormRTTI.ActionRefreshExecute(Sender: TObject);
var
  aclass: TComponent;
  proplist: PPropList; // uses TypInfo
  propinfo: PPropInfo;
  i: Integer;
begin
  New(proplist);
  try
    case ComboBoxClasses.ItemIndex of
      0: aclass := FormRTTI;
      1: aclass := FMyClass;
      else Exit;
    end;

    // list all public and published properties of the class
    GetPropInfos(aclass.ClassInfo(), proplist);

    ListViewProperties.Items.BeginUpdate();
    try
      ListViewProperties.Items.Clear();

      for i := 0 to GetTypeData(aclass.ClassInfo())^.PropCount - 1 do
      begin
        propinfo := proplist^[i];
        with ListViewProperties.Items.Add() do
        begin
         Caption := propinfo^.Name;
//         SubItems.Add(VarToStr(GetPropValue(aclass, propinfo)));
        end;
      end;
    finally
      ListViewProperties.Items.EndUpdate();
    end;
  finally
    Dispose(proplist);
  end;
end;

procedure TFormRTTI.FormCreate(Sender: TObject);
begin
  ActionRefresh.Execute();
  FMyClass := TMyClass.Create(Self);
  FMyClass.IntegerValue := 4;
  FMyClass.StringValue := 'some text';
end;

procedure TFormRTTI.SetTestInteger(const Value: Integer);
begin
  FTestInteger := Value;
end;

procedure TFormRTTI.SetTestString(const Value: String);
begin
  FTestString := Value;
end;

end.
This is the form:
Code:
object FormRTTI: TFormRTTI
  Left = 414
  Top = 186
  Width = 536
  Height = 412
  Caption = 'FormRTTI'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object ButtonRefresh: TButton
    Left = 408
    Top = 352
    Width = 113
    Height = 25
    Action = ActionRefresh
    TabOrder = 0
  end
  object ComboBoxClasses: TComboBox
    Left = 56
    Top = 352
    Width = 209
    Height = 21
    Style = csDropDownList
    ItemHeight = 13
    TabOrder = 1
    Items.Strings = (
      'TFormRTTI'
      'TMyClass')
  end
  object ListViewProperties: TListView
    Left = 8
    Top = 8
    Width = 513
    Height = 329
    Columns = <
      item
        Width = 200
      end
      item
        Width = 200
      end>
    TabOrder = 2
    ViewStyle = vsReport
  end
  object ActionList: TActionList
    Left = 16
    Top = 352
    object ActionRefresh: TAction
      Caption = 'ActionRefresh'
      OnExecute = ActionRefreshExecute
    end
  end
end
Program does not give any error and the application runs. But nothing happens since I put double slashes in front of the line:

// SubItems.Add(VarToStr(GetPropValue(aclass, propinfo)));

When I run this line I get type mismatch error (string and PPropInfo) and application does not run.

How can I solve this?
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On

Forum Jump


All times are GMT. The time now is 11:10 AM.


Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2018, vBulletin Solutions, Inc.