Недавно добавленные исходники

•  DeLiKaTeS Tetris (Тетрис)  119

•  TDictionary Custom Sort  3 307

•  Fast Watermark Sources  3 057

•  3D Designer  4 811

•  Sik Screen Capture  3 308

•  Patch Maker  3 524

•  Айболит (remote control)  3 625

•  ListBox Drag & Drop  2 986

•  Доска для игры Реверси  81 504

•  Графические эффекты  3 914

•  Рисование по маске  3 221

•  Перетаскивание изображений  2 604

•  Canvas Drawing  2 727

•  Рисование Луны  2 550

•  Поворот изображения  2 159

•  Рисование стержней  2 158

•  Paint on Shape  1 562

•  Генератор кроссвордов  2 221

•  Головоломка Paletto  1 762

•  Теорема Монжа об окружностях  2 207

•  Пазл Numbrix  1 679

•  Заборы и коммивояжеры  2 050

•  Игра HIP  1 275

•  Игра Go (Го)  1 221

•  Симулятор лифта  1 468

•  Программа укладки плитки  1 212

•  Генератор лабиринта  1 539

•  Проверка числового ввода  1 347

•  HEX View  1 486

•  Физический маятник  1 352

 
скрыть


Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Delphi Sources

Использование интерфейсов и TInterfaceList



Оформил: DeeCo

{ 
  The Classes unit provides a class TInterfaceList which is a TList that can store 
  interfaces (yes, those that are descendants of IUnknonw). If you need to store 
  interfaces do not use a TList, use TInterfaceList, otherwise you will run into 
  trouble. 

  Here is how to do it: 
}

 type
   IMyInterface = interface
     procedure AMethod;
   end;

 type
   TMyObject = class(TInterfacedObject, IMyInterface)
     procedure AMethod;
   end;

   {....}

 var
   InterfaceList: TInterfaceList;
   MyInt: IMyInterface;

   {....}
   MyInt := TMyObject.Create;
   InterfaceList.Add(MyInt);

      {....}

   MyInt := IMyInterface(InterfaceList[Index]);
   MyInt.AMethod;

   {Easy, but there is a catch. The following code will crash: }

   {... declarations like above ...}
   InterfaceList.Add(TMyObject.Create);
   MyInt := IMyInterface(InterfaceList[0]);
   MyInt.AMethod; // -> Access Violation 

{ 
  Why is that? That is because instead of storing the IMyInterface if TMyObject we 
  stored its IUnknown interface in the InterfaceList. Retrieving this resulted in an 
  invalid typecast of a non-IMyInterface interface to IMyInterface. The resulting 
  interface pointer pointed to a IUnknown interface which simply does not have the 
  AMethod method. When we tried to call this method, the code tried to get the 
  corresponding method pointer from the interface's VMT and got some garbage instead. 

  The following, minimally changed code works: 
}

   {... declarations like above ...}
   InterfaceList.Add(IMyInterface(TMyObject.Create));
   MyInt := IMyInterface(InterfaceList[0]);
   MyInt.AMethod; // -> Access Violation 

   { 
  That is, because the explicit typecast to IMyInterface before adding the TMyObject 
  object to the list returned the IMyInterface interface of TMyObject rather than 
  the IUnknown interface. But since IMyInterface is a descendant interface of 
  IUnknown, it can still be stored in the InterfaceList. 

  Confused? Yes, so was I. It took me ages to figure out what was wrong with my 
  program that crashed unexpectedly. I hope this will help others to avaoid this 
  problem or at least find the reason why their programs don't behave as they should. 
}







Copyright © 2004-2024 "Delphi Sources" by BrokenByte Software. Delphi World FAQ

Группа ВКонтакте