Реферат: Семь чудес и два фокуса на Дельфи
Как вы уже наверное догадались FControl опять окажется не TControl. Найдите в модуле System процедуру _IsClass. Хоть она и написана на ассемблере, нетрудно понять, что в ней происходит - в цикле просматриваются ссылки на классы (сначала собственная - обьекта, а потом - всех предков) и среди них ищется равная правому операнду. Давайте изменим немного процедуру:
procedureTfrmAllMiracles.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: