![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как идентифицировать объект по указателю на него ? [D6]
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]
> Есть процедура, которой передается указатель
А заодно и тип переменной передать?