Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.08.14;
Скачать: CL | DM;

Вниз

Как идентифицировать объект по указателю на него ?   Найти похожие ветки 

 
msguns ©   (2005-07-22 15:20) [0]

На простом примере :
Есть процедура, которой передается указатель, куда надо положить некое число. Она должна определить, что "скрывается" под этим указателем. Если, например, это обект винкотрольный, то преобразовать число в строку и положить в св-во Text или Caption (в зависимомти от класса объекта), если строка - то просто положить туда. Если же Integer, то просто записать по этому адресу само число и т.д.

Благодарю всех участников.


 
Джо ©   (2005-07-22 15:21) [1]

В общем случае, имхо, никак.


 
Digitman ©   (2005-07-22 15:35) [2]

procedure (ptr: Pointer; Number: Integer);
begin
 try
   if TObject(ptr) is TSomeControl then
     begin
       TSomeControl(ptr).Text := IntToStr(Number);
       Exit;
     end;
 except
 end;

 try
   if TObject(ptr) is TSomeOtherControl then
     begin
       TSomeOtherControl(ptr).Text := IntToStr(Number);
       Exit;
     end;
 except
 end;

 try
   if строка then
     просто положить туда (черт-те что подразумевается под "строка" и "просто положить туда")
 except
 end;

 PInteger(ptr)^ := Number;
end;


 
Lamer@fools.ua ©   (2005-07-22 15:44) [3]

>Как идентифицировать объект по указателю на него ?

Либо пользоваться Variant"ами либо использовать технологии с поддержкой определения типа в ран-тайм (.NET, Java).


 
Digitman ©   (2005-07-22 15:47) [4]


> Lamer@fools.ua ©   (22.07.05 15:44) [3]


теже фаберже, но вид сбоку


 
msguns ©   (2005-07-22 15:49) [5]

>Digitman ©   (22.07.05 15:35) [2]

Ну, до метода научного тыка я бы и сам догадался ;))


 
Digitman ©   (2005-07-22 15:53) [6]


> msguns ©   (22.07.05 15:49) [5]


а тебя хак-методы интересуют ?)


 
msguns ©   (2005-07-22 16:04) [7]

>Digitman ©   (22.07.05 15:53) [6]
>а тебя хак-методы интересуют ?)

Меня интересует грамотно.
И красиво ;)


 
Digitman ©   (2005-07-22 16:20) [8]


> msguns ©   (22.07.05 16:04) [7]


тогда грамотно же и излагай суть вопроса.


> передается указатель


типизированный ? упоминай тип.
нетипизированный ? см. [1]


 
Джо ©   (2005-07-22 16:21) [9]


> [7] msguns ©   (22.07.05 16:04)
> Меня интересует грамотно.
> И красиво ;)

Для этого лучше всего грамотно подойти к проектированию алгоритма. Тогда и не будет нужды в хаках.


 
evvcom ©   (2005-07-22 16:24) [10]

Посмотри как работают функции New/Dispose с TypInfo.


 
oldman ©   (2005-07-22 16:33) [11]


> Есть процедура, которой передается указатель


А заодно и тип переменной передать?


 
Digitman ©   (2005-07-22 16:34) [12]


> evvcom ©   (22.07.05 16:24) [10]


не катит.
абсолютно.


 
Digitman ©   (2005-07-22 16:37) [13]


> процедура, которой передается указатель


мол, нА тебе, процедура, адрес, по этому адресу что-то там лежит, что конкретно - разбирайся сама, это твои проблемы..


 
Джо ©   (2005-07-22 16:39) [14]

Еще раз о

> Меня интересует грамотно.
> И красиво ;)
Обращение к области памяти, не зная, что в ней лежит (или не лежит) - само по себе так "некрасиво", что о каких уж тут красивых решениях может идти речь?.. Сорри за занудство, но может обрисуешь задачу?


 
evvcom ©   (2005-07-22 16:42) [15]


> не катит.
> абсолютно.

Ну так если вместе с указателем еще TypInfo передавать, должно ж прокатить? Хотя с тем же успехом можно и свой какой идентификатор передавать.
А вообще, конечно, задачи народ выдумывает странные. Я передал указатель, а ты попробуй угадай, что это?


 
Digitman ©   (2005-07-22 16:45) [16]


> evvcom ©   (22.07.05 16:42) [15]



> если вместе с указателем еще TypInfo передавать, должно
> ж прокатить?


да мало ли чего должно !

автор, как я понял, не желает передавать ничего иного, кроме как нетип.указатель


 
msguns ©   (2005-07-22 16:45) [17]

>oldman ©   (22.07.05 16:33) [11]
>А заодно и тип переменной передать?

Поясняю предмет.

procedure CalcAggregate(DataSet: TSQLDataSet; FieldList: TList; TargetValues: TList);

Процедура по переданному датасету строит запрос на вычисление агрегатов по полям, указанным в переданному же списку. Выполняет его и полученный результат должна положить по адресам, указанным в списке указателей, которые также передается. А вызывающая может дать ссылку на TEdit, TLabel, переменные типа Integer, double, string и т.д.


 
Digitman ©   (2005-07-22 16:50) [18]


> А вызывающая может дать ссылку на


а вызывающая ДОЛЖНА дать список ВАРИАНТОВ, а не список абстрактных указателей !

вот тогда и вопрос сам собой рассосется)


 
evvcom ©   (2005-07-22 16:52) [19]


> А вызывающая может дать ссылку на TEdit, TLabel, переменные
> типа Integer, double, string и т.д.

Ну так дай ссылку на record где присутствует информация о типе переменной.


 
msguns ©   (2005-07-22 16:53) [20]

>Digitman ©   (22.07.05 16:50) [18]
>а вызывающая ДОЛЖНА дать список ВАРИАНТОВ, а не список абстрактных указателей !

Можно примерчик. Как вызывающая сможет получить четыре числа:
одно в Эдите, второе в лабеле, третье как строку, а четвертое - как флоат. И как вызываемая со всех этой фигней разберется


 
msguns ©   (2005-07-22 16:55) [21]

>evvcom ©   (22.07.05 16:52) [19]
>Ну так дай ссылку на record где присутствует информация о типе переменной.

Ну какой же рекорд ? Процедура универсальная. К ней могут обращаться за получением как рдного агрегата, так и 100. И в абсолютно разные контролы или переменные.


 
DiamondShark ©   (2005-07-22 16:55) [22]

Не. Это фантастика.
Допустим, указатель на TEdit от TLabel отличить можно (хотя при выполнении кода, подобного [2] надо усиленно молиться). Но указатель на Integer отличить от указателя на Double -- унреально.


 
DiamondShark ©   (2005-07-22 16:58) [23]

Передавать массив обёрток, унаследованных от абстрактного класса -- и будет щасье.


 
Digitman ©   (2005-07-22 17:02) [24]


> Как вызывающая сможет получить четыре числа:
> одно в Эдите, второе в лабеле,


да нет там, ни в Эдите ни в лабеле, никаких "чисел" !)

и вообще это проблемы вызывающего кода - где, как и какими средствами он изобразит рез-т работы вызываемого кода

вызываемый же код в данном случае может (и, вероятно, должен) вернуть вариантный массив, с которым вызывающий код уже волен делать все что угодно - хоть в лабеле хоть не в лабеле рисовать результаты ..


 
reonid ©   (2005-07-22 17:02) [25]

Можно сделать что-нибудь типа этого:
(Подобной техникой я пользовался, когда мне надо было реализовать обобщённые алгоритмы)

type
 TAdapter = record
   SetValue: procedure(Value: Integer) of object;
 end;

implementation

{----}
procedure __SetInt(P: Pointer; Value: Integer);
begin
 PInteger(P)^ := Value;
end;

procedure __SetStr(P: Pointer; Value: Integer);
begin
 PString(P)^ := IntToStr(Value);
end;

procedure __SetWin(P: Pointer; Value: Integer);
begin
 if GetPropInfo(TWinControl(P), "Caption") <> nil then
   SetPropValue(TWinControl(P), "Caption", Value)
 else if GetPropInfo(TWinControl(P), "Text") <> nil then
   SetPropValue(TWinControl(P), "Text", Value)
end;

{-----}
function Adapter(var I: Integer): TAdapter; overload;
begin
 TMethod(Result.SetValue).Data := @I;
 TMethod(Result.SetValue).Code := @__SetInt;
end;

function Adapter(var S: string): TAdapter; overload;
begin
 TMethod(Result.SetValue).Data := @S;
 TMethod(Result.SetValue).Code := @__SetStr;
end;

function Adapter(Win: TWinControl): TAdapter; overload;
begin
 TMethod(Result.SetValue).Data := Pointer(Win);
 TMethod(Result.SetValue).Code := @__SetWin;
end;
{-----}

procedure Test(Adapters: array of TAdapter);
var i: Integer;
begin
 for i := 0 to High(Adapters) do
   Adapters[i].SetValue(6);
end;

procedure TForm1.FormCreate(Sender: TObject);
var I: Integer;
   s: string;
begin
 Test([Adapter(Self), Adapter(Panel1), Adapter(s), Adapter(I)]);
end;


 
evvcom ©   (2005-07-22 17:03) [26]


> Ну какой же рекорд ? Процедура универсальная. К ней могут
> обращаться за получением как рдного агрегата, так и 100.

А что массивы уже отменили? У меня, например, так работают процедуры/классы. И никаких проблем.


 
Digitman ©   (2005-07-22 17:12) [27]


> msguns ©   (22.07.05 16:45) [17]


и вообще - imho, крайне неразумно месить в функц-ти данной процедуры работу с СУБД и работу с виз.контролами

ну состряпай ты, коль приспичило, рекорд вида

TOutputKind = packed record
 Kind: TKind; // 0 - TLabel, 1 - TEdit, 2 - PInteger, 3 - еще чего-то
 ptr: Pointer; // поле Kind проинформирует, как с этим указателем обращаться
end;

и передай TList таких рекордов !


 
Anatoly Podgoretsky ©   (2005-07-22 19:48) [28]

msguns ©   (22.07.05 15:20)  
В указаной постановке забудь, как сказали это фантастика.


 
Mx ©   (2005-07-22 22:16) [29]

Я вот тоже много мудрил с подобными фишками. По нетипизированному указателю ты такого не получишь. Остается либо [27], либо [23]. Для меня последний вариант оказался наиболее удобным. В конце концов от использования объектов ты мало что потеряешь, зато многие механизмы станут доступными.


 
msguns ©   (2005-07-27 09:35) [30]

>Digitman ©   (22.07.05 17:12) [27]
>и вообще - imho, крайне неразумно месить в функц-ти данной процедуры работу с СУБД и работу с виз.контролами

Я ничего и не месю ;) Библиотека, которую я пишу, содержит универсальные модули обработки датасетов, как правило, отображаемых (фильтрации, сортировки, поиски, печати, модификации, агрегаты и т.д. посредством диалогов с пользователем). Как получен датасет (т.е. собственно "работа с СУБД") этим модулям (точнее, процедурам и функциям в этих модулях) фиолетово.

Спасибо за критику и советы.
Отдельное мерси reonid © и Digitman ©



Страницы: 1 вся ветка

Текущий архив: 2005.08.14;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.065 c
14-1121759304
Knight
2005-07-19 11:48
2005.08.14
Стандартные поля для стандартной инфы в базах...


3-1120634051
vitzol
2005-07-06 11:14
2005.08.14
Подсветка символов в DBgrid при фильтрации


1-1122270847
Korvet
2005-07-25 09:54
2005.08.14
Help!


14-1122001061
NewWonder
2005-07-22 06:57
2005.08.14
Пишу экзамен!


14-1122138485
Kerk
2005-07-23 21:08
2005.08.14
Кто убил Киру?