GetPropInfo & MethodTypeData

6 отговора 131 прегледа
#1

GetPropInfo & MethodTypeData

Моля, помогнете ми да извикам евентуално съществуващ метод на някакъв обект.
Прочетох пет пъти горното изречение и не успях да го формулирам по-точно.

Ще дам пример със свойствата (а питам за методите):

procedure TForm1.Button1Click(Sender: TObject);
begin
..if GetPropInfo(Sender.ClassInfo,'Color')<> nil then
....ShowMessage(Sender.ClassName+' has no color property');{}
..else
....SetOrdProp(Sender, p, clRed)
end;

Ако методът е присвоен на OnClick на няколко визуални компонента, при клик ще се смени цвета само на тези, които има свойство "цвят".
По този начин се получава информация за наличните свойства по време на изпълнение.

МОЯТ ВЪПРОС се отнася за възможността за откриване и изпълнение на методи.
Пробвах:
procedure TForm1.Button1Click(Sender: TObject);
var
....m: tMethod;
....Key: word;
begin
..m := GetMethodProp(Sender, 'OnKeyDown');
..if m.Code = nil then
....ShowMessage(Sender.ClassName+' has no OnKeyDown metod')
..else begin
....Key:=13;
....TKeyEvent(m)(Sender,Key,[]);
..end;
end;

Проблемът е, че не мога да позная кога "m" е валидно - явно проверката m.Code не е коректна.
Та очаквам съвети

Отговор
в отговор на NikB #2

Спретнах нещо, сякаш изглежда коректно.

procedure TForm1.Button1Click(Sender: TObject);
var
....p : pointer;
....m: tMethod;
....Key: word;
begin
....p := GetPropInfo(Sender.ClassInfo, 'OnKeyDown');
....if p=nil then begin
......ShowMessage(Sender.ClassName+' has no OnKeyDown metod')
....end else begin
......m := GetMethodProp(Sender, 'OnKeyDown');
......if m.Code = nil then begin
........ShowMessage(Sender.ClassName+' OnKeyDown metod is not Assignet')
......end else begin
........Key:=13;
........TKeyEvent(m)(Sender,Key,[]);
......end;
....end;
end;

Редактирано от NikB на

Отговор
в отговор на NikB #3

Re: Спретнах нещо, сякаш изглежда коректно.

аха, изглежда е добре... но май си трябва едно допълнение - проверка дали метода е от съответния тип /за OnKeyDown - TKeyEvent/:


//имаш един такъв обект
TCheatObj = Class(TWinControl)
private
fOnKeyDown : TNotifyEvent;
published
property OnKeyDown : TNotifyEvent read fOnKeyDown write fOnKeyDown;
end;

//и когато искаш да правиш KeyDown:
procedure TForm1.Button2Click(Sender: TObject);
var
p : PPropInfo;
m: tMethod;
Key: word;
tmpOBJ : TObject;
tmpCheatObj : TCheatObj;
begin
tmpCheatObj := TCheatObj.Create(self);
tmpCheatObj.OnKeyDown := FalseKeyDown;
tmpOBJ := tmpCheatObj;

p := GetPropInfo(tmpOBJ.ClassInfo, 'OnKeyDown');
if p=nil then begin
ShowMessage(tmpOBJ.ClassName+' has no OnKeyDown metod')
end else begin
//showmessage('p.PropType^.Name=' + p.PropType^.Name);
m := GetMethodProp(tmpOBJ, 'OnKeyDown');
if m.Code = nil then begin
ShowMessage(tmpOBJ.ClassName+' OnKeyDown metod is not Assignet')
end else begin
if (p.PropType^.Name = 'TKeyEvent') then begin
Key:=13;
TKeyEvent(m)(tmpOBJ,Key,[]);
end else begin
showMessage('Unsupported Method Kind: ' + p.PropType^.Name);
end;
end;
end;
tmpCheatObj.Free;
end;

procedure TForm1.FalseKeyDown(Sender: TObject);
begin
showmessage('FalseKeyDown');
end;


прочее, TKeyEvent(m)(tmpOBJ,Key,[]); минава и когато OnKeyDown е TNotifyEvent, ама за по-сигурно :-)))

Am I evil?
Yes I am.
Отговор
в отговор на Hateras #4

Благодаря!

Благодаря!
Не успях да видя продължението, но се предполага.

Редактирано от NikB на

Отговор
в отговор на Hateras #5

Още въпрос

В смисъла на казаното
if (p.PropType^.Name = 'TKeyEvent') then begin
какъв е по-стилния начин за проверка, нещо от рода
if m is TKeyEvent then begin

Отговор
в отговор на NikB #6

Re: Още въпрос

мхм, и аз това щях да питам /с IS май няма да стане.../
:-)))

Am I evil?
Yes I am.
Отговор
в отговор на Hateras #7

Не става

Че не става - не става. Прерових сорсовете в Д5 - нищо интересно по въпроса. Ако никой не отговори - когато имам време ще ровя книгите. Може би най-вероятно в "Тайните ..." на Том Суон да има нещо.
Благодаря ти за времето!

Отговор