Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Возможно ли имея имя класса в переменной обратится


Страницы:   1 2 3

dmk ©   (2015-03-16 16:53:00) 

к строке как к классу в рантайм не делая кучу условий?
Например:
s := 'TEdit';
s.text := 'something';


  (2015-10-20 19:37:00) [1]

Удалено модератором


  (2015-10-20 19:26:00) [2]

Удалено модератором


dmk   (2015-03-24 12:09:00) [3]

У себя тоже нашел ошибку. Она вообще в другом месте была. По крайней мере получил опыт с переназначением методов :)


Leonid Troyanovsky   (2015-03-24 09:22:00) [4]


> dmk ©   (23.03.15 16:17) [42]

> Вот так заработало:

Ну, и как хотелось:

type
 TForm1 = class(TForm)
   Label1: TLabel;
   Label2: TLabel;
   Label3: TLabel;
   Button1: TButton;
   procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

uses
 TypInfo;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
begin
 if Sender is TLabel then
   Caption := Format( '%s.%s: %d %d',
                       [Name, TLabel(Sender).Caption, X, Y]);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 ppi: PPropInfo;
 AMethod: TMethod;
 i : Longint;
begin
 ppi := GetPropInfo(TLabel, 'OnMouseUp');
 if ppi = nil then
   raise Exception.Create('Property not exist');
 AMethod.Code := MethodAddress('FormMouseUp');
 AMethod.Data := Self;

 for i := 0 to ControlCount-1 do
   if Controls[i] is TLabel then
     SetMethodProp(Controls[i], ppi, AMethod);
end;

--
Regards, LVT.


dmk   (2015-03-23 16:17:00) [5]

Вот так заработало:
unit test1;

interface

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

type
 TForm1 = class(TForm)
   Edit1: TEdit;
   procedure FormCreate(Sender: TObject);
   procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
 private
   { Private declarations }
   FInt: integer;
   FStr: string;
   procedure AssignNewMethod;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

function ObjPropInfo(AObject: TObject; const PropName: String): PPropInfo;
begin
 Result := GetPropInfo(AObject.ClassInfo, PropName);
 if Result = nil then raise Exception.Create('Property not exist');
end;

procedure SetMethodProperty(AObject: TObject; const PropName: string; const Value: Pointer; const ASelf: pointer);
var
 AMethod: TMethod;

begin
 AMethod.Code := Value;
 if ASelf = nil then AMethod.Data := AObject else AMethod.Data := ASelf;
 SetMethodProp(AObject, ObjPropInfo(AObject, PropName), AMethod);
end;

procedure TForm1.AssignNewMethod;
var
 i: integer;
 c: TWinControl;
 p1: pointer;

begin
 for i := 0 to ControlCount - 1 do
 begin
   if Controls[i] is TWinControl then
   begin
     c := TWinControl(Controls[i]);
     p1 := @Self.OnMouseDown;
     if IsPublishedProp(c, 'OnMouseDown') then SetMethodProperty(c, 'OnMouseDown', p1, Self);
   end;
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FInt := 10;
 FStr := 'Правильно';
 AssignNewMethod;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
 s1, s2: string;

begin
 //Только оконные объекты
 if (Sender is TWinControl) then
 begin
   Self.Caption := FStr;
   s1 := TWinControl(Sender).Name;
   s2 := 'No parent';
   if TWinControl(Sender).Parent <> nil then s2 := TWinControl(Sender).Parent.Name;
   ShowMessage('Mouse down from (' + s1 + ') FInt: ' + IntToStr(FInt) + ' Caption: ' + FStr + #13 + 'Parent form is (' + s2 + ')');
 end;//if sender
end;

end.

Видимо у меня там где 50к кода ошибка где-то. будем разбираться. Спасибо!


Leonid Troyanovsky   (2015-03-22 19:09:00) [6]


> dmk ©   (22.03.15 16:21) [40]

> Работает только такой вариант.

Не верю.

--
Regards, LVT.


dmk   (2015-03-22 16:21:00) [7]

>Ну, тогда  б предпочел GetParentForm.

Работает только такой вариант.


Leonid Troyanovsky   (2015-03-22 09:29:00) [8]


> Leonid Troyanovsky ©   (22.03.15 09:20) [38]

Поторопился, sorry.

procedure TForm1.SetMethodProperty( AObject: TObject; const PropName:String; const Value: Pointer);
var
 AMethod: TMethod;
begin
 AMethod.Code := Value;
 AMethod.Data := Self;
 SetMethodProp(AObject, ObjPropInfo(AObject, PropName), AMethod);
end;


Все работает как обычно.

--
Regards, LVT.


Leonid Troyanovsky   (2015-03-22 09:20:00) [9]


> dmk ©   (22.03.15 01:18) [36]

> не работает.

А... Понял.
Ну, тогда  б предпочел GetParentForm.

--
Regards, LVT.


Leonid Troyanovsky   (2015-03-22 09:04:00) [10]


> dmk ©   (22.03.15 01:18) [36]

> AMethod.Data := AObject; написать AMethod.Data := Self.Так
> не работает. Вызова не происходит.

Код в студию.
Сдается мне, что не в _методе_ пытаешься.

--
Regards, LVT.


dmk   (2015-03-22 01:18:00) [11]

>Еже ли хочется того самого Self из методов формы, то
>procedure SetMethodProperty надо сделать методом формы,
>где вместо AMethod.Data := AObject; написать AMethod.Data := Self.

Так не работает. Вызова не происходит.
Сделал пока обращение напрямую к полям формы, но выглядит не очень. Будем разбираться. Спасибо за помощь!


Leonid Troyanovsky   (2015-03-20 17:29:00) [12]


> dmk ©   (20.03.15 16:45) [34]

> один и тот же метод: http://s15.postimg.org/swpyqo1ob/dump1.jpg

@Self.OnMouseUp - поубивав бы.

> когда назначается метод, то self от TForm1, а когда он вызывается,
> то self становится указателем на Edit1

Он становится Edit1 при AMethod.Data := AObject.

> Видимо надо родителя проверять или не обращаться к self.

Еже ли хочется того самого Self из методов формы, то
procedure SetMethodProperty надо сделать методом формы,
где вместо AMethod.Data := AObject; написать AMethod.Data := Self.

--
Regards, LVT.


dmk   (2015-03-20 16:45:00) [13]

>> Даже если назначить от TForm1, а не от self, то разницы нет.
>Обоснуй.

без проблем, переменные p1 и p2 ссылаются на один и тот же метод:
http://s15.postimg.org/swpyqo1ob/dump1.jpg

>> Доступ к полям ошибочный.
>Показывай.

когда назначается метод, то self от TForm1, а когда он вызывается, то self становится указателем на Edit1 у которого таких полей как у TForm нет.
http://s21.postimg.org/4yu3q8mkn/dump2.jpg

Видимо надо родителя проверять или не обращаться к self.


Leonid Troyanovsky   (2015-03-20 15:54:00) [14]


> что известно в оном форме, на который его положат.

что известно в оном о форме, на которую его положат.

Sorry.

--
Regards, LVT.


Leonid Troyanovsky   (2015-03-20 15:45:00) [15]


> dmk ©   (20.03.15 15:30) [30]

>  Заменять метод небезопасно.

и загадочно.

--
Regards, LVT.


Leonid Troyanovsky   (2015-03-20 15:40:00) [16]


> dmk ©   (20.03.15 15:26) [29]

> Даже если назначить от TForm1, а не от self, то разницы нет.

Обоснуй.

> Доступ к полям ошибочный.

Показывай.

> Поля от TForm1 в случае вызова из TEdit не видны.

Предположим, что у Edit есть обработчик OnMouseUp,
скажем, EditMouseUp.
Спросим, что известно в оном форме, на который его положат.
Ну, или, не положат.

Где-то сгодится GetParentForm, а где-то - нет. Всё как в жизни.

--
Regards, LVT.


dmk   (2015-03-20 15:30:00) [17]

я про это и писал выше, что self, что TForm1 разницы нет. Заменять метод небезопасно.


dmk   (2015-03-20 15:26:00) [18]

Даже если назначить от TForm1, а не от self, то разницы нет. Доступ к полям ошибочный. Поля от TForm1 в случае вызова из TEdit не видны.


Leonid Troyanovsky   (2015-03-20 14:59:00) [19]


> @Self.OnMouseUp

Поубивав бы.


Leonid Troyanovsky   (2015-03-20 14:54:00) [20]


> dmk ©   (20.03.15 13:46) [26]

> В последнем случае возникает AV.

Внезапно?

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 ShowMessage(TWinControl(Sender).Name);
 ShowMessage(Self.Name + '>' +Name); // wow
 ShowMessage(FStr); // surprise
end;

--
Regards, LVT.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо