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

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

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


Страницы:   1 2

msguns ©   (2005-07-22 15:20:00) 

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

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


msguns   (2005-07-27 09:35:00) [1]

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

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

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


Mx   (2005-07-22 22:16:00) [2]

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


Anatoly Podgoretsky   (2005-07-22 19:48:00) [3]

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


Digitman   (2005-07-22 17:12:00) [4]


> 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 таких рекордов !


evvcom   (2005-07-22 17:03:00) [5]


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

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


reonid   (2005-07-22 17:02:00) [6]

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

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;


Digitman   (2005-07-22 17:02:00) [7]


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


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

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

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


DiamondShark   (2005-07-22 16:58:00) [8]

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


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

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


msguns   (2005-07-22 16:55:00) [10]

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

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


msguns   (2005-07-22 16:53:00) [11]

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

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


evvcom   (2005-07-22 16:52:00) [12]


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

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


Digitman   (2005-07-22 16:50:00) [13]


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


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

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


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


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



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


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

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


msguns   (2005-07-22 16:45:00) [15]

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

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

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

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


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


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

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


Джо   (2005-07-22 16:39:00) [17]

Еще раз о

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


Digitman   (2005-07-22 16:37:00) [18]


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


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


Digitman   (2005-07-22 16:34:00) [19]


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


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


oldman   (2005-07-22 16:33:00) [20]


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


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


Страницы:   1 2

Наверх

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