Среда, 24 Апр 2024, 11:25
Uchi.ucoz.ru
Меню сайта
Форма входа

Категории раздела
Высшая математика [11]
Экономическая социология [95]
Основы Менеджмента [64]
Бухгалтерский учёт [157]
Философия [163]
Мировая Экономика [603]
Бизнес планирование [29]
Финансирование и кредитование инвест [105]
Ценообразование [46]
Гражданское право [196]
Права Человека [173]
Основы Маркетинга [207]
Основы энергосбережения [55]
Информатика [0]
Экология и устойчивое развитие [0]
Физика для студентов [0]
Основы права [0]
Политология [0]
Не стандартные примеры на Delphi [169]
Примеры на Delphi7 [108]
Алгоритмы [94]
API [110]
Pascal [152]
Базы Данных [6]
Новости
Чего не хватает сайту?
500
Статистика
Зарегистрировано на сайте:
Всего: 51635


Онлайн всего: 11
Гостей: 11
Пользователей: 0
Яндекс.Метрика
Рейтинг@Mail.ru

Каталог статей


Главная » Статьи » Студентам » Примеры на Delphi7

Семь чудес и два фокуса на Delphi (2 часть)
Чудо шестое (Is-Miracle II)

Давайте посмотрим еще на одно, похожее чудо связанное с оператором is. Добавим к нашей группе проектов (ProjectGroup1) новый проект - DLL с именем AllMirrLib, в единственном модуле которого будет следующий код:

library AllMirrLib;
uses
Controls;

function IsControlLib(const anObj: TObject): boolean;
begin
Result := anObj is TControl;
end;

exports
IsControlLib;
Figure 9.

Как вы видите эта библиотека экспортирует только одну очень простую функцию, которая возвращает знечение True в том случае, если ее единственный параметр происходит от TControl и False - в остальных случаях.

В модуль формы нашего основного проекта добавим следующее определение:

unit AllMir;

interface
...
implementation

{$R *.DFM}

function IsControlLib(const anObj: TObject): boolean; external 'AllMirrLib.DLL';
Figure 10.

Теперь, как обычно, добавим на форму новую кнопку:

procedure TfrmAllMiracles.btnIsMrcl2Click(Sender: TObject);
begin
FControl := TControl.Create(nil);
try
if not IsControlLib(FControl) then
ShowMessage('Not a Control');
finally
FreeAndNil(FControl);
end;
end;
Figure 11.

Как вы уже наверное догадались FControl опять окажется не TControl. Найдите в модуле System процедуру _IsClass. Хоть она и написана на ассемблере, нетрудно понять, что в ней происходит - в цикле просматриваются ссылки на классы (сначала собственная - обьекта, а потом - всех предков) и среди них ищется равная правому операнду. Давайте изменим немного процедуру:

procedure TfrmAllMiracles.btnIsMrcl2Click(Sender: TObject);
var
p1, p2: pointer;
begin
FControl := TControl.Create(nil);
try
p1 := pointer(FControl.ClassType);
p2 := pointer(TControl);
if not IsControlLib(FControl) then
ShowMessage('Not a Control');
finally
FreeAndNil(FControl);
end;
end;
Figure 12.

Посмотрите под отладчиком значения p1 и p2 - они равны. Теперь изменим и функцию IsControlLib:

function IsControlLib(const anObj: TObject): boolean;
var
p3,p4: pointer;
begin
p3 := pointer(anObj.ClassType);
p4 := pointer(TControl);
Result := anObj is TControl;
end;
Figure 13.

Здесь тоже поставим точку останова и сравним значения. Переменные p1, p2 и p3 имеют одно и тоже значение, а вот p4 - указывает куда-то ни туда. Проблема в том, что в аппликации и в DLL сосуществуют два разных класса TControl, вот поэтому равества быть и не может.
Косвенное указание на эту проблему в Help'е можно найти в описании метода ClassNameIs.

Читаем Help:
Use ClassNameIs when writing conditional code based on an object's type or to query objects across modules, or DLLs.

Да, кстати, не забудьте, что у вас два проекта в группе и компилируется всегда только активный проект. Так что не забывайте перпеключаться на нужный проект по мере необходимости или компилируйте сразу все: Alt-P, U.

Следующее чудо я встретил в программе одного начинающего программиста и оно было конечно слегка закамуфлировано, так что я, к своему стыду, даже не сразу понял в чем дело. Я видел значения переменных, знал, что это - переменные типа variant, но никак не мог понять почему результат вычисления некоего несложного выражения все время ошибочный. Проверьте себя и вы.

Чудо седьмое (Miracle with Variants).

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

procedure TfrmAllMiracles.btnVarMrclClick(Sender: TObject);
var
X,Y,Z: variant;
begin
X := '1';
Y := '2';
Z := 3;
ShowMessage(X+Y+Z);
end;
Figure 14.

Можете ли вы предсказать результат выражения '1'+ '2'+3? Если вы сказали '6', то вы тоже попались. Посмотрим повнимательнее, '1'+ '2' будет... конечно '12', 12+3=15. Это и есть правильный ответ.

Итак, мы увидели семь чудес Delphi, семь - из многих. Это не значит, что они - самые яркие или самые чудесные. Но на них можно многому научиться. Возьмем последнее, только что рассмотренное нами, чудо. Задумайтесь, как Delphi удается сводить в одном выражении значения разных типов? А если один из членов выражения - variant?

Фокус первый (Variant trick)

Читаем Help в разделе "Variants in expressions":
...In a binary operation, if only one operand is a variant, the other is converted to a variant..

Не кажется ли вам это удивительным - variant можно складывать с чем угодно. Например, integer плюс variant - будет variant, а variant можно опять складывать с чем угодно...

Новая кнопка на форме будет выполнять следующие действия:

procedure TfrmAllMiracles.btnVarTrickClick(Sender: TObject);
var
v: variant;
b: boolean;
i: integer;
s: string;
d: TDatetime;
x: Double;
begin
v:=0;
b := true;
i := 2;
s := '3';
d := StrToDateTime('01/01/01');
x := 5;
v := v+b+i+s+d+x;
ShowMessage(VarToStr(v));
end;
Figure 15.

Не кажется ли вам, что чудо уже то, что этот код компилируется, а ведь он еще и выдает какой-то результат. А ведь все очень просто - "variant можно складывать с чем угодно" и снова получим - variant.

Однажды ко мне обратился один мой знакомый с вопросом нет ли в Delphi чего-то подобного скрытому параметру Self, но для оператора with. Нет - ответил я ему сперва, а потом задумался...

Фокус второй (With-trick)

Предположим у нас есть следующая функция:

procedure ShowText(sl: TStringList);
begin
ShowMessage(sl.text);
end;
Figure 16.

И кнопка на форме:

procedure TfrmAllMiracles.btnWithSelfTrickClick(Sender: TObject);
var
sl: TStringList;
begin
sl := TStringList.Create;
try
sl.CommaText := '1,2,3,4,5,6,7,8,9,0';
ShowText(sl);
finally
sl.Free;
end;
end;
Figure 17.

И мы, по каким-то причинам, хотим избавиться от локальной переменной sl. Но для того, что бы обратиться к функции ShowText, мы должны передать ей параметр типа TStringList. Откуда же его взять?

Давайте порассуждаем. Каждый метод получает скрытый параметр Self, может быть как-то можно вытащить его оттуда? Писать для этого специальный метод какого-то класса не хотелось бы - ведь это работало бы только для его потомков.

Давайте почитаем Help, раздел "TMethod type":
...This type can be used in a type cast of a method pointer to access the code and data parts of the method pointer...

Не это ли то, что мы ищем?
Определим тип и функцию:

type
TSimpleMethod = procedure of object;

function GetWithSelf(const pr: TSimpleMethod): TObject;
begin
Result := TMethod(pr).Data;
end;
Figure 18.

Как видите, функция принимает указатель на метод, а возвращает обьект, являющийся владельцем этого метода. Но каким же методом мы воспользуемся? Например, метод Free, ведь его история восходит еще к самому TObject'у. Теперь проверим себя:

procedure TfrmAllMiracles.btnWithSelfTrickClick(Sender: TObject);
begin
with TStringList.Create do
try
CommaText := '1,2,3,4,5,6,7,8,9,0';
ShowText(TStringList(GetWithSelf(Free)));
finally
Free;
end;
end;
Figure 19.

Проверьте - работает.
Категория: Примеры на Delphi7 | Добавил: Lerka (21 Ноя 2012)
Просмотров: 676 | Рейтинг: 1.0/ 5 Оштрафовать | Жаловаться на материал
Похожие материалы
Всего комментариев: 0

Для блога (HTML)


Для форума (BB-Code)


Прямая ссылка

Профиль
Среда
24 Апр 2024
11:25


Вы из группы: Гости
Вы уже дней на сайте
У вас: непрочитанных сообщений
Добавить статью
Прочитать сообщения
Регистрация
Вход
Улучшенный поиск
Поиск по сайту Поиск по всему интернету
Наши партнеры
Интересное
Популярное статьи
Портфолио ученика начальной школы
УХОД ЗА ВОЛОСАМИ ОЧЕНЬ ПРОСТ — ХОЧУ Я ЭТИМ ПОДЕЛИТ...
Диктанты 2 класс
Детство Л.Н. Толстого
Библиографический обзор литературы о музыке
Авторская программа элективного курса "Практи...
Контрольная работа по теме «Углеводороды»
Поиск
Главная страница
Используются технологии uCoz