Объектное ориентирование Delphi — среда быстрой разработки, где в качестве языка программирования используется Object Pascal. На сегодняшний день позволяет разрабатывать ПО для Microsoft Windows, Mac OS, iOS и Android и входит в состав Embarcadero RAD Studio https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie.feed 2022-09-13T04:32:44+07:00 Delphi help info@delphi-hlp.ru Joomla! - Open Source Content Management Override/Vitual/Dynamic - методы 2013-08-19T15:51:52+07:00 2013-08-19T15:51:52+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/metody/override-vitual-dynamic-metody.html Super User toto44@inbox.ru <p><span style="color: #000000;">Если метод в классе предка объявлен как виртуальный (virtual) или динамический (dynamic), вам необходимо перекрыть его во всех классах-наследниках. Если вы объявляете унаследованный метод виртуальным или динамическим, вы начинаете строить его новое виртуальное/динамическое дерево наследования. Допустим, у нас есть следующая иерархия: A (родитель) - B - C - D. Если вы объявляете метод как виртуальный (или динамический) в A, перекрываете в B, создаете виртуальным в C и перекрываете в D, вот что получается:</span></p> <p> </p> <p> </p> <p><span style="color: #000000;">фактический класс, используемый класс, использующий</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">класс для доступа к методу метод</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">-----------+---------------------+--------------------</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> D D D</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> D C D</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> D B B</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> D A B</span></p> <p> </p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> C C C</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> C B B</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> C A B</span></p> <p> </p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> B B B</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> B A B</span></p> <p> </p> <p><span style="color: #000000;">Вывод: работа виртуального/динамического наследования прекращается в момент создания одноименного виртуального/динамического метода наследниками класса.</span></p> <p><span style="color: #000000;">Mark </span></p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от</span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> <p><span style="color: #000000;">Если метод в классе предка объявлен как виртуальный (virtual) или динамический (dynamic), вам необходимо перекрыть его во всех классах-наследниках. Если вы объявляете унаследованный метод виртуальным или динамическим, вы начинаете строить его новое виртуальное/динамическое дерево наследования. Допустим, у нас есть следующая иерархия: A (родитель) - B - C - D. Если вы объявляете метод как виртуальный (или динамический) в A, перекрываете в B, создаете виртуальным в C и перекрываете в D, вот что получается:</span></p> <p> </p> <p> </p> <p><span style="color: #000000;">фактический класс, используемый класс, использующий</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">класс для доступа к методу метод</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">-----------+---------------------+--------------------</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> D D D</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> D C D</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> D B B</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> D A B</span></p> <p> </p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> C C C</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> C B B</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> C A B</span></p> <p> </p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> B B B</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;"> B A B</span></p> <p> </p> <p><span style="color: #000000;">Вывод: работа виртуального/динамического наследования прекращается в момент создания одноименного виртуального/динамического метода наследниками класса.</span></p> <p><span style="color: #000000;">Mark </span></p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от</span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> Динамические и виртуальные методы 2013-08-19T15:50:56+07:00 2013-08-19T15:50:56+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/metody/dinamicheskie-i-virtualnye-metody.html Super User toto44@inbox.ru <p><span style="color: #000000;">Согласно онлайновой документации, динамические и виртуальные методы семантически идентичны, единственно различие заключается в их реализации, нижеследующий код генерирует указанную ошибку компиляции:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> t = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> a: integer; </span><span class="f_CodeExample" style="color: #000080;">{статический}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> b: integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> c: integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">dynamic</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> i: integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> a; </span><span class="f_CodeExample" style="color: #000080;">{ ok }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> j: integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> b; </span><span class="f_CodeExample" style="color: #000080;">{ ok }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> k: integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> c;</span><span class="f_CodeExample" style="color: #000080;">{ ОШИБКА: type mismatch (не совпадение типа) }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> <p><span style="color: #000000;">Согласно онлайновой документации, динамические и виртуальные методы семантически идентичны, единственно различие заключается в их реализации, нижеследующий код генерирует указанную ошибку компиляции:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> t = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> a: integer; </span><span class="f_CodeExample" style="color: #000080;">{статический}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> b: integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> c: integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">dynamic</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> i: integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> a; </span><span class="f_CodeExample" style="color: #000080;">{ ok }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> j: integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> b; </span><span class="f_CodeExample" style="color: #000080;">{ ok }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> k: integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> c;</span><span class="f_CodeExample" style="color: #000080;">{ ОШИБКА: type mismatch (не совпадение типа) }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> Как вызвать метод предка? 2013-08-19T15:45:46+07:00 2013-08-19T15:45:46+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/metody/kak-vyzvat-metod-predka.html Super User toto44@inbox.ru <p><span style="font-family: 'Times New Roman'; color: #000000;">1) Есть Class1, с методом Mtd.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">2) Есть Class2 унаследованный от Class1, метод Mtd перезаписан</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">3) В программе используется переменная типа Class2</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Можно ли из программы вызвать Mtd от Class1, Другими словами, можно ли вызвать перезаписанный метод класса-предка?</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Способ 1(только для не виртуальных методов)</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{©Drkb v.3(2007): www.drkb.ru}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">a:class2;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">a:=class2.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">class1(a).mtd;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">....</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #ff0000; font-size: 10pt; font-weight: bold;">Автор:</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Fantasist</span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingrad.ru</span><span style="color: #0000ff; text-decoration: underline;">https://forum.vingrad</span></p> <p> </p> <p> </p> <hr size="1" noshade="noshade" style="color: #000000;" /> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Способ со статическим приведением годится только для</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">не виртуальных методов, имеющих одно имя.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Вызов же виртуальных методов от статического типа не зависит.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В твоём простейшем случае достаточно написать inherited Mtd;</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">(ты его можешь вызвать из любого метода TClass2, не только из Mtd).</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Трудности возникнут, когда нужно вызвать метод "дедушки" или "прадедушки" и т.д.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Один из способов, описанных в литературе, - временная замена</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">VMT объекта на "дедушку" и обратно. Но если у дедушки такого метода не было - будет облом.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Я предпочитаю такой способ:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{©Drkb v.3(2007): www.drkb.ru}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TProc = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">object</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TClassN.SomeMethod;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Proc: TProc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMethod(Proc).Code := @TClass1.Mtd; </span><span class="f_CodeExample" style="color: #000080;">// Статический адрес</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMethod(Proc).Data := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Proc();</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #008000; font-weight: bold;">Автор ответа:</span><span style="font-family: 'Times New Roman'; color: #ff0000;">Le Taon</span></p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingrad.ru</span><span style="color: #0000ff; text-decoration: underline;">https://forum.vingrad</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">1) Есть Class1, с методом Mtd.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">2) Есть Class2 унаследованный от Class1, метод Mtd перезаписан</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">3) В программе используется переменная типа Class2</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Можно ли из программы вызвать Mtd от Class1, Другими словами, можно ли вызвать перезаписанный метод класса-предка?</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Способ 1(только для не виртуальных методов)</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{©Drkb v.3(2007): www.drkb.ru}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">a:class2;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">a:=class2.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">class1(a).mtd;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">....</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #ff0000; font-size: 10pt; font-weight: bold;">Автор:</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Fantasist</span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingrad.ru</span><span style="color: #0000ff; text-decoration: underline;">https://forum.vingrad</span></p> <p> </p> <p> </p> <hr size="1" noshade="noshade" style="color: #000000;" /> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Способ со статическим приведением годится только для</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">не виртуальных методов, имеющих одно имя.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Вызов же виртуальных методов от статического типа не зависит.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В твоём простейшем случае достаточно написать inherited Mtd;</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">(ты его можешь вызвать из любого метода TClass2, не только из Mtd).</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Трудности возникнут, когда нужно вызвать метод "дедушки" или "прадедушки" и т.д.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Один из способов, описанных в литературе, - временная замена</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">VMT объекта на "дедушку" и обратно. Но если у дедушки такого метода не было - будет облом.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Я предпочитаю такой способ:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{©Drkb v.3(2007): www.drkb.ru}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TProc = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">object</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TClassN.SomeMethod;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Proc: TProc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMethod(Proc).Code := @TClass1.Mtd; </span><span class="f_CodeExample" style="color: #000080;">// Статический адрес</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMethod(Proc).Data := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Proc();</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #008000; font-weight: bold;">Автор ответа:</span><span style="font-family: 'Times New Roman'; color: #ff0000;">Le Taon</span></p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingrad.ru</span><span style="color: #0000ff; text-decoration: underline;">https://forum.vingrad</span></p> Как преобразовать указатель на метод в указатель на функцию? 2013-08-19T14:07:36+07:00 2013-08-19T14:07:36+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/metody/kak-preobrazovat-ukazatel-na-metod-v-ukazatel-na-funktsiyu.html Super User toto44@inbox.ru <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Converting method pointers into function pointers </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Often you need a function pointer for a callback function. But what, if you want to specify a method as </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// an callback? Converting a method pointer to a function pointer is not a trivial task; both types are </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// incompatible with each other. Although you have the possibility to convert like this "@TClass.SomeMethod", </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// this is more a hack than a solution, because it restricts the use of this method to some kind of a class </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// function, where you cannot access instance variables. If you fail to do so, you'll get a wonderful gpf. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// But there is a better solution: run time code generation! Just allocate an executable memory block, and </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// write 4 machine code instructions into it: 2 instructions loads the two pointers of the method pointer </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// (code &amp; data) into the registers, one calls the method via the code pointer, and the last is just a return </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Now you can use this pointer to the allocated memory as a plain function pointer, but in fact you are </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// calling a method for a specific instance of a Class. </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> TMyMethod = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">object</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> MakeProcInstance(M: TMethod): Pointer; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// allocate memory </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GetMem(Result, </span><span class="f_CodeExample" style="color: #800000;">15</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// MOV ECX, </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX], $B9 </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV ECX, M.Data </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV DWORD PTR [EAX+$1], ECX </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// POP EDX </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX+$5], $5A </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// PUSH ECX </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX+$6], $51 </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// PUSH EDX </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX+$7], $52 </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// MOV ECX, </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX+$8], $B9 </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV ECX, M.Code </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV DWORD PTR [EAX+$9], ECX </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// JMP ECX </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX+$D], $FF </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX+$E], $E1 </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FreeProcInstance(ProcInstance: Pointer); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// free memory </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FreeMem(ProcInstance, </span><span class="f_CodeExample" style="color: #800000;">15</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с сайта</span>https://www.swissdelphicenter.ch/en/tipsindex</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Converting method pointers into function pointers </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Often you need a function pointer for a callback function. But what, if you want to specify a method as </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// an callback? Converting a method pointer to a function pointer is not a trivial task; both types are </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// incompatible with each other. Although you have the possibility to convert like this "@TClass.SomeMethod", </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// this is more a hack than a solution, because it restricts the use of this method to some kind of a class </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// function, where you cannot access instance variables. If you fail to do so, you'll get a wonderful gpf. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// But there is a better solution: run time code generation! Just allocate an executable memory block, and </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// write 4 machine code instructions into it: 2 instructions loads the two pointers of the method pointer </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// (code &amp; data) into the registers, one calls the method via the code pointer, and the last is just a return </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Now you can use this pointer to the allocated memory as a plain function pointer, but in fact you are </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// calling a method for a specific instance of a Class. </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> TMyMethod = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">object</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> MakeProcInstance(M: TMethod): Pointer; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// allocate memory </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GetMem(Result, </span><span class="f_CodeExample" style="color: #800000;">15</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// MOV ECX, </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX], $B9 </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV ECX, M.Data </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV DWORD PTR [EAX+$1], ECX </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// POP EDX </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX+$5], $5A </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// PUSH ECX </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX+$6], $51 </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// PUSH EDX </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX+$7], $52 </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// MOV ECX, </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX+$8], $B9 </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV ECX, M.Code </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV DWORD PTR [EAX+$9], ECX </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// JMP ECX </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX+$D], $FF </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV BYTE PTR [EAX+$E], $E1 </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FreeProcInstance(ProcInstance: Pointer); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// free memory </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FreeMem(ProcInstance, </span><span class="f_CodeExample" style="color: #800000;">15</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с сайта</span>https://www.swissdelphicenter.ch/en/tipsindex</p> Как редактировать таблицы виртуальных и динамических методов? 2013-08-19T15:47:47+07:00 2013-08-19T15:47:47+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/metody/kak-redaktirovat-tablitsy-virtualnykh-i-dinamicheskikh-metodov.html Super User toto44@inbox.ru <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> EditorVMTandDMTTables;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// функция служит для выяснения существования VMT у класса</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// возвращает True, если класс имеет VMT и False - если нет</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> IsVMTExist(Cls: TClass): Boolean;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// процедура служит для замены адреса метода в VMT класса со смещением</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Offset(должно быть кратно 4) новым адресом, хранящимся в NewMet</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// примечание: перед вызовом этой процедуры проверяйте существование</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// VMT у класса функцией IsVMTExist</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> VirtMethodReplace(Cls: TClass; Offset: LongWord; NewMet: Pointer); overload;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// процедура служит для замены адреса метода, хранящегося в OldMet,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// в VMT класса новым адресом, хранящимся в NewMet</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// примечание: перед вызовом этой процедуры проверяйте существование</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// VMT у класса функцией IsVMTExist</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> VirtMethodReplace(Cls: TClass; OldMet, NewMet: Pointer); overload;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// функция служит для замены адреса динамического метода класса с индексом,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// хранящимся в Index, новым адресом, хранящимся в NewMet</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// возвращает True, если метод с данным индексом найден и False - если нет</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> DynMethodReplace(Cls: TClass; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Word; NewMet: Pointer): Boolean; overload;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// функция служит для замены адреса динамического метода класса, хранящегося</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// в OldMet, новым адресом, хранящимся в NewMet</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// возвращает True, если метод с данным адресом найден и False - если нет</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> DynMethodReplace(Cls: TClass; OldMet, NewMet: Pointer): Boolean; overload;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// функция служит для получения указателя на байт, следующий за адресом</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// последнего метода в VMT класса</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// возвращает nil в случае, если у класса нет VMT</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// функция является "внутренней" в модуле</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// (используется другими подпрограммами и не объявлена в секции interface)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// , поэтому используйте её только если</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вы полностью уверены в своих действиях(она изменяет "рабочие" регистры</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// ECX и EDX)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetVMTEnd(Cls: TClass): Pointer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вход: Cls --&gt; EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Выход: Result --&gt; EAX</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH EBX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV ECX, 8</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EBX, -1</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDX, vmtSelfPtr</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@cycle:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> ADD EDX, 4</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> CMP [EAX + EDX], EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JE @@vmt_not_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JB @@continue</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> CMP [EAX + EDX], EBX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JAE @@continue</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EBX, [EAX + EDX]</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@continue:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> DEC ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JNZ @@cycle</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EAX, EBX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@exit</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@vmt_not_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EAX, EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@exit:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EBX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> IsVMTExist(Cls: TClass): Boolean;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вход: Cls --&gt; EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Выход: Result --&gt; AL</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> CALL GetVMTEnd</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> TEST EAX, EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JZ @@vmt_not_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV AL, 1</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@vmt_not_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> VirtMethodReplace(Cls: TClass; Offset: LongWord; NewMet: Pointer); overload;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вход: Cls --&gt; EAX, Offset --&gt; EDX, NewMet --&gt; ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV [EAX + EDX], ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> VirtMethodReplace(Cls: TClass; OldMet, NewMet: Pointer); overload;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вход: Cls --&gt; EAX, OldMet --&gt; EDX, NewMet --&gt; ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH EDI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDI, EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> CALL GetVMTEnd</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> SUB EAX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff; font-weight: bold;">SHR</span><span class="f_CodeExample" style="color: #ff00ff;"> EAX, 2</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV ECX, EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EAX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> REPNE SCASD</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JNE @@OldMet_</span><span class="f_CodeExample" style="color: #ff00ff; font-weight: bold;">not</span><span class="f_CodeExample" style="color: #ff00ff;">_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV [EDI - 4], EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@OldMet_</span><span class="f_CodeExample" style="color: #ff00ff; font-weight: bold;">not</span><span class="f_CodeExample" style="color: #ff00ff;">_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EDI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> DynMethodReplace(Cls: TClass; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Word; NewMet: Pointer): Boolean; overload;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вход: Cls --&gt; EAX, Index --&gt; DX, NewMet --&gt; ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Выход: Result --&gt; AL</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH EDI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH ESI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV ESI, ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EAX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EDX, EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EAX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@start</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@cycle:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDX, [EDX]</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@start:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDI, [EDX].vmtDynamicTable</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> TEST EDI, EDI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JZ @@get_parent_dmt</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOVZX ECX, WORD PTR [EDI]</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> ADD EDI, 2</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> REPNE SCASW</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JE @@Index_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@get_parent_dmt:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDX, [EDX].vmtParent</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> TEST EDX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JNZ @@cycle</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@Index_not_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@Index_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> SHL EAX, 1</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> SUB EAX, ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV [EDI + EAX * 2 - 4], ESI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV AL, 1</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@exit</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@Index_not_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR AL, AL</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@exit:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP ESI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EDI</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> DynMethodReplace(Cls: TClass; OldMet, NewMet: Pointer): Boolean; overload;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вход: Cls --&gt; EAX, OldMet --&gt; EDX, NewMet --&gt; ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Выход: Result --&gt; AL</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH EDI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH ESI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV ESI, ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EAX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EDX, EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EAX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@start</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@cycle:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDX, [EDX]</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@start:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDI, [EDX].vmtDynamicTable</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> TEST EDI, EDI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JZ @@get_parent_dmt</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOVZX ECX, WORD PTR [EDI]</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> LEA EDI, EDI + 2 * ECX + 2</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> REPNE SCASD</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JE @@OldMet_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@get_parent_dmt:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDX, [EDX].vmtParent</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> TEST EDX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JNZ @@cycle</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@OldMet_not_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@OldMet_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV [EDI - 4], ESI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV AL, 1</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@exit</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@OldMet_not_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR AL, AL</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@exit:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP ESI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EDI</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p><span style="color: #000000; font-weight: bold;">Автор ___ALex___ </span><span style="color: #000000;">Форум:</span>https://forum.pascal.dax</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> EditorVMTandDMTTables;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// функция служит для выяснения существования VMT у класса</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// возвращает True, если класс имеет VMT и False - если нет</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> IsVMTExist(Cls: TClass): Boolean;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// процедура служит для замены адреса метода в VMT класса со смещением</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Offset(должно быть кратно 4) новым адресом, хранящимся в NewMet</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// примечание: перед вызовом этой процедуры проверяйте существование</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// VMT у класса функцией IsVMTExist</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> VirtMethodReplace(Cls: TClass; Offset: LongWord; NewMet: Pointer); overload;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// процедура служит для замены адреса метода, хранящегося в OldMet,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// в VMT класса новым адресом, хранящимся в NewMet</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// примечание: перед вызовом этой процедуры проверяйте существование</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// VMT у класса функцией IsVMTExist</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> VirtMethodReplace(Cls: TClass; OldMet, NewMet: Pointer); overload;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// функция служит для замены адреса динамического метода класса с индексом,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// хранящимся в Index, новым адресом, хранящимся в NewMet</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// возвращает True, если метод с данным индексом найден и False - если нет</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> DynMethodReplace(Cls: TClass; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Word; NewMet: Pointer): Boolean; overload;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// функция служит для замены адреса динамического метода класса, хранящегося</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// в OldMet, новым адресом, хранящимся в NewMet</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// возвращает True, если метод с данным адресом найден и False - если нет</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> DynMethodReplace(Cls: TClass; OldMet, NewMet: Pointer): Boolean; overload;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// функция служит для получения указателя на байт, следующий за адресом</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// последнего метода в VMT класса</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// возвращает nil в случае, если у класса нет VMT</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// функция является "внутренней" в модуле</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// (используется другими подпрограммами и не объявлена в секции interface)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// , поэтому используйте её только если</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вы полностью уверены в своих действиях(она изменяет "рабочие" регистры</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// ECX и EDX)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetVMTEnd(Cls: TClass): Pointer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вход: Cls --&gt; EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Выход: Result --&gt; EAX</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH EBX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV ECX, 8</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EBX, -1</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDX, vmtSelfPtr</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@cycle:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> ADD EDX, 4</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> CMP [EAX + EDX], EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JE @@vmt_not_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JB @@continue</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> CMP [EAX + EDX], EBX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JAE @@continue</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EBX, [EAX + EDX]</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@continue:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> DEC ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JNZ @@cycle</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EAX, EBX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@exit</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@vmt_not_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EAX, EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@exit:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EBX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> IsVMTExist(Cls: TClass): Boolean;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вход: Cls --&gt; EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Выход: Result --&gt; AL</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> CALL GetVMTEnd</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> TEST EAX, EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JZ @@vmt_not_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV AL, 1</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@vmt_not_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> VirtMethodReplace(Cls: TClass; Offset: LongWord; NewMet: Pointer); overload;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вход: Cls --&gt; EAX, Offset --&gt; EDX, NewMet --&gt; ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV [EAX + EDX], ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> VirtMethodReplace(Cls: TClass; OldMet, NewMet: Pointer); overload;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вход: Cls --&gt; EAX, OldMet --&gt; EDX, NewMet --&gt; ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH EDI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDI, EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> CALL GetVMTEnd</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> SUB EAX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff; font-weight: bold;">SHR</span><span class="f_CodeExample" style="color: #ff00ff;"> EAX, 2</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV ECX, EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EAX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> REPNE SCASD</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JNE @@OldMet_</span><span class="f_CodeExample" style="color: #ff00ff; font-weight: bold;">not</span><span class="f_CodeExample" style="color: #ff00ff;">_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV [EDI - 4], EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@OldMet_</span><span class="f_CodeExample" style="color: #ff00ff; font-weight: bold;">not</span><span class="f_CodeExample" style="color: #ff00ff;">_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EDI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> DynMethodReplace(Cls: TClass; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Word; NewMet: Pointer): Boolean; overload;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вход: Cls --&gt; EAX, Index --&gt; DX, NewMet --&gt; ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Выход: Result --&gt; AL</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH EDI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH ESI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV ESI, ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EAX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EDX, EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EAX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@start</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@cycle:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDX, [EDX]</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@start:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDI, [EDX].vmtDynamicTable</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> TEST EDI, EDI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JZ @@get_parent_dmt</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOVZX ECX, WORD PTR [EDI]</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> ADD EDI, 2</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> REPNE SCASW</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JE @@Index_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@get_parent_dmt:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDX, [EDX].vmtParent</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> TEST EDX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JNZ @@cycle</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@Index_not_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@Index_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> SHL EAX, 1</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> SUB EAX, ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV [EDI + EAX * 2 - 4], ESI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV AL, 1</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@exit</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@Index_not_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR AL, AL</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@exit:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP ESI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EDI</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> DynMethodReplace(Cls: TClass; OldMet, NewMet: Pointer): Boolean; overload;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">asm</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Вход: Cls --&gt; EAX, OldMet --&gt; EDX, NewMet --&gt; ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Выход: Result --&gt; AL</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH EDI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> PUSH ESI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV ESI, ECX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EAX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EDX, EAX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR EAX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@start</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@cycle:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDX, [EDX]</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@start:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDI, [EDX].vmtDynamicTable</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> TEST EDI, EDI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JZ @@get_parent_dmt</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOVZX ECX, WORD PTR [EDI]</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> LEA EDI, EDI + 2 * ECX + 2</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> REPNE SCASD</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JE @@OldMet_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@get_parent_dmt:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV EDX, [EDX].vmtParent</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> TEST EDX, EDX</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JNZ @@cycle</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@OldMet_not_found</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@OldMet_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV [EDI - 4], ESI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> MOV AL, 1</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> JMP @@exit</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@OldMet_not_found:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> XOR AL, AL</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;">@@exit:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP ESI</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff00ff;"> POP EDI</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p><span style="color: #000000; font-weight: bold;">Автор ___ALex___ </span><span style="color: #000000;">Форум:</span>https://forum.pascal.dax</p> Как явно вызвать виртуальный метод дедушки? 2013-08-19T15:39:50+07:00 2013-08-19T15:39:50+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/metody/kak-yavno-vyzvat-virtualnyj-metod-dedushki.html Super User toto44@inbox.ru <p><span style="color: #000000;">Проблема в следующем. Допустим, есть иерархия классов, у которых перекрывается один и тот же виртуальный (или динамический - не важно) метод и в одной из реализаций этого метода вы хотите вызвать виртуальный метод предка своего предка. Новая объектная модель Delphi допускает только вызов методов предка (с помощью ключевого слова inherited) либо вызов методов класса с префиксом - типом класса (например, TLevel1.ClassName).</span></p> <p> </p> <p><span style="color: #000000;">Эта проблема стандартными средствами не решается. Но сделать требуемый вызов можно. Причем способом, показанным ниже, можно вызвать любой метод для любого класса, однако, в этом случае вся ответственность за правильность работы с методами и полями ложится на программиста. Ниже в методе VirtualFunction класса TLevel3 вызывается метод класса TLevel1, а в функции Level1Always всегда вызывается метод класса TLevel1 для любого его наследника.</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TLevel1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TComponent)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> VirtualFunction: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TLevel2 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TLevel1)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> VirtualFunction: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TLevel3 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TLevel2)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> VirtualFunction: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Level1Always(MyLevel: TLevel1): </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PClass = ^TClass;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TLevel1.VirtualFunction: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := </span><span class="f_CodeExample" style="color: #ff0000;">'Level1'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TLevel2.VirtualFunction: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> VirtualFunction+</span><span class="f_CodeExample" style="color: #ff0000;">' Level2'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TLevel3.VirtualFunction: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ClassOld: TClass;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ClassOld := PClass(Self)^;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PClass(Self)^ := TLevel1;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := VirtualFunction + </span><span class="f_CodeExample" style="color: #ff0000;">' Level3'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PClass(Self)^ := ClassOld;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Level1Always(MyObject: TObject): </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ClassOld: TClass;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ClassOld := PClass(MyObject)^;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PClass(MyObject)^ := TLevel1;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := (MyObject </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TLevel1).VirtualFunction;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PClass(MyObject)^ := ClassOld;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">Как же это работает? Стандартные так называемые объектные типы (object types - class of ...) на самом деле представляют из себя указатель на VMT (Virtual Method Table) - таблицу виртуальных методов, который (указатель) лежит по смещению 0 в экземпляре класса. Воспользовавшись этим, мы сначала сохраняем 'старый тип класса' - указатель на VMT, присваиваем ему указатель на VMT нужного класса, делаем вызов и восстанавливаем все как было. Причем нигде не требуется, чтобы один из этих классов был бы порожден от другого, т.е. функция Level1Always вызовет требуемый метод вообще для любого экземпляра любого класса.</span></p> <p> </p> <p><span style="color: #000000;">Если в функции Level1Always сделать попробовать вызов</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := MyObject.VirtualFunction;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="color: #000000;">то будет ошибка на стадии компиляции, так как у класса TObject нет метода VirtualFunction. Другой вызов</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := (MyObject </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TLevel3).VirtualFunction;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p><span style="color: #000000;">будет пропущен компилятором, но вызовет Run-time ошибку, даже если передается экземпляр класса TLevel3 или один из его потомком, так как информация о типе объекта меняется. Динамически распределяемые (dynamic) методы можно вызывать точно таким же образом, т.к. информация о них тоже хранится в VMT. Статические методы объектов вызываются гораздо более простым способом, например</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MyLevel3: TLevel3;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> (MyLevel3 </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TLevel1).SomeMethode;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="color: #000000;">вызовет метод класса TLevel1 даже если у MyLevel3 есть свой такой же метод.</span></p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Copyright © 1996 Epsylon Technologies</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из FAQ Epsylon Technologies </span></p> <p><span style="color: #000000;">Проблема в следующем. Допустим, есть иерархия классов, у которых перекрывается один и тот же виртуальный (или динамический - не важно) метод и в одной из реализаций этого метода вы хотите вызвать виртуальный метод предка своего предка. Новая объектная модель Delphi допускает только вызов методов предка (с помощью ключевого слова inherited) либо вызов методов класса с префиксом - типом класса (например, TLevel1.ClassName).</span></p> <p> </p> <p><span style="color: #000000;">Эта проблема стандартными средствами не решается. Но сделать требуемый вызов можно. Причем способом, показанным ниже, можно вызвать любой метод для любого класса, однако, в этом случае вся ответственность за правильность работы с методами и полями ложится на программиста. Ниже в методе VirtualFunction класса TLevel3 вызывается метод класса TLevel1, а в функции Level1Always всегда вызывается метод класса TLevel1 для любого его наследника.</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TLevel1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TComponent)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> VirtualFunction: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TLevel2 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TLevel1)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> VirtualFunction: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TLevel3 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TLevel2)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> VirtualFunction: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Level1Always(MyLevel: TLevel1): </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PClass = ^TClass;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TLevel1.VirtualFunction: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := </span><span class="f_CodeExample" style="color: #ff0000;">'Level1'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TLevel2.VirtualFunction: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> VirtualFunction+</span><span class="f_CodeExample" style="color: #ff0000;">' Level2'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TLevel3.VirtualFunction: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ClassOld: TClass;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ClassOld := PClass(Self)^;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PClass(Self)^ := TLevel1;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := VirtualFunction + </span><span class="f_CodeExample" style="color: #ff0000;">' Level3'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PClass(Self)^ := ClassOld;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Level1Always(MyObject: TObject): </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ClassOld: TClass;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ClassOld := PClass(MyObject)^;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PClass(MyObject)^ := TLevel1;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := (MyObject </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TLevel1).VirtualFunction;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PClass(MyObject)^ := ClassOld;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">Как же это работает? Стандартные так называемые объектные типы (object types - class of ...) на самом деле представляют из себя указатель на VMT (Virtual Method Table) - таблицу виртуальных методов, который (указатель) лежит по смещению 0 в экземпляре класса. Воспользовавшись этим, мы сначала сохраняем 'старый тип класса' - указатель на VMT, присваиваем ему указатель на VMT нужного класса, делаем вызов и восстанавливаем все как было. Причем нигде не требуется, чтобы один из этих классов был бы порожден от другого, т.е. функция Level1Always вызовет требуемый метод вообще для любого экземпляра любого класса.</span></p> <p> </p> <p><span style="color: #000000;">Если в функции Level1Always сделать попробовать вызов</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := MyObject.VirtualFunction;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="color: #000000;">то будет ошибка на стадии компиляции, так как у класса TObject нет метода VirtualFunction. Другой вызов</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := (MyObject </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TLevel3).VirtualFunction;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p><span style="color: #000000;">будет пропущен компилятором, но вызовет Run-time ошибку, даже если передается экземпляр класса TLevel3 или один из его потомком, так как информация о типе объекта меняется. Динамически распределяемые (dynamic) методы можно вызывать точно таким же образом, т.к. информация о них тоже хранится в VMT. Статические методы объектов вызываются гораздо более простым способом, например</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MyLevel3: TLevel3;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> (MyLevel3 </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TLevel1).SomeMethode;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="color: #000000;">вызовет метод класса TLevel1 даже если у MyLevel3 есть свой такой же метод.</span></p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Copyright © 1996 Epsylon Technologies</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из FAQ Epsylon Technologies </span></p> Перекрытие виртуальных методов 2013-08-19T15:50:07+07:00 2013-08-19T15:50:07+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/metody/perekrytie-virtualnykh-metodov.html Super User toto44@inbox.ru <p><span style="font-style: italic; color: #000000;">Кто-нибудь знает, в чем разница между перекрытием (OVERRIDING) виртуального метода и заменой (REPLACING) его? Я немного запутался.</span></p> <p> </p> <p><span style="color: #000000;">Допустим у вас есть класс:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyObject = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> (TObject) </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">и его наследник:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TOverrideObject = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> (TMyObject) </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">К примеру, TMyObject имеет метод Wiggle:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Wiggle; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">а TOverrideObject перекрывает Wiggle:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Wiggle; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">и, естественно, вы реализовали оба метода.</span></p> <p> </p> <p><span style="color: #000000;">Теперь вы создаете TList, содержащий целую кучу MyObjects и OverrideObjects в свойстве TList.Items[n]. Свойство Items является указателем, поэтому для вызова метода Wiggle вам достаточно вызвать необходимый элемент списка. Например так:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> TObject(Items[</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">]) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">is</span><span class="f_CodeExample" style="color: #000000;"> TMyObject </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyObject(Items[</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">]).Wiggle</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> TObject(Items[</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">]) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">is</span><span class="f_CodeExample" style="color: #000000;"> TOverrideObject </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TOverrideObject(Items[</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">]).Wiggle;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">но возможности полиморфизма и директива override позволяют вам сделать так:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyObject(Items[</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">]).Wiggle; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">Ваше приложение посмотрит на экземпляр специфического объекта, ссылка на который содержится в Items[1] и скажет: "Да, это - TMyObject, но, точнее говоря, это TOverrideObject; но поскольку метод Wiggle является виртуальным методом и TOverrideObject переопределил метод Wiggle, я собираюсь выполнить метод TOverrideObject.Wiggle, а не метод TMyObject.Wiggle."</span></p> <p> </p> <p><span style="color: #000000;">Теперь представьте себе, что при декларации метода вы пропустили директиву override, попробуйте это выполнить теперь:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyObject(Items[</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">]).Wiggle; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="color: #000000;">Приложение и в этом случае должно "видеть" данный метод, даже если Items[1] - TOverrideObject; но у него отсутствует перекрытая версия метода Wiggle, поэтому приложение выполнит TMyObject.Wiggle, а не TOverrideObject.Wiggle (поведение, которое вы можете как хотеть, так и избегать).</span></p> <p> </p> <p><span style="color: #000000;">Так, перекрытый метод функционально может отличаться от декларированного метода, содержащего директиву virtual (или dynamic) в базовом классе, и объявленный с директивой override в классе-наследнике. Для замены метода необходимо объявить его в классе-наследнике без директивы override. Перекрытые методы могут выполняться даже тогда, когда специфический экземпляр класса-предка является точной копией базового класса. "Замененные" методы могут выполняться только тогда, когда специфический экземпляр является "слепком" только этого класса.</span></p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от</span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> <p><span style="font-style: italic; color: #000000;">Кто-нибудь знает, в чем разница между перекрытием (OVERRIDING) виртуального метода и заменой (REPLACING) его? Я немного запутался.</span></p> <p> </p> <p><span style="color: #000000;">Допустим у вас есть класс:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyObject = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> (TObject) </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">и его наследник:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TOverrideObject = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> (TMyObject) </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">К примеру, TMyObject имеет метод Wiggle:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Wiggle; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">а TOverrideObject перекрывает Wiggle:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Wiggle; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">и, естественно, вы реализовали оба метода.</span></p> <p> </p> <p><span style="color: #000000;">Теперь вы создаете TList, содержащий целую кучу MyObjects и OverrideObjects в свойстве TList.Items[n]. Свойство Items является указателем, поэтому для вызова метода Wiggle вам достаточно вызвать необходимый элемент списка. Например так:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> TObject(Items[</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">]) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">is</span><span class="f_CodeExample" style="color: #000000;"> TMyObject </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyObject(Items[</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">]).Wiggle</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> TObject(Items[</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">]) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">is</span><span class="f_CodeExample" style="color: #000000;"> TOverrideObject </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TOverrideObject(Items[</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">]).Wiggle;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">но возможности полиморфизма и директива override позволяют вам сделать так:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyObject(Items[</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">]).Wiggle; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">Ваше приложение посмотрит на экземпляр специфического объекта, ссылка на который содержится в Items[1] и скажет: "Да, это - TMyObject, но, точнее говоря, это TOverrideObject; но поскольку метод Wiggle является виртуальным методом и TOverrideObject переопределил метод Wiggle, я собираюсь выполнить метод TOverrideObject.Wiggle, а не метод TMyObject.Wiggle."</span></p> <p> </p> <p><span style="color: #000000;">Теперь представьте себе, что при декларации метода вы пропустили директиву override, попробуйте это выполнить теперь:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyObject(Items[</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">]).Wiggle; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="color: #000000;">Приложение и в этом случае должно "видеть" данный метод, даже если Items[1] - TOverrideObject; но у него отсутствует перекрытая версия метода Wiggle, поэтому приложение выполнит TMyObject.Wiggle, а не TOverrideObject.Wiggle (поведение, которое вы можете как хотеть, так и избегать).</span></p> <p> </p> <p><span style="color: #000000;">Так, перекрытый метод функционально может отличаться от декларированного метода, содержащего директиву virtual (или dynamic) в базовом классе, и объявленный с директивой override в классе-наследнике. Для замены метода необходимо объявить его в классе-наследнике без директивы override. Перекрытые методы могут выполняться даже тогда, когда специфический экземпляр класса-предка является точной копией базового класса. "Замененные" методы могут выполняться только тогда, когда специфический экземпляр является "слепком" только этого класса.</span></p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от</span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> Вызов процедуры, имя которой содержится в переменной 2013-08-19T19:04:34+07:00 2013-08-19T19:04:34+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/vyzov-protsedury-imya-kotoroj-soderzhitsya-v-peremennoj.html Super User toto44@inbox.ru <p><span style="font-style: italic; color: #000000;">Как я могу вызвать процедуру, чье имя хранится в таблице, списке, и т.п.? Другими словами, я хочу сохранить имя процедуры в переменной и для ее вызова обращаться к значению этой переменной. Какие предложения? </span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> ProcDict;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> MyProc = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;">(s: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> RegisterProc(procName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; proc: MyProc);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ExecuteProc(procName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; arg: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> Classes;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> ProcDict: TStringList;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> RegisterProc(procName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; proc: MyProc);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ProcDict.AddObject(procName, TObject(@proc));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ExecuteProc(procName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; arg: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000000;">: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000000;"> := ProcDict.IndexOf(ProcName);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000000;"> &gt;= </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MyProc(ProcDict.objects[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000000;">])(arg);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Можно вставить обработку исключительной ситуации - сообщение об ошибке</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">initialization</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ProcDict := TStringList.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ProcDict.Sorted := true;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finalization</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ProcDict.Free;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p><span style="font-family: 'Courier New'; font-size: 10pt;">вы могли бы создать StringList как показано ниже:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StringList.Create; StringList.AddObject(</span><span class="f_CodeExample" style="color: #ff0000;">'Proc1'</span><span class="f_CodeExample" style="color: #000000;">,@Proc1);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StringList.AddObject(</span><span class="f_CodeExample" style="color: #ff0000;">'Proc2'</span><span class="f_CodeExample" style="color: #000000;">,@Proc2); </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Courier New'; font-size: 10pt;">и затем реализовать это в вашей программе:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">myFunc: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Stringlist.indexof(S) = -</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageDlg(</span><span class="f_CodeExample" style="color: #ff0000;">'Не понял процедуру '</span><span class="f_CodeExample" style="color: #000000;"> + S, mtError, [mbOk], </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> @myFunc := Stringlist.Objects[Stringlist.indexof(S)];</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> myFunc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p><span style="color: #000000;">RAM </span></p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> <p><span style="font-style: italic; color: #000000;">Как я могу вызвать процедуру, чье имя хранится в таблице, списке, и т.п.? Другими словами, я хочу сохранить имя процедуры в переменной и для ее вызова обращаться к значению этой переменной. Какие предложения? </span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> ProcDict;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> MyProc = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;">(s: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> RegisterProc(procName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; proc: MyProc);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ExecuteProc(procName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; arg: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> Classes;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> ProcDict: TStringList;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> RegisterProc(procName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; proc: MyProc);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ProcDict.AddObject(procName, TObject(@proc));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ExecuteProc(procName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; arg: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000000;">: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000000;"> := ProcDict.IndexOf(ProcName);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000000;"> &gt;= </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MyProc(ProcDict.objects[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000000;">])(arg);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Можно вставить обработку исключительной ситуации - сообщение об ошибке</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">initialization</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ProcDict := TStringList.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ProcDict.Sorted := true;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finalization</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ProcDict.Free;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p><span style="font-family: 'Courier New'; font-size: 10pt;">вы могли бы создать StringList как показано ниже:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StringList.Create; StringList.AddObject(</span><span class="f_CodeExample" style="color: #ff0000;">'Proc1'</span><span class="f_CodeExample" style="color: #000000;">,@Proc1);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StringList.AddObject(</span><span class="f_CodeExample" style="color: #ff0000;">'Proc2'</span><span class="f_CodeExample" style="color: #000000;">,@Proc2); </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Courier New'; font-size: 10pt;">и затем реализовать это в вашей программе:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">myFunc: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Stringlist.indexof(S) = -</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageDlg(</span><span class="f_CodeExample" style="color: #ff0000;">'Не понял процедуру '</span><span class="f_CodeExample" style="color: #000000;"> + S, mtError, [mbOk], </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> @myFunc := Stringlist.Objects[Stringlist.indexof(S)];</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> myFunc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p><span style="color: #000000;">RAM </span></p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> Выполнение процедуры по адресу 2013-08-19T19:05:36+07:00 2013-08-19T19:05:36+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/vypolnenie-protsedury-po-adresu.html Super User toto44@inbox.ru <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> F: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;">(x, y: double);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">@F := GetProcAddress(hDLL, </span><span class="f_CodeExample" style="color: #ff0000;">'SOMEPROC'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">F(</span><span class="f_CodeExample" style="color: #800000;">3</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">4</span><span class="f_CodeExample" style="color: #000000;">);</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="color: #000000;">Ключом здесь является использование оператора @, располагаемого с левой части процедурной переменной. Он говорит компилятору: "Не волнуйтесь здесь о совместимости типов, просто присвойте полученный в правой части выражения адрес переменной в левой части выражения (и процедурные переменные являются переменными-указателями).</span></p> <p> </p> <p><span style="color: #000000;">- Peter Below </span></p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> F: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;">(x, y: double);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">@F := GetProcAddress(hDLL, </span><span class="f_CodeExample" style="color: #ff0000;">'SOMEPROC'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">F(</span><span class="f_CodeExample" style="color: #800000;">3</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">4</span><span class="f_CodeExample" style="color: #000000;">);</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="color: #000000;">Ключом здесь является использование оператора @, располагаемого с левой части процедурной переменной. Он говорит компилятору: "Не волнуйтесь здесь о совместимости типов, просто присвойте полученный в правой части выражения адрес переменной в левой части выражения (и процедурные переменные являются переменными-указателями).</span></p> <p> </p> <p><span style="color: #000000;">- Peter Below </span></p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> Информация о TClass 2013-08-19T19:06:38+07:00 2013-08-19T19:06:38+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/informatsiya-o-tclass.html Super User toto44@inbox.ru <p><span style="color: #000000;">TObject - "корневой" объект.</span></p> <p> </p> <p><span style="color: #000000;">TClass определен как Class of TObject. Переменная Class НЕ является указателем на экземпляр объекта. Это указатель на *ТИП* объекта Class.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Obj1: TWinControl;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Class1: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TWinControl;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Courier New'; font-size: 9pt;">Class1 := TWinControl</span><span style="color: #000000;"> - правильное присваивание. Мы не распределяем память, у нас нет экземпляра TWinControl, мы не можем вызвать Class1.OnClick.</span></p> <p> </p> <p><span style="color: #000000;">Class1 - это *тип* TWinControl с тем же контекстом использования, что и "TWinControl".</span></p> <p> </p> <p><span style="color: #000000;">Поскольку мы можем использовать TWinControl.Create, то также мы можем использовать и Class1.Create, при этом создавая новый экземпляр TWinControl.</span></p> <p> </p> <p><span style="color: #000000;">С тех пор как TEdit - наследник TWinControl, </span><span style="font-family: 'Courier New'; font-size: 9pt;">Class1 := TEdit</span><span style="color: #000000;"> правильное присваивание и Class1.Create создает экземпляр TEdit.</span></p> <p> </p> <p><span style="color: #000000;">Если у меня имеется переменная Obj2: TWinControl, и даже если я присвоил экземпляр TListbox Obj2, я не могу ссылаться на Obj2.Items, поскольку Obj2 определен как TWinControl, а TWinControl не имеет свойства Items.</span></p> <p> </p> <p><span style="color: #000000;">Те же характеристики верны и для Class1. Class1 определен как Class of TWinControl, поэтому они имеют общий конструктор, определенный в классе TWinControl.</span></p> <p> </p> <p><span style="color: #000000;">Это не пугает меня при создании дополнительных типов:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyObj1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TEdit)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> CreateMagic; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyObj2 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TMyObj1)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> CreateMagic; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyClass = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TMyObj;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyObj1: TMyObj1;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyObj2: TMyObj2;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> MakeAnother(AClass: TMyClass): TMyObj1;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := AClass.CreateMagic;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyObj2 := TMyObj2.CreateMagic;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyObj1 := MakeAnother(MyObj2.ClassType);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> <p><span style="color: #000000;">TObject - "корневой" объект.</span></p> <p> </p> <p><span style="color: #000000;">TClass определен как Class of TObject. Переменная Class НЕ является указателем на экземпляр объекта. Это указатель на *ТИП* объекта Class.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Obj1: TWinControl;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Class1: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TWinControl;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Courier New'; font-size: 9pt;">Class1 := TWinControl</span><span style="color: #000000;"> - правильное присваивание. Мы не распределяем память, у нас нет экземпляра TWinControl, мы не можем вызвать Class1.OnClick.</span></p> <p> </p> <p><span style="color: #000000;">Class1 - это *тип* TWinControl с тем же контекстом использования, что и "TWinControl".</span></p> <p> </p> <p><span style="color: #000000;">Поскольку мы можем использовать TWinControl.Create, то также мы можем использовать и Class1.Create, при этом создавая новый экземпляр TWinControl.</span></p> <p> </p> <p><span style="color: #000000;">С тех пор как TEdit - наследник TWinControl, </span><span style="font-family: 'Courier New'; font-size: 9pt;">Class1 := TEdit</span><span style="color: #000000;"> правильное присваивание и Class1.Create создает экземпляр TEdit.</span></p> <p> </p> <p><span style="color: #000000;">Если у меня имеется переменная Obj2: TWinControl, и даже если я присвоил экземпляр TListbox Obj2, я не могу ссылаться на Obj2.Items, поскольку Obj2 определен как TWinControl, а TWinControl не имеет свойства Items.</span></p> <p> </p> <p><span style="color: #000000;">Те же характеристики верны и для Class1. Class1 определен как Class of TWinControl, поэтому они имеют общий конструктор, определенный в классе TWinControl.</span></p> <p> </p> <p><span style="color: #000000;">Это не пугает меня при создании дополнительных типов:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyObj1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TEdit)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> CreateMagic; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyObj2 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TMyObj1)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> CreateMagic; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyClass = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TMyObj;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyObj1: TMyObj1;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyObj2: TMyObj2;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> MakeAnother(AClass: TMyClass): TMyObj1;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := AClass.CreateMagic;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyObj2 := TMyObj2.CreateMagic;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyObj1 := MakeAnother(MyObj2.ClassType);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> Как внести изменения в код VCL? 2013-08-19T17:09:01+07:00 2013-08-19T17:09:01+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/kak-vnesti-izmeneniya-v-kod-vcl.html Super User toto44@inbox.ru <p><span style="color: #000000;">Примечание: внесение изменений в VCL не поддерживается Borland или Borland Developer Support.</span></p> <p><span style="color: #000000;">-Но если Вы решили сделать это...</span></p> <p><span style="color: #000000;">Изменения в код VCL никогда не должны вносится в секцию "interface" модуля - только в секцию "implimentation". Наиболее безопасный способ внести изменения в VCL - создать новый каталог названный "исправленный VCL". Скопируйте файл VCL который Вы хотите изменить в этот каталог. Внесите изменения (лучше прокомментировать их) в этот файл. Затем добавьте путь к Вашему каталогу "исправленный VCL" в самое начало "library path". Перезапустите Delphi/C++ Builder и перекомпилируйте Ваш проект. "library path" можно изменить в меню: </span></p> <p> </p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">Delphi 1 : Options | Environment | Library</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">Delphi 2 : Tools | Options | Library</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">Delphi 3 : Tools | Environment Options | Library</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">Delphi 4 : Tools | Environment Options | Library</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">C++ Builder : Options | Environment | Library</span></p> <p><span style="color: #000000;">Примечание: внесение изменений в VCL не поддерживается Borland или Borland Developer Support.</span></p> <p><span style="color: #000000;">-Но если Вы решили сделать это...</span></p> <p><span style="color: #000000;">Изменения в код VCL никогда не должны вносится в секцию "interface" модуля - только в секцию "implimentation". Наиболее безопасный способ внести изменения в VCL - создать новый каталог названный "исправленный VCL". Скопируйте файл VCL который Вы хотите изменить в этот каталог. Внесите изменения (лучше прокомментировать их) в этот файл. Затем добавьте путь к Вашему каталогу "исправленный VCL" в самое начало "library path". Перезапустите Delphi/C++ Builder и перекомпилируйте Ваш проект. "library path" можно изменить в меню: </span></p> <p> </p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">Delphi 1 : Options | Environment | Library</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">Delphi 2 : Tools | Options | Library</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">Delphi 3 : Tools | Environment Options | Library</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">Delphi 4 : Tools | Environment Options | Library</span></p> <p><span style="font-family: 'Courier New'; color: #000000; font-size: 9pt;">C++ Builder : Options | Environment | Library</span></p> Как забыть о необходимости разрушать объекты? 2013-08-19T19:08:27+07:00 2013-08-19T19:08:27+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/kak-zabyt-o-neobkhodimosti-razrushat-ob-ekty.html Super User toto44@inbox.ru <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ISelfDestroy = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//forget about GUID, if you are not using COM</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TSelfDestroy = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TInterfacedObject, ISelfDestroy)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FObject: TObject;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AObject: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TSelfDestroy.Create(AObject: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FObject := AObject;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TSelfDestroy.Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FreeAndNil(FObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// So when you use, just do like this...</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyObject: TMyObject;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SelfDestroy: TSelfDestroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyObject := TMyObject.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SelfDestroy := TSelfDestroy.Create(MyObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// The MyObject will free automatically as soon as TSelfDestroy</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// goes out of scope.</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Carry on your code here...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с сайта</span>https://www.swissdelphicenter.ch/en/tipsindex</p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ISelfDestroy = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//forget about GUID, if you are not using COM</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TSelfDestroy = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TInterfacedObject, ISelfDestroy)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FObject: TObject;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AObject: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TSelfDestroy.Create(AObject: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FObject := AObject;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TSelfDestroy.Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FreeAndNil(FObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// So when you use, just do like this...</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyObject: TMyObject;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SelfDestroy: TSelfDestroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyObject := TMyObject.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SelfDestroy := TSelfDestroy.Create(MyObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// The MyObject will free automatically as soon as TSelfDestroy</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// goes out of scope.</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Carry on your code here...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с сайта</span>https://www.swissdelphicenter.ch/en/tipsindex</p> Как можно работать с объектами не заботясь об их разрушении? 2013-08-19T17:01:39+07:00 2013-08-19T17:01:39+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/kak-mozhno-rabotat-s-ob-ektami-ne-zabotyas-ob-ikh-razrushenii.html Super User toto44@inbox.ru <p><span style="color: #000000;">Вначале сделаем интерфейс для нашего объекта:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">IAutoClean = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> [</span><span class="f_CodeExample" style="color: #ff0000;">'{61D9CBA6-B1CE-4297-9319-66CC86CE6922}'</span><span class="f_CodeExample" style="color: #000000;">]</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TAutoClean = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TInterfacedObject, IAutoClean)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FObj: TObject;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AObj: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TAutoClean.Create(AObj: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FObj := AObj;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TAutoClean.Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FreeAndNil(FObj);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">А теперь будем использовать его вместо объекта:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">a: IAutoClean;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//must declare as local variable, so when this procedure finished, it's out of scope</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">o: TOpenDialog; </span><span class="f_CodeExample" style="color: #000080;">//any component</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">o := TOpenDialog.Create(self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">a := TAutoClean.Create(o);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> o.Execute </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ShowMessage(o.FileName);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с Delphi Knowledge Base: </span>https://www.baltsoft</p> <p><span style="color: #000000;">Вначале сделаем интерфейс для нашего объекта:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">IAutoClean = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> [</span><span class="f_CodeExample" style="color: #ff0000;">'{61D9CBA6-B1CE-4297-9319-66CC86CE6922}'</span><span class="f_CodeExample" style="color: #000000;">]</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TAutoClean = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TInterfacedObject, IAutoClean)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FObj: TObject;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AObj: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TAutoClean.Create(AObj: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FObj := AObj;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TAutoClean.Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FreeAndNil(FObj);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">А теперь будем использовать его вместо объекта:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">a: IAutoClean;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//must declare as local variable, so when this procedure finished, it's out of scope</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">o: TOpenDialog; </span><span class="f_CodeExample" style="color: #000080;">//any component</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">o := TOpenDialog.Create(self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">a := TAutoClean.Create(o);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> o.Execute </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ShowMessage(o.FileName);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с Delphi Knowledge Base: </span>https://www.baltsoft</p> Как создать компонент во время выполнения приложения? 2013-08-19T17:06:34+07:00 2013-08-19T17:06:34+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/kak-sozdat-komponent-vo-vremya-vypolneniya-prilozheniya.html Super User toto44@inbox.ru <p><span style="font-family: 'Times New Roman'; color: #000000;">При создании визуальных контролов в runtime, важным моментом является назначение родительских свойств и использование метода SetBounds, чтобы этот контрол стал видимы.</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TForm1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TForm) </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MyLabel: TLabel; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> LabelClick(Sender: TObject); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> CreateControl; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.LabelClick(Sender: TObject); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">(Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Label</span><span class="f_CodeExample" style="color: #000000;">).Caption := ... </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.CreateControl; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ALeft, ATop, AWidth, AHeight: Integer; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ALeft := </span><span class="f_CodeExample" style="color: #800000;">10</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ATop := </span><span class="f_CodeExample" style="color: #800000;">10</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">AWidth := </span><span class="f_CodeExample" style="color: #800000;">50</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">AHeight := </span><span class="f_CodeExample" style="color: #800000;">13</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyLabel := TLabel.Create(Self); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyLabel.Parent := Self; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyLabel.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">:=</span><span class="f_CodeExample" style="color: #ff0000;">'LabelName'</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyLabel.SetBounds(ALeft, ATop, AWidth, AHeight); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyLabel.OnClick := LabelClick; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">https://forum.sources</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">При создании визуальных контролов в runtime, важным моментом является назначение родительских свойств и использование метода SetBounds, чтобы этот контрол стал видимы.</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TForm1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TForm) </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MyLabel: TLabel; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> LabelClick(Sender: TObject); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> CreateControl; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.LabelClick(Sender: TObject); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">(Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Label</span><span class="f_CodeExample" style="color: #000000;">).Caption := ... </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.CreateControl; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ALeft, ATop, AWidth, AHeight: Integer; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ALeft := </span><span class="f_CodeExample" style="color: #800000;">10</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ATop := </span><span class="f_CodeExample" style="color: #800000;">10</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">AWidth := </span><span class="f_CodeExample" style="color: #800000;">50</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">AHeight := </span><span class="f_CodeExample" style="color: #800000;">13</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyLabel := TLabel.Create(Self); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyLabel.Parent := Self; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyLabel.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">:=</span><span class="f_CodeExample" style="color: #ff0000;">'LabelName'</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyLabel.SetBounds(ALeft, ATop, AWidth, AHeight); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyLabel.OnClick := LabelClick; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">https://forum.sources</span></p> Как создать копию произвольного компонента? 2013-08-19T17:09:40+07:00 2013-08-19T17:09:40+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/kak-sozdat-kopiyu-proizvolnogo-komponenta.html Super User toto44@inbox.ru <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">Здесь пpоцедypа CreateClone, котоpая кpеатит компонентy ОЧЕHЬ ПОХОЖУЮ на </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">входнyю. С такими же значениями свойств. Пpисваивается все, кpоме методов. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> CreateClone(Src: TComponent): TComponent; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">F: TStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">F := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> F := TMemoryStream.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> F.WriteComponent(Src); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> RegisterClass(TComponentClass(Src.ClassType)); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> F.Position := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := F.ReadComponent(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finally</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> F.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">Здесь пpоцедypа CreateClone, котоpая кpеатит компонентy ОЧЕHЬ ПОХОЖУЮ на </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">входнyю. С такими же значениями свойств. Пpисваивается все, кpоме методов. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> CreateClone(Src: TComponent): TComponent; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">F: TStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">F := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> F := TMemoryStream.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> F.WriteComponent(Src); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> RegisterClass(TComponentClass(Src.ClassType)); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> F.Position := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := F.ReadComponent(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finally</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> F.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> Клонирование объектов 2013-08-19T19:11:28+07:00 2013-08-19T19:11:28+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/klonirovanie-ob-ektov.html Super User toto44@inbox.ru <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Создать</span><span style="font-family: 'Times New Roman'; color: #000000;">копию</span><span style="font-family: 'Times New Roman'; color: #000000;">объекта</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;"> Delphi </span><span style="font-family: 'Times New Roman'; color: #000000;">очень</span><span style="font-family: 'Times New Roman'; color: #000000;">просто</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Конвертируем</span><span style="font-family: 'Times New Roman'; color: #000000;">объект</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">текст</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">затем</span><span style="font-family: 'Times New Roman'; color: #000000;"> - </span><span style="font-family: 'Times New Roman'; color: #000000;">обратно</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">При</span><span style="font-family: 'Times New Roman'; color: #000000;">этом</span><span style="font-family: 'Times New Roman'; color: #000000;">будут</span><span style="font-family: 'Times New Roman'; color: #000000;">продублированы</span><span style="font-family: 'Times New Roman'; color: #000000;">все</span><span style="font-family: 'Times New Roman'; color: #000000;">свойства</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">кроме</span><span style="font-family: 'Times New Roman'; color: #000000;">ссылок</span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">обработчики</span><span style="font-family: 'Times New Roman'; color: #000000;">событий</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Для</span><span style="font-family: 'Times New Roman'; color: #000000;">преобразования</span><span style="font-family: 'Times New Roman'; color: #000000;">компонента</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">файл</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">обратно</span><span style="font-family: 'Times New Roman'; color: #000000;">нам</span><span style="font-family: 'Times New Roman'; color: #000000;">понадобятся</span><span style="font-family: 'Times New Roman'; color: #000000;">функции</span><span style="font-family: 'Times New Roman'; color: #000000;">потоков</span><span style="font-family: 'Times New Roman'; color: #000000;"> WriteComponent(TComponent) </span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;"> ReadComponent(TComponent). </span><span style="font-family: 'Times New Roman'; color: #000000;">При</span><span style="font-family: 'Times New Roman'; color: #000000;">этом</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">поток</span><span style="font-family: 'Times New Roman'; color: #000000;">записывается</span><span style="font-family: 'Times New Roman'; color: #000000;">двоичный</span><span style="font-family: 'Times New Roman'; color: #000000;">ресурс</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Последний</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">помощью</span><span style="font-family: 'Times New Roman'; color: #000000;">функции</span><span style="font-family: 'Times New Roman'; color: #000000;"> ObjectBinaryToText </span><span style="font-family: 'Times New Roman'; color: #000000;">можно</span><span style="font-family: 'Times New Roman'; color: #000000;">преобразовать</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">текст</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><br /><span style="font-family: 'Times New Roman'; color: #000000;">Создадим</span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;">основе</span><span style="font-family: 'Times New Roman'; color: #000000;">функции</span><span style="font-family: 'Times New Roman'; color: #000000;">преобразования</span><span style="font-family: 'Times New Roman'; color: #000000;">:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> ComponentToString(Component: TComponent): </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms: TMemoryStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ss: TStringStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ss := TStringStream.Create(</span><span class="f_CodeExample" style="color: #ff0000;">' '</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms := TMemoryStream.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.WriteComponent(Component); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.position := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ObjectBinaryToText(ms, ss); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ss.position := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := ss.DataString; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finally</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ss.free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> StringToComponent(Component: TComponent; Value: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StrStream:TStringStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms: TMemoryStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StrStream := TStringStream.Create(Value); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms := TMemoryStream.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ObjectTextToBinary(StrStream, ms); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.position := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.ReadComponent(Component); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finally</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finally</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> StrStream.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">С</span><span style="font-family: 'Times New Roman'; color: #000000;">помощью</span><span style="font-family: 'Times New Roman'; color: #000000;">пары</span><span style="font-family: 'Times New Roman'; color: #000000;">этих</span><span style="font-family: 'Times New Roman'; color: #000000;">функций</span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">можем</span><span style="font-family: 'Times New Roman'; color: #000000;">преобразовать</span><span style="font-family: 'Times New Roman'; color: #000000;">любой</span><span style="font-family: 'Times New Roman'; color: #000000;">компонент</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">текст</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">затем</span><span style="font-family: 'Times New Roman'; color: #000000;">проинициализировать</span><span style="font-family: 'Times New Roman'; color: #000000;">другой</span><span style="font-family: 'Times New Roman'; color: #000000;">компонент</span><span style="font-family: 'Times New Roman'; color: #000000;">того</span><span style="font-family: 'Times New Roman'; color: #000000;">же</span><span style="font-family: 'Times New Roman'; color: #000000;">класса</span><span style="font-family: 'Times New Roman'; color: #000000;">этими</span><span style="font-family: 'Times New Roman'; color: #000000;">данными</span><span style="font-family: 'Times New Roman'; color: #000000;">.</span><br /><span style="font-family: 'Times New Roman'; color: #000000;">Ниже</span><span style="font-family: 'Times New Roman'; color: #000000;">приведен</span><span style="font-family: 'Times New Roman'; color: #000000;">ресурс</span><span style="font-family: 'Times New Roman'; color: #000000;">формы</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">одной</span><span style="font-family: 'Times New Roman'; color: #000000;">кнопкой</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">текст</span><span style="font-family: 'Times New Roman'; color: #000000;">обработчика</span><span style="font-family: 'Times New Roman'; color: #000000;">нажатия</span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">эту</span><span style="font-family: 'Times New Roman'; color: #000000;">кнопку</span><span style="font-family: 'Times New Roman'; color: #000000;">.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">object</span><span class="f_CodeExample" style="color: #000000;"> Form1: TForm1 </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Left = </span><span class="f_CodeExample" style="color: #800000;">262</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Top = </span><span class="f_CodeExample" style="color: #800000;">129</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Width = </span><span class="f_CodeExample" style="color: #800000;">525</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Height = </span><span class="f_CodeExample" style="color: #800000;">153</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption = </span><span class="f_CodeExample" style="color: #ff0000;">'Form1'</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Color = clBtnFace </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Font.Charset = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">DEFAULT</span><span class="f_CodeExample" style="color: #000000;">_CHARSET </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Font.Color = clWindowText </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Font.Height = -</span><span class="f_CodeExample" style="color: #800000;">11</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Font.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> = </span><span class="f_CodeExample" style="color: #ff0000;">'MS Sans Serif'</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Font.Style = [] </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OldCreateOrder = False </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Scaled = False </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PixelsPerInch = </span><span class="f_CodeExample" style="color: #800000;">96</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TextHeight = </span><span class="f_CodeExample" style="color: #800000;">13</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">object</span><span class="f_CodeExample" style="color: #000000;"> Button1: TButton </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Left = </span><span class="f_CodeExample" style="color: #800000;">16</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Top = </span><span class="f_CodeExample" style="color: #800000;">32</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Width = </span><span class="f_CodeExample" style="color: #800000;">57</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Height = </span><span class="f_CodeExample" style="color: #800000;">49</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Caption = </span><span class="f_CodeExample" style="color: #ff0000;">'Caption'</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TabOrder = </span><span class="f_CodeExample" style="color: #800000;">0</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> OnClick = Button1Click </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button: TButton; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OldName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button := TButton.Create(self); </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...сохраняем имя компонента </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OldName := (Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TButton).</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...стираем имя компонента, чтобы избежать конфликта имен.</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...После этого Button1 станет = nil. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">(Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TButton).</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> := </span><span class="f_CodeExample" style="color: #ff0000;">''</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...преобразуем в текст и обратно </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StringToComponent( Button, ComponentToString(Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TButton) ); </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...дадим компоненту уникальное(?) имя </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> := </span><span class="f_CodeExample" style="color: #ff0000;">'Button'</span><span class="f_CodeExample" style="color: #000000;"> + IntToStr(random(</span><span class="f_CodeExample" style="color: #800000;">1000</span><span class="f_CodeExample" style="color: #000000;">)); </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...вернем исходному компоненту имя.</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...После этого Button1 станет снова указывать на объект. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">(Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TButton).</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> := OldName; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...размещаем новую кнопку справа от исходной </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button.parent := self; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button1.Tag := Button1.Tag + </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button.Left := Button.Left + Button.Width * Button1.Tag + </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Приведенный</span><span style="font-family: 'Times New Roman'; color: #000000;">метод</span><span style="font-family: 'Times New Roman'; color: #000000;">не</span><span style="font-family: 'Times New Roman'; color: #000000;">дублирует</span><span style="font-family: 'Times New Roman'; color: #000000;">указатели</span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">обработчики</span><span style="font-family: 'Times New Roman'; color: #000000;">событий</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Однако</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">если</span><span style="font-family: 'Times New Roman'; color: #000000;">таким</span><span style="font-family: 'Times New Roman'; color: #000000;">образом</span><span style="font-family: 'Times New Roman'; color: #000000;">дублировать</span><span style="font-family: 'Times New Roman'; color: #000000;">формы</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">то</span><span style="font-family: 'Times New Roman'; color: #000000;">все</span><span style="font-family: 'Times New Roman'; color: #000000;">дочерние</span><span style="font-family: 'Times New Roman'; color: #000000;">компоненты</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">все</span><span style="font-family: 'Times New Roman'; color: #000000;">обработчики</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранятся</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <p style="text-align: right; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">составление</span><span style="font-family: 'Times New Roman'; color: #000000;">статьи</span><span style="font-family: 'Times New Roman'; color: #000000;">: </span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Андрей</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Чудин</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">ЦПР</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">ТД</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Библио</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">-</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Глобус</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из  https://delphi.chertenok</span></p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Создать</span><span style="font-family: 'Times New Roman'; color: #000000;">копию</span><span style="font-family: 'Times New Roman'; color: #000000;">объекта</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;"> Delphi </span><span style="font-family: 'Times New Roman'; color: #000000;">очень</span><span style="font-family: 'Times New Roman'; color: #000000;">просто</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Конвертируем</span><span style="font-family: 'Times New Roman'; color: #000000;">объект</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">текст</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">затем</span><span style="font-family: 'Times New Roman'; color: #000000;"> - </span><span style="font-family: 'Times New Roman'; color: #000000;">обратно</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">При</span><span style="font-family: 'Times New Roman'; color: #000000;">этом</span><span style="font-family: 'Times New Roman'; color: #000000;">будут</span><span style="font-family: 'Times New Roman'; color: #000000;">продублированы</span><span style="font-family: 'Times New Roman'; color: #000000;">все</span><span style="font-family: 'Times New Roman'; color: #000000;">свойства</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">кроме</span><span style="font-family: 'Times New Roman'; color: #000000;">ссылок</span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">обработчики</span><span style="font-family: 'Times New Roman'; color: #000000;">событий</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Для</span><span style="font-family: 'Times New Roman'; color: #000000;">преобразования</span><span style="font-family: 'Times New Roman'; color: #000000;">компонента</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">файл</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">обратно</span><span style="font-family: 'Times New Roman'; color: #000000;">нам</span><span style="font-family: 'Times New Roman'; color: #000000;">понадобятся</span><span style="font-family: 'Times New Roman'; color: #000000;">функции</span><span style="font-family: 'Times New Roman'; color: #000000;">потоков</span><span style="font-family: 'Times New Roman'; color: #000000;"> WriteComponent(TComponent) </span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;"> ReadComponent(TComponent). </span><span style="font-family: 'Times New Roman'; color: #000000;">При</span><span style="font-family: 'Times New Roman'; color: #000000;">этом</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">поток</span><span style="font-family: 'Times New Roman'; color: #000000;">записывается</span><span style="font-family: 'Times New Roman'; color: #000000;">двоичный</span><span style="font-family: 'Times New Roman'; color: #000000;">ресурс</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Последний</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">помощью</span><span style="font-family: 'Times New Roman'; color: #000000;">функции</span><span style="font-family: 'Times New Roman'; color: #000000;"> ObjectBinaryToText </span><span style="font-family: 'Times New Roman'; color: #000000;">можно</span><span style="font-family: 'Times New Roman'; color: #000000;">преобразовать</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">текст</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><br /><span style="font-family: 'Times New Roman'; color: #000000;">Создадим</span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;">основе</span><span style="font-family: 'Times New Roman'; color: #000000;">функции</span><span style="font-family: 'Times New Roman'; color: #000000;">преобразования</span><span style="font-family: 'Times New Roman'; color: #000000;">:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> ComponentToString(Component: TComponent): </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms: TMemoryStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ss: TStringStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ss := TStringStream.Create(</span><span class="f_CodeExample" style="color: #ff0000;">' '</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms := TMemoryStream.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.WriteComponent(Component); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.position := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ObjectBinaryToText(ms, ss); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ss.position := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := ss.DataString; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finally</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ss.free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> StringToComponent(Component: TComponent; Value: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StrStream:TStringStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms: TMemoryStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StrStream := TStringStream.Create(Value); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms := TMemoryStream.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ObjectTextToBinary(StrStream, ms); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.position := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.ReadComponent(Component); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finally</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finally</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> StrStream.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">С</span><span style="font-family: 'Times New Roman'; color: #000000;">помощью</span><span style="font-family: 'Times New Roman'; color: #000000;">пары</span><span style="font-family: 'Times New Roman'; color: #000000;">этих</span><span style="font-family: 'Times New Roman'; color: #000000;">функций</span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">можем</span><span style="font-family: 'Times New Roman'; color: #000000;">преобразовать</span><span style="font-family: 'Times New Roman'; color: #000000;">любой</span><span style="font-family: 'Times New Roman'; color: #000000;">компонент</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">текст</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">затем</span><span style="font-family: 'Times New Roman'; color: #000000;">проинициализировать</span><span style="font-family: 'Times New Roman'; color: #000000;">другой</span><span style="font-family: 'Times New Roman'; color: #000000;">компонент</span><span style="font-family: 'Times New Roman'; color: #000000;">того</span><span style="font-family: 'Times New Roman'; color: #000000;">же</span><span style="font-family: 'Times New Roman'; color: #000000;">класса</span><span style="font-family: 'Times New Roman'; color: #000000;">этими</span><span style="font-family: 'Times New Roman'; color: #000000;">данными</span><span style="font-family: 'Times New Roman'; color: #000000;">.</span><br /><span style="font-family: 'Times New Roman'; color: #000000;">Ниже</span><span style="font-family: 'Times New Roman'; color: #000000;">приведен</span><span style="font-family: 'Times New Roman'; color: #000000;">ресурс</span><span style="font-family: 'Times New Roman'; color: #000000;">формы</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">одной</span><span style="font-family: 'Times New Roman'; color: #000000;">кнопкой</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">текст</span><span style="font-family: 'Times New Roman'; color: #000000;">обработчика</span><span style="font-family: 'Times New Roman'; color: #000000;">нажатия</span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">эту</span><span style="font-family: 'Times New Roman'; color: #000000;">кнопку</span><span style="font-family: 'Times New Roman'; color: #000000;">.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">object</span><span class="f_CodeExample" style="color: #000000;"> Form1: TForm1 </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Left = </span><span class="f_CodeExample" style="color: #800000;">262</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Top = </span><span class="f_CodeExample" style="color: #800000;">129</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Width = </span><span class="f_CodeExample" style="color: #800000;">525</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Height = </span><span class="f_CodeExample" style="color: #800000;">153</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption = </span><span class="f_CodeExample" style="color: #ff0000;">'Form1'</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Color = clBtnFace </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Font.Charset = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">DEFAULT</span><span class="f_CodeExample" style="color: #000000;">_CHARSET </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Font.Color = clWindowText </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Font.Height = -</span><span class="f_CodeExample" style="color: #800000;">11</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Font.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> = </span><span class="f_CodeExample" style="color: #ff0000;">'MS Sans Serif'</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Font.Style = [] </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OldCreateOrder = False </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Scaled = False </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PixelsPerInch = </span><span class="f_CodeExample" style="color: #800000;">96</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TextHeight = </span><span class="f_CodeExample" style="color: #800000;">13</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">object</span><span class="f_CodeExample" style="color: #000000;"> Button1: TButton </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Left = </span><span class="f_CodeExample" style="color: #800000;">16</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Top = </span><span class="f_CodeExample" style="color: #800000;">32</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Width = </span><span class="f_CodeExample" style="color: #800000;">57</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Height = </span><span class="f_CodeExample" style="color: #800000;">49</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Caption = </span><span class="f_CodeExample" style="color: #ff0000;">'Caption'</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TabOrder = </span><span class="f_CodeExample" style="color: #800000;">0</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> OnClick = Button1Click </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button: TButton; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OldName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button := TButton.Create(self); </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...сохраняем имя компонента </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OldName := (Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TButton).</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...стираем имя компонента, чтобы избежать конфликта имен.</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...После этого Button1 станет = nil. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">(Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TButton).</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> := </span><span class="f_CodeExample" style="color: #ff0000;">''</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...преобразуем в текст и обратно </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StringToComponent( Button, ComponentToString(Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TButton) ); </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...дадим компоненту уникальное(?) имя </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> := </span><span class="f_CodeExample" style="color: #ff0000;">'Button'</span><span class="f_CodeExample" style="color: #000000;"> + IntToStr(random(</span><span class="f_CodeExample" style="color: #800000;">1000</span><span class="f_CodeExample" style="color: #000000;">)); </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...вернем исходному компоненту имя.</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...После этого Button1 станет снова указывать на объект. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">(Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TButton).</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> := OldName; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...размещаем новую кнопку справа от исходной </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button.parent := self; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button1.Tag := Button1.Tag + </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button.Left := Button.Left + Button.Width * Button1.Tag + </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Приведенный</span><span style="font-family: 'Times New Roman'; color: #000000;">метод</span><span style="font-family: 'Times New Roman'; color: #000000;">не</span><span style="font-family: 'Times New Roman'; color: #000000;">дублирует</span><span style="font-family: 'Times New Roman'; color: #000000;">указатели</span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">обработчики</span><span style="font-family: 'Times New Roman'; color: #000000;">событий</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Однако</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">если</span><span style="font-family: 'Times New Roman'; color: #000000;">таким</span><span style="font-family: 'Times New Roman'; color: #000000;">образом</span><span style="font-family: 'Times New Roman'; color: #000000;">дублировать</span><span style="font-family: 'Times New Roman'; color: #000000;">формы</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">то</span><span style="font-family: 'Times New Roman'; color: #000000;">все</span><span style="font-family: 'Times New Roman'; color: #000000;">дочерние</span><span style="font-family: 'Times New Roman'; color: #000000;">компоненты</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">все</span><span style="font-family: 'Times New Roman'; color: #000000;">обработчики</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранятся</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <p style="text-align: right; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">составление</span><span style="font-family: 'Times New Roman'; color: #000000;">статьи</span><span style="font-family: 'Times New Roman'; color: #000000;">: </span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Андрей</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Чудин</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">ЦПР</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">ТД</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Библио</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">-</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Глобус</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из  https://delphi.chertenok</span></p> Работа метода Assign 2013-08-19T19:07:31+07:00 2013-08-19T19:07:31+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/rabota-metoda-assign.html Super User toto44@inbox.ru <p><span style="color: #000000;">В общем случае, утверждение "Destination := Source" не идентично утверждению "Destination.Assign(Source)".</span></p> <p> </p> <p><span style="color: #000000;">Утверждение "Destination := Source" принуждает Destination ссылаться на тот же объект, что и Source, а "Destination.Assign(Source)" копирует содержание объектных ссылок Source в объектные ссылки Destination.</span></p> <p> </p> <p><span style="color: #000000;">Если Destination является свойством некоторого объекта (тем не менее, и свойство не является ссылкой на другой объект, как, например, свойство формы ActiveControl, или свойство DataSource элементов управления для работы с базами данных), тогда утверждение "Destination := Source" идентично утверждению "Destination.Assign(Source)". Это объясняет, почему LB.Items := MemStr работает, когда MemStr := LB.Items нет. </span></p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> <p><span style="color: #000000;">В общем случае, утверждение "Destination := Source" не идентично утверждению "Destination.Assign(Source)".</span></p> <p> </p> <p><span style="color: #000000;">Утверждение "Destination := Source" принуждает Destination ссылаться на тот же объект, что и Source, а "Destination.Assign(Source)" копирует содержание объектных ссылок Source в объектные ссылки Destination.</span></p> <p> </p> <p><span style="color: #000000;">Если Destination является свойством некоторого объекта (тем не менее, и свойство не является ссылкой на другой объект, как, например, свойство формы ActiveControl, или свойство DataSource элементов управления для работы с базами данных), тогда утверждение "Destination := Source" идентично утверждению "Destination.Assign(Source)". Это объясняет, почему LB.Items := MemStr работает, когда MemStr := LB.Items нет. </span></p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> Сгруппировать свойства наподобие Font 2013-08-19T19:10:14+07:00 2013-08-19T19:10:14+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/sgruppirovat-svojstva-napodobie-font.html Super User toto44@inbox.ru <p><span style="color: #000000;">...чтобы сгруппировать свойства наподобие Font, вам необходимо создать наследника (подкласс) TPersistent. Например:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TBoolList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TPersistent)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FValue1: Boolean;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FValue2: Boolean</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Value1: Boolean </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FValue1 </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FValue1;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Value2: Boolean </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FValue2 </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FValue2;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="color: #000000;">Затем, в вашем новом компоненте, для этого подкласса необходимо создать ivar. Чтобы все работало правильно, вам необходимо перекрыть конструктор.</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyPanel = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TCustomPanel)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FBoolList: TBoolList;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create( AOwner: TComponent ); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> BoolList: TBoolList </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FBoolList </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FBoolLisr;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">Затем добавьте следующий код в ваш конструктор:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TMyPanel.Create( AOwner: TComponent );</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create( AOwner );</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FBoolList := TBoolList.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с </span>https://delphiworld.narod</p> <p><span style="color: #000000;">...чтобы сгруппировать свойства наподобие Font, вам необходимо создать наследника (подкласс) TPersistent. Например:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TBoolList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TPersistent)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FValue1: Boolean;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FValue2: Boolean</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Value1: Boolean </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FValue1 </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FValue1;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Value2: Boolean </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FValue2 </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FValue2;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="color: #000000;">Затем, в вашем новом компоненте, для этого подкласса необходимо создать ivar. Чтобы все работало правильно, вам необходимо перекрыть конструктор.</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyPanel = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TCustomPanel)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FBoolList: TBoolList;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create( AOwner: TComponent ); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> BoolList: TBoolList </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FBoolList </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FBoolLisr;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="color: #000000;">Затем добавьте следующий код в ваш конструктор:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TMyPanel.Create( AOwner: TComponent );</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create( AOwner );</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FBoolList := TBoolList.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с </span>https://delphiworld.narod</p> Сохранение и загрузка данных в объекты на примере коллекций. 2013-08-19T19:12:45+07:00 2013-08-19T19:12:45+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/sokhranenie-i-zagruzka-dannykh-v-ob-ekty-na-primere-kollektsij.html Super User toto44@inbox.ru <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Если</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">Вашей</span><span style="font-family: 'Times New Roman'; color: #000000;">программе</span><span style="font-family: 'Times New Roman'; color: #000000;">используются</span><span style="font-family: 'Times New Roman'; color: #000000;">классы</span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">описания</span><span style="font-family: 'Times New Roman'; color: #000000;">объектов</span><span style="font-family: 'Times New Roman'; color: #000000;">некоторой</span><span style="font-family: 'Times New Roman'; color: #000000;">предметной</span><span style="font-family: 'Times New Roman'; color: #000000;">области</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">то</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;">инициализирующие</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">можно</span><span style="font-family: 'Times New Roman'; color: #000000;">хранить</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">базе</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Но</span><span style="font-family: 'Times New Roman'; color: #000000;">можно</span><span style="font-family: 'Times New Roman'; color: #000000;">выбрать</span><span style="font-family: 'Times New Roman'; color: #000000;">гораздо</span><span style="font-family: 'Times New Roman'; color: #000000;">более</span><span style="font-family: 'Times New Roman'; color: #000000;">продуктивный</span><span style="font-family: 'Times New Roman'; color: #000000;">подход</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">который</span><span style="font-family: 'Times New Roman'; color: #000000;">доступен</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;"> Delphi/C++ Builder. </span><span style="font-family: 'Times New Roman'; color: #000000;">Среда</span><span style="font-family: 'Times New Roman'; color: #000000;">разработки</span><span style="font-family: 'Times New Roman'; color: #000000;"> Delphi/C++ Builder </span><span style="font-family: 'Times New Roman'; color: #000000;">хранит</span><span style="font-family: 'Times New Roman'; color: #000000;">ресурсы</span><span style="font-family: 'Times New Roman'; color: #000000;">всех</span><span style="font-family: 'Times New Roman'; color: #000000;">форм</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">двоичных</span><span style="font-family: 'Times New Roman'; color: #000000;">или</span><span style="font-family: 'Times New Roman'; color: #000000;">текстовых</span><span style="font-family: 'Times New Roman'; color: #000000;">файлах</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">эта</span><span style="font-family: 'Times New Roman'; color: #000000;">возможность</span><span style="font-family: 'Times New Roman'; color: #000000;">доступна</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">разрабатываемых</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">ее</span><span style="font-family: 'Times New Roman'; color: #000000;">помощью</span><span style="font-family: 'Times New Roman'; color: #000000;">программ</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">В</span><span style="font-family: 'Times New Roman'; color: #000000;">данном</span><span style="font-family: 'Times New Roman'; color: #000000;">случае</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">оценки</span><span style="font-family: 'Times New Roman'; color: #000000;">удобств</span><span style="font-family: 'Times New Roman'; color: #000000;">такого</span><span style="font-family: 'Times New Roman'; color: #000000;">подхода</span><span style="font-family: 'Times New Roman'; color: #000000;">лучше</span><span style="font-family: 'Times New Roman'; color: #000000;">всего</span><span style="font-family: 'Times New Roman'; color: #000000;">рассмотреть</span><span style="font-family: 'Times New Roman'; color: #000000;">конкретный</span><span style="font-family: 'Times New Roman'; color: #000000;">пример</span><span style="font-family: 'Times New Roman'; color: #000000;">.</span></p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Необходимо</span><span style="font-family: 'Times New Roman'; color: #000000;">реализовать</span><span style="font-family: 'Times New Roman'; color: #000000;">хранение</span><span style="font-family: 'Times New Roman'; color: #000000;">информации</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">некоей</span><span style="font-family: 'Times New Roman'; color: #000000;">службе</span><span style="font-family: 'Times New Roman'; color: #000000;">рассылки</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">ее</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчиках</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Будем</span><span style="font-family: 'Times New Roman'; color: #000000;">хранить</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">почтовом</span><span style="font-family: 'Times New Roman'; color: #000000;">сервере</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">список</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчиков</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Каждая</span><span style="font-family: 'Times New Roman'; color: #000000;">запись</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчике</span><span style="font-family: 'Times New Roman'; color: #000000;">хранит</span><span style="font-family: 'Times New Roman'; color: #000000;">его</span><span style="font-family: 'Times New Roman'; color: #000000;">личные</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">адрес</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">также</span><span style="font-family: 'Times New Roman'; color: #000000;">список</span><span style="font-family: 'Times New Roman'; color: #000000;">тем</span><span style="font-family: 'Times New Roman'; color: #000000;">(</span><span style="font-family: 'Times New Roman'; color: #000000;">или</span><span style="font-family: 'Times New Roman'; color: #000000;">каталогов</span><span style="font-family: 'Times New Roman'; color: #000000;">), </span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">которые</span><span style="font-family: 'Times New Roman'; color: #000000;">он</span><span style="font-family: 'Times New Roman'; color: #000000;">подписан</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Как</span><span style="font-family: 'Times New Roman'; color: #000000;">большие</span><span style="font-family: 'Times New Roman'; color: #000000;">поклонники</span><span style="font-family: 'Times New Roman'; color: #000000;">Гради</span><span style="font-family: 'Times New Roman'; color: #000000;">Буча</span><span style="font-family: 'Times New Roman'; color: #000000;"> (Grady Booch), </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">также</span><span style="font-family: 'Times New Roman'; color: #000000;">будучи</span><span style="font-family: 'Times New Roman'; color: #000000;">заинтересованы</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">удобной</span><span style="font-family: 'Times New Roman'; color: #000000;">организации</span><span style="font-family: 'Times New Roman'; color: #000000;">кода</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">организуем</span><span style="font-family: 'Times New Roman'; color: #000000;">информацию</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчиках</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">виде</span><span style="font-family: 'Times New Roman'; color: #000000;">объектов</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">В</span><span style="font-family: 'Times New Roman'; color: #000000;"> Delphi </span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">данной</span><span style="font-family: 'Times New Roman'; color: #000000;">задачи</span><span style="font-family: 'Times New Roman'; color: #000000;">идеально</span><span style="font-family: 'Times New Roman'; color: #000000;">подходит</span><span style="font-family: 'Times New Roman'; color: #000000;">класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TCollection, </span><span style="font-family: 'Times New Roman'; color: #000000;">реализующий</span><span style="font-family: 'Times New Roman'; color: #000000;">всю</span><span style="font-family: 'Times New Roman'; color: #000000;">необходимую</span><span style="font-family: 'Times New Roman'; color: #000000;">функциональность</span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">работы</span><span style="font-family: 'Times New Roman'; color: #000000;">со</span><span style="font-family: 'Times New Roman'; color: #000000;">списками</span><span style="font-family: 'Times New Roman'; color: #000000;">типизированных</span><span style="font-family: 'Times New Roman'; color: #000000;">объектов</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Для</span><span style="font-family: 'Times New Roman'; color: #000000;">этого</span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">наследуемся</span><span style="font-family: 'Times New Roman'; color: #000000;">от</span><span style="font-family: 'Times New Roman'; color: #000000;"> TCollection, </span><span style="font-family: 'Times New Roman'; color: #000000;">называя</span><span style="font-family: 'Times New Roman'; color: #000000;">новый</span><span style="font-family: 'Times New Roman'; color: #000000;">класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailList - </span><span style="font-family: 'Times New Roman'; color: #000000;">список</span><span style="font-family: 'Times New Roman'; color: #000000;">рассылки</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">также</span><span style="font-family: 'Times New Roman'; color: #000000;">создаем</span><span style="font-family: 'Times New Roman'; color: #000000;">наследника</span><span style="font-family: 'Times New Roman'; color: #000000;">от</span><span style="font-family: 'Times New Roman'; color: #000000;"> TCollectionItem - TMailClient - </span><span style="font-family: 'Times New Roman'; color: #000000;">адресат</span><span style="font-family: 'Times New Roman'; color: #000000;">рассылки</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Последний</span><span style="font-family: 'Times New Roman'; color: #000000;">будет</span><span style="font-family: 'Times New Roman'; color: #000000;">содержать</span><span style="font-family: 'Times New Roman'; color: #000000;">все</span><span style="font-family: 'Times New Roman'; color: #000000;">необходимые</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчике</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">также</span><span style="font-family: 'Times New Roman'; color: #000000;">реализовывать</span><span style="font-family: 'Times New Roman'; color: #000000;">необходимые</span><span style="font-family: 'Times New Roman'; color: #000000;">функции</span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">работы</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">ним</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Саму</span><span style="font-family: 'Times New Roman'; color: #000000;">коллекцию</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчиками</span><span style="font-family: 'Times New Roman'; color: #000000;">нам</span><span style="font-family: 'Times New Roman'; color: #000000;">нужно</span><span style="font-family: 'Times New Roman'; color: #000000;">будет</span><span style="font-family: 'Times New Roman'; color: #000000;">поместить</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">некий</span><span style="font-family: 'Times New Roman'; color: #000000;">базовый</span><span style="font-family: 'Times New Roman'; color: #000000;">класс</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">который</span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">будем</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранять</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">загружать</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">На</span><span style="font-family: 'Times New Roman'; color: #000000;">роль</span><span style="font-family: 'Times New Roman'; color: #000000;">такового</span><span style="font-family: 'Times New Roman'; color: #000000;">подходит</span><span style="font-family: 'Times New Roman'; color: #000000;">класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailer - </span><span style="font-family: 'Times New Roman'; color: #000000;">почтовый</span><span style="font-family: 'Times New Roman'; color: #000000;">клиент</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><br /><span style="font-family: 'Times New Roman'; color: #000000;">Начнем</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailClient.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMailClient = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TCollectionItem) </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FAddress: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FEnabled: boolean; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FFolders: TStringList; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Files: TStringList; </span><span class="f_CodeExample" style="color: #000080;">// список файлов к рассылке. заполняется в run-time. Сохранению не подлежит </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(Collection: TCollection); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> PickFiles; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FName </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FName; </span><span class="f_CodeExample" style="color: #000080;">// имя адресата </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Address: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FAddress </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FAddress; </span><span class="f_CodeExample" style="color: #000080;">// почтовый адрес </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Enabled: boolean </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FEnabled </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FEnabled </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">default</span><span class="f_CodeExample" style="color: #000000;"> true;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Folders: TStringList </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FFolders </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FFolders; </span><span class="f_CodeExample" style="color: #000080;">// список папок (тем) подписки </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"><br /><span style="font-family: 'Times New Roman'; color: #000000;">Класс</span><span style="font-family: 'Times New Roman'; color: #000000;">содержит</span><span style="font-family: 'Times New Roman'; color: #000000;">сведения</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">имени</span><span style="font-family: 'Times New Roman'; color: #000000;">клиента</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">его</span><span style="font-family: 'Times New Roman'; color: #000000;">адресе</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">его</span><span style="font-family: 'Times New Roman'; color: #000000;">статусе</span><span style="font-family: 'Times New Roman'; color: #000000;">(Enabled), </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">также</span><span style="font-family: 'Times New Roman'; color: #000000;">список</span><span style="font-family: 'Times New Roman'; color: #000000;">каталогов</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">которые</span><span style="font-family: 'Times New Roman'; color: #000000;">он</span><span style="font-family: 'Times New Roman'; color: #000000;">подписан</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Процедура</span><span style="font-family: 'Times New Roman'; color: #000000;"> PickFiles </span><span style="font-family: 'Times New Roman'; color: #000000;">составляет</span><span style="font-family: 'Times New Roman'; color: #000000;">список</span><span style="font-family: 'Times New Roman'; color: #000000;">файлов</span><span style="font-family: 'Times New Roman'; color: #000000;">к</span><span style="font-family: 'Times New Roman'; color: #000000;">отправке</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">сохраняет</span><span style="font-family: 'Times New Roman'; color: #000000;">его</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">свойстве</span><span style="font-family: 'Times New Roman'; color: #000000;"> Files</span><br /><span style="font-family: 'Times New Roman'; color: #000000;">Класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailList, </span><span style="font-family: 'Times New Roman'; color: #000000;">хранящий</span><span style="font-family: 'Times New Roman'; color: #000000;">объекты</span><span style="font-family: 'Times New Roman'; color: #000000;">класса</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailClient, </span><span style="font-family: 'Times New Roman'; color: #000000;">приведен</span><span style="font-family: 'Times New Roman'; color: #000000;">ниже</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMailList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TCollection) </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetMailClient(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer): TMailClient; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetMailClient(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer; Value: TMailClient); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Add: TMailClient; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Items[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer]: TMailClient </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetMailClient </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetMailClient; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">default</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Теперь</span><span style="font-family: 'Times New Roman'; color: #000000;">поместим</span><span style="font-family: 'Times New Roman'; color: #000000;">класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailList </span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailer. </span><span style="font-family: 'Times New Roman'; color: #000000;">В</span><span style="font-family: 'Times New Roman'; color: #000000;">него</span><span style="font-family: 'Times New Roman'; color: #000000;">можно</span><span style="font-family: 'Times New Roman'; color: #000000;">будет</span><span style="font-family: 'Times New Roman'; color: #000000;">потом</span><span style="font-family: 'Times New Roman'; color: #000000;">включить</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">параметрах</span><span style="font-family: 'Times New Roman'; color: #000000;">доступа</span><span style="font-family: 'Times New Roman'; color: #000000;">к</span><span style="font-family: 'Times New Roman'; color: #000000;">почтовому</span><span style="font-family: 'Times New Roman'; color: #000000;">серверу</span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">отправки</span><span style="font-family: 'Times New Roman'; color: #000000;">почты</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Он</span><span style="font-family: 'Times New Roman'; color: #000000;">мог</span><span style="font-family: 'Times New Roman'; color: #000000;">бы</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">отправлять</span><span style="font-family: 'Times New Roman'; color: #000000;">почту</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">но</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">данном</span><span style="font-family: 'Times New Roman'; color: #000000;">примере</span><span style="font-family: 'Times New Roman'; color: #000000;">это</span><span style="font-family: 'Times New Roman'; color: #000000;">не</span><span style="font-family: 'Times New Roman'; color: #000000;">использовано</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">дабы</span><span style="font-family: 'Times New Roman'; color: #000000;">не</span><span style="font-family: 'Times New Roman'; color: #000000;">перегружать</span><span style="font-family: 'Times New Roman'; color: #000000;">код</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">То</span><span style="font-family: 'Times New Roman'; color: #000000;">есть</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">нашем</span><span style="font-family: 'Times New Roman'; color: #000000;">примере</span><span style="font-family: 'Times New Roman'; color: #000000;">он</span><span style="font-family: 'Times New Roman'; color: #000000;">выполняет</span><span style="font-family: 'Times New Roman'; color: #000000;">только</span><span style="font-family: 'Times New Roman'; color: #000000;">роль</span><span style="font-family: 'Times New Roman'; color: #000000;">носителя</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчиках</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;">подписке</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TComponent, </span><span style="font-family: 'Times New Roman'; color: #000000;">от</span><span style="font-family: 'Times New Roman'; color: #000000;">которого</span><span style="font-family: 'Times New Roman'; color: #000000;">он</span><span style="font-family: 'Times New Roman'; color: #000000;">наследуется</span><span style="font-family: 'Times New Roman'; color: #000000;">можно</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранить</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">файл</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">то</span><span style="font-family: 'Times New Roman'; color: #000000;">время</span><span style="font-family: 'Times New Roman'; color: #000000;">как</span><span style="font-family: 'Times New Roman'; color: #000000;"> TCollection </span><span style="font-family: 'Times New Roman'; color: #000000;">самостоятельно</span><span style="font-family: 'Times New Roman'; color: #000000;">не</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранится</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Только</span><span style="font-family: 'Times New Roman'; color: #000000;">если</span><span style="font-family: 'Times New Roman'; color: #000000;">она</span><span style="font-family: 'Times New Roman'; color: #000000;">агрегирована</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;"> TComponent. </span><span style="font-family: 'Times New Roman'; color: #000000;">Именно</span><span style="font-family: 'Times New Roman'; color: #000000;">это</span><span style="font-family: 'Times New Roman'; color: #000000;">у</span><span style="font-family: 'Times New Roman'; color: #000000;">нас</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">реализовано</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMailer = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TComponent) </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FMailList: TMailList; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner: TComponent); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> MailList: TMailList </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FMailList </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FMailList; </span><span class="f_CodeExample" style="color: #000080;">// коллекция - список рассылки. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// здесь можно поместить, к примеру, данные о соединении с почтовым сервером </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 7px 0px;"><br /><span style="font-family: 'Times New Roman'; color: #000000;">Повторюсь</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">В</span><span style="font-family: 'Times New Roman'; color: #000000;">данном</span><span style="font-family: 'Times New Roman'; color: #000000;">случае</span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">наследуемся</span><span style="font-family: 'Times New Roman'; color: #000000;">от</span><span style="font-family: 'Times New Roman'; color: #000000;">класса</span><span style="font-family: 'Times New Roman'; color: #000000;"> TComponent, </span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">того</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">чтобы</span><span style="font-family: 'Times New Roman'; color: #000000;">была</span><span style="font-family: 'Times New Roman'; color: #000000;">возможности</span><span style="font-family: 'Times New Roman'; color: #000000;">записи</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">объекта</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">файл</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Свойство</span><span style="font-family: 'Times New Roman'; color: #000000;"> MailList </span><span style="font-family: 'Times New Roman'; color: #000000;">содержит</span><span style="font-family: 'Times New Roman'; color: #000000;">уже</span><span style="font-family: 'Times New Roman'; color: #000000;">объект</span><span style="font-family: 'Times New Roman'; color: #000000;">класса</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailList. </span><br /><span style="font-family: 'Times New Roman'; color: #000000;">Реализация</span><span style="font-family: 'Times New Roman'; color: #000000;">всех</span><span style="font-family: 'Times New Roman'; color: #000000;">приведенных</span><span style="font-family: 'Times New Roman'; color: #000000;">классов</span><span style="font-family: 'Times New Roman'; color: #000000;">приведена</span><span style="font-family: 'Times New Roman'; color: #000000;">ниже</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TMailClient.Create(Collection: TCollection); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Folders := TStringList.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Files := TStringList.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FEnabled := true; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TMailClient.Destroy; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Folders.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Files.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// здесь во всех каталогах Folders ищем файлы для рассылки и помещаем их в Files. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMailClient.PickFiles; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> i: integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> i:=</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> Folders.Count-</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #000000;"> CreateFileList(Files, Folders[i]); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Стандартный код при наследовании от класса коллекции: переопределяем тип </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TMailList.GetMailClient(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer): TMailClient; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := TMailClient(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Items[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">]); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Стандартный код при наследовании от класса коллекции </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMailList.SetMailClient(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer; Value: TMailClient); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Items[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">].Assign(Value); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Стандартный код при наследовании от класса коллекции: переопределяем тип </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TMailList.Add: TMailClient; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := TMailClient(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Add); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// создаем коллекцию адресатов рассылки TMailList </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TMailer.Create(AOwner: TComponent); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MailList := TMailList.Create(TMailClient); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TMailer.Destroy; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MailList.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//--------------------- </span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Функция</span><span style="font-family: 'Times New Roman'; color: #000000;"> CreateFileList </span><span style="font-family: 'Times New Roman'; color: #000000;">создает</span><span style="font-family: 'Times New Roman'; color: #000000;">по</span><span style="font-family: 'Times New Roman'; color: #000000;">каким</span><span style="font-family: 'Times New Roman'; color: #000000;">-</span><span style="font-family: 'Times New Roman'; color: #000000;">либо</span><span style="font-family: 'Times New Roman'; color: #000000;">правилам</span><span style="font-family: 'Times New Roman'; color: #000000;">список</span><span style="font-family: 'Times New Roman'; color: #000000;">файлов</span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">основе</span><span style="font-family: 'Times New Roman'; color: #000000;">переданного</span><span style="font-family: 'Times New Roman'; color: #000000;">ей</span><span style="font-family: 'Times New Roman'; color: #000000;">списка</span><span style="font-family: 'Times New Roman'; color: #000000;">каталогов</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">обходя</span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;">рекурсивно</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">К</span><span style="font-family: 'Times New Roman'; color: #000000;">примеру</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">она</span><span style="font-family: 'Times New Roman'; color: #000000;">может</span><span style="font-family: 'Times New Roman'; color: #000000;">быть</span><span style="font-family: 'Times New Roman'; color: #000000;">реализована</span><span style="font-family: 'Times New Roman'; color: #000000;">так</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> CreateFileList(sl: TStringList; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> FilePath: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">sr: TSearchRec; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ProcessFile; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> (sr.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> = </span><span class="f_CodeExample" style="color: #ff0000;">'.'</span><span class="f_CodeExample" style="color: #000000;">)</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">or</span><span class="f_CodeExample" style="color: #000000;">(sr.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> = </span><span class="f_CodeExample" style="color: #ff0000;">'..'</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> exit; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> sr.Attr &lt;&gt; faDirectory </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> sl.Add(FilePath + </span><span class="f_CodeExample" style="color: #ff0000;">'\'</span><span class="f_CodeExample" style="color: #000000;"> + sr.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> sr.Attr = faDirectory </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> CreateFileList(sl, FilePath + </span><span class="f_CodeExample" style="color: #ff0000;">'\'</span><span class="f_CodeExample" style="color: #000000;"> + sr.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">not</span><span class="f_CodeExample" style="color: #000000;"> DirectoryExists(FilePath) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> exit; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> FindFirst(FilePath + </span><span class="f_CodeExample" style="color: #ff0000;">'\'</span><span class="f_CodeExample" style="color: #000000;"> + </span><span class="f_CodeExample" style="color: #ff0000;">'*.*'</span><span class="f_CodeExample" style="color: #000000;">, faAnyFile , sr) = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> ProcessFile; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">while</span><span class="f_CodeExample" style="color: #000000;"> FindNext(sr) = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #000000;"> ProcessFile; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FindClose(sr); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">В</span><span style="font-family: 'Times New Roman'; color: #000000;">итоге</span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">располагаем</span><span style="font-family: 'Times New Roman'; color: #000000;">классом</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailer, </span><span style="font-family: 'Times New Roman'; color: #000000;">содержащим</span><span style="font-family: 'Times New Roman'; color: #000000;">всю</span><span style="font-family: 'Times New Roman'; color: #000000;">необходимую</span><span style="font-family: 'Times New Roman'; color: #000000;">нам</span><span style="font-family: 'Times New Roman'; color: #000000;">информацию</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Теперь</span><span style="font-family: 'Times New Roman'; color: #000000;">перейдем</span><span style="font-family: 'Times New Roman'; color: #000000;">к</span><span style="font-family: 'Times New Roman'; color: #000000;">созданию</span><span style="font-family: 'Times New Roman'; color: #000000;">объекта</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранению</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">загрузке</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Mailer: TMailer; </span><span class="f_CodeExample" style="color: #000080;">// это наш объект для хранения данных о почтовой рассылки</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Процедура загрузки данных в объект. Может быть процедурой OnCreate() главной формы.</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TfMain.FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">sDataFile, sTmp: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">i, j: integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Mailer := TMailer.Create(self); </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// будем считать, что данные были сохранены в файл users.dat в каталоге программы</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">sDataFile := ExtractFilePath(ParamStr(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">)) + </span><span class="f_CodeExample" style="color: #ff0000;">'users.dat'</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...загрузка данных из файла </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> FileExists(sDataFile) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> LoadComponentFromTextFile(Mailer, sDataFile); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ здесь данные из файла загружены }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...перебор подписчиков </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> i:=</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> Mailer.MailList.Count-</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> sTmp := Mailer.MailList[i].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #000080;">//...обращение к имени </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> sTmp := Mailer.MailList[i].Address; </span><span class="f_CodeExample" style="color: #000080;">//...обращение к адресу </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//... sTmp - фиктивная переменная. Поменяйте ее на свои. </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Mailer.MailList[i].PickFiles; </span><span class="f_CodeExample" style="color: #000080;">//... поиск файлов для отправки очередному подписчику. </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...перебор найденных файлов к отправке </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> j:=</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> Mailer.MailList[i].Files.Count-</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> sTmp := Mailer.MailList[i].Files[j]; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">После</span><span style="font-family: 'Times New Roman'; color: #000000;">загрузки</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">можем</span><span style="font-family: 'Times New Roman'; color: #000000;">работать</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">данными</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">нашей</span><span style="font-family: 'Times New Roman'; color: #000000;">коллекции</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчиков</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Добавлять</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">удалять</span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;"> ( Mailer.MailList.Add; Mailer.MailList.Delete(Index); ). </span><span style="font-family: 'Times New Roman'; color: #000000;">При</span><span style="font-family: 'Times New Roman'; color: #000000;">завершении</span><span style="font-family: 'Times New Roman'; color: #000000;">работы</span><span style="font-family: 'Times New Roman'; color: #000000;">программы</span><span style="font-family: 'Times New Roman'; color: #000000;">необходимо</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранить</span><span style="font-family: 'Times New Roman'; color: #000000;">уже</span><span style="font-family: 'Times New Roman'; color: #000000;">новые</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">тот</span><span style="font-family: 'Times New Roman'; color: #000000;">же</span><span style="font-family: 'Times New Roman'; color: #000000;">файл</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Процедура сохранения данных из объекта в файл. Может быть процедурой OnDestroy() главной формы.</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TfMain.OnDestroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...сохранение данных в файл users.dat</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SaveComponentToTextFile(Mailer, ExtractFilePath(ParamStr(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">)) + </span><span class="f_CodeExample" style="color: #ff0000;">'users.dat'</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Хранение</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">файле</span><span style="font-family: 'Times New Roman'; color: #000000;">позволяет</span><span style="font-family: 'Times New Roman'; color: #000000;">оказаться</span><span style="font-family: 'Times New Roman'; color: #000000;">от</span><span style="font-family: 'Times New Roman'; color: #000000;">использования</span><span style="font-family: 'Times New Roman'; color: #000000;">БД</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">если</span><span style="font-family: 'Times New Roman'; color: #000000;">объем</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">не</span><span style="font-family: 'Times New Roman'; color: #000000;">слишком</span><span style="font-family: 'Times New Roman'; color: #000000;">велик</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">нет</span><span style="font-family: 'Times New Roman'; color: #000000;">необходимости</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">совместном</span><span style="font-family: 'Times New Roman'; color: #000000;">доступе</span><span style="font-family: 'Times New Roman'; color: #000000;">к</span><span style="font-family: 'Times New Roman'; color: #000000;">данным</span><span style="font-family: 'Times New Roman'; color: #000000;">.</span><br /><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Самое</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">главное</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> - </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">мы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">организуем</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">все</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">данные</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">в</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">виде</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">набора</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">удобных</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">для</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">работы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">классов</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">не</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">тратим</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">время</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">на</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">их</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">сохранение</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">инициализацию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">из</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">БД</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">.</span><br /><span style="font-family: 'Times New Roman'; color: #000000;">Приведенный</span><span style="font-family: 'Times New Roman'; color: #000000;">пример</span><span style="font-family: 'Times New Roman'; color: #000000;">лишь</span><span style="font-family: 'Times New Roman'; color: #000000;">иллюстрирует</span><span style="font-family: 'Times New Roman'; color: #000000;">этот</span><span style="font-family: 'Times New Roman'; color: #000000;">подход</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Для</span><span style="font-family: 'Times New Roman'; color: #000000;">его</span><span style="font-family: 'Times New Roman'; color: #000000;">реализации</span><span style="font-family: 'Times New Roman'; color: #000000;">могут</span><span style="font-family: 'Times New Roman'; color: #000000;">подойти</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;"> 2 </span><span style="font-family: 'Times New Roman'; color: #000000;">таблицы</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">БД</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Однако</span><span style="font-family: 'Times New Roman'; color: #000000;">приведенный</span><span style="font-family: 'Times New Roman'; color: #000000;">подход</span><span style="font-family: 'Times New Roman'; color: #000000;">удобен</span><span style="font-family: 'Times New Roman'; color: #000000;">при</span><span style="font-family: 'Times New Roman'; color: #000000;">условии</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">что</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">имеют</span><span style="font-family: 'Times New Roman'; color: #000000;">сложную</span><span style="font-family: 'Times New Roman'; color: #000000;">иерархию</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">К</span><span style="font-family: 'Times New Roman'; color: #000000;">примеру</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">вложенные</span><span style="font-family: 'Times New Roman'; color: #000000;">коллекции</span><span style="font-family: 'Times New Roman'; color: #000000;">разных</span><span style="font-family: 'Times New Roman'; color: #000000;">типов</span><span style="font-family: 'Times New Roman'; color: #000000;">гораздо</span><span style="font-family: 'Times New Roman'; color: #000000;">сложнее</span><span style="font-family: 'Times New Roman'; color: #000000;">разложить</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">базе</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;">извлечения</span><span style="font-family: 'Times New Roman'; color: #000000;">потребуется</span><span style="font-family: 'Times New Roman'; color: #000000;"> SQL. </span><span style="font-family: 'Times New Roman'; color: #000000;">Решайте</span><span style="font-family: 'Times New Roman'; color: #000000;">сами</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">судя</span><span style="font-family: 'Times New Roman'; color: #000000;">по</span><span style="font-family: 'Times New Roman'; color: #000000;">своей</span><span style="font-family: 'Times New Roman'; color: #000000;">конкретной</span><span style="font-family: 'Times New Roman'; color: #000000;">задаче</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Далее</span><span style="font-family: 'Times New Roman'; color: #000000;">приведен</span><span style="font-family: 'Times New Roman'; color: #000000;">код</span><span style="font-family: 'Times New Roman'; color: #000000;">функций</span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранения</span><span style="font-family: 'Times New Roman'; color: #000000;">/</span><span style="font-family: 'Times New Roman'; color: #000000;">чтения</span><span style="font-family: 'Times New Roman'; color: #000000;">компонента</span><span style="font-family: 'Times New Roman'; color: #000000;">.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...процедура загружает(инициализирует) компонент из текстового файла с ресурсом </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> LoadComponentFromTextFile(Component: TComponent; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> FileName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms: TMemoryStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">fs: TFileStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">fs := TFileStream.Create(FileName, fmOpenRead); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms := TMemoryStream.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ObjectTextToBinary(fs, ms); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.position := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.ReadComponent(Component); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finally</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> fs.free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...процедура сохраняет компонент в текстовый файл </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SaveComponentToTextFile(Component: TComponent; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> FileName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms: TMemoryStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">fs: TFileStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">fs := TFileStream.Create(FileName, fmCreate </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">or</span><span class="f_CodeExample" style="color: #000000;"> fmOpenWrite); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms := TMemoryStream.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.WriteComponent(Component); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.position := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ObjectBinaryToText(ms, fs); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finally</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> fs.free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="text-align: right; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">составление</span><span style="font-family: 'Times New Roman'; color: #000000;">статьи</span><span style="font-family: 'Times New Roman'; color: #000000;">: </span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Андрей</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Чудин</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">ЦПР</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">ТД</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Библио</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">-</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Глобус</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <p style="text-align: justify; margin: 7px 0px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из https://delphi.chertenok</span></p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Если</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">Вашей</span><span style="font-family: 'Times New Roman'; color: #000000;">программе</span><span style="font-family: 'Times New Roman'; color: #000000;">используются</span><span style="font-family: 'Times New Roman'; color: #000000;">классы</span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">описания</span><span style="font-family: 'Times New Roman'; color: #000000;">объектов</span><span style="font-family: 'Times New Roman'; color: #000000;">некоторой</span><span style="font-family: 'Times New Roman'; color: #000000;">предметной</span><span style="font-family: 'Times New Roman'; color: #000000;">области</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">то</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;">инициализирующие</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">можно</span><span style="font-family: 'Times New Roman'; color: #000000;">хранить</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">базе</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Но</span><span style="font-family: 'Times New Roman'; color: #000000;">можно</span><span style="font-family: 'Times New Roman'; color: #000000;">выбрать</span><span style="font-family: 'Times New Roman'; color: #000000;">гораздо</span><span style="font-family: 'Times New Roman'; color: #000000;">более</span><span style="font-family: 'Times New Roman'; color: #000000;">продуктивный</span><span style="font-family: 'Times New Roman'; color: #000000;">подход</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">который</span><span style="font-family: 'Times New Roman'; color: #000000;">доступен</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;"> Delphi/C++ Builder. </span><span style="font-family: 'Times New Roman'; color: #000000;">Среда</span><span style="font-family: 'Times New Roman'; color: #000000;">разработки</span><span style="font-family: 'Times New Roman'; color: #000000;"> Delphi/C++ Builder </span><span style="font-family: 'Times New Roman'; color: #000000;">хранит</span><span style="font-family: 'Times New Roman'; color: #000000;">ресурсы</span><span style="font-family: 'Times New Roman'; color: #000000;">всех</span><span style="font-family: 'Times New Roman'; color: #000000;">форм</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">двоичных</span><span style="font-family: 'Times New Roman'; color: #000000;">или</span><span style="font-family: 'Times New Roman'; color: #000000;">текстовых</span><span style="font-family: 'Times New Roman'; color: #000000;">файлах</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">эта</span><span style="font-family: 'Times New Roman'; color: #000000;">возможность</span><span style="font-family: 'Times New Roman'; color: #000000;">доступна</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">разрабатываемых</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">ее</span><span style="font-family: 'Times New Roman'; color: #000000;">помощью</span><span style="font-family: 'Times New Roman'; color: #000000;">программ</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">В</span><span style="font-family: 'Times New Roman'; color: #000000;">данном</span><span style="font-family: 'Times New Roman'; color: #000000;">случае</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">оценки</span><span style="font-family: 'Times New Roman'; color: #000000;">удобств</span><span style="font-family: 'Times New Roman'; color: #000000;">такого</span><span style="font-family: 'Times New Roman'; color: #000000;">подхода</span><span style="font-family: 'Times New Roman'; color: #000000;">лучше</span><span style="font-family: 'Times New Roman'; color: #000000;">всего</span><span style="font-family: 'Times New Roman'; color: #000000;">рассмотреть</span><span style="font-family: 'Times New Roman'; color: #000000;">конкретный</span><span style="font-family: 'Times New Roman'; color: #000000;">пример</span><span style="font-family: 'Times New Roman'; color: #000000;">.</span></p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Необходимо</span><span style="font-family: 'Times New Roman'; color: #000000;">реализовать</span><span style="font-family: 'Times New Roman'; color: #000000;">хранение</span><span style="font-family: 'Times New Roman'; color: #000000;">информации</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">некоей</span><span style="font-family: 'Times New Roman'; color: #000000;">службе</span><span style="font-family: 'Times New Roman'; color: #000000;">рассылки</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">ее</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчиках</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Будем</span><span style="font-family: 'Times New Roman'; color: #000000;">хранить</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">почтовом</span><span style="font-family: 'Times New Roman'; color: #000000;">сервере</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">список</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчиков</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Каждая</span><span style="font-family: 'Times New Roman'; color: #000000;">запись</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчике</span><span style="font-family: 'Times New Roman'; color: #000000;">хранит</span><span style="font-family: 'Times New Roman'; color: #000000;">его</span><span style="font-family: 'Times New Roman'; color: #000000;">личные</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">адрес</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">также</span><span style="font-family: 'Times New Roman'; color: #000000;">список</span><span style="font-family: 'Times New Roman'; color: #000000;">тем</span><span style="font-family: 'Times New Roman'; color: #000000;">(</span><span style="font-family: 'Times New Roman'; color: #000000;">или</span><span style="font-family: 'Times New Roman'; color: #000000;">каталогов</span><span style="font-family: 'Times New Roman'; color: #000000;">), </span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">которые</span><span style="font-family: 'Times New Roman'; color: #000000;">он</span><span style="font-family: 'Times New Roman'; color: #000000;">подписан</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Как</span><span style="font-family: 'Times New Roman'; color: #000000;">большие</span><span style="font-family: 'Times New Roman'; color: #000000;">поклонники</span><span style="font-family: 'Times New Roman'; color: #000000;">Гради</span><span style="font-family: 'Times New Roman'; color: #000000;">Буча</span><span style="font-family: 'Times New Roman'; color: #000000;"> (Grady Booch), </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">также</span><span style="font-family: 'Times New Roman'; color: #000000;">будучи</span><span style="font-family: 'Times New Roman'; color: #000000;">заинтересованы</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">удобной</span><span style="font-family: 'Times New Roman'; color: #000000;">организации</span><span style="font-family: 'Times New Roman'; color: #000000;">кода</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">организуем</span><span style="font-family: 'Times New Roman'; color: #000000;">информацию</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчиках</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">виде</span><span style="font-family: 'Times New Roman'; color: #000000;">объектов</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">В</span><span style="font-family: 'Times New Roman'; color: #000000;"> Delphi </span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">данной</span><span style="font-family: 'Times New Roman'; color: #000000;">задачи</span><span style="font-family: 'Times New Roman'; color: #000000;">идеально</span><span style="font-family: 'Times New Roman'; color: #000000;">подходит</span><span style="font-family: 'Times New Roman'; color: #000000;">класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TCollection, </span><span style="font-family: 'Times New Roman'; color: #000000;">реализующий</span><span style="font-family: 'Times New Roman'; color: #000000;">всю</span><span style="font-family: 'Times New Roman'; color: #000000;">необходимую</span><span style="font-family: 'Times New Roman'; color: #000000;">функциональность</span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">работы</span><span style="font-family: 'Times New Roman'; color: #000000;">со</span><span style="font-family: 'Times New Roman'; color: #000000;">списками</span><span style="font-family: 'Times New Roman'; color: #000000;">типизированных</span><span style="font-family: 'Times New Roman'; color: #000000;">объектов</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Для</span><span style="font-family: 'Times New Roman'; color: #000000;">этого</span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">наследуемся</span><span style="font-family: 'Times New Roman'; color: #000000;">от</span><span style="font-family: 'Times New Roman'; color: #000000;"> TCollection, </span><span style="font-family: 'Times New Roman'; color: #000000;">называя</span><span style="font-family: 'Times New Roman'; color: #000000;">новый</span><span style="font-family: 'Times New Roman'; color: #000000;">класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailList - </span><span style="font-family: 'Times New Roman'; color: #000000;">список</span><span style="font-family: 'Times New Roman'; color: #000000;">рассылки</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">также</span><span style="font-family: 'Times New Roman'; color: #000000;">создаем</span><span style="font-family: 'Times New Roman'; color: #000000;">наследника</span><span style="font-family: 'Times New Roman'; color: #000000;">от</span><span style="font-family: 'Times New Roman'; color: #000000;"> TCollectionItem - TMailClient - </span><span style="font-family: 'Times New Roman'; color: #000000;">адресат</span><span style="font-family: 'Times New Roman'; color: #000000;">рассылки</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Последний</span><span style="font-family: 'Times New Roman'; color: #000000;">будет</span><span style="font-family: 'Times New Roman'; color: #000000;">содержать</span><span style="font-family: 'Times New Roman'; color: #000000;">все</span><span style="font-family: 'Times New Roman'; color: #000000;">необходимые</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчике</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">также</span><span style="font-family: 'Times New Roman'; color: #000000;">реализовывать</span><span style="font-family: 'Times New Roman'; color: #000000;">необходимые</span><span style="font-family: 'Times New Roman'; color: #000000;">функции</span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">работы</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">ним</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Саму</span><span style="font-family: 'Times New Roman'; color: #000000;">коллекцию</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчиками</span><span style="font-family: 'Times New Roman'; color: #000000;">нам</span><span style="font-family: 'Times New Roman'; color: #000000;">нужно</span><span style="font-family: 'Times New Roman'; color: #000000;">будет</span><span style="font-family: 'Times New Roman'; color: #000000;">поместить</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">некий</span><span style="font-family: 'Times New Roman'; color: #000000;">базовый</span><span style="font-family: 'Times New Roman'; color: #000000;">класс</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">который</span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">будем</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранять</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">загружать</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">На</span><span style="font-family: 'Times New Roman'; color: #000000;">роль</span><span style="font-family: 'Times New Roman'; color: #000000;">такового</span><span style="font-family: 'Times New Roman'; color: #000000;">подходит</span><span style="font-family: 'Times New Roman'; color: #000000;">класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailer - </span><span style="font-family: 'Times New Roman'; color: #000000;">почтовый</span><span style="font-family: 'Times New Roman'; color: #000000;">клиент</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><br /><span style="font-family: 'Times New Roman'; color: #000000;">Начнем</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailClient.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMailClient = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TCollectionItem) </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FAddress: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FEnabled: boolean; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FFolders: TStringList; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Files: TStringList; </span><span class="f_CodeExample" style="color: #000080;">// список файлов к рассылке. заполняется в run-time. Сохранению не подлежит </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(Collection: TCollection); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> PickFiles; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FName </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FName; </span><span class="f_CodeExample" style="color: #000080;">// имя адресата </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Address: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FAddress </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FAddress; </span><span class="f_CodeExample" style="color: #000080;">// почтовый адрес </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Enabled: boolean </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FEnabled </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FEnabled </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">default</span><span class="f_CodeExample" style="color: #000000;"> true;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Folders: TStringList </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FFolders </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FFolders; </span><span class="f_CodeExample" style="color: #000080;">// список папок (тем) подписки </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"><br /><span style="font-family: 'Times New Roman'; color: #000000;">Класс</span><span style="font-family: 'Times New Roman'; color: #000000;">содержит</span><span style="font-family: 'Times New Roman'; color: #000000;">сведения</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">имени</span><span style="font-family: 'Times New Roman'; color: #000000;">клиента</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">его</span><span style="font-family: 'Times New Roman'; color: #000000;">адресе</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">его</span><span style="font-family: 'Times New Roman'; color: #000000;">статусе</span><span style="font-family: 'Times New Roman'; color: #000000;">(Enabled), </span><span style="font-family: 'Times New Roman'; color: #000000;">а</span><span style="font-family: 'Times New Roman'; color: #000000;">также</span><span style="font-family: 'Times New Roman'; color: #000000;">список</span><span style="font-family: 'Times New Roman'; color: #000000;">каталогов</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">которые</span><span style="font-family: 'Times New Roman'; color: #000000;">он</span><span style="font-family: 'Times New Roman'; color: #000000;">подписан</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Процедура</span><span style="font-family: 'Times New Roman'; color: #000000;"> PickFiles </span><span style="font-family: 'Times New Roman'; color: #000000;">составляет</span><span style="font-family: 'Times New Roman'; color: #000000;">список</span><span style="font-family: 'Times New Roman'; color: #000000;">файлов</span><span style="font-family: 'Times New Roman'; color: #000000;">к</span><span style="font-family: 'Times New Roman'; color: #000000;">отправке</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">сохраняет</span><span style="font-family: 'Times New Roman'; color: #000000;">его</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">свойстве</span><span style="font-family: 'Times New Roman'; color: #000000;"> Files</span><br /><span style="font-family: 'Times New Roman'; color: #000000;">Класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailList, </span><span style="font-family: 'Times New Roman'; color: #000000;">хранящий</span><span style="font-family: 'Times New Roman'; color: #000000;">объекты</span><span style="font-family: 'Times New Roman'; color: #000000;">класса</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailClient, </span><span style="font-family: 'Times New Roman'; color: #000000;">приведен</span><span style="font-family: 'Times New Roman'; color: #000000;">ниже</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMailList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TCollection) </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetMailClient(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer): TMailClient; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetMailClient(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer; Value: TMailClient); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Add: TMailClient; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Items[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer]: TMailClient </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetMailClient </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetMailClient; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">default</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Теперь</span><span style="font-family: 'Times New Roman'; color: #000000;">поместим</span><span style="font-family: 'Times New Roman'; color: #000000;">класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailList </span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailer. </span><span style="font-family: 'Times New Roman'; color: #000000;">В</span><span style="font-family: 'Times New Roman'; color: #000000;">него</span><span style="font-family: 'Times New Roman'; color: #000000;">можно</span><span style="font-family: 'Times New Roman'; color: #000000;">будет</span><span style="font-family: 'Times New Roman'; color: #000000;">потом</span><span style="font-family: 'Times New Roman'; color: #000000;">включить</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">параметрах</span><span style="font-family: 'Times New Roman'; color: #000000;">доступа</span><span style="font-family: 'Times New Roman'; color: #000000;">к</span><span style="font-family: 'Times New Roman'; color: #000000;">почтовому</span><span style="font-family: 'Times New Roman'; color: #000000;">серверу</span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">отправки</span><span style="font-family: 'Times New Roman'; color: #000000;">почты</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Он</span><span style="font-family: 'Times New Roman'; color: #000000;">мог</span><span style="font-family: 'Times New Roman'; color: #000000;">бы</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">отправлять</span><span style="font-family: 'Times New Roman'; color: #000000;">почту</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">но</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">данном</span><span style="font-family: 'Times New Roman'; color: #000000;">примере</span><span style="font-family: 'Times New Roman'; color: #000000;">это</span><span style="font-family: 'Times New Roman'; color: #000000;">не</span><span style="font-family: 'Times New Roman'; color: #000000;">использовано</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">дабы</span><span style="font-family: 'Times New Roman'; color: #000000;">не</span><span style="font-family: 'Times New Roman'; color: #000000;">перегружать</span><span style="font-family: 'Times New Roman'; color: #000000;">код</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">То</span><span style="font-family: 'Times New Roman'; color: #000000;">есть</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">нашем</span><span style="font-family: 'Times New Roman'; color: #000000;">примере</span><span style="font-family: 'Times New Roman'; color: #000000;">он</span><span style="font-family: 'Times New Roman'; color: #000000;">выполняет</span><span style="font-family: 'Times New Roman'; color: #000000;">только</span><span style="font-family: 'Times New Roman'; color: #000000;">роль</span><span style="font-family: 'Times New Roman'; color: #000000;">носителя</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">о</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчиках</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;">подписке</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> TComponent, </span><span style="font-family: 'Times New Roman'; color: #000000;">от</span><span style="font-family: 'Times New Roman'; color: #000000;">которого</span><span style="font-family: 'Times New Roman'; color: #000000;">он</span><span style="font-family: 'Times New Roman'; color: #000000;">наследуется</span><span style="font-family: 'Times New Roman'; color: #000000;">можно</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранить</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">файл</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">то</span><span style="font-family: 'Times New Roman'; color: #000000;">время</span><span style="font-family: 'Times New Roman'; color: #000000;">как</span><span style="font-family: 'Times New Roman'; color: #000000;"> TCollection </span><span style="font-family: 'Times New Roman'; color: #000000;">самостоятельно</span><span style="font-family: 'Times New Roman'; color: #000000;">не</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранится</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Только</span><span style="font-family: 'Times New Roman'; color: #000000;">если</span><span style="font-family: 'Times New Roman'; color: #000000;">она</span><span style="font-family: 'Times New Roman'; color: #000000;">агрегирована</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;"> TComponent. </span><span style="font-family: 'Times New Roman'; color: #000000;">Именно</span><span style="font-family: 'Times New Roman'; color: #000000;">это</span><span style="font-family: 'Times New Roman'; color: #000000;">у</span><span style="font-family: 'Times New Roman'; color: #000000;">нас</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">реализовано</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMailer = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TComponent) </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FMailList: TMailList; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner: TComponent); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> MailList: TMailList </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FMailList </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FMailList; </span><span class="f_CodeExample" style="color: #000080;">// коллекция - список рассылки. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// здесь можно поместить, к примеру, данные о соединении с почтовым сервером </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 7px 0px;"><br /><span style="font-family: 'Times New Roman'; color: #000000;">Повторюсь</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">В</span><span style="font-family: 'Times New Roman'; color: #000000;">данном</span><span style="font-family: 'Times New Roman'; color: #000000;">случае</span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">наследуемся</span><span style="font-family: 'Times New Roman'; color: #000000;">от</span><span style="font-family: 'Times New Roman'; color: #000000;">класса</span><span style="font-family: 'Times New Roman'; color: #000000;"> TComponent, </span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">того</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">чтобы</span><span style="font-family: 'Times New Roman'; color: #000000;">была</span><span style="font-family: 'Times New Roman'; color: #000000;">возможности</span><span style="font-family: 'Times New Roman'; color: #000000;">записи</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">объекта</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">файл</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Свойство</span><span style="font-family: 'Times New Roman'; color: #000000;"> MailList </span><span style="font-family: 'Times New Roman'; color: #000000;">содержит</span><span style="font-family: 'Times New Roman'; color: #000000;">уже</span><span style="font-family: 'Times New Roman'; color: #000000;">объект</span><span style="font-family: 'Times New Roman'; color: #000000;">класса</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailList. </span><br /><span style="font-family: 'Times New Roman'; color: #000000;">Реализация</span><span style="font-family: 'Times New Roman'; color: #000000;">всех</span><span style="font-family: 'Times New Roman'; color: #000000;">приведенных</span><span style="font-family: 'Times New Roman'; color: #000000;">классов</span><span style="font-family: 'Times New Roman'; color: #000000;">приведена</span><span style="font-family: 'Times New Roman'; color: #000000;">ниже</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TMailClient.Create(Collection: TCollection); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Folders := TStringList.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Files := TStringList.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FEnabled := true; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TMailClient.Destroy; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Folders.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Files.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// здесь во всех каталогах Folders ищем файлы для рассылки и помещаем их в Files. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMailClient.PickFiles; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> i: integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> i:=</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> Folders.Count-</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #000000;"> CreateFileList(Files, Folders[i]); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Стандартный код при наследовании от класса коллекции: переопределяем тип </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TMailList.GetMailClient(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer): TMailClient; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := TMailClient(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Items[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">]); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Стандартный код при наследовании от класса коллекции </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMailList.SetMailClient(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer; Value: TMailClient); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Items[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">].Assign(Value); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Стандартный код при наследовании от класса коллекции: переопределяем тип </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TMailList.Add: TMailClient; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := TMailClient(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Add); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// создаем коллекцию адресатов рассылки TMailList </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TMailer.Create(AOwner: TComponent); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MailList := TMailList.Create(TMailClient); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TMailer.Destroy; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MailList.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//--------------------- </span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Функция</span><span style="font-family: 'Times New Roman'; color: #000000;"> CreateFileList </span><span style="font-family: 'Times New Roman'; color: #000000;">создает</span><span style="font-family: 'Times New Roman'; color: #000000;">по</span><span style="font-family: 'Times New Roman'; color: #000000;">каким</span><span style="font-family: 'Times New Roman'; color: #000000;">-</span><span style="font-family: 'Times New Roman'; color: #000000;">либо</span><span style="font-family: 'Times New Roman'; color: #000000;">правилам</span><span style="font-family: 'Times New Roman'; color: #000000;">список</span><span style="font-family: 'Times New Roman'; color: #000000;">файлов</span><span style="font-family: 'Times New Roman'; color: #000000;">на</span><span style="font-family: 'Times New Roman'; color: #000000;">основе</span><span style="font-family: 'Times New Roman'; color: #000000;">переданного</span><span style="font-family: 'Times New Roman'; color: #000000;">ей</span><span style="font-family: 'Times New Roman'; color: #000000;">списка</span><span style="font-family: 'Times New Roman'; color: #000000;">каталогов</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">обходя</span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;">рекурсивно</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">К</span><span style="font-family: 'Times New Roman'; color: #000000;">примеру</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">она</span><span style="font-family: 'Times New Roman'; color: #000000;">может</span><span style="font-family: 'Times New Roman'; color: #000000;">быть</span><span style="font-family: 'Times New Roman'; color: #000000;">реализована</span><span style="font-family: 'Times New Roman'; color: #000000;">так</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> CreateFileList(sl: TStringList; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> FilePath: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">sr: TSearchRec; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ProcessFile; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> (sr.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> = </span><span class="f_CodeExample" style="color: #ff0000;">'.'</span><span class="f_CodeExample" style="color: #000000;">)</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">or</span><span class="f_CodeExample" style="color: #000000;">(sr.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> = </span><span class="f_CodeExample" style="color: #ff0000;">'..'</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> exit; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> sr.Attr &lt;&gt; faDirectory </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> sl.Add(FilePath + </span><span class="f_CodeExample" style="color: #ff0000;">'\'</span><span class="f_CodeExample" style="color: #000000;"> + sr.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> sr.Attr = faDirectory </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> CreateFileList(sl, FilePath + </span><span class="f_CodeExample" style="color: #ff0000;">'\'</span><span class="f_CodeExample" style="color: #000000;"> + sr.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">not</span><span class="f_CodeExample" style="color: #000000;"> DirectoryExists(FilePath) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> exit; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> FindFirst(FilePath + </span><span class="f_CodeExample" style="color: #ff0000;">'\'</span><span class="f_CodeExample" style="color: #000000;"> + </span><span class="f_CodeExample" style="color: #ff0000;">'*.*'</span><span class="f_CodeExample" style="color: #000000;">, faAnyFile , sr) = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> ProcessFile; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">while</span><span class="f_CodeExample" style="color: #000000;"> FindNext(sr) = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #000000;"> ProcessFile; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FindClose(sr); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">В</span><span style="font-family: 'Times New Roman'; color: #000000;">итоге</span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">располагаем</span><span style="font-family: 'Times New Roman'; color: #000000;">классом</span><span style="font-family: 'Times New Roman'; color: #000000;"> TMailer, </span><span style="font-family: 'Times New Roman'; color: #000000;">содержащим</span><span style="font-family: 'Times New Roman'; color: #000000;">всю</span><span style="font-family: 'Times New Roman'; color: #000000;">необходимую</span><span style="font-family: 'Times New Roman'; color: #000000;">нам</span><span style="font-family: 'Times New Roman'; color: #000000;">информацию</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Теперь</span><span style="font-family: 'Times New Roman'; color: #000000;">перейдем</span><span style="font-family: 'Times New Roman'; color: #000000;">к</span><span style="font-family: 'Times New Roman'; color: #000000;">созданию</span><span style="font-family: 'Times New Roman'; color: #000000;">объекта</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранению</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">загрузке</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Mailer: TMailer; </span><span class="f_CodeExample" style="color: #000080;">// это наш объект для хранения данных о почтовой рассылки</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Процедура загрузки данных в объект. Может быть процедурой OnCreate() главной формы.</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TfMain.FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">sDataFile, sTmp: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">i, j: integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Mailer := TMailer.Create(self); </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// будем считать, что данные были сохранены в файл users.dat в каталоге программы</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">sDataFile := ExtractFilePath(ParamStr(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">)) + </span><span class="f_CodeExample" style="color: #ff0000;">'users.dat'</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...загрузка данных из файла </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> FileExists(sDataFile) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> LoadComponentFromTextFile(Mailer, sDataFile); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ здесь данные из файла загружены }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...перебор подписчиков </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> i:=</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> Mailer.MailList.Count-</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> sTmp := Mailer.MailList[i].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #000080;">//...обращение к имени </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> sTmp := Mailer.MailList[i].Address; </span><span class="f_CodeExample" style="color: #000080;">//...обращение к адресу </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//... sTmp - фиктивная переменная. Поменяйте ее на свои. </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Mailer.MailList[i].PickFiles; </span><span class="f_CodeExample" style="color: #000080;">//... поиск файлов для отправки очередному подписчику. </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...перебор найденных файлов к отправке </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> j:=</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> Mailer.MailList[i].Files.Count-</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> sTmp := Mailer.MailList[i].Files[j]; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">После</span><span style="font-family: 'Times New Roman'; color: #000000;">загрузки</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">мы</span><span style="font-family: 'Times New Roman'; color: #000000;">можем</span><span style="font-family: 'Times New Roman'; color: #000000;">работать</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">данными</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">нашей</span><span style="font-family: 'Times New Roman'; color: #000000;">коллекции</span><span style="font-family: 'Times New Roman'; color: #000000;">подписчиков</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Добавлять</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">удалять</span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;"> ( Mailer.MailList.Add; Mailer.MailList.Delete(Index); ). </span><span style="font-family: 'Times New Roman'; color: #000000;">При</span><span style="font-family: 'Times New Roman'; color: #000000;">завершении</span><span style="font-family: 'Times New Roman'; color: #000000;">работы</span><span style="font-family: 'Times New Roman'; color: #000000;">программы</span><span style="font-family: 'Times New Roman'; color: #000000;">необходимо</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранить</span><span style="font-family: 'Times New Roman'; color: #000000;">уже</span><span style="font-family: 'Times New Roman'; color: #000000;">новые</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">тот</span><span style="font-family: 'Times New Roman'; color: #000000;">же</span><span style="font-family: 'Times New Roman'; color: #000000;">файл</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Процедура сохранения данных из объекта в файл. Может быть процедурой OnDestroy() главной формы.</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TfMain.OnDestroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...сохранение данных в файл users.dat</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SaveComponentToTextFile(Mailer, ExtractFilePath(ParamStr(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">)) + </span><span class="f_CodeExample" style="color: #ff0000;">'users.dat'</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Хранение</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">файле</span><span style="font-family: 'Times New Roman'; color: #000000;">позволяет</span><span style="font-family: 'Times New Roman'; color: #000000;">оказаться</span><span style="font-family: 'Times New Roman'; color: #000000;">от</span><span style="font-family: 'Times New Roman'; color: #000000;">использования</span><span style="font-family: 'Times New Roman'; color: #000000;">БД</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">если</span><span style="font-family: 'Times New Roman'; color: #000000;">объем</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">не</span><span style="font-family: 'Times New Roman'; color: #000000;">слишком</span><span style="font-family: 'Times New Roman'; color: #000000;">велик</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">нет</span><span style="font-family: 'Times New Roman'; color: #000000;">необходимости</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">совместном</span><span style="font-family: 'Times New Roman'; color: #000000;">доступе</span><span style="font-family: 'Times New Roman'; color: #000000;">к</span><span style="font-family: 'Times New Roman'; color: #000000;">данным</span><span style="font-family: 'Times New Roman'; color: #000000;">.</span><br /><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Самое</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">главное</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> - </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">мы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">организуем</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">все</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">данные</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">в</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">виде</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">набора</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">удобных</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">для</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">работы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">классов</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">не</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">тратим</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">время</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">на</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">их</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">сохранение</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">инициализацию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">из</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">БД</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">.</span><br /><span style="font-family: 'Times New Roman'; color: #000000;">Приведенный</span><span style="font-family: 'Times New Roman'; color: #000000;">пример</span><span style="font-family: 'Times New Roman'; color: #000000;">лишь</span><span style="font-family: 'Times New Roman'; color: #000000;">иллюстрирует</span><span style="font-family: 'Times New Roman'; color: #000000;">этот</span><span style="font-family: 'Times New Roman'; color: #000000;">подход</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Для</span><span style="font-family: 'Times New Roman'; color: #000000;">его</span><span style="font-family: 'Times New Roman'; color: #000000;">реализации</span><span style="font-family: 'Times New Roman'; color: #000000;">могут</span><span style="font-family: 'Times New Roman'; color: #000000;">подойти</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;"> 2 </span><span style="font-family: 'Times New Roman'; color: #000000;">таблицы</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">БД</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Однако</span><span style="font-family: 'Times New Roman'; color: #000000;">приведенный</span><span style="font-family: 'Times New Roman'; color: #000000;">подход</span><span style="font-family: 'Times New Roman'; color: #000000;">удобен</span><span style="font-family: 'Times New Roman'; color: #000000;">при</span><span style="font-family: 'Times New Roman'; color: #000000;">условии</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">что</span><span style="font-family: 'Times New Roman'; color: #000000;">данные</span><span style="font-family: 'Times New Roman'; color: #000000;">имеют</span><span style="font-family: 'Times New Roman'; color: #000000;">сложную</span><span style="font-family: 'Times New Roman'; color: #000000;">иерархию</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">К</span><span style="font-family: 'Times New Roman'; color: #000000;">примеру</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">вложенные</span><span style="font-family: 'Times New Roman'; color: #000000;">коллекции</span><span style="font-family: 'Times New Roman'; color: #000000;">разных</span><span style="font-family: 'Times New Roman'; color: #000000;">типов</span><span style="font-family: 'Times New Roman'; color: #000000;">гораздо</span><span style="font-family: 'Times New Roman'; color: #000000;">сложнее</span><span style="font-family: 'Times New Roman'; color: #000000;">разложить</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">базе</span><span style="font-family: 'Times New Roman'; color: #000000;">данных</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">их</span><span style="font-family: 'Times New Roman'; color: #000000;">извлечения</span><span style="font-family: 'Times New Roman'; color: #000000;">потребуется</span><span style="font-family: 'Times New Roman'; color: #000000;"> SQL. </span><span style="font-family: 'Times New Roman'; color: #000000;">Решайте</span><span style="font-family: 'Times New Roman'; color: #000000;">сами</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">судя</span><span style="font-family: 'Times New Roman'; color: #000000;">по</span><span style="font-family: 'Times New Roman'; color: #000000;">своей</span><span style="font-family: 'Times New Roman'; color: #000000;">конкретной</span><span style="font-family: 'Times New Roman'; color: #000000;">задаче</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <p style="text-align: justify; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Далее</span><span style="font-family: 'Times New Roman'; color: #000000;">приведен</span><span style="font-family: 'Times New Roman'; color: #000000;">код</span><span style="font-family: 'Times New Roman'; color: #000000;">функций</span><span style="font-family: 'Times New Roman'; color: #000000;">для</span><span style="font-family: 'Times New Roman'; color: #000000;">сохранения</span><span style="font-family: 'Times New Roman'; color: #000000;">/</span><span style="font-family: 'Times New Roman'; color: #000000;">чтения</span><span style="font-family: 'Times New Roman'; color: #000000;">компонента</span><span style="font-family: 'Times New Roman'; color: #000000;">.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...процедура загружает(инициализирует) компонент из текстового файла с ресурсом </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> LoadComponentFromTextFile(Component: TComponent; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> FileName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms: TMemoryStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">fs: TFileStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">fs := TFileStream.Create(FileName, fmOpenRead); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms := TMemoryStream.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ObjectTextToBinary(fs, ms); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.position := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.ReadComponent(Component); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finally</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> fs.free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//...процедура сохраняет компонент в текстовый файл </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SaveComponentToTextFile(Component: TComponent; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> FileName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms: TMemoryStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">fs: TFileStream; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">fs := TFileStream.Create(FileName, fmCreate </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">or</span><span class="f_CodeExample" style="color: #000000;"> fmOpenWrite); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ms := TMemoryStream.Create; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.WriteComponent(Component); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.position := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ObjectBinaryToText(ms, fs); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">finally</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ms.Free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> fs.free; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="text-align: right; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">составление</span><span style="font-family: 'Times New Roman'; color: #000000;">статьи</span><span style="font-family: 'Times New Roman'; color: #000000;">: </span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Андрей</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Чудин</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">ЦПР</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">ТД</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Библио</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">-</span><span style="font-family: 'Times New Roman'; color: #0000ff; text-decoration: underline;">Глобус</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span></p> <p style="text-align: justify; margin: 7px 0px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из https://delphi.chertenok</span></p> Список handle всех окон моего приложения 2013-08-19T19:09:20+07:00 2013-08-19T19:09:20+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/spisok-handle-vsekh-okon-moego-prilozheniya.html Super User toto44@inbox.ru <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> EnumProc(wnd: HWND; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> count: DWORD): Bool; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Inc(count);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">result := True;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">EnumChildWindows(wnd, @EnumProc, integer(@count));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">count: DWORD;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">count := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">EnumThreadWindows(GetCurrentThreadID, @EnumProc, Integer(@count));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption := Format(</span><span class="f_CodeExample" style="color: #ff0000;">'%d window handles in use'</span><span class="f_CodeExample" style="color: #000000;">, [count]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с сайта</span>https://www.swissdelphicenter.ch/en/tipsindex</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> EnumProc(wnd: HWND; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> count: DWORD): Bool; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Inc(count);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">result := True;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">EnumChildWindows(wnd, @EnumProc, integer(@count));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">count: DWORD;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">count := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">EnumThreadWindows(GetCurrentThreadID, @EnumProc, Integer(@count));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption := Format(</span><span class="f_CodeExample" style="color: #ff0000;">'%d window handles in use'</span><span class="f_CodeExample" style="color: #000000;">, [count]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с сайта</span>https://www.swissdelphicenter.ch/en/tipsindex</p> Шаблоны в Object Pascal 2013-08-19T17:08:00+07:00 2013-08-19T17:08:00+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/raznye-voprosy/shablony-v-object-pascal.html Super User toto44@inbox.ru <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаблоны в Object Pascal</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">( перевод одноименной статьи с сайта community.borland.com )</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Наверное каждый Delphi программист хоть раз общался с программистом C++ и объяснял насколько</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Delphi мощнее и удобнее. Но в некоторый момент, программист C++ заявляет примерно следующее</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">"OK, но Delphi использует Pascal, а значит не поддерживает множественное наследование и шаблоны,</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">поэтому он не так хорош как C++."</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Насчет множественного наследования можно легко заявить, что Delphi имеет интерфейсы, которые</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">прекрасно справляются со своей задачей, но вот насчет шаблонов Вам придётся согласится, так как</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Object Pascal не поддерживает их.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Давайте посмотрим на эту проблему по-внимательней</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаблоны позволяют делать универсальные контейнеры такие как списки, стеки, очереди, и т.д.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Если Вы хотите осуществить что-то подобное в Delphi, то у Вас есть два пути:</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Использовать контейнер TList, который содержит указатели. В этом случае Вам придётся всё</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">время делать явное приведение типов. </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Сделать подкласс контейнера TCollection или TObjectList, и убрать все методы, зависящие от типов</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">каждый раз, когда Вы захотите использовать новый тип данных. </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Третий вариант, это сделать модуль с универсальным классом контейнера, и каждый раз, когда нужно</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">использовать новый тип данных, нам прийдётся в редакторе искать и вносить исправления. Было бы</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">здорово, если всю эту работу за Вас делал компилятор.... вот этим мы сейчас и займёмся!</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Например, возьмём классы TCollection и TCollectionItem. Когда Вы объявляете нового потомка TCollectionItem</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">, то так же Вы наследуете новый класс от TOwnedCollection и переопределяете большинство методов, чтобы</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">их можно было вызывать с новыми типами.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Давайте посмотрим, как создать универсальную коллекцию шаблонов класса:</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаг 1: Создайте новый текстовый файл (не юнитовский) с именем TemplateCollectionInterface.pas:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">_COLLECTION_ = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> (TOwnedCollection)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetItem (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetItem (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _COLLECTION_ITEM_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aOwner : TComponent);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Add : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> FindItemID (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aID : Integer) : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Insert (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Items [</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer] : _COLLECTION_ITEM_ </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetItem </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetItem;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Обратите внимание, что нет никаких uses или interface clauses, только универсальное объявление</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">типа, в котором _COLLECTION_ это имя универсальной коллекции класса, а _COLLECTION_ITEM_</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">это имя методов, содержащихся в нашем шаблоне.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаг 2: Создайте второй текстовый файл и сохраните его как TemplateCollectionImplementation.pas:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_.Create (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aOwner : TComponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create (aOwner, _COLLECTION_ITEM_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_.Add : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := _COLLECTION_ITEM_ (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Add);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_.FindItemID (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aID : Integer) : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := _COLLECTION_ITEM_ (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> FindItemID (aID));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_.GetItem (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := _COLLECTION_ITEM_ (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> GetItem (aIndex));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_.Insert (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := _COLLECTION_ITEM_ (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Insert (aIndex));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_.SetItem (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _COLLECTION_ITEM_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> SetItem (aIndex, aValue);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Снова нет никаких uses или interface clauses , а только код универсального типа.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаг 3: Создайте новый unit-файл с именем MyCollectionUnit.pas:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> MyCollectionUnit;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> Classes;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> TMyCollectionItem = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> (TCollectionItem)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FMyStringData : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FMyIntegerData : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Assign (aSource : TPersistent); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> MyStringData : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FMyStringData </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FMyStringData;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> MyIntegerData : Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FMyIntegerData </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FMyIntegerData;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// !!! Указываем универсальному классу на реальный тип</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_ITEM_ = TMyCollectionItem; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// !!! директива добавления интерфейса универсального класса</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$INCLUDE TemplateCollectionInterface}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// !!! переименовываем универсальный класс</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TMyCollection = _COLLECTION_; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> SysUtils;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// !!! препроцессорная директива добавления универсального класса</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$INCLUDE TemplateCollectionImplementation}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMyCollectionItem.Assign (aSource : TPersistent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> aSource </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">is</span><span class="f_CodeExample" style="color: #000000;"> TMyCollectionItem </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FMyStringData := TMyCollectionItem(aSource).FMyStringData;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FMyIntegerData := TMyCollectionItem(aSource).FMyIntegerData;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">else</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Вот и всё! Теперь компилятор будет делать всю работу за Вас! Если Вы измените интерфейс</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">универсального класса, то изменения автоматически распространятся на все модули, которые</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">он использует.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Второй пример</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Давайте создадим универсальный класс для динамических массивов.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаг 1: Создайте текстовый файл с именем TemplateVectorInterface.pas:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">_VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_ = nterface</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetLength : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetLength (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetItems (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetItems (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetFirst : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetFirst (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetLast : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetLast (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> High : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Low : Integer;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Clear : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Extend (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aDelta : Word = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">) : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Contract (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aDelta : Word = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">) : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Length : Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetLength </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetLength;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Items [</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer] : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_ </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetItems </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetItems; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">default</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> First : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_ </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetFirst </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetFirst;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Last : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_ </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetLast </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetLast;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">_VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_ = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> (TInterfacedObject, _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FArray : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">array</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetLength : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetLength (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetItems (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetItems (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetFirst : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetFirst (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetLast : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetLast (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> High : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Low : Integer;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Clear : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Extend (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aDelta : Word = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">) : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Contract (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aDelta : Word = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">) : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаг 2: Создайте текстовый файл и сохраните его как TemplateVectorImplementation.pas:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.Create (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SetLength (aLength);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.GetLength : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := System.Length (FArray);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.SetLength (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">System.SetLength (FArray, aLength);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.GetItems (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FArray [aIndex];</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.SetItems (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FArray [aIndex] := aValue;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.High : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := System.High (FArray);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.Low : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := System.Low (FArray);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.GetFirst : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FArray [System.Low (FArray)];</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.SetFirst (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FArray [System.Low (FArray)] := aValue;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.GetLast : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FArray [System.High (FArray)];</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.SetLast (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FArray [System.High (FArray)] := aValue;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.Clear : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FArray := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Nil</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.Extend (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aDelta : Word) : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">System.SetLength (FArray, System.Length (FArray) + aDelta);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.Contract (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aDelta : Word) : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">System.SetLength (FArray, System.Length (FArray) - aDelta);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Courier New'; font-size: 9pt;">Шаг </span><span style="font-family: 'Courier New'; color: #800000; font-size: 9pt;">3</span><span style="font-family: 'Courier New'; font-size: 9pt;">: Создайте </span><span style="font-family: 'Courier New'; color: #008000; font-size: 9pt; font-weight: bold;">unit</span><span style="font-family: 'Courier New'; font-size: 9pt;"> файл с именем FloatVectorUnit.pas:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> FloatVectorUnit;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> Classes; </span><span class="f_CodeExample" style="color: #000080;">// !!! Модуль "Classes" содержит объявление класса TInterfacedObject</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_ = Double; </span><span class="f_CodeExample" style="color: #000080;">// !!! тип данных для класса массива Double</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$INCLUDE TemplateVectorInterface}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> IFloatVector = _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_; </span><span class="f_CodeExample" style="color: #000080;">// !!! give the interface a meanigful name</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TFloatVector = _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_; </span><span class="f_CodeExample" style="color: #000080;">// !!! give the class a meanigful name</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> CreateFloatVector (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">) : IFloatVector; </span><span class="f_CodeExample" style="color: #000080;">// !!! дополнительная функция </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$INCLUDE TemplateVectorImplementation}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> CreateFloatVector (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">) : IFloatVector; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := TFloatVector.Create (aLength);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Естественно, можно дополнить универсальный класс дополнительными</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">функциями. Всё зависит от Вашей фантазии!</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Использование шаблонов</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Вот пример использования нового векторного интерфейса:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TestFloatVector;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> aFloatVector : IFloatVector;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">aFloatVector := CreateFloatVector;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">aFloatVector.Extend.Last := </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">aFloatVector.Extend.Last := </span><span class="f_CodeExample" style="color: #800000;">2</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> aIndex := aFloatVector.Low </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> aFloatVector.High </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WriteLn (FloatToStr (aFloatVector [aIndex]));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Единственное требование при создании шаблонов таким способом, это то, что</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">каждый новый тип должен быть объявлен в отдельном модуле, а так же Вы должны</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">иметь исходники для универсальных классов.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;"> </span></p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">https://forum.sources</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаблоны в Object Pascal</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">( перевод одноименной статьи с сайта community.borland.com )</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Наверное каждый Delphi программист хоть раз общался с программистом C++ и объяснял насколько</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Delphi мощнее и удобнее. Но в некоторый момент, программист C++ заявляет примерно следующее</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">"OK, но Delphi использует Pascal, а значит не поддерживает множественное наследование и шаблоны,</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">поэтому он не так хорош как C++."</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Насчет множественного наследования можно легко заявить, что Delphi имеет интерфейсы, которые</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">прекрасно справляются со своей задачей, но вот насчет шаблонов Вам придётся согласится, так как</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Object Pascal не поддерживает их.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Давайте посмотрим на эту проблему по-внимательней</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаблоны позволяют делать универсальные контейнеры такие как списки, стеки, очереди, и т.д.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Если Вы хотите осуществить что-то подобное в Delphi, то у Вас есть два пути:</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Использовать контейнер TList, который содержит указатели. В этом случае Вам придётся всё</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">время делать явное приведение типов. </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Сделать подкласс контейнера TCollection или TObjectList, и убрать все методы, зависящие от типов</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">каждый раз, когда Вы захотите использовать новый тип данных. </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Третий вариант, это сделать модуль с универсальным классом контейнера, и каждый раз, когда нужно</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">использовать новый тип данных, нам прийдётся в редакторе искать и вносить исправления. Было бы</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">здорово, если всю эту работу за Вас делал компилятор.... вот этим мы сейчас и займёмся!</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Например, возьмём классы TCollection и TCollectionItem. Когда Вы объявляете нового потомка TCollectionItem</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">, то так же Вы наследуете новый класс от TOwnedCollection и переопределяете большинство методов, чтобы</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">их можно было вызывать с новыми типами.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Давайте посмотрим, как создать универсальную коллекцию шаблонов класса:</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаг 1: Создайте новый текстовый файл (не юнитовский) с именем TemplateCollectionInterface.pas:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">_COLLECTION_ = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> (TOwnedCollection)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetItem (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetItem (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _COLLECTION_ITEM_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aOwner : TComponent);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Add : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> FindItemID (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aID : Integer) : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Insert (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Items [</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer] : _COLLECTION_ITEM_ </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetItem </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetItem;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Обратите внимание, что нет никаких uses или interface clauses, только универсальное объявление</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">типа, в котором _COLLECTION_ это имя универсальной коллекции класса, а _COLLECTION_ITEM_</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">это имя методов, содержащихся в нашем шаблоне.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаг 2: Создайте второй текстовый файл и сохраните его как TemplateCollectionImplementation.pas:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_.Create (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aOwner : TComponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create (aOwner, _COLLECTION_ITEM_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_.Add : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := _COLLECTION_ITEM_ (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Add);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_.FindItemID (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aID : Integer) : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := _COLLECTION_ITEM_ (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> FindItemID (aID));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_.GetItem (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := _COLLECTION_ITEM_ (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> GetItem (aIndex));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_.Insert (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _COLLECTION_ITEM_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := _COLLECTION_ITEM_ (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Insert (aIndex));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_.SetItem (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _COLLECTION_ITEM_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> SetItem (aIndex, aValue);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Снова нет никаких uses или interface clauses , а только код универсального типа.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаг 3: Создайте новый unit-файл с именем MyCollectionUnit.pas:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> MyCollectionUnit;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> Classes;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> TMyCollectionItem = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> (TCollectionItem)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FMyStringData : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FMyIntegerData : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Assign (aSource : TPersistent); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> MyStringData : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FMyStringData </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FMyStringData;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> MyIntegerData : Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FMyIntegerData </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FMyIntegerData;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// !!! Указываем универсальному классу на реальный тип</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> _COLLECTION_ITEM_ = TMyCollectionItem; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// !!! директива добавления интерфейса универсального класса</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$INCLUDE TemplateCollectionInterface}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// !!! переименовываем универсальный класс</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TMyCollection = _COLLECTION_; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> SysUtils;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// !!! препроцессорная директива добавления универсального класса</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$INCLUDE TemplateCollectionImplementation}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMyCollectionItem.Assign (aSource : TPersistent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> aSource </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">is</span><span class="f_CodeExample" style="color: #000000;"> TMyCollectionItem </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FMyStringData := TMyCollectionItem(aSource).FMyStringData;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FMyIntegerData := TMyCollectionItem(aSource).FMyIntegerData;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">else</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Вот и всё! Теперь компилятор будет делать всю работу за Вас! Если Вы измените интерфейс</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">универсального класса, то изменения автоматически распространятся на все модули, которые</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">он использует.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Второй пример</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Давайте создадим универсальный класс для динамических массивов.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаг 1: Создайте текстовый файл с именем TemplateVectorInterface.pas:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">_VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_ = nterface</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetLength : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetLength (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetItems (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetItems (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetFirst : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetFirst (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetLast : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetLast (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> High : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Low : Integer;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Clear : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Extend (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aDelta : Word = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">) : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Contract (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aDelta : Word = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">) : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Length : Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetLength </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetLength;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Items [</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer] : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_ </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetItems </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetItems; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">default</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> First : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_ </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetFirst </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetFirst;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Last : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_ </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetLast </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetLast;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">_VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_ = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> (TInterfacedObject, _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FArray : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">array</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetLength : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetLength (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetItems (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetItems (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetFirst : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetFirst (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetLast : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetLast (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> High : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Low : Integer;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Clear : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Extend (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aDelta : Word = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">) : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Contract (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aDelta : Word = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">) : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Шаг 2: Создайте текстовый файл и сохраните его как TemplateVectorImplementation.pas:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.Create (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SetLength (aLength);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.GetLength : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := System.Length (FArray);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.SetLength (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">System.SetLength (FArray, aLength);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.GetItems (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer) : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FArray [aIndex];</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.SetItems (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FArray [aIndex] := aValue;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.High : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := System.High (FArray);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.Low : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := System.Low (FArray);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.GetFirst : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FArray [System.Low (FArray)];</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.SetFirst (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FArray [System.Low (FArray)] := aValue;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.GetLast : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FArray [System.High (FArray)];</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.SetLast (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aValue : _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FArray [System.High (FArray)] := aValue;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.Clear : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FArray := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Nil</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.Extend (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aDelta : Word) : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">System.SetLength (FArray, System.Length (FArray) + aDelta);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_.Contract (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aDelta : Word) : _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">System.SetLength (FArray, System.Length (FArray) - aDelta);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Courier New'; font-size: 9pt;">Шаг </span><span style="font-family: 'Courier New'; color: #800000; font-size: 9pt;">3</span><span style="font-family: 'Courier New'; font-size: 9pt;">: Создайте </span><span style="font-family: 'Courier New'; color: #008000; font-size: 9pt; font-weight: bold;">unit</span><span style="font-family: 'Courier New'; font-size: 9pt;"> файл с именем FloatVectorUnit.pas:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> FloatVectorUnit;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> Classes; </span><span class="f_CodeExample" style="color: #000080;">// !!! Модуль "Classes" содержит объявление класса TInterfacedObject</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> _VECTOR_DATA_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">TYPE</span><span class="f_CodeExample" style="color: #000000;">_ = Double; </span><span class="f_CodeExample" style="color: #000080;">// !!! тип данных для класса массива Double</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$INCLUDE TemplateVectorInterface}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> IFloatVector = _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">INTERFACE</span><span class="f_CodeExample" style="color: #000000;">_; </span><span class="f_CodeExample" style="color: #000080;">// !!! give the interface a meanigful name</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TFloatVector = _VECTOR_</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">CLASS</span><span class="f_CodeExample" style="color: #000000;">_; </span><span class="f_CodeExample" style="color: #000080;">// !!! give the class a meanigful name</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> CreateFloatVector (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">) : IFloatVector; </span><span class="f_CodeExample" style="color: #000080;">// !!! дополнительная функция </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$INCLUDE TemplateVectorImplementation}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> CreateFloatVector (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> aLength : Integer = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">) : IFloatVector; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := TFloatVector.Create (aLength);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Естественно, можно дополнить универсальный класс дополнительными</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">функциями. Всё зависит от Вашей фантазии!</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Использование шаблонов</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Вот пример использования нового векторного интерфейса:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TestFloatVector;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> aFloatVector : IFloatVector;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> aIndex : Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">aFloatVector := CreateFloatVector;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">aFloatVector.Extend.Last := </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">aFloatVector.Extend.Last := </span><span class="f_CodeExample" style="color: #800000;">2</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> aIndex := aFloatVector.Low </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> aFloatVector.High </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WriteLn (FloatToStr (aFloatVector [aIndex]));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Единственное требование при создании шаблонов таким способом, это то, что</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">каждый новый тип должен быть объявлен в отдельном модуле, а так же Вы должны</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">иметь исходники для универсальных классов.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;"> </span></p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">https://forum.sources</span></p> Как заставить код компонента работать только в дизайне? 2013-08-19T13:31:31+07:00 2013-08-19T13:31:31+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/razrabotka-komponentov-i-klassov/kak-zastavit-kod-komponenta-rabotat-tolko-v-dizajne.html Super User toto44@inbox.ru <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> csDesigning </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">in</span><span class="f_CodeExample" style="color: #000000;"> ComponentState </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">... код, работающий только в дизайне ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #7f0000; font-size: 10pt; font-weight: bold;">в</span><span style="font-family: 'Times New Roman'; color: #7f0000; font-size: 10pt; font-weight: bold;">модификации </span><span style="font-family: 'Times New Roman'; color: #7f0000; font-size: 10pt; font-weight: bold;">Vit</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> csDesigning </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">in</span><span class="f_CodeExample" style="color: #000000;"> ComponentState </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">... код, работающий только в дизайне ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от </span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #7f0000; font-size: 10pt; font-weight: bold;">в</span><span style="font-family: 'Times New Roman'; color: #7f0000; font-size: 10pt; font-weight: bold;">модификации </span><span style="font-family: 'Times New Roman'; color: #7f0000; font-size: 10pt; font-weight: bold;">Vit</span></p> Как написать собственный класс? 2013-08-19T13:30:10+07:00 2013-08-19T13:30:10+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/razrabotka-komponentov-i-klassov/kak-napisat-sobstvennyj-klass.html Super User toto44@inbox.ru <p><span style="font-family: 'Times New Roman'; color: #000000;">Вот пример написания класса. Этот класс вычисляет сумму квадратов введенных чисел. Этот класс написан мной только для примера, и я исходил из соображений наглядности, а не оптимальности. Большая часть реализации не только не оптимальна, но и бессмысленна, но показывает большую часть простейших приемов создания класса.</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> Unit2;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{©Drkb v.3(2007): www.drkb.ru, </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">®Vit (Vitaly Nevzorov) - <a class="weblink" href="mailto:nevzorov@yahoo.com">nevzorov@yahoo.com</a>}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Uses</span><span class="f_CodeExample" style="color: #000000;"> classes, Sysutils;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Нам нужен процедурный тип для создания собственного события. Собственно - это описание процедуры которая должна будет исполнятся при каких-нибудь обстоятельствах}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TError = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;">(Sender:TObject; Error: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">object</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Описание нашего класса, мы его наследуем от TObject, потому ?то нам практи?ески не нужна</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">никакия функциональность предков}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Type</span><span class="f_CodeExample" style="color: #000000;"> TStatistic=</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Class</span><span class="f_CodeExample" style="color: #000000;">(TObject)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span><span class="f_CodeExample" style="color: #000080;">{здесь описываются только внутренние переменные и процедуры - "для служебного пользования"}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Описание полей, т.е. переменных которые работают только внутри класса, "снаружи" они не</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">доступны.}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FList:TStringList;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FPrecision: byte;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Тоже переменная - для определения события}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FonError: TError;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{функция - будет использоваться только внутри класса, "снаружи" напрямую не доступна}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetCount: integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span><span class="f_CodeExample" style="color: #000080;">{Описанное здесь доступно для пользователя класса}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Конструктор - метод создания класса, имеет смысл его описывать только если он делает</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">?то-то специфи?еское - например нам надо будет создать переменную FList. В противном слу?ае</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">его описание можно опустить - будет работать конструктор родительского класса}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Constructor</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Деструктор - метод разрушения класса}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Описание методов - собственно методы мало ?ем отли?аются от процедур}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> AddValue(Value:</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> Clear;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> Solve:real;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Описание свойств. Обратите внимание само свойство не способно хранить никакую информацию, это</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">только указатель на внутренюю струкруру. Например для хранения свойства Precision используется</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">переменная FPrecision. А для ?тение свойства Count используется функция GetCount}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Property</span><span class="f_CodeExample" style="color: #000000;"> Precision:byte </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FPrecision </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FPrecision;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Property</span><span class="f_CodeExample" style="color: #000000;"> Count:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Описание событий. ?то такое событие? - Это указатель на процедуру. Сам класс реализации этой процедуры</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">не знает. Классу известно только заголовок процедуры, вы в коде программы будете писать реализацию</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">процедуры, а класс только в нужный момент передаст ей управление, используя указатель onError}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Property</span><span class="f_CodeExample" style="color: #000000;"> onError:TError </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FonError </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FonError;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ TStatistic }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TStatistic.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #000080;">{Вна?але надо вызвать конструктор класса-родителя}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FList:=TStringList.create;</span><span class="f_CodeExample" style="color: #000080;">{создаем структуры нашего класса}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TStatistic.Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FList.Free;</span><span class="f_CodeExample" style="color: #000080;">{Разрушаем структуры нашего класса}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">;</span><span class="f_CodeExample" style="color: #000080;">{в последнюю о?ередь вызываем деструктор клсса-родителя}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TStatistic.AddValue(Value: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FList.add(Value); </span><span class="f_CodeExample" style="color: #000080;">{Примерно так мы реализуем метод}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TStatistic.Clear;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FList.clear;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TStatistic.GetCount: integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result:=FList.count+</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TStatistic.Solve: real;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> i:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">result:=</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> i:=</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> FList.count-</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">result:=result+(Sqr(strtofloat(FList[i])));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">except</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{интересная конструкция. "on e:exception do" - мы "отлавливаем" ошибку как переменную "e".</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">Эта переменная имеет о?ень полезное свойство e.message - оно содержит описание ошибки. Далее</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">следует вызов события. Вна?але мы проверяем использует ли пользователь событие:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">"if Assigned(FOnError) then", если использует то вызываем его процедуру: FOnError, с параметрами:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">self - зарезервированная переменная - указатель на экземпляр нашего класса, e.message - описание</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">ошибки}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">on e:exception </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Assigned(FOnError) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> FOnError(Self, e.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">message</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Вот пример использования этого класса:</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> Unit1;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TForm1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button1: TButton;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> OnError(Sender:TObject; Error: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Form1: TForm1;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> Unit2;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R *.DFM}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> Statistic:TStatistic;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic:=TStatistic.create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.onError:=onError;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.AddValue(</span><span class="f_CodeExample" style="color: #ff0000;">'123423'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.AddValue(</span><span class="f_CodeExample" style="color: #ff0000;">'123423'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">showmessage(floattostr(Statistic.solve));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.Clear;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.AddValue(</span><span class="f_CodeExample" style="color: #ff0000;">'123423'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.AddValue(</span><span class="f_CodeExample" style="color: #ff0000;">'12ssss3'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">showmessage(floattostr(Statistic.solve));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.Free;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.OnError(Sender: TObject; Error: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">showmessage(</span><span class="f_CodeExample" style="color: #ff0000;">'Error inside class:'</span><span class="f_CodeExample" style="color: #000000;">+Sender.ClassName+</span><span class="f_CodeExample" style="color: #ff0000;">#13#10</span><span class="f_CodeExample" style="color: #000000;">+Error);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #ff0000; font-size: 10pt; font-weight: bold;">Автор:</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Vit</span><span style="font-family: 'Times New Roman'; font-size: 10pt; font-weight: bold;">  </span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingrad</span><span style="color: #0000ff; text-decoration: underline;">https://forum.vingrad</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Вот пример написания класса. Этот класс вычисляет сумму квадратов введенных чисел. Этот класс написан мной только для примера, и я исходил из соображений наглядности, а не оптимальности. Большая часть реализации не только не оптимальна, но и бессмысленна, но показывает большую часть простейших приемов создания класса.</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> Unit2;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{©Drkb v.3(2007): www.drkb.ru, </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">®Vit (Vitaly Nevzorov) - <a class="weblink" href="mailto:nevzorov@yahoo.com">nevzorov@yahoo.com</a>}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Uses</span><span class="f_CodeExample" style="color: #000000;"> classes, Sysutils;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Нам нужен процедурный тип для создания собственного события. Собственно - это описание процедуры которая должна будет исполнятся при каких-нибудь обстоятельствах}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TError = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;">(Sender:TObject; Error: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">object</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Описание нашего класса, мы его наследуем от TObject, потому ?то нам практи?ески не нужна</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">никакия функциональность предков}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Type</span><span class="f_CodeExample" style="color: #000000;"> TStatistic=</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Class</span><span class="f_CodeExample" style="color: #000000;">(TObject)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span><span class="f_CodeExample" style="color: #000080;">{здесь описываются только внутренние переменные и процедуры - "для служебного пользования"}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Описание полей, т.е. переменных которые работают только внутри класса, "снаружи" они не</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">доступны.}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FList:TStringList;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FPrecision: byte;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Тоже переменная - для определения события}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FonError: TError;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{функция - будет использоваться только внутри класса, "снаружи" напрямую не доступна}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetCount: integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span><span class="f_CodeExample" style="color: #000080;">{Описанное здесь доступно для пользователя класса}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Конструктор - метод создания класса, имеет смысл его описывать только если он делает</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">?то-то специфи?еское - например нам надо будет создать переменную FList. В противном слу?ае</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">его описание можно опустить - будет работать конструктор родительского класса}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Constructor</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Деструктор - метод разрушения класса}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Описание методов - собственно методы мало ?ем отли?аются от процедур}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> AddValue(Value:</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> Clear;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> Solve:real;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Описание свойств. Обратите внимание само свойство не способно хранить никакую информацию, это</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">только указатель на внутренюю струкруру. Например для хранения свойства Precision используется</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">переменная FPrecision. А для ?тение свойства Count используется функция GetCount}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Property</span><span class="f_CodeExample" style="color: #000000;"> Precision:byte </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FPrecision </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FPrecision;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Property</span><span class="f_CodeExample" style="color: #000000;"> Count:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Описание событий. ?то такое событие? - Это указатель на процедуру. Сам класс реализации этой процедуры</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">не знает. Классу известно только заголовок процедуры, вы в коде программы будете писать реализацию</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">процедуры, а класс только в нужный момент передаст ей управление, используя указатель onError}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Property</span><span class="f_CodeExample" style="color: #000000;"> onError:TError </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FonError </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FonError;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ TStatistic }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TStatistic.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #000080;">{Вна?але надо вызвать конструктор класса-родителя}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FList:=TStringList.create;</span><span class="f_CodeExample" style="color: #000080;">{создаем структуры нашего класса}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TStatistic.Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FList.Free;</span><span class="f_CodeExample" style="color: #000080;">{Разрушаем структуры нашего класса}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">;</span><span class="f_CodeExample" style="color: #000080;">{в последнюю о?ередь вызываем деструктор клсса-родителя}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TStatistic.AddValue(Value: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FList.add(Value); </span><span class="f_CodeExample" style="color: #000080;">{Примерно так мы реализуем метод}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TStatistic.Clear;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FList.clear;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TStatistic.GetCount: integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result:=FList.count+</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TStatistic.Solve: real;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> i:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">result:=</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> i:=</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> FList.count-</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">result:=result+(Sqr(strtofloat(FList[i])));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">except</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{интересная конструкция. "on e:exception do" - мы "отлавливаем" ошибку как переменную "e".</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">Эта переменная имеет о?ень полезное свойство e.message - оно содержит описание ошибки. Далее</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">следует вызов события. Вна?але мы проверяем использует ли пользователь событие:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">"if Assigned(FOnError) then", если использует то вызываем его процедуру: FOnError, с параметрами:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">self - зарезервированная переменная - указатель на экземпляр нашего класса, e.message - описание</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">ошибки}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">on e:exception </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Assigned(FOnError) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> FOnError(Self, e.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">message</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Вот пример использования этого класса:</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> Unit1;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TForm1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Button1: TButton;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> OnError(Sender:TObject; Error: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Form1: TForm1;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> Unit2;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R *.DFM}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> Statistic:TStatistic;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic:=TStatistic.create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.onError:=onError;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.AddValue(</span><span class="f_CodeExample" style="color: #ff0000;">'123423'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.AddValue(</span><span class="f_CodeExample" style="color: #ff0000;">'123423'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">showmessage(floattostr(Statistic.solve));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.Clear;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.AddValue(</span><span class="f_CodeExample" style="color: #ff0000;">'123423'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.AddValue(</span><span class="f_CodeExample" style="color: #ff0000;">'12ssss3'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">showmessage(floattostr(Statistic.solve));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Statistic.Free;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.OnError(Sender: TObject; Error: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">showmessage(</span><span class="f_CodeExample" style="color: #ff0000;">'Error inside class:'</span><span class="f_CodeExample" style="color: #000000;">+Sender.ClassName+</span><span class="f_CodeExample" style="color: #ff0000;">#13#10</span><span class="f_CodeExample" style="color: #000000;">+Error);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #ff0000; font-size: 10pt; font-weight: bold;">Автор:</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Vit</span><span style="font-family: 'Times New Roman'; font-size: 10pt; font-weight: bold;">  </span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingrad</span><span style="color: #0000ff; text-decoration: underline;">https://forum.vingrad</span></p> Пособие по написанию своих компонентов 2013-08-19T13:35:03+07:00 2013-08-19T13:35:03+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/razrabotka-komponentov-i-klassov/posobie-po-napisaniyu-svoikh-komponentov.html Super User toto44@inbox.ru <p><span class="f_Heading1">Пособие</span><span class="f_Heading1">по</span><span class="f_Heading1">написанию</span><span class="f_Heading1">своих</span><span class="f_Heading1">компонентов</span><span class="f_Heading1">на</span><span class="f_Heading1"> Delphi </span><span class="f_Heading1">для</span><span class="f_Heading1">начинающих</span></p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Почему</span><span class="f_Heading1">я</span><span class="f_Heading1">сел</span><span class="f_Heading1">писать</span><span class="f_Heading1">это</span><span class="f_Heading1">пособие</span></p> <p>Во-первых, потому что когда я очень хотел написать свой первый компонент, я прочитал две книги, и у меня ничего интересного собственно не вышло. Потом я прочитал еще одну книгу (в ней хотя бы пример рабочий был), вроде разобрался. Но там был разобран такой простой компонент, что все более сложное мне приходилось делать самому, иногда методом тыка, иногда сидел разбирался и так далее. Результат - разобрался, чего и вам желаю и надеюсь помочь этим пособием.</p> <p>Все мои готовые компоненты можно найти на сайте https://delphid.dax </p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Для</span><span class="f_Heading1">чего</span><span class="f_Heading1">нужны</span><span class="f_Heading1">компоненты</span></p> <p>Дельфи имеет открытую архитектуру - это значит, что каждый программист волен усовершенствовать эту среду разработки, как он захочет. К стандартным наборам компонентов, которые поставляются вместе с Дельфи можно создать еще массу своих интересных компонентов, которые заметно упростят вам жизнь (это я вам гарантирую). А еще можно зайти на какой-нибудь крутой сайт о Дельфи и там скачать кучу крутых компонентов, и на их основе сделать какую-нибудь крутую прогу. Так же компоненты освобождают вас от написания "тысячи тонн словесной руды". Пример: вы создали компонент - кнопку, при щелчке на которую данные из Memo сохранятся во временный файл. Теперь как только вам понадобится эта функция вы просто ставите этот компонент на форму и наслаждаетесь результатом. И не надо будет каждый раз прописывать это, для ваших новых программ - просто воспользуйтесь компонентом.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">Шаг</span><span class="f_Heading1"> 1. </span><span class="f_Heading1">Придумывание</span><span class="f_Heading1">идеи</span></p> <p>Первым шагом нужно ответить себе на вопрос: "Для чего мне этот компонент и что он будет делать?". Затем необходимо в общих чертах продумать его свойства, события, на которые он будет реагировать и те функции и процедуры, которыми компонент должен обладать. Затем очень важно выбрать "предка" компонента, то есть наследником какого класса он будет являться. Тут есть два пути. Либо в качестве наследника взять уже готовый компонент (то есть модифицировать уже существующий класс), либо создать новый класс.</p> <p> </p> <p>Для создания нового класса можно выделить 4 случая:</p> <p>1. Создание Windows-элемента управления (TWinControl)</p> <p>2. Создание графического элемента управления (TGraphicControl)</p> <p>3. Создание нового класса или элемента управления (TCustomControl)</p> <p>4. Создание невизуального компонента (не видимого) (TComponent)</p> <p> </p> <p>Теперь попробую объяснить что же такое визуальные и невизуальные компоненты. Визуальные компоненты видны во время работы приложения, с ними напрямую может взаимодействовать пользователь, например кнопка Button - является визуальным компонентом.</p> <p>Невизуальные компоненты видны только во время разработки приложения (Design-Time), а во время работы приложения (Run-Time) их не видно, но они могут выполнять какую-нибудь работу. Наиболее часто используемый невизуальный компонент - это Timer.</p> <p>Итак, что бы приступить от слов к делу, попробуем сделать какой-нибудь супер простой компонент (только в целях ознакомления с техникой создания компонентов), а потом будем его усложнять.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">Шаг</span><span class="f_Heading1"> 2. </span><span class="f_Heading1">Создание</span><span class="f_Heading1">пустого</span><span class="f_Heading1">модуля</span><span class="f_Heading1">компонента</span></p> <p>Рассматривать этот шаг я буду исходя из устройства Дельфи 3, в других версиях этот процесс не сильно отличается. Давайте попробуем создать кнопку, у которой будет доступна информация о количестве кликов по ней.</p> <p> </p> <p>Чтобы приступить к непосредственному написанию компонента, вам необходимо сделать следующее:</p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>Закройте проекты, которые вы разрабатывали (формы и модули)</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>В основном меню выберите Component -&gt; New Component...</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>Перед вами откроется диалоговое окно с названием "New Component"</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>В поле Ancestor Type (тип предка) выберите класс компонента, который вы хотите модифицировать. В нашем случае вам надо выбрать класс TButton</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>В поле Class Name введите имя класса, который вы хотите получить. Имя обязательно должно начинаться с буквы "T". Мы напишем туда, например, TCountBtn</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>В поле Palette Page укажите имя закладки на которой этот компонент появиться после установки. Введем туда MyComponents (теперь у вас в Делфьи будет своя закладка с компонентами!).</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>Поле Unit File Name заполняется автоматически, в зависимости от выбранного имени компонента. Это путь куда будет сохранен ваш модуль.</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>В поле Search Path ничего изменять не нужно.</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>Теперь нажмите на кнопку Create Unit и получите следующее:</td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"> </p> <div style="text-align: left; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> CountBtn;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TCountBtn = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'MyComponents'</span><span class="f_CodeExample" style="color: #000000;">, [TCountBtn]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"> </p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Шаг</span><span class="f_Heading1"> 3. </span><span class="f_Heading1">Начинаем</span><span class="f_Heading1">разбираться</span><span class="f_Heading1">во</span><span class="f_Heading1">всех</span><span class="f_Heading1">директивах</span></p> <p>Что же здесь написано? да собственно пока ничего интересного. Здесь объявлен новый класс TCountBtn и процедура регистрации вашего компонента в палитре компонентов.</p> <p>Директива Private Здесь вы будете писать все скрытые поля которые вам понадобятся для создания компонента. Так же в этой директиве описываются процедуры и функции, необходимые для работы своего компонента, эти процедуры и функции пользователю не доступны. Для нашего компонент мы напишем туда следующее (запись должна состоять из буквы "F" имени поля: тип этого поля):</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:integer;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Буква "F" должна присутсвовать обязательно. Здесь мы создали скрытое поле Count, в котором и будет храниться число кликов по кнопке.</p> <p>Директива Protected. Обычно я здесь пишу различные обработчики событий мыши и клавиатуры. Мы напишем здесь следующую строку:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Click; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Это указывает на то, что мы будем обрабатывать щелчок мыши по компоненту. Слово "override" указывает на то, что мы перекроем стандартное событие OnClick для компонента предка.</p> <p>В директиве Public описываются те процедуры и функции компонента, которые будут доступны пользователю. (Например, в процессе написания кода вы пишите имя компонента, ставите точку и перед вами список доступных функций, объявленных в диретиве Public). Для нашего компонента, чтобы показать принцип использования этой директивы создадим функцию - ShowCount, которая покажет сообщение, уведомляя пользователя сколько раз он уже нажал на кнопку. Для этого в директиве Public напишем такой код:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ShowCount;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Осталась последняя директива Published. В ней также используется объявления доступных пользователю, свойств и методов компонента. Для того, чтобы наш компонент появился на форме необходимо описать метод создания компонента (конструктор), можно прописать и деструктор, но это не обязательно. Следует обратить внимание на то, что если вы хотите, чтобы какие-то свойства вашего компонента появились в Инспекторе Объектов (Object Inspector) вам необходимо описать эти свойства в директиве Published. Это делается так: property Имя_свойства (но помните здесь букву "F" уже не нужно писать), затем ставиться двоеточие ":" тип свойства, read процедура для чтения значения, write функция для записи значения;. Но похоже это все сильно запутано. Посмотрите, что нужно написать для нашего компонента и все поймете:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(aowner:Tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #000080;">//Конструктор</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Count:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FCount; </span><span class="f_CodeExample" style="color: #000080;">//Свойство Count </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Итак все объявления сделаны и мы можем приступить к написанию непосредственно всех объявленных процедур.</p> <p> </p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Шаг</span><span class="f_Heading1"> 4. </span><span class="f_Heading1">Пишем</span><span class="f_Heading1">процедуры</span><span class="f_Heading1">и</span><span class="f_Heading1">функции</span><span class="f_Heading1">.</span></p> <p>Начнем с написания конструктора. Это делается примерно так:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.Create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> create(Aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"> </p> <p>Здесь в принципе понимать ничего не надо. Во всех своих компонентах я писал именно это (только класс компонента менял и все). Также сюда можно записывать любые действия, которые вы хотите сделать в самом начале работы компонента, то есть в момент установки компонента на форму. Например можно установить начальное значение нашего свойства Count. Но мы этого делать не будем.</p> <p> </p> <p>Теперь мы напишем процедуру обработки щелчка мышкой по кнопке:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Tcountbtn.Click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:=FCount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"> </p> <p>"Inherited click" означает, что мы повторяем стандартные методы обработки щелчка мышью (зачем напрягаться и делать лишнюю работу:)).</p> <p>У нас осталась последняя процедура ShowCount. Она может выглядеть примерно так:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.ShowCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Showmessage(</span><span class="f_CodeExample" style="color: #ff0000;">'По кнопке '</span><span class="f_CodeExample" style="color: #000000;">+ caption+</span><span class="f_CodeExample" style="color: #ff0000;">' вы сделали: '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(FCount)+</span><span class="f_CodeExample" style="color: #ff0000;">' клик(а/ов)'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Здесь выводится сообщение в котором показывается количество кликов по кнопке (к тому же выводится имя этой кнопки, ну это я добавил только с эстетической целью).</p> <p>И если вы все поняли и сделали правильно, то у вас должно получится следующее:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> CountBtn;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls, ExtCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TCountBtn = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Click;</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ShowCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Count:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(aowner:Tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TCountBtn]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.Create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> create(Aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Tcountbtn.Click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:=FCount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.ShowCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Showmessage(</span><span class="f_CodeExample" style="color: #ff0000;">'По кнопке '</span><span class="f_CodeExample" style="color: #000000;">+ caption+</span><span class="f_CodeExample" style="color: #ff0000;">' вы сделали: '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(FCount)+</span><span class="f_CodeExample" style="color: #ff0000;">' клик(а/ов)'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">. </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Скорее сохраняйтесь, дабы не потерять случайным образом байты набранного кода:)).</p> <p style="text-align: center; margin: 7px 0px;"> </p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Шаг</span><span class="f_Heading1"> 5. </span><span class="f_Heading1">Устанавливаем</span><span class="f_Heading1">компонент</span></p> <p>Если вы сумели написать и понять, все то что здесь предложено, то установка компонента не должна вызвать у вас никаких проблем. Все здесь делается очень просто. В главном меню выберите пункт Component -&gt; Install Component. перед вами открылось диалоговое окно Install Component. В нем вы увидите две закладки: Into exsisting Package и Into new Package. Вам предоставляется выбор установить ваш компонент в уже существующий пакет или в новый пакет соответственно. Мы выберем в уже существующий пакет.</p> <p>В поле Unit File Name напишите имя вашего сохранненого модуля (естественно необходимо еще и указать путь к нему), а лучше воспользуйтесь кнопкой Browse и выберите ваш файл в открывшемся окне.</p> <p>В Search Path ничего изменять не нужно, Делфьи сама за вас все туда добавит.</p> <p>В поле Package File Name выберите имя пакета, в который будет установлен ваш компонент. Мы согласимся с предложенным по умолчанию пакетом.</p> <p>Теперь нажимаем кнопочку Ok. И тут появиться предупреждение Package dclusr30.dpk will be rebuilt. Continue? Дельфи спрашивает: "Пакет такой-то будет изменен. Продолжить?". Конечно же надо ответить "Да". И если вы все сделали правильно, то появиться сообщение, что ваш компонент установлен. Что ж можно кричать Ура! Это ваш первый компонент.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">Создание</span><span class="f_Heading1">свойств</span><span class="f_Heading1">своего</span><span class="f_Heading1">типа</span></p> <p>Теперь мы попробуем создать свойство нестандартного типа. Рассмотрим это на примере метки - TLabel. У этого компонента есть такое свойство: Alignment. Оно может принимать следующие значения: taLeftJustify, taCenter, taRightJustify. Приступаем к созданию свойства. Ничего интересного мне придумать не удалось, но тем не менее я вам покажу это на примере того свойства, которое я придумал. Оно очень простое и поможет вам разобраться. Свойство будет называться ShowType (тип TShowTp), в нашем компоненте оно будет отвечать за отображение свойства Count. Если пользователь установит свойство ShowType в Normal, то кнопка будет работать, как и работала. А если пользователь присвоит этому свойтсву значение CountToCaption, то количество кликов, будет отображаться на самой кнопке.</p> <p> </p> <p>Для начале нам необходимо объявить новый тип. Описание типа нужно добавить после слова Type. Вот так это выглядело вначале:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TCountBtn = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton) </span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"> </p> <p style="margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Вот</span><span style="font-family: 'Times New Roman'; color: #000000;">так</span><span style="font-family: 'Times New Roman'; color: #000000;">это</span><span style="font-family: 'Times New Roman'; color: #000000;">должно</span><span style="font-family: 'Times New Roman'; color: #000000;">выглядеть</span><span style="font-family: 'Times New Roman'; color: #000000;">: </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TShowTp = (Normal, CountToCaption); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TCountBtn = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton) </span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"> </p> <p>Здесь мы объявили новый тип TShowTp, который может принимать только два значения. Все значения, которые вы хотите добавить перечисляются через запятую. Теперь нам понадобиться создать поле этого типа. Это мы уже умеем и делать и поэтому не должно вызвать никаких сложностей. В директиву Private напишите:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FShowType:TShowTp; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Мы создали поле ShowType, типа TShowTp.</p> <p>Конечно же необходимо добавить это свойство в инспектор объектов:</p> <p>property ShowType: TshowTp read FshowType write FShowType;</p> <p>Ну и наконец, чтобы наш компонент реагировал на изменение этого свойства пользователем надо слегка изменить обработчик события OnClick. После небольшой модификации он может иметь примерно такой вид:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Tcountbtn.Click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:=Fcount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ShowType = Normal </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption:=Caption;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ShowType = CountToCaption </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption:=</span><span class="f_CodeExample" style="color: #ff0000;">'Count= '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(count);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Объясню что произошло. Вначале мы увеличиваем счетчик на единицу. Затем проверяем какое значение имеет свойство ShowType. Если Normal, то ничего не делаем, а если CountToCaption, то в надпись на кнопке выводим количество кликов. Не так уж и сложно как это могло показаться с первого раза.</p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Имплантируем</span><span class="f_Heading1">таймер</span><span class="f_Heading1">в</span><span class="f_Heading1">компонент</span></p> <p class="p_Heading1"> </p> <p>Очень часто бывает, что вам необходимо вставить в компонент, какой-нибудь другой компонент, например, таймер. Как обычно будем рассматривать этот процесс на конкретном примере. Сделаем так, что через каждые 10 секунд значение счетчика кликов будет удваиваться. Для этого мы встроим таймер в нашу кнопку. Нам понадобиться сделать несколько несложных шагов.</p> <p> </p> <p>После раздела uses, где описаны добавленные в программу модули, объявите переменную типа TTimer. Назовем ее Timer. Приведу небольшой участок кода:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> CountBtn;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls, ExtCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> Timer: TTimer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Дальше в директиву Protected необходимо добавить обработчик события OnTimer для нашего таймера. Это делается так:</p> <p>procedure OnTimer(Sender: TObject);</p> <p>Поскольку наш таймер это не переменная, а компонент, его тоже надо создать, для этого в конструктор нашей кнопки напишем:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.Create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> create(Aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer:=TTimer.Create(self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.Enabled:=true;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.OnTimer:=OnTimer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.Interval:=</span><span class="f_CodeExample" style="color: #000080;">10000</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Здесь создается экземпляр нашего таймера и его свойству Iterval (измеряется в миллисекундах) присваивается значение 10000 (то есть 10 секунд если по простому).</p> <p>Собственно осталось написать саму процедуру OnTimer. Я сделал это так:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.OnTimer(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:=FCount*</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Вот примерно то, что у вас должно получиться в конце: </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> CountBtn;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls, ExtCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> Timer: TTimer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TShowTp = (Normal, CountToCaption);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TCountBtn = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton)</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FShowType:TShowTp;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> OnTimer(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Click;</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ShowCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Count:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(aowner:Tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> ShowType: TshowTp </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FshowType </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FShowType;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TCountBtn]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.Create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> create(Aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer:=TTimer.Create(self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.Enabled:=false;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.OnTimer:=OnTimer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.Interval:=</span><span class="f_CodeExample" style="color: #000080;">1000</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Tcountbtn.Click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:=Fcount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.Enabled:=true;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ShowType = Normal </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption:=Caption;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ShowType = CountToCaption </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption:=</span><span class="f_CodeExample" style="color: #ff0000;">'Count= '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(count);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.ShowCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Showmessage(</span><span class="f_CodeExample" style="color: #ff0000;">'По кнопке '</span><span class="f_CodeExample" style="color: #000000;">+ caption+</span><span class="f_CodeExample" style="color: #ff0000;">' вы сделали: '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(FCount)+</span><span class="f_CodeExample" style="color: #ff0000;">' клик(а/ов)'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.OnTimer(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:=FCount*</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">. </span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p>Если у вас что-то не сработало, то в начале проверьте все ли у вас написано правильно. Затем проверьте может у вас не хватает какого-нибудь модуля в разделе Uses.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">Переустановка</span><span class="f_Heading1">компонента</span></p> <p>Очень часто бывает необходимо переустановить ваш компонент. Если вы попробуете сделать это путем выбора Component-&gt;Install Component, то Дельфи вас честно предупредит о том, что пакет уже содержит модуль с таким именем. Перед вами открывается окно с содержимым пакета. В нем вы должны найти имя вашего компонента и удалить его (либо нажать кнопочку Remove). Теперь в пакете уже нет вашего компонента. Затем проделайте стандартную процедуру по установке компонента.</p> <p> </p> <p><span class="f_Heading1">Редактирование</span><span class="f_Heading1">значения</span><span class="f_Heading1">, </span><span class="f_Heading1">которое</span><span class="f_Heading1">ввел</span><span class="f_Heading1">пользователь</span><span class="f_Heading1">, </span><span class="f_Heading1">изменяя</span><span class="f_Heading1">какое</span><span class="f_Heading1">-</span><span class="f_Heading1">нибудь</span><span class="f_Heading1">свойство</span><span class="f_Heading1">.</span></p> <p>Простой пример. Допустим у нас есть компонент (основанный на Tedit), у него есть два свойства: FirstNumber и SecondNumber. И у него есть процедура Division, в которой первое число делится на второе и результат присаивается свойству текст нашего компонента. Вот код этого компонента:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> DivEdit;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDivEdit = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(Tedit)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FFirstNumber:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FSecondNumber:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FResult:Single; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">//в компонентах нельзя использовать Real!!!</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Division;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> create(aowner:Tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> FirstNumber:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FFirstNumber </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FFirstNumber;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> SecondNumber:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FSecondNumber </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FSecondNumber;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Result:Single </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> Fresult </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FResult;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Constructor</span><span class="f_CodeExample" style="color: #000000;"> TDivEdit.create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> create(aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FFirtsNumber:=</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FSecondNumber:=</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDivEdit.Division;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FResult:=FFirstNumber/FSecondNumber;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">text:=floattostr(FResult);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TDivEdit]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p>Хочется обратить ваше внимание на то, что в компонентах нельзя использовать переменные и поля типа Real, вместо него нужно брать переменные типов Single, Double, Extended.</p> <p>Здесь все просто. Но вот если пользователю вздумается поделить на ноль (ну вдруг он математики не знает), то компонент выдаст ошибку DivisionByZero, а кому они нужны. Обойти эту проблему можно так: в код компонента добавить процедуру, которая проанализирует данные введенные пользователь и если все будет в порядке, то она присвоит значения соответствующим свойтсвам. В директиве Private объявите такую процедуру:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetSecondNumber(value:integer);</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Обычно такие процедуры начинаются с приставки Set, затем идет имя свойства, и в конце тип переменной. Теперь в директиве Published надо сделать небольшие изменения:</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> SecondNumber:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FSecondNumber </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetSecondNumber;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>А теперь напишем саму процедуру:</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDivEdit.SetSecondNumber(value:Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> value&lt;&gt;FSecondNumber </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">//надо проверить совпадают ли исходное и вводимое значения</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FSecondNumber:=value; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">//если нет, то изменить значение</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> FSecondNumber=</span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FSecondNumber:=</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p>Теперь сколько бы пользователь не вводил нулей значение SecondNumber будет единицей. Такие процедуры проверки рекомендуется использовать везде, где только допустимо появление исключительной ситуации.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">Использование</span><span class="f_Heading1">другого</span><span class="f_Heading1">компонента</span><span class="f_Heading1">в</span><span class="f_Heading1">вашем</span></p> <p class="p_Heading1"> </p> <p>Попробуем создать такой компонент. Это будет обычная метка (Label), у которой будет две процедуры: ChangeBackColor и ChangeFontColor, которые соответственно будут менять цвет фона метки и цвет текста. Для этого нам понадобиться ColorDialog, который будет создаваться вместе с компонентом, а потом с помощью процедур он будет активироваться. Назовем компонент ColorLabel. Вначале добавим в uses два модуля: Dialogs, StdCtrls (в них находятся описания классаов диалога и метки). Теперь нам надо объявить переменную типа TColorDialog. Объявление идет сразу после секции Uses.</p> <p> </p> <p>Примерно это выглядит так:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> ColorDialog:TColorDialog;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p>Теперь в конструкторе (Create), нам надо создать этот компонент:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TColorLabel.create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ColorDialog:=TColorDialog.Create(self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p>Теперь надо объявить процедуры ChangeBackColor, ChangeFontColor. Чтобы они были доступны пользователю их надо поместить в директиву Public:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ChangeBackColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ChangeFontColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p>Осталось написать сами процедуры. Все очень просто: открываете диалог методом Execute, а затем присваиваете полученное значение цвета метке. У меня эти процедуры имеют такой вид:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TColorLabel.ChangeBackColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ColorDialog.Execute </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">color:=ColorDialog.color;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TColorLabel.ChangeFontColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ColorDialog.Execute </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">font.color:=ColorDialog.color;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Если у вас вдруг что-то не получилось, то взгляните на мой код целиком:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> ColorLabel;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> ColorDialog:TColorDialog;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TColorLabel = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(Tlabel)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ChangeBackColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ChangeFontColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> create(aowner:tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TColorLabel.create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ColorDialog:=TColorDialog.Create(self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TColorLabel.ChangeBackColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ColorDialog.Execute </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">color:=ColorDialog.color;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TColorLabel.ChangeFontColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ColorDialog.Execute </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">font.color:=ColorDialog.color;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TColorLabel]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Доступ</span><span class="f_Heading1">к</span><span class="f_Heading1">свойствам</span><span class="f_Heading1">другого</span><span class="f_Heading1">компонента</span></p> <p>Сейчас нам предстоит более сложная задача. Мы будем создавать компонент, вместе с которым будет создаваться какой-нибудь визуальный компонент. Например создадим кнопку, которая будет сопровождаться поясняющей надписью сверху. За основу возмем тип TButton. Нам надо будет создать еще и Label. Здесь существует одна проблемка: при перемещении компонента по форме, метка должна двигаться вместе с кнопкой, поэтому нам придется обрабатывать сообщение WmMove. Итак, объявляем переменную Label (в данном примере она объявлена в директиве Private, что тоже допустимо):</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Forms, Dialogs, StdCtrls,buttons;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TLabelButton = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel : TLabel ;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p>Теперь я приведу весь код этого компонента и походу буду вставлять необходимые пояснения:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> LabelBtn;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Forms, Dialogs, StdCtrls,buttons;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TLabelButton = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel : TLabel ; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{создаем поле типа Tlabel}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> WMMove( </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> Msg : TWMMove ) ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">message</span><span class="f_CodeExample" style="color: #000000;"> WM_MOVE ;</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{процедура для обработки сообщения Wm_move, чтобы метка перемещалась вместе с кнопкой}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetParent( Value : TWinControl ) ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;"> ;</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{необходимо воспользоваться и этой процедурой, так как нужно убедиться, имеют ли кнопка и метка общего предка}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetLabelCaption : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;"> ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;"> ; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Вот пример доступа из компонента к свойствам другого. Эти две процедуры для изменения текста метки}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetLabelCaption( </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> Value : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;"> ) ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create( AOwner : TComponent ) ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> LabelCaption : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetLabelCaption </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SetLabelCaption ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TLabelButton.Create( AOwner : TComponent ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create( AOwner ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ создаем TLabel }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel := TLabel.Create( </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;"> ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel.Caption := </span><span class="f_CodeExample" style="color: #ff0000;">'Описание:'</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TLabelButton.SetParent( Value : TWinControl ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{надо убедиться, что у них предок один, чтоб проблем потом не было}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ( Owner = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;"> ) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">or</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">not</span><span class="f_CodeExample" style="color: #000000;"> ( csDestroying </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">in</span><span class="f_CodeExample" style="color: #000000;"> Owner.ComponentState ) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel.Parent := Value ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> SetParent( Value ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TLabelButton.Destroy ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ( FLabel &lt;&gt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;"> ) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">and</span><span class="f_CodeExample" style="color: #000000;"> ( FLabel.Parent = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;"> ) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel.Free ;</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Уничтожаем метку, т.к. она нам больше не нужна}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Destroy ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TLabelButton.GetLabelCaption : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FLabel.Caption ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TLabelButton.SetLabelCaption( </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> Value : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;"> ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel.Caption := Value ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TLabelButton.WMMove( </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> Msg : TWMMove ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> FLabel &lt;&gt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> Flabel </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SetBounds( Msg.XPos, Msg.YPos - Height, Width,Height ) ; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{изменяем левое и верхнее положение метки исходя из полученных координат}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TLabelButton]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">initialization</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterClass( TLabel ) ; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Это делается для обеспечения поточности, но об этом не думайте, этим редко придется пользоваться}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Вы можете пользоваться этим компонентом сколько угодно, но распространять его можно только указывая авторство}</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Можно сделать доступ к любым свойствам метки, например, к шрифту, цвету и так далее, используя необходимые процедуры.</p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Использование</span><span class="f_Heading1">в</span><span class="f_Heading1">качестве</span><span class="f_Heading1">предка</span><span class="f_Heading1">класс</span><span class="f_Heading1"> TWinControl</span></p> <p>Предыдущий пример был очень сложным, к тому же пришлось обрабатывать системные сообщения. Есть другое решение этой проблемы, более простое для понимания и для реализации: использовать в качестве контейнера класс TWinControl и в этот контейнер помещать другие компоненты. Теперь попробуем совместить Edit и Label. Давайте вместе создадим такой компонент. В качестве предка нужно выбрать класс TWinControl, а в качестве типа вашего компонента выберите TlabelEdit. Будем разбирать код по кусочкам.</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> LabelEdit;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Forms, Dialogs, stdctrls; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TLabelEdit = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TWinControl) </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FEdit: TEdit; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel: TLabel; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//Здесь объявляются поля для метки и для Edita. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetLabelCaption: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetLabelCaption(LabelCaption: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetEditText: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetEditText(EditText: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//Здесь объявлены функции для работы со свойствами Caption у метки и Text у Edita.</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Public declarations }</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner: TComponent); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> LabelCaption: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetLabelCaption </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetLabelCaption; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> EditText: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetEditText </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetEditText; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TLabelEdit.Create(AOwner: TComponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FEdit := TEdit.Create(self);</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{создаем поле редактирования Edit}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel := TLabel.Create(self);</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{создаем Label}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> FLabel </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Width := FEdit.Width; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">visible := true; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Parent := self; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption := </span><span class="f_CodeExample" style="color: #ff0000;">'Описание:'</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> FEdit </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Top := FLabel.Height+</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Parent := self; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Visible := true; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Top := </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Left := </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Width := FEdit.Width; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Height := FEdit.Height+FLabel.Height;</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{определяются размеры и положение компонентов}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Visible := true; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TLabelEdit.GetLabelCaption: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FLabel.Caption; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TLabelEdit.SetLabelCaption(LabelCaption: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel.Caption := LabelCaption; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TLabelEdit.GetEditText: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FEdit.Text; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TLabelEdit.SetEditText(EditText: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FEdit.Text := EditText; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TLabelEdit]); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">. </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Попробуйте установить этот компонент. Когда вы будете размещать его на форме, то будет виден "контейнер", на котором располагаются Edit и Label. Использование в качестве предка компонента класса TWinControl, очень удобно если вы хотите объединить несколько визуальных компонентов.</p> <p> </p> <p class="p_Heading1"> </p> <p class="p_Heading1"><span class="f_Heading1">Обработка</span><span class="f_Heading1">событий</span><span class="f_Heading1"> OnMouseDown, OnMouseMove </span><span class="f_Heading1">и</span><span class="f_Heading1"> OnMouseUp </span></p> <p>Часто возникает необходимость обработки событий нажатия и отпускания кнопки в вашем компоненте. Сейчас мы это и рассмотрим. Только ради примера сделаем компонент, который будет считать количество нажатий и отпусканий кнопки в его области, допустим это будет панель (Tpanel). Для этого в директиве Private надо объявить следующие процедуры и поля:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FClickCount:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FUpCount:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> MouseDown(Button:TMouseButton; Shift: TShiftState; X,Y: Integer); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> MouseMove(Shift: TShiftState; X, Y: Integer); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> MouseUp(Button:TMouseButton; Shift:TShiftState; X, Y: Integer); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p>А в директиве Published надо написать:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> create(aowner:tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> ClickCount:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FclickCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FClickCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> UpCount:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FUpCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FUpCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OnMouseDown;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OnMouseMove;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OnMouseUp;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Ну и теперь осталось описать нужные процедуры:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.MouseDown(Button:TMouseButton; Shift: TShiftState; X,Y: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FClickCount:=FClickCount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.MouseMove(Shift: TShiftState; X, Y: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">caption:=inttostr(x)+</span><span class="f_CodeExample" style="color: #ff0000;">' '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(y);</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{для демонстрации работы этой процедуры. Надпись на панели будет отражать координаты курсора мыши над этой панелью}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.MouseUp(Button:TMouseButton; Shift:TShiftState; X, Y: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FUpCount:=FUpCount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Таким образом весь код компонента был таким:</p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> Mpanel;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ExtCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMpanel = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TPanel)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FClickCount:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FUpCount:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> MouseDown(Button:TMouseButton; Shift: TShiftState; X,Y: Integer); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> MouseMove(Shift: TShiftState; X, Y: Integer); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> MouseUp(Button:TMouseButton; Shift:TShiftState; X, Y: Integer); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> create(aowner:tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> ClickCount:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FclickCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FClickCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> UpCount:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FUpCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FUpCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OnMouseDown;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OnMouseMove;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OnMouseUp;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> create(aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.MouseDown(Button:TMouseButton; Shift: TShiftState; X,Y: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FClickCount:=FClickCount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.MouseMove(Shift: TShiftState; X, Y: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">caption:=inttostr(x)+</span><span class="f_CodeExample" style="color: #ff0000;">' '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(y);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.MouseUp(Button:TMouseButton; Shift:TShiftState; X, Y: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FUpCount:=FUpCount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TMpanel]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Создание</span><span class="f_Heading1">и</span><span class="f_Heading1">использование</span><span class="f_Heading1">своей</span><span class="f_Heading1">иконки</span><span class="f_Heading1">для</span><span class="f_Heading1">компонента</span></p> <p>Когда вы создали свой компонент и установили его, та на палитре компонентов, его иконка будет такой же как и у компонента, который вы выбрали в качестве предка. Конечно же вам хотелось бы видеть свой компонент со своей иконкой. Для этого необходимо создать файл ресурсов компонента. Сейчас я расскажу вам как это делается.</p> <p>Откройте Image Editor (Tools-&gt;Image Editor) и выберите File-&gt;New-&gt;Component Resourse File. Перед вами появится небольшое окно с надписью Untitled.dcr в нем будет только одно слово: Contents. Нажмите на него правой кнопкой и в появившемся меню выберите New-&gt;Bitmap. Откроется диалоговое окно для настройки параметров изображения. Они должны быть такими: Размер 32x32, цветовой режим VGA (16 colors). Теперь нажмите ok. Теперь надо нажать правой кнопкой на появившейся надписи Bitmap1 и выбрать пункт Rename. Название картинки должно совпадать с названием класса компонента, для которого вы делаете эту иконку (например, TMPanel). Нажмите два раза на Bitmap1 и перед вами появится окно для рисования. Нарисуйте, что вам надо и перейдите на окно с надписью Untitled.dcr и в меню File выберите Save. Имя файла ресурса компонента должно совпадать с именем модуля компонента (без расширения конечно же, например, Mpanel). Файл ресурса готов. Теперь установите ваш компонент заново и в палитре компонентов ваш компонент будет уже с новой иконкой.</p> <p style="text-align: center; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">Источник</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">: </span><span style="font-family: 'Times New Roman'; color: #000080; font-size: 10pt;">https://delphid.dax</span></p> <p><span class="f_Heading1">Пособие</span><span class="f_Heading1">по</span><span class="f_Heading1">написанию</span><span class="f_Heading1">своих</span><span class="f_Heading1">компонентов</span><span class="f_Heading1">на</span><span class="f_Heading1"> Delphi </span><span class="f_Heading1">для</span><span class="f_Heading1">начинающих</span></p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Почему</span><span class="f_Heading1">я</span><span class="f_Heading1">сел</span><span class="f_Heading1">писать</span><span class="f_Heading1">это</span><span class="f_Heading1">пособие</span></p> <p>Во-первых, потому что когда я очень хотел написать свой первый компонент, я прочитал две книги, и у меня ничего интересного собственно не вышло. Потом я прочитал еще одну книгу (в ней хотя бы пример рабочий был), вроде разобрался. Но там был разобран такой простой компонент, что все более сложное мне приходилось делать самому, иногда методом тыка, иногда сидел разбирался и так далее. Результат - разобрался, чего и вам желаю и надеюсь помочь этим пособием.</p> <p>Все мои готовые компоненты можно найти на сайте https://delphid.dax </p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Для</span><span class="f_Heading1">чего</span><span class="f_Heading1">нужны</span><span class="f_Heading1">компоненты</span></p> <p>Дельфи имеет открытую архитектуру - это значит, что каждый программист волен усовершенствовать эту среду разработки, как он захочет. К стандартным наборам компонентов, которые поставляются вместе с Дельфи можно создать еще массу своих интересных компонентов, которые заметно упростят вам жизнь (это я вам гарантирую). А еще можно зайти на какой-нибудь крутой сайт о Дельфи и там скачать кучу крутых компонентов, и на их основе сделать какую-нибудь крутую прогу. Так же компоненты освобождают вас от написания "тысячи тонн словесной руды". Пример: вы создали компонент - кнопку, при щелчке на которую данные из Memo сохранятся во временный файл. Теперь как только вам понадобится эта функция вы просто ставите этот компонент на форму и наслаждаетесь результатом. И не надо будет каждый раз прописывать это, для ваших новых программ - просто воспользуйтесь компонентом.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">Шаг</span><span class="f_Heading1"> 1. </span><span class="f_Heading1">Придумывание</span><span class="f_Heading1">идеи</span></p> <p>Первым шагом нужно ответить себе на вопрос: "Для чего мне этот компонент и что он будет делать?". Затем необходимо в общих чертах продумать его свойства, события, на которые он будет реагировать и те функции и процедуры, которыми компонент должен обладать. Затем очень важно выбрать "предка" компонента, то есть наследником какого класса он будет являться. Тут есть два пути. Либо в качестве наследника взять уже готовый компонент (то есть модифицировать уже существующий класс), либо создать новый класс.</p> <p> </p> <p>Для создания нового класса можно выделить 4 случая:</p> <p>1. Создание Windows-элемента управления (TWinControl)</p> <p>2. Создание графического элемента управления (TGraphicControl)</p> <p>3. Создание нового класса или элемента управления (TCustomControl)</p> <p>4. Создание невизуального компонента (не видимого) (TComponent)</p> <p> </p> <p>Теперь попробую объяснить что же такое визуальные и невизуальные компоненты. Визуальные компоненты видны во время работы приложения, с ними напрямую может взаимодействовать пользователь, например кнопка Button - является визуальным компонентом.</p> <p>Невизуальные компоненты видны только во время разработки приложения (Design-Time), а во время работы приложения (Run-Time) их не видно, но они могут выполнять какую-нибудь работу. Наиболее часто используемый невизуальный компонент - это Timer.</p> <p>Итак, что бы приступить от слов к делу, попробуем сделать какой-нибудь супер простой компонент (только в целях ознакомления с техникой создания компонентов), а потом будем его усложнять.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">Шаг</span><span class="f_Heading1"> 2. </span><span class="f_Heading1">Создание</span><span class="f_Heading1">пустого</span><span class="f_Heading1">модуля</span><span class="f_Heading1">компонента</span></p> <p>Рассматривать этот шаг я буду исходя из устройства Дельфи 3, в других версиях этот процесс не сильно отличается. Давайте попробуем создать кнопку, у которой будет доступна информация о количестве кликов по ней.</p> <p> </p> <p>Чтобы приступить к непосредственному написанию компонента, вам необходимо сделать следующее:</p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>Закройте проекты, которые вы разрабатывали (формы и модули)</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>В основном меню выберите Component -&gt; New Component...</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>Перед вами откроется диалоговое окно с названием "New Component"</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>В поле Ancestor Type (тип предка) выберите класс компонента, который вы хотите модифицировать. В нашем случае вам надо выбрать класс TButton</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>В поле Class Name введите имя класса, который вы хотите получить. Имя обязательно должно начинаться с буквы "T". Мы напишем туда, например, TCountBtn</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>В поле Palette Page укажите имя закладки на которой этот компонент появиться после установки. Введем туда MyComponents (теперь у вас в Делфьи будет своя закладка с компонентами!).</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>Поле Unit File Name заполняется автоматически, в зависимости от выбранного имени компонента. Это путь куда будет сохранен ваш модуль.</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>В поле Search Path ничего изменять не нужно.</td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="13"><span style="font-style: normal; font-family: 'Symbol'; color: #000000; font-size: 12pt; text-decoration: none;">·</span></td> <td>Теперь нажмите на кнопку Create Unit и получите следующее:</td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"> </p> <div style="text-align: left; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> CountBtn;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TCountBtn = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'MyComponents'</span><span class="f_CodeExample" style="color: #000000;">, [TCountBtn]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"> </p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Шаг</span><span class="f_Heading1"> 3. </span><span class="f_Heading1">Начинаем</span><span class="f_Heading1">разбираться</span><span class="f_Heading1">во</span><span class="f_Heading1">всех</span><span class="f_Heading1">директивах</span></p> <p>Что же здесь написано? да собственно пока ничего интересного. Здесь объявлен новый класс TCountBtn и процедура регистрации вашего компонента в палитре компонентов.</p> <p>Директива Private Здесь вы будете писать все скрытые поля которые вам понадобятся для создания компонента. Так же в этой директиве описываются процедуры и функции, необходимые для работы своего компонента, эти процедуры и функции пользователю не доступны. Для нашего компонент мы напишем туда следующее (запись должна состоять из буквы "F" имени поля: тип этого поля):</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:integer;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Буква "F" должна присутсвовать обязательно. Здесь мы создали скрытое поле Count, в котором и будет храниться число кликов по кнопке.</p> <p>Директива Protected. Обычно я здесь пишу различные обработчики событий мыши и клавиатуры. Мы напишем здесь следующую строку:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Click; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Это указывает на то, что мы будем обрабатывать щелчок мыши по компоненту. Слово "override" указывает на то, что мы перекроем стандартное событие OnClick для компонента предка.</p> <p>В директиве Public описываются те процедуры и функции компонента, которые будут доступны пользователю. (Например, в процессе написания кода вы пишите имя компонента, ставите точку и перед вами список доступных функций, объявленных в диретиве Public). Для нашего компонента, чтобы показать принцип использования этой директивы создадим функцию - ShowCount, которая покажет сообщение, уведомляя пользователя сколько раз он уже нажал на кнопку. Для этого в директиве Public напишем такой код:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ShowCount;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Осталась последняя директива Published. В ней также используется объявления доступных пользователю, свойств и методов компонента. Для того, чтобы наш компонент появился на форме необходимо описать метод создания компонента (конструктор), можно прописать и деструктор, но это не обязательно. Следует обратить внимание на то, что если вы хотите, чтобы какие-то свойства вашего компонента появились в Инспекторе Объектов (Object Inspector) вам необходимо описать эти свойства в директиве Published. Это делается так: property Имя_свойства (но помните здесь букву "F" уже не нужно писать), затем ставиться двоеточие ":" тип свойства, read процедура для чтения значения, write функция для записи значения;. Но похоже это все сильно запутано. Посмотрите, что нужно написать для нашего компонента и все поймете:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(aowner:Tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #000080;">//Конструктор</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Count:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FCount; </span><span class="f_CodeExample" style="color: #000080;">//Свойство Count </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Итак все объявления сделаны и мы можем приступить к написанию непосредственно всех объявленных процедур.</p> <p> </p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Шаг</span><span class="f_Heading1"> 4. </span><span class="f_Heading1">Пишем</span><span class="f_Heading1">процедуры</span><span class="f_Heading1">и</span><span class="f_Heading1">функции</span><span class="f_Heading1">.</span></p> <p>Начнем с написания конструктора. Это делается примерно так:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.Create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> create(Aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"> </p> <p>Здесь в принципе понимать ничего не надо. Во всех своих компонентах я писал именно это (только класс компонента менял и все). Также сюда можно записывать любые действия, которые вы хотите сделать в самом начале работы компонента, то есть в момент установки компонента на форму. Например можно установить начальное значение нашего свойства Count. Но мы этого делать не будем.</p> <p> </p> <p>Теперь мы напишем процедуру обработки щелчка мышкой по кнопке:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Tcountbtn.Click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:=FCount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"> </p> <p>"Inherited click" означает, что мы повторяем стандартные методы обработки щелчка мышью (зачем напрягаться и делать лишнюю работу:)).</p> <p>У нас осталась последняя процедура ShowCount. Она может выглядеть примерно так:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.ShowCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Showmessage(</span><span class="f_CodeExample" style="color: #ff0000;">'По кнопке '</span><span class="f_CodeExample" style="color: #000000;">+ caption+</span><span class="f_CodeExample" style="color: #ff0000;">' вы сделали: '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(FCount)+</span><span class="f_CodeExample" style="color: #ff0000;">' клик(а/ов)'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Здесь выводится сообщение в котором показывается количество кликов по кнопке (к тому же выводится имя этой кнопки, ну это я добавил только с эстетической целью).</p> <p>И если вы все поняли и сделали правильно, то у вас должно получится следующее:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> CountBtn;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls, ExtCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TCountBtn = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Click;</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ShowCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Count:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(aowner:Tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TCountBtn]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.Create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> create(Aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Tcountbtn.Click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:=FCount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.ShowCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Showmessage(</span><span class="f_CodeExample" style="color: #ff0000;">'По кнопке '</span><span class="f_CodeExample" style="color: #000000;">+ caption+</span><span class="f_CodeExample" style="color: #ff0000;">' вы сделали: '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(FCount)+</span><span class="f_CodeExample" style="color: #ff0000;">' клик(а/ов)'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">. </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Скорее сохраняйтесь, дабы не потерять случайным образом байты набранного кода:)).</p> <p style="text-align: center; margin: 7px 0px;"> </p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Шаг</span><span class="f_Heading1"> 5. </span><span class="f_Heading1">Устанавливаем</span><span class="f_Heading1">компонент</span></p> <p>Если вы сумели написать и понять, все то что здесь предложено, то установка компонента не должна вызвать у вас никаких проблем. Все здесь делается очень просто. В главном меню выберите пункт Component -&gt; Install Component. перед вами открылось диалоговое окно Install Component. В нем вы увидите две закладки: Into exsisting Package и Into new Package. Вам предоставляется выбор установить ваш компонент в уже существующий пакет или в новый пакет соответственно. Мы выберем в уже существующий пакет.</p> <p>В поле Unit File Name напишите имя вашего сохранненого модуля (естественно необходимо еще и указать путь к нему), а лучше воспользуйтесь кнопкой Browse и выберите ваш файл в открывшемся окне.</p> <p>В Search Path ничего изменять не нужно, Делфьи сама за вас все туда добавит.</p> <p>В поле Package File Name выберите имя пакета, в который будет установлен ваш компонент. Мы согласимся с предложенным по умолчанию пакетом.</p> <p>Теперь нажимаем кнопочку Ok. И тут появиться предупреждение Package dclusr30.dpk will be rebuilt. Continue? Дельфи спрашивает: "Пакет такой-то будет изменен. Продолжить?". Конечно же надо ответить "Да". И если вы все сделали правильно, то появиться сообщение, что ваш компонент установлен. Что ж можно кричать Ура! Это ваш первый компонент.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">Создание</span><span class="f_Heading1">свойств</span><span class="f_Heading1">своего</span><span class="f_Heading1">типа</span></p> <p>Теперь мы попробуем создать свойство нестандартного типа. Рассмотрим это на примере метки - TLabel. У этого компонента есть такое свойство: Alignment. Оно может принимать следующие значения: taLeftJustify, taCenter, taRightJustify. Приступаем к созданию свойства. Ничего интересного мне придумать не удалось, но тем не менее я вам покажу это на примере того свойства, которое я придумал. Оно очень простое и поможет вам разобраться. Свойство будет называться ShowType (тип TShowTp), в нашем компоненте оно будет отвечать за отображение свойства Count. Если пользователь установит свойство ShowType в Normal, то кнопка будет работать, как и работала. А если пользователь присвоит этому свойтсву значение CountToCaption, то количество кликов, будет отображаться на самой кнопке.</p> <p> </p> <p>Для начале нам необходимо объявить новый тип. Описание типа нужно добавить после слова Type. Вот так это выглядело вначале:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TCountBtn = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton) </span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"> </p> <p style="margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Вот</span><span style="font-family: 'Times New Roman'; color: #000000;">так</span><span style="font-family: 'Times New Roman'; color: #000000;">это</span><span style="font-family: 'Times New Roman'; color: #000000;">должно</span><span style="font-family: 'Times New Roman'; color: #000000;">выглядеть</span><span style="font-family: 'Times New Roman'; color: #000000;">: </span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TShowTp = (Normal, CountToCaption); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TCountBtn = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton) </span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"> </p> <p>Здесь мы объявили новый тип TShowTp, который может принимать только два значения. Все значения, которые вы хотите добавить перечисляются через запятую. Теперь нам понадобиться создать поле этого типа. Это мы уже умеем и делать и поэтому не должно вызвать никаких сложностей. В директиву Private напишите:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FShowType:TShowTp; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Мы создали поле ShowType, типа TShowTp.</p> <p>Конечно же необходимо добавить это свойство в инспектор объектов:</p> <p>property ShowType: TshowTp read FshowType write FShowType;</p> <p>Ну и наконец, чтобы наш компонент реагировал на изменение этого свойства пользователем надо слегка изменить обработчик события OnClick. После небольшой модификации он может иметь примерно такой вид:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Tcountbtn.Click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:=Fcount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ShowType = Normal </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption:=Caption;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ShowType = CountToCaption </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption:=</span><span class="f_CodeExample" style="color: #ff0000;">'Count= '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(count);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Объясню что произошло. Вначале мы увеличиваем счетчик на единицу. Затем проверяем какое значение имеет свойство ShowType. Если Normal, то ничего не делаем, а если CountToCaption, то в надпись на кнопке выводим количество кликов. Не так уж и сложно как это могло показаться с первого раза.</p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Имплантируем</span><span class="f_Heading1">таймер</span><span class="f_Heading1">в</span><span class="f_Heading1">компонент</span></p> <p class="p_Heading1"> </p> <p>Очень часто бывает, что вам необходимо вставить в компонент, какой-нибудь другой компонент, например, таймер. Как обычно будем рассматривать этот процесс на конкретном примере. Сделаем так, что через каждые 10 секунд значение счетчика кликов будет удваиваться. Для этого мы встроим таймер в нашу кнопку. Нам понадобиться сделать несколько несложных шагов.</p> <p> </p> <p>После раздела uses, где описаны добавленные в программу модули, объявите переменную типа TTimer. Назовем ее Timer. Приведу небольшой участок кода:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> CountBtn;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls, ExtCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> Timer: TTimer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Дальше в директиву Protected необходимо добавить обработчик события OnTimer для нашего таймера. Это делается так:</p> <p>procedure OnTimer(Sender: TObject);</p> <p>Поскольку наш таймер это не переменная, а компонент, его тоже надо создать, для этого в конструктор нашей кнопки напишем:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.Create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> create(Aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer:=TTimer.Create(self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.Enabled:=true;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.OnTimer:=OnTimer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.Interval:=</span><span class="f_CodeExample" style="color: #000080;">10000</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Здесь создается экземпляр нашего таймера и его свойству Iterval (измеряется в миллисекундах) присваивается значение 10000 (то есть 10 секунд если по простому).</p> <p>Собственно осталось написать саму процедуру OnTimer. Я сделал это так:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.OnTimer(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:=FCount*</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Вот примерно то, что у вас должно получиться в конце: </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> CountBtn;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls, ExtCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> Timer: TTimer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TShowTp = (Normal, CountToCaption);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TCountBtn = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton)</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FShowType:TShowTp;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> OnTimer(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Click;</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ShowCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Count:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(aowner:Tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> ShowType: TshowTp </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FshowType </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FShowType;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TCountBtn]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.Create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> create(Aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer:=TTimer.Create(self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.Enabled:=false;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.OnTimer:=OnTimer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.Interval:=</span><span class="f_CodeExample" style="color: #000080;">1000</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Tcountbtn.Click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:=Fcount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Timer.Enabled:=true;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ShowType = Normal </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption:=Caption;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ShowType = CountToCaption </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption:=</span><span class="f_CodeExample" style="color: #ff0000;">'Count= '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(count);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.ShowCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Showmessage(</span><span class="f_CodeExample" style="color: #ff0000;">'По кнопке '</span><span class="f_CodeExample" style="color: #000000;">+ caption+</span><span class="f_CodeExample" style="color: #ff0000;">' вы сделали: '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(FCount)+</span><span class="f_CodeExample" style="color: #ff0000;">' клик(а/ов)'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TCountBtn.OnTimer(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FCount:=FCount*</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">. </span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p>Если у вас что-то не сработало, то в начале проверьте все ли у вас написано правильно. Затем проверьте может у вас не хватает какого-нибудь модуля в разделе Uses.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">Переустановка</span><span class="f_Heading1">компонента</span></p> <p>Очень часто бывает необходимо переустановить ваш компонент. Если вы попробуете сделать это путем выбора Component-&gt;Install Component, то Дельфи вас честно предупредит о том, что пакет уже содержит модуль с таким именем. Перед вами открывается окно с содержимым пакета. В нем вы должны найти имя вашего компонента и удалить его (либо нажать кнопочку Remove). Теперь в пакете уже нет вашего компонента. Затем проделайте стандартную процедуру по установке компонента.</p> <p> </p> <p><span class="f_Heading1">Редактирование</span><span class="f_Heading1">значения</span><span class="f_Heading1">, </span><span class="f_Heading1">которое</span><span class="f_Heading1">ввел</span><span class="f_Heading1">пользователь</span><span class="f_Heading1">, </span><span class="f_Heading1">изменяя</span><span class="f_Heading1">какое</span><span class="f_Heading1">-</span><span class="f_Heading1">нибудь</span><span class="f_Heading1">свойство</span><span class="f_Heading1">.</span></p> <p>Простой пример. Допустим у нас есть компонент (основанный на Tedit), у него есть два свойства: FirstNumber и SecondNumber. И у него есть процедура Division, в которой первое число делится на второе и результат присаивается свойству текст нашего компонента. Вот код этого компонента:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> DivEdit;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDivEdit = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(Tedit)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FFirstNumber:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FSecondNumber:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FResult:Single; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">//в компонентах нельзя использовать Real!!!</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Division;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> create(aowner:Tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> FirstNumber:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FFirstNumber </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FFirstNumber;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> SecondNumber:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FSecondNumber </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FSecondNumber;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Result:Single </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> Fresult </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FResult;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Constructor</span><span class="f_CodeExample" style="color: #000000;"> TDivEdit.create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> create(aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FFirtsNumber:=</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FSecondNumber:=</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDivEdit.Division;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FResult:=FFirstNumber/FSecondNumber;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">text:=floattostr(FResult);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TDivEdit]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p>Хочется обратить ваше внимание на то, что в компонентах нельзя использовать переменные и поля типа Real, вместо него нужно брать переменные типов Single, Double, Extended.</p> <p>Здесь все просто. Но вот если пользователю вздумается поделить на ноль (ну вдруг он математики не знает), то компонент выдаст ошибку DivisionByZero, а кому они нужны. Обойти эту проблему можно так: в код компонента добавить процедуру, которая проанализирует данные введенные пользователь и если все будет в порядке, то она присвоит значения соответствующим свойтсвам. В директиве Private объявите такую процедуру:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetSecondNumber(value:integer);</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Обычно такие процедуры начинаются с приставки Set, затем идет имя свойства, и в конце тип переменной. Теперь в директиве Published надо сделать небольшие изменения:</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> SecondNumber:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FSecondNumber </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetSecondNumber;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>А теперь напишем саму процедуру:</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDivEdit.SetSecondNumber(value:Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> value&lt;&gt;FSecondNumber </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">//надо проверить совпадают ли исходное и вводимое значения</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FSecondNumber:=value; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">//если нет, то изменить значение</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> FSecondNumber=</span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FSecondNumber:=</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p>Теперь сколько бы пользователь не вводил нулей значение SecondNumber будет единицей. Такие процедуры проверки рекомендуется использовать везде, где только допустимо появление исключительной ситуации.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">Использование</span><span class="f_Heading1">другого</span><span class="f_Heading1">компонента</span><span class="f_Heading1">в</span><span class="f_Heading1">вашем</span></p> <p class="p_Heading1"> </p> <p>Попробуем создать такой компонент. Это будет обычная метка (Label), у которой будет две процедуры: ChangeBackColor и ChangeFontColor, которые соответственно будут менять цвет фона метки и цвет текста. Для этого нам понадобиться ColorDialog, который будет создаваться вместе с компонентом, а потом с помощью процедур он будет активироваться. Назовем компонент ColorLabel. Вначале добавим в uses два модуля: Dialogs, StdCtrls (в них находятся описания классаов диалога и метки). Теперь нам надо объявить переменную типа TColorDialog. Объявление идет сразу после секции Uses.</p> <p> </p> <p>Примерно это выглядит так:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> ColorDialog:TColorDialog;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p>Теперь в конструкторе (Create), нам надо создать этот компонент:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TColorLabel.create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ColorDialog:=TColorDialog.Create(self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p>Теперь надо объявить процедуры ChangeBackColor, ChangeFontColor. Чтобы они были доступны пользователю их надо поместить в директиву Public:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ChangeBackColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ChangeFontColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p>Осталось написать сами процедуры. Все очень просто: открываете диалог методом Execute, а затем присваиваете полученное значение цвета метке. У меня эти процедуры имеют такой вид:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TColorLabel.ChangeBackColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ColorDialog.Execute </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">color:=ColorDialog.color;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TColorLabel.ChangeFontColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ColorDialog.Execute </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">font.color:=ColorDialog.color;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Если у вас вдруг что-то не получилось, то взгляните на мой код целиком:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> ColorLabel;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> ColorDialog:TColorDialog;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TColorLabel = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(Tlabel)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ChangeBackColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ChangeFontColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> create(aowner:tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TColorLabel.create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ColorDialog:=TColorDialog.Create(self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TColorLabel.ChangeBackColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ColorDialog.Execute </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">color:=ColorDialog.color;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TColorLabel.ChangeFontColor;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ColorDialog.Execute </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">font.color:=ColorDialog.color;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TColorLabel]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Доступ</span><span class="f_Heading1">к</span><span class="f_Heading1">свойствам</span><span class="f_Heading1">другого</span><span class="f_Heading1">компонента</span></p> <p>Сейчас нам предстоит более сложная задача. Мы будем создавать компонент, вместе с которым будет создаваться какой-нибудь визуальный компонент. Например создадим кнопку, которая будет сопровождаться поясняющей надписью сверху. За основу возмем тип TButton. Нам надо будет создать еще и Label. Здесь существует одна проблемка: при перемещении компонента по форме, метка должна двигаться вместе с кнопкой, поэтому нам придется обрабатывать сообщение WmMove. Итак, объявляем переменную Label (в данном примере она объявлена в директиве Private, что тоже допустимо):</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Forms, Dialogs, StdCtrls,buttons;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TLabelButton = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel : TLabel ;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p>Теперь я приведу весь код этого компонента и походу буду вставлять необходимые пояснения:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> LabelBtn;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Forms, Dialogs, StdCtrls,buttons;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TLabelButton = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TButton)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel : TLabel ; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{создаем поле типа Tlabel}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> WMMove( </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> Msg : TWMMove ) ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">message</span><span class="f_CodeExample" style="color: #000000;"> WM_MOVE ;</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{процедура для обработки сообщения Wm_move, чтобы метка перемещалась вместе с кнопкой}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetParent( Value : TWinControl ) ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;"> ;</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{необходимо воспользоваться и этой процедурой, так как нужно убедиться, имеют ли кнопка и метка общего предка}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetLabelCaption : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;"> ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;"> ; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Вот пример доступа из компонента к свойствам другого. Эти две процедуры для изменения текста метки}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetLabelCaption( </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> Value : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;"> ) ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create( AOwner : TComponent ) ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> LabelCaption : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetLabelCaption </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SetLabelCaption ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TLabelButton.Create( AOwner : TComponent ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create( AOwner ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ создаем TLabel }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel := TLabel.Create( </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;"> ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel.Caption := </span><span class="f_CodeExample" style="color: #ff0000;">'Описание:'</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TLabelButton.SetParent( Value : TWinControl ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{надо убедиться, что у них предок один, чтоб проблем потом не было}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ( Owner = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;"> ) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">or</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">not</span><span class="f_CodeExample" style="color: #000000;"> ( csDestroying </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">in</span><span class="f_CodeExample" style="color: #000000;"> Owner.ComponentState ) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel.Parent := Value ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> SetParent( Value ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TLabelButton.Destroy ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> ( FLabel &lt;&gt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;"> ) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">and</span><span class="f_CodeExample" style="color: #000000;"> ( FLabel.Parent = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;"> ) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel.Free ;</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Уничтожаем метку, т.к. она нам больше не нужна}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Destroy ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TLabelButton.GetLabelCaption : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FLabel.Caption ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TLabelButton.SetLabelCaption( </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">const</span><span class="f_CodeExample" style="color: #000000;"> Value : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;"> ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel.Caption := Value ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TLabelButton.WMMove( </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> Msg : TWMMove ) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> FLabel &lt;&gt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> Flabel </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SetBounds( Msg.XPos, Msg.YPos - Height, Width,Height ) ; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{изменяем левое и верхнее положение метки исходя из полученных координат}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TLabelButton]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">initialization</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterClass( TLabel ) ; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Это делается для обеспечения поточности, но об этом не думайте, этим редко придется пользоваться}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Вы можете пользоваться этим компонентом сколько угодно, но распространять его можно только указывая авторство}</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Можно сделать доступ к любым свойствам метки, например, к шрифту, цвету и так далее, используя необходимые процедуры.</p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Использование</span><span class="f_Heading1">в</span><span class="f_Heading1">качестве</span><span class="f_Heading1">предка</span><span class="f_Heading1">класс</span><span class="f_Heading1"> TWinControl</span></p> <p>Предыдущий пример был очень сложным, к тому же пришлось обрабатывать системные сообщения. Есть другое решение этой проблемы, более простое для понимания и для реализации: использовать в качестве контейнера класс TWinControl и в этот контейнер помещать другие компоненты. Теперь попробуем совместить Edit и Label. Давайте вместе создадим такой компонент. В качестве предка нужно выбрать класс TWinControl, а в качестве типа вашего компонента выберите TlabelEdit. Будем разбирать код по кусочкам.</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> LabelEdit;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Forms, Dialogs, stdctrls; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TLabelEdit = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TWinControl) </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FEdit: TEdit; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel: TLabel; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//Здесь объявляются поля для метки и для Edita. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetLabelCaption: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetLabelCaption(LabelCaption: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetEditText: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetEditText(EditText: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">//Здесь объявлены функции для работы со свойствами Caption у метки и Text у Edita.</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Public declarations }</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner: TComponent); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> LabelCaption: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetLabelCaption </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetLabelCaption; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> EditText: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetEditText </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetEditText; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TLabelEdit.Create(AOwner: TComponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FEdit := TEdit.Create(self);</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{создаем поле редактирования Edit}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel := TLabel.Create(self);</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{создаем Label}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> FLabel </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Width := FEdit.Width; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">visible := true; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Parent := self; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Caption := </span><span class="f_CodeExample" style="color: #ff0000;">'Описание:'</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> FEdit </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Top := FLabel.Height+</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Parent := self; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Visible := true; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Top := </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Left := </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Width := FEdit.Width; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Height := FEdit.Height+FLabel.Height;</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{определяются размеры и положение компонентов}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Visible := true; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TLabelEdit.GetLabelCaption: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FLabel.Caption; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TLabelEdit.SetLabelCaption(LabelCaption: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FLabel.Caption := LabelCaption; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TLabelEdit.GetEditText: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FEdit.Text; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TLabelEdit.SetEditText(EditText: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FEdit.Text := EditText; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TLabelEdit]); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">. </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Попробуйте установить этот компонент. Когда вы будете размещать его на форме, то будет виден "контейнер", на котором располагаются Edit и Label. Использование в качестве предка компонента класса TWinControl, очень удобно если вы хотите объединить несколько визуальных компонентов.</p> <p> </p> <p class="p_Heading1"> </p> <p class="p_Heading1"><span class="f_Heading1">Обработка</span><span class="f_Heading1">событий</span><span class="f_Heading1"> OnMouseDown, OnMouseMove </span><span class="f_Heading1">и</span><span class="f_Heading1"> OnMouseUp </span></p> <p>Часто возникает необходимость обработки событий нажатия и отпускания кнопки в вашем компоненте. Сейчас мы это и рассмотрим. Только ради примера сделаем компонент, который будет считать количество нажатий и отпусканий кнопки в его области, допустим это будет панель (Tpanel). Для этого в директиве Private надо объявить следующие процедуры и поля:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FClickCount:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FUpCount:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> MouseDown(Button:TMouseButton; Shift: TShiftState; X,Y: Integer); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> MouseMove(Shift: TShiftState; X, Y: Integer); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> MouseUp(Button:TMouseButton; Shift:TShiftState; X, Y: Integer); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p>А в директиве Published надо написать:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> create(aowner:tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> ClickCount:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FclickCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FClickCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> UpCount:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FUpCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FUpCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OnMouseDown;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OnMouseMove;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OnMouseUp;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Ну и теперь осталось описать нужные процедуры:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.MouseDown(Button:TMouseButton; Shift: TShiftState; X,Y: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FClickCount:=FClickCount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.MouseMove(Shift: TShiftState; X, Y: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">caption:=inttostr(x)+</span><span class="f_CodeExample" style="color: #ff0000;">' '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(y);</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{для демонстрации работы этой процедуры. Надпись на панели будет отражать координаты курсора мыши над этой панелью}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.MouseUp(Button:TMouseButton; Shift:TShiftState; X, Y: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FUpCount:=FUpCount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Таким образом весь код компонента был таким:</p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> Mpanel;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ExtCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMpanel = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TPanel)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FClickCount:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FUpCount:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> MouseDown(Button:TMouseButton; Shift: TShiftState; X,Y: Integer); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> MouseMove(Shift: TShiftState; X, Y: Integer); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> MouseUp(Button:TMouseButton; Shift:TShiftState; X, Y: Integer); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> create(aowner:tcomponent);</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> ClickCount:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FclickCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FClickCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> UpCount:integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FUpCount </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FUpCount;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OnMouseDown;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OnMouseMove;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OnMouseUp;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.create(aowner:Tcomponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> create(aowner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.MouseDown(Button:TMouseButton; Shift: TShiftState; X,Y: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FClickCount:=FClickCount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.MouseMove(Shift: TShiftState; X, Y: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">caption:=inttostr(x)+</span><span class="f_CodeExample" style="color: #ff0000;">' '</span><span class="f_CodeExample" style="color: #000000;">+inttostr(y);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMpanel.MouseUp(Button:TMouseButton; Shift:TShiftState; X, Y: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FUpCount:=FUpCount+</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Mihan Components'</span><span class="f_CodeExample" style="color: #000000;">, [TMpanel]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 7px 0px;"> </p> <p class="p_Heading1"><span class="f_Heading1">Создание</span><span class="f_Heading1">и</span><span class="f_Heading1">использование</span><span class="f_Heading1">своей</span><span class="f_Heading1">иконки</span><span class="f_Heading1">для</span><span class="f_Heading1">компонента</span></p> <p>Когда вы создали свой компонент и установили его, та на палитре компонентов, его иконка будет такой же как и у компонента, который вы выбрали в качестве предка. Конечно же вам хотелось бы видеть свой компонент со своей иконкой. Для этого необходимо создать файл ресурсов компонента. Сейчас я расскажу вам как это делается.</p> <p>Откройте Image Editor (Tools-&gt;Image Editor) и выберите File-&gt;New-&gt;Component Resourse File. Перед вами появится небольшое окно с надписью Untitled.dcr в нем будет только одно слово: Contents. Нажмите на него правой кнопкой и в появившемся меню выберите New-&gt;Bitmap. Откроется диалоговое окно для настройки параметров изображения. Они должны быть такими: Размер 32x32, цветовой режим VGA (16 colors). Теперь нажмите ok. Теперь надо нажать правой кнопкой на появившейся надписи Bitmap1 и выбрать пункт Rename. Название картинки должно совпадать с названием класса компонента, для которого вы делаете эту иконку (например, TMPanel). Нажмите два раза на Bitmap1 и перед вами появится окно для рисования. Нарисуйте, что вам надо и перейдите на окно с надписью Untitled.dcr и в меню File выберите Save. Имя файла ресурса компонента должно совпадать с именем модуля компонента (без расширения конечно же, например, Mpanel). Файл ресурса готов. Теперь установите ваш компонент заново и в палитре компонентов ваш компонент будет уже с новой иконкой.</p> <p style="text-align: center; margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">Источник</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">: </span><span style="font-family: 'Times New Roman'; color: #000080; font-size: 10pt;">https://delphid.dax</span></p> Создание компонент в Delphi 2013-08-19T13:33:48+07:00 2013-08-19T13:33:48+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/razrabotka-komponentov-i-klassov/sozdanie-komponent-v-delphi.html Super User toto44@inbox.ru <p>Перед созданием своего компонента нужно выбрать для него предка. Кто же может быть предком для вашего компонента? Как правило, используются в виде предков TComponent, TControl, TWinControl, TGraphicControl, TCustomXXXXXX, а также все компоненты палитры компонентов. Возьмем для примера компонент TOpenDialog, который находится на странице Dialogs палитры компонентов. Он хорошо справляется со своей задачей, но у него есть одно маленькое неудобство. Каждый раз, когда его используешь необходимо каждый раз изменять значение свойства Options. И причем это, как правило, одни и те же действия.</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OpenDialog1.Options := OpenDialog1.Options + [ofFileMustExist, ofPathMustExist];</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>чтобы файл, который мы пытаемся открыть с помощью этого диалогового окна, действительно существовал на диске.<br />Задание для себя мы уже выбрали, осталось за малым - создать компонент. Заготовку для компонента создаем, выбирая из меню команду Component/New Component... и в диалоговом окне выбираем <br />Ancestor type: TOpenDialog<br />Class Name: TOurOpenDialog<br />Palette Page: Our Test<br />Нажали Ok и у нас появился шаблон нашего будущего компонента.<br /> <br />Переопределяем конструктор у этого компонента, т.е. в секции public вставляем строку:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner: TComponent); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p>нажатие на этой строке Ctrl + Shift + C создает шаблон для этого метода, внутри которого мы вставляем такие строки:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner); </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Вызываем унаследованный конструктор}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Options := Options + [ofFileMustExist, ofPathMustExist]; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Выполняем необходимые нам действия}</span></p> </td> </tr> </tbody> </table> </div> <p><br />Обратите внимание: Комбинации клавиш Ctrl + Shift + стрелки вверх/вниз позволяют перемещаться между объявлением метода и его реализацией.<br /> <br />Установка созданного компонента Component/Install Component...<br />Install Into New Package<br />Package file name: C:\Program Files\Borland\Delphi4\Lib\OurTest.dpk<br />Package description: Our tested package<br /> <br />Вам не нравится, что у нашего компонента иконка такая же как у стандартного? Тогда создадим для него свою собственную. Для этого нам необходимо вызвать Tools/Image Editor. Создаем новый *.dcr файл. <br />Вставляем в него рисунок Resource/New/Bitmap. Устанавливаем размер картинки 24x24 точек. А дальше - ваше творчество... Обратите внимание: цвет точек, совпадающий с цветом точки в левом нижнем углу рисунка, будет считаться ПРОЗРАЧНЫМ! После того как вы создали свой рисунок, переименуйте его из Bitmap1 в TOurOpenDialog и сохраните файл с именем OurOpenDialog.dcr. Удалите компонент из пакета и установите его снова (только в этом случае добавится и ссылка на *.dcr файл). Compile, Install и удачи!</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;">Code:</p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample">{======================================================}</p> <p class="p_CodeExample">unit OurOpenDialog;</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">interface</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">uses</p> <p class="p_CodeExample">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">type</p> <p class="p_CodeExample">TOurOpenDialog = class(TOpenDialog)</p> <p class="p_CodeExample">private</p> <p class="p_CodeExample">{ Private declarations }</p> <p class="p_CodeExample">protected</p> <p class="p_CodeExample">{ Protected declarations }</p> <p class="p_CodeExample">public</p> <p class="p_CodeExample">{ Public declarations }</p> <p class="p_CodeExample">constructor Create(AOwner: TComponent); override;</p> <p class="p_CodeExample">published</p> <p class="p_CodeExample">{ Published declarations }</p> <p class="p_CodeExample">end;</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">procedure register;</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">implementation</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">procedure register;</p> <p class="p_CodeExample">begin</p> <p class="p_CodeExample">RegisterComponents('Samples', [TOurOpenDialog]);</p> <p class="p_CodeExample">end;</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">{ TOurOpenDialog }</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">constructor TOurOpenDialog.Create(AOwner: TComponent);</p> <p class="p_CodeExample">begin</p> <p class="p_CodeExample">inherited Create(AOwner); {Вызываем</p> <p class="p_CodeExample">унаследованный конструктор}</p> <p class="p_CodeExample">Options := Options + [ofFileMustExist, ofPathMustExist];</p> <p class="p_CodeExample">{Выполняем необходимые нам действия}</p> <p class="p_CodeExample">end;</p> <p class="p_CodeExample">end.</p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p>Объявление компонента состоит из секций, таких как <span style="font-weight: bold;">private</span>, <span style="font-weight: bold;">protected</span>, <span style="font-weight: bold;">public</span> и <span style="font-weight: bold;">published</span>. Что они означают? <br />Это директивы видимости. Все что объявлено в секции <span style="font-weight: bold;">private</span>, доступно только внутри модуля в котором объявлен класс (приватные объявления). Здесь как правило объявляются переменные, в которых хранятся значения свойств, а также методы (процедуры или функции) доступа к ним. Все что объявлено в секции <span style="font-weight: bold;">protected</span>, доступно как и в секции private, а также наследникам данного класса (интерфейс разработчика). Здесь можно объявить методы доступа к значениям свойств (если вы хотите позволить изменять эти методы потомкам вашего компенента), <br />а также свойства, методы и события (методы реакции на события) в компонентах типа TCustomXXX. <br />Все что объявлено в секции <span style="font-weight: bold;">public</span>, доступно любому пользователю компонента (интерфейс этапа выполнения). <br />Здесь объявляются, как правило методы. В секции <span style="font-weight: bold;">published</span> можно объявлять только свойства и события (они объявляются в виде свойств). Они доступны во время проектирования приложения (интерфейс этапа проектирования).</p> <p class="p_Heading1"> </p> <p class="p_Heading1"><span class="f_Heading1">Свойства</span></p> <p>Свойства типа масив - обычные массива Object Pascal, но в отличии от последних могут индексироваться не только числовыми значениями но и строковыми. К сожалению этот тип свойства требует пользовательского редактора свойств (в инспекторе объектов редактор свойства имеет кнопку с тремя точками [...]), по-этому в указанном ниже примере свойство ArrayProp объявлено в секции public.</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;">Code:</p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample">type</p> <p class="p_CodeExample">TOurComponent = class(TComponent)</p> <p class="p_CodeExample">private</p> <p class="p_CodeExample">{ Private declarations }</p> <p class="p_CodeExample">FArrayProp: array[0..9] of integer;</p> <p class="p_CodeExample">function GetArrayProp(aIndex: integer): integer;</p> <p class="p_CodeExample">procedure SetArrayProp(aIndex: integer; const</p> <p class="p_CodeExample">Value: integer);</p> <p class="p_CodeExample">protected</p> <p class="p_CodeExample">{ Protected declarations }</p> <p class="p_CodeExample">public</p> <p class="p_CodeExample">{ Public declarations }</p> <p class="p_CodeExample">property ArrayProp[aIndex: integer]: integer read</p> <p class="p_CodeExample">GetArrayProp</p> <p class="p_CodeExample">write SetArrayProp;</p> <p class="p_CodeExample">published</p> <p class="p_CodeExample">{ Published declarations }</p> <p class="p_CodeExample">end;</p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Спецификаторы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">свойств</span></p> <p style="margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">Спецификатор</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt; font-weight: bold;">default</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">указывает</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">сохранять</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">значение</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">в</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">файле</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">формы</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">или</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">нет</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">. </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">Если</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">значение</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">совпадает</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">со</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">значением</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt; font-weight: bold;">default</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;"> - </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">значение</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">в</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">файле</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">формы</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">не</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">сохраняется</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">, </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">если</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">значения</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">не</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">равны</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;"> - </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">сохраняется</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">. </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">Это</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">можно</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">проверить</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">, </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">положив</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">компонент</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">на</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">форму</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">и</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">выбрать</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">правой</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">кнопкой</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">мыши</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">пункт</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">меню</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;"> "View as Text". </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt; font-weight: bold;">Default</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">не</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">устанавливает</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">первоначальное</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">значение</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">к</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">указанному</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">. </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">Это</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">необходимо</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">сделать</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">в</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">конструкторе</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">компонента</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> OurComponent;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> Windows, SysUtils, Classes, Graphics, Forms, Controls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TOurComponent = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TComponent)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FMyInteger: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner: TComponent); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> MyInteger: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FMyInteger</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FMyInteger </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">default</span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TOurComponent.Create(AOwner: TComponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FInteger := </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Спецификатор nodefault отменяет заданное по умолчанию значение свойства. Этот спецификатор, как правило, используется для отмены заданого по умолчанию значения унаследованного свойства.</p> <p><br />Например:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> AutoSize </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nodefault</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Спецификатор stored указывает когда сохранять в файле формы значение свойства. После stored может стоять true (всегда сохранять), false (никогда не сохранять) или название функции, которая возвращает логический результат.</p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_Heading1"><span class="f_Heading1">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OneProp: integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FOneProp</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SetOneProp </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">stored</span><span class="f_CodeExample" style="color: #000000;"> False;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> TwoProp: integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FTwoProp</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SetTwoProp </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">stored</span><span class="f_CodeExample" style="color: #000000;"> True;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> ThreeProp: integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FThreeProp</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetThreeProp </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">stored</span><span class="f_CodeExample" style="color: #000000;"> Fuct;</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: center;"> </p> <p style="text-align: center;"> </p> <p style="text-align: left;"><br /><span style="font-family: 'Verdana'; color: #000000;">Автор</span><span style="font-family: 'Verdana'; color: #000000;">: </span><span style="font-family: 'Verdana'; color: #000000;">Александр</span><span style="font-family: 'Verdana'; color: #000000;">Василевский</span><br /><span style="font-family: 'Verdana'; color: #000000;">Источник</span><span style="font-family: 'Verdana'; color: #000000;">: </span><span style="font-family: 'Verdana'; color: #0000ff; text-decoration: underline;">https://alvas.hypermart</span></p> <p>Перед созданием своего компонента нужно выбрать для него предка. Кто же может быть предком для вашего компонента? Как правило, используются в виде предков TComponent, TControl, TWinControl, TGraphicControl, TCustomXXXXXX, а также все компоненты палитры компонентов. Возьмем для примера компонент TOpenDialog, который находится на странице Dialogs палитры компонентов. Он хорошо справляется со своей задачей, но у него есть одно маленькое неудобство. Каждый раз, когда его используешь необходимо каждый раз изменять значение свойства Options. И причем это, как правило, одни и те же действия.</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OpenDialog1.Options := OpenDialog1.Options + [ofFileMustExist, ofPathMustExist];</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>чтобы файл, который мы пытаемся открыть с помощью этого диалогового окна, действительно существовал на диске.<br />Задание для себя мы уже выбрали, осталось за малым - создать компонент. Заготовку для компонента создаем, выбирая из меню команду Component/New Component... и в диалоговом окне выбираем <br />Ancestor type: TOpenDialog<br />Class Name: TOurOpenDialog<br />Palette Page: Our Test<br />Нажали Ok и у нас появился шаблон нашего будущего компонента.<br /> <br />Переопределяем конструктор у этого компонента, т.е. в секции public вставляем строку:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner: TComponent); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p>нажатие на этой строке Ctrl + Shift + C создает шаблон для этого метода, внутри которого мы вставляем такие строки:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner); </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Вызываем унаследованный конструктор}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Options := Options + [ofFileMustExist, ofPathMustExist]; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Выполняем необходимые нам действия}</span></p> </td> </tr> </tbody> </table> </div> <p><br />Обратите внимание: Комбинации клавиш Ctrl + Shift + стрелки вверх/вниз позволяют перемещаться между объявлением метода и его реализацией.<br /> <br />Установка созданного компонента Component/Install Component...<br />Install Into New Package<br />Package file name: C:\Program Files\Borland\Delphi4\Lib\OurTest.dpk<br />Package description: Our tested package<br /> <br />Вам не нравится, что у нашего компонента иконка такая же как у стандартного? Тогда создадим для него свою собственную. Для этого нам необходимо вызвать Tools/Image Editor. Создаем новый *.dcr файл. <br />Вставляем в него рисунок Resource/New/Bitmap. Устанавливаем размер картинки 24x24 точек. А дальше - ваше творчество... Обратите внимание: цвет точек, совпадающий с цветом точки в левом нижнем углу рисунка, будет считаться ПРОЗРАЧНЫМ! После того как вы создали свой рисунок, переименуйте его из Bitmap1 в TOurOpenDialog и сохраните файл с именем OurOpenDialog.dcr. Удалите компонент из пакета и установите его снова (только в этом случае добавится и ссылка на *.dcr файл). Compile, Install и удачи!</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;">Code:</p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample">{======================================================}</p> <p class="p_CodeExample">unit OurOpenDialog;</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">interface</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">uses</p> <p class="p_CodeExample">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">type</p> <p class="p_CodeExample">TOurOpenDialog = class(TOpenDialog)</p> <p class="p_CodeExample">private</p> <p class="p_CodeExample">{ Private declarations }</p> <p class="p_CodeExample">protected</p> <p class="p_CodeExample">{ Protected declarations }</p> <p class="p_CodeExample">public</p> <p class="p_CodeExample">{ Public declarations }</p> <p class="p_CodeExample">constructor Create(AOwner: TComponent); override;</p> <p class="p_CodeExample">published</p> <p class="p_CodeExample">{ Published declarations }</p> <p class="p_CodeExample">end;</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">procedure register;</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">implementation</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">procedure register;</p> <p class="p_CodeExample">begin</p> <p class="p_CodeExample">RegisterComponents('Samples', [TOurOpenDialog]);</p> <p class="p_CodeExample">end;</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">{ TOurOpenDialog }</p> <p class="p_CodeExample"> </p> <p class="p_CodeExample">constructor TOurOpenDialog.Create(AOwner: TComponent);</p> <p class="p_CodeExample">begin</p> <p class="p_CodeExample">inherited Create(AOwner); {Вызываем</p> <p class="p_CodeExample">унаследованный конструктор}</p> <p class="p_CodeExample">Options := Options + [ofFileMustExist, ofPathMustExist];</p> <p class="p_CodeExample">{Выполняем необходимые нам действия}</p> <p class="p_CodeExample">end;</p> <p class="p_CodeExample">end.</p> </td> </tr> </tbody> </table> </div> <p style="text-align: justify; margin: 7px 0px;"> </p> <p>Объявление компонента состоит из секций, таких как <span style="font-weight: bold;">private</span>, <span style="font-weight: bold;">protected</span>, <span style="font-weight: bold;">public</span> и <span style="font-weight: bold;">published</span>. Что они означают? <br />Это директивы видимости. Все что объявлено в секции <span style="font-weight: bold;">private</span>, доступно только внутри модуля в котором объявлен класс (приватные объявления). Здесь как правило объявляются переменные, в которых хранятся значения свойств, а также методы (процедуры или функции) доступа к ним. Все что объявлено в секции <span style="font-weight: bold;">protected</span>, доступно как и в секции private, а также наследникам данного класса (интерфейс разработчика). Здесь можно объявить методы доступа к значениям свойств (если вы хотите позволить изменять эти методы потомкам вашего компенента), <br />а также свойства, методы и события (методы реакции на события) в компонентах типа TCustomXXX. <br />Все что объявлено в секции <span style="font-weight: bold;">public</span>, доступно любому пользователю компонента (интерфейс этапа выполнения). <br />Здесь объявляются, как правило методы. В секции <span style="font-weight: bold;">published</span> можно объявлять только свойства и события (они объявляются в виде свойств). Они доступны во время проектирования приложения (интерфейс этапа проектирования).</p> <p class="p_Heading1"> </p> <p class="p_Heading1"><span class="f_Heading1">Свойства</span></p> <p>Свойства типа масив - обычные массива Object Pascal, но в отличии от последних могут индексироваться не только числовыми значениями но и строковыми. К сожалению этот тип свойства требует пользовательского редактора свойств (в инспекторе объектов редактор свойства имеет кнопку с тремя точками [...]), по-этому в указанном ниже примере свойство ArrayProp объявлено в секции public.</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;">Code:</p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample">type</p> <p class="p_CodeExample">TOurComponent = class(TComponent)</p> <p class="p_CodeExample">private</p> <p class="p_CodeExample">{ Private declarations }</p> <p class="p_CodeExample">FArrayProp: array[0..9] of integer;</p> <p class="p_CodeExample">function GetArrayProp(aIndex: integer): integer;</p> <p class="p_CodeExample">procedure SetArrayProp(aIndex: integer; const</p> <p class="p_CodeExample">Value: integer);</p> <p class="p_CodeExample">protected</p> <p class="p_CodeExample">{ Protected declarations }</p> <p class="p_CodeExample">public</p> <p class="p_CodeExample">{ Public declarations }</p> <p class="p_CodeExample">property ArrayProp[aIndex: integer]: integer read</p> <p class="p_CodeExample">GetArrayProp</p> <p class="p_CodeExample">write SetArrayProp;</p> <p class="p_CodeExample">published</p> <p class="p_CodeExample">{ Published declarations }</p> <p class="p_CodeExample">end;</p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Спецификаторы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">свойств</span></p> <p style="margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">Спецификатор</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt; font-weight: bold;">default</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">указывает</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">сохранять</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">значение</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">в</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">файле</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">формы</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">или</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">нет</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">. </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">Если</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">значение</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">совпадает</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">со</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">значением</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt; font-weight: bold;">default</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;"> - </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">значение</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">в</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">файле</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">формы</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">не</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">сохраняется</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">, </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">если</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">значения</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">не</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">равны</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;"> - </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">сохраняется</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">. </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">Это</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">можно</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">проверить</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">, </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">положив</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">компонент</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">на</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">форму</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">и</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">выбрать</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">правой</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">кнопкой</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">мыши</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">пункт</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">меню</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;"> "View as Text". </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt; font-weight: bold;">Default</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">не</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">устанавливает</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">первоначальное</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">значение</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">к</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">указанному</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">. </span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">Это</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">необходимо</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">сделать</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">в</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">конструкторе</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">компонента</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 10pt;">.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> OurComponent;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> Windows, SysUtils, Classes, Graphics, Forms, Controls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TOurComponent = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TComponent)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FMyInteger: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner: TComponent); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> MyInteger: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FMyInteger</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> FMyInteger </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">default</span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TOurComponent.Create(AOwner: TComponent);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FInteger := </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Спецификатор nodefault отменяет заданное по умолчанию значение свойства. Этот спецификатор, как правило, используется для отмены заданого по умолчанию значения унаследованного свойства.</p> <p><br />Например:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> AutoSize </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nodefault</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Спецификатор stored указывает когда сохранять в файле формы значение свойства. После stored может стоять true (всегда сохранять), false (никогда не сохранять) или название функции, которая возвращает логический результат.</p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_Heading1"><span class="f_Heading1">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> OneProp: integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FOneProp</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SetOneProp </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">stored</span><span class="f_CodeExample" style="color: #000000;"> False;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> TwoProp: integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FTwoProp</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SetTwoProp </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">stored</span><span class="f_CodeExample" style="color: #000000;"> True;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> ThreeProp: integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FThreeProp</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetThreeProp </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">stored</span><span class="f_CodeExample" style="color: #000000;"> Fuct;</span></p> </td> </tr> </tbody> </table> </div> <p style="text-align: center;"> </p> <p style="text-align: center;"> </p> <p style="text-align: left;"><br /><span style="font-family: 'Verdana'; color: #000000;">Автор</span><span style="font-family: 'Verdana'; color: #000000;">: </span><span style="font-family: 'Verdana'; color: #000000;">Александр</span><span style="font-family: 'Verdana'; color: #000000;">Василевский</span><br /><span style="font-family: 'Verdana'; color: #000000;">Источник</span><span style="font-family: 'Verdana'; color: #000000;">: </span><span style="font-family: 'Verdana'; color: #0000ff; text-decoration: underline;">https://alvas.hypermart</span></p> Self 2013-08-19T16:51:50+07:00 2013-08-19T16:51:50+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/self/self.html Super User toto44@inbox.ru <p><span style="font-family: 'Times New Roman'; color: #000000;">Self - это явное задание экземпляра класса в его методе.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Например для твоей формы это указание на саму форму:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">showmessage(self.classname+</span><span class="f_CodeExample" style="color: #ff0000;">#13#10</span><span class="f_CodeExample" style="color: #000000;">+self.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">name</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Если например это MDI форма то это будет указатель именно на тот экземпляр для которого выполняется этот код. На практике Self обычно применяется при написании своих классов, когда ты пишешь класс или компонент, то у тебя нет переменной с экземпляром этого компонента, следовательно чтобы обратится к экземпляру (который появится только в коде конечного пользователя, который будет использовать компонент) класса нужна переменная - вот она и берётся за self.</span></p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #ff0000; font-size: 10pt; font-weight: bold;">Автор:</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Vit</span><span style="font-family: 'Times New Roman'; font-size: 10pt; font-weight: bold;">  </span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingrad.ru</span><span style="color: #0000ff; text-decoration: underline;">https://forum.vingrad</span></p> <p> </p> <p> </p> <p> </p> <hr size="1" noshade="noshade" style="color: #000000;" /> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Чтобы понять, что такое self надо понять что такое метод класса. Метод класса - это просто функция(процедура) который имеет дополнительный неявный параметр - указатель на экземпляр класса. То есть:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMy=</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">x:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Proc(val:integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMy.Proc(val:integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">x:=val;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>После компиляции это будет практически то же самое, что:</p> <p style="text-align: justify; margin: 7px 0px;"> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Proc(self:TMy;val:integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">self.x:=val;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">То есть на самом деле в методе Proc обращаясь к x мы на самом деле обращаемся к self.x, просто переменная self опускается. В откомпилированном коде нет такого понятия как классы - есть только код и память. Все методы классов превращаются в обыкновенные функции, в которым качестве первого параметра передается указатель на область памяти где лежит созданный пользователем экземпляр класса, который они и используют для чтения или записи(а так же для вызова) того, что мы называем членами класса.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">m1,m2:TMy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">.....</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">m1.Proc(</span><span class="f_CodeExample" style="color: #800000;">4</span><span class="f_CodeExample" style="color: #000000;">); </span><span class="f_CodeExample" style="color: #000080;">// -&gt; Proc(m1,4)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">m2.Proc(</span><span class="f_CodeExample" style="color: #800000;">4</span><span class="f_CodeExample" style="color: #000000;">); </span><span class="f_CodeExample" style="color: #000080;">// -&gt; Proc(m2,4)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #ff0000; font-size: 10pt; font-weight: bold;">Автор:</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Fantasist</span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingradru</span><span style="color: #0000ff; text-decoration: underline;">https://forum.vingrad</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Self - это явное задание экземпляра класса в его методе.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Например для твоей формы это указание на саму форму:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">showmessage(self.classname+</span><span class="f_CodeExample" style="color: #ff0000;">#13#10</span><span class="f_CodeExample" style="color: #000000;">+self.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">name</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Если например это MDI форма то это будет указатель именно на тот экземпляр для которого выполняется этот код. На практике Self обычно применяется при написании своих классов, когда ты пишешь класс или компонент, то у тебя нет переменной с экземпляром этого компонента, следовательно чтобы обратится к экземпляру (который появится только в коде конечного пользователя, который будет использовать компонент) класса нужна переменная - вот она и берётся за self.</span></p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #ff0000; font-size: 10pt; font-weight: bold;">Автор:</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Vit</span><span style="font-family: 'Times New Roman'; font-size: 10pt; font-weight: bold;">  </span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingrad.ru</span><span style="color: #0000ff; text-decoration: underline;">https://forum.vingrad</span></p> <p> </p> <p> </p> <p> </p> <hr size="1" noshade="noshade" style="color: #000000;" /> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Чтобы понять, что такое self надо понять что такое метод класса. Метод класса - это просто функция(процедура) который имеет дополнительный неявный параметр - указатель на экземпляр класса. То есть:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMy=</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">x:integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Proc(val:integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMy.Proc(val:integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">x:=val;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>После компиляции это будет практически то же самое, что:</p> <p style="text-align: justify; margin: 7px 0px;"> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Proc(self:TMy;val:integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">self.x:=val;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">То есть на самом деле в методе Proc обращаясь к x мы на самом деле обращаемся к self.x, просто переменная self опускается. В откомпилированном коде нет такого понятия как классы - есть только код и память. Все методы классов превращаются в обыкновенные функции, в которым качестве первого параметра передается указатель на область памяти где лежит созданный пользователем экземпляр класса, который они и используют для чтения или записи(а так же для вызова) того, что мы называем членами класса.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">m1,m2:TMy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">.....</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">m1.Proc(</span><span class="f_CodeExample" style="color: #800000;">4</span><span class="f_CodeExample" style="color: #000000;">); </span><span class="f_CodeExample" style="color: #000080;">// -&gt; Proc(m1,4)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">m2.Proc(</span><span class="f_CodeExample" style="color: #800000;">4</span><span class="f_CodeExample" style="color: #000000;">); </span><span class="f_CodeExample" style="color: #000080;">// -&gt; Proc(m2,4)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #ff0000; font-size: 10pt; font-weight: bold;">Автор:</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Fantasist</span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingradru</span><span style="color: #0000ff; text-decoration: underline;">https://forum.vingrad</span></p> В чем отличие между Create(Self) и Create(Application)? 2013-08-19T16:52:46+07:00 2013-08-19T16:52:46+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/self/v-chem-otlichie-mezhdu-create-self-i-create-application.html Super User toto44@inbox.ru <p><span style="color: #000000;">Self может быть использовано только в методе класса, и ссылается на текущий экземпляр класса. Таким образом "Self" в методе класса TForm1 ссылается на текущий экземпляр TForm1. При создании компонента Вы передаете его владельца (owner) в конструктор. При уничтожении формы или компонента автоматически уничтожаются и все компоненты владельцем которого она является. Таким образом если при создании формы передать в качестве владельца Application эта форма будет автоматически уничтожена при уничтожении Application. Если же при создании формы передать в качестве владельца другую форму, вновь созданная форма будет автоматически уничтоженна при уничтожении формы-владельца. </span></p> <p><span style="color: #000000;">Self может быть использовано только в методе класса, и ссылается на текущий экземпляр класса. Таким образом "Self" в методе класса TForm1 ссылается на текущий экземпляр TForm1. При создании компонента Вы передаете его владельца (owner) в конструктор. При уничтожении формы или компонента автоматически уничтожаются и все компоненты владельцем которого она является. Таким образом если при создании формы передать в качестве владельца Application эта форма будет автоматически уничтожена при уничтожении Application. Если же при создании формы передать в качестве владельца другую форму, вновь созданная форма будет автоматически уничтоженна при уничтожении формы-владельца. </span></p> Работа с Sender 2013-08-19T16:59:11+07:00 2013-08-19T16:59:11+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/sender/rabota-s-sender.html Super User toto44@inbox.ru <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> TestInputForm;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls, DdhInpuB;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TForm1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Edit1: TEdit;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Label1: TLabel;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DdhInputButton1: TDdhInputButton;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DdhInputButton2: TDdhInputButton;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DdhInputButton3: TDdhInputButton;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> DdhInputButtonClick(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Form1: TForm1;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R *.DFM}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.DdhInputButtonClick(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ShowMessage (</span><span class="f_CodeExample" style="color: #ff0000;">'You have clicked the '</span><span class="f_CodeExample" style="color: #000000;"> +</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> (Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TButton).</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> + </span><span class="f_CodeExample" style="color: #ff0000;">','#13</span><span class="f_CodeExample" style="color: #000000;"> +</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'having the caption '</span><span class="f_CodeExample" style="color: #000000;"> +</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> (Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TButton).Caption);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с </span>https://delphiworld.narod</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> TestInputForm;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls, DdhInpuB;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TForm1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Edit1: TEdit;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Label1: TLabel;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DdhInputButton1: TDdhInputButton;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DdhInputButton2: TDdhInputButton;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DdhInputButton3: TDdhInputButton;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> DdhInputButtonClick(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Form1: TForm1;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R *.DFM}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.DdhInputButtonClick(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ShowMessage (</span><span class="f_CodeExample" style="color: #ff0000;">'You have clicked the '</span><span class="f_CodeExample" style="color: #000000;"> +</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> (Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TButton).</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> + </span><span class="f_CodeExample" style="color: #ff0000;">','#13</span><span class="f_CodeExample" style="color: #000000;"> +</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'having the caption '</span><span class="f_CodeExample" style="color: #000000;"> +</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> (Sender </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TButton).Caption);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с </span>https://delphiworld.narod</p> Как получить список всех назначенных событий? 2013-08-19T16:48:56+07:00 2013-08-19T16:48:56+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/sobytiya/kak-poluchit-spisok-vsekh-naznachennykh-sobytij.html Super User toto44@inbox.ru <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> TypInfo;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ .... }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">x, y, z: Word;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">pl: PPropList;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">y := GetPropList(Self, pl);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> x := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> y - </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Copy(pl[x].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">2</span><span class="f_CodeExample" style="color: #000000;">) &lt;&gt; </span><span class="f_CodeExample" style="color: #ff0000;">'On'</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Continue;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetMethodProp(Self, pl[x].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">).Code &lt;&gt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Memo1.Lines.Add(Self.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> + </span><span class="f_CodeExample" style="color: #ff0000;">' - '</span><span class="f_CodeExample" style="color: #000000;"> + pl[x].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> z := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> Self.ComponentCount - </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> y := GetPropList(Self.Components[z], pl);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> x := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> y - </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Copy(pl[x].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">2</span><span class="f_CodeExample" style="color: #000000;">) &lt;&gt; </span><span class="f_CodeExample" style="color: #ff0000;">'On'</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Continue;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetMethodProp(Self.Components[z], pl[x].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">).Code &lt;&gt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Memo1.Lines.Add(Self.Components[z].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> + </span><span class="f_CodeExample" style="color: #ff0000;">' - '</span><span class="f_CodeExample" style="color: #000000;"> + pl[x].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с сайта</span>https://www.swissdelphicenter.ch/en/tipsindex</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span><span class="f_CodeExample" style="color: #000000;"> TypInfo;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ .... }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">x, y, z: Word;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">pl: PPropList;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">y := GetPropList(Self, pl);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> x := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> y - </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Copy(pl[x].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">2</span><span class="f_CodeExample" style="color: #000000;">) &lt;&gt; </span><span class="f_CodeExample" style="color: #ff0000;">'On'</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Continue;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetMethodProp(Self, pl[x].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">).Code &lt;&gt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Memo1.Lines.Add(Self.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> + </span><span class="f_CodeExample" style="color: #ff0000;">' - '</span><span class="f_CodeExample" style="color: #000000;"> + pl[x].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> z := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> Self.ComponentCount - </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> y := GetPropList(Self.Components[z], pl);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> x := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> y - </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Copy(pl[x].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">2</span><span class="f_CodeExample" style="color: #000000;">) &lt;&gt; </span><span class="f_CodeExample" style="color: #ff0000;">'On'</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Continue;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetMethodProp(Self.Components[z], pl[x].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">).Code &lt;&gt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Memo1.Lines.Add(Self.Components[z].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;"> + </span><span class="f_CodeExample" style="color: #ff0000;">' - '</span><span class="f_CodeExample" style="color: #000000;"> + pl[x].</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Name</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято с сайта</span>https://www.swissdelphicenter.ch/en/tipsindex</p> Как присвоить событие в run-time? 2013-08-19T16:47:55+07:00 2013-08-19T16:47:55+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/sobytiya/kak-prisvoit-sobytie-v-run-time.html Super User toto44@inbox.ru <p>Пример стандартного присвоения события в run-time:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{©Drkb v.3(2007): www.drkb.ru, </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">®Vit (Vitaly Nevzorov) - <a class="weblink" href="mailto:nevzorov@yahoo.com">nevzorov@yahoo.com</a>}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TForm1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Button1: TButton;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> Form1: TForm1;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// do something</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">button1.OnClick:=Click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #ff0000; font-size: 10pt; font-weight: bold;">Автор:</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Vit</span><span style="font-family: 'Times New Roman'; font-size: 10pt; font-weight: bold;">  </span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingradru</span><span style="color: #0000ff; text-decoration: underline;">https://forum.vingrad</span><span style="color: #0000ff; text-decoration: underline;"><br /></span></p> <p>Пример стандартного присвоения события в run-time:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{©Drkb v.3(2007): www.drkb.ru, </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">®Vit (Vitaly Nevzorov) - <a class="weblink" href="mailto:nevzorov@yahoo.com">nevzorov@yahoo.com</a>}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TForm1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Button1: TButton;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> Form1: TForm1;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// do something</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm1.FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">button1.OnClick:=Click;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #ff0000; font-size: 10pt; font-weight: bold;">Автор:</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Vit</span><span style="font-family: 'Times New Roman'; font-size: 10pt; font-weight: bold;">  </span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingradru</span><span style="color: #0000ff; text-decoration: underline;">https://forum.vingrad</span><span style="color: #0000ff; text-decoration: underline;"><br /></span></p> Введение 2013-08-15T20:27:20+07:00 2013-08-15T20:27:20+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/sushchnost-oop/vvedenie.html Super User toto44@inbox.ru <p style="text-align: center; margin: 0px 113px;"><span class="f_Heading1">Объектно-ориентированное программирование (ООП</span><span class="f_Heading1">)</span></p> <p> </p> <p>Объекты – это крупнейшее достижение в современной технологии программирования. Смеем утверждать, что изобретение и практическая реализация объектов являются подвигом человеческого гения. Это не пустые слова: объекты позволили строить программу не из чудовищных по сложности процедур и функций, а из кирпичиков-объектов, заранее наделенных нужными свойствами. Самое приятное в этом то, что внутренняя сложность объектов скрыта от программиста, он просто пользуется готовым строительным материалом.</p> <p> </p> <p>Сейчас преимущества использования объектов очевидны для всех. Однако так было всегда. Сначала старая гвардия не поняла и не приняла объекты, поэтому они почти лет потихоньку развивались в различных языках, первыми из которых были Simula 67 и Smalltalk 72. Постепенно объектно-ориентированный подход нашел себе место и в более мощных языках: С++, Turbo Pascal 6.0/7.0, Modula, ADA и множестве других. Блестящим примером реализации объектов была библиотека Turbo Vision, предназначенная для построения пользовательского интерфейса DOS-программ.</p> <p> </p> <p>Полную победу объекты одержали после воцарения Windows: теперь без них в программировании просто не обойтись. Delphi – не исключение, она в своей основе является объектно-ориентированной и говорить о программировании без объектов про бессмысленно. Чтобы вы не рылись в других книгах, собирая информацию по крохам, мы не поленились и собрали в этой главе все, что нужно знать об объектах Delphi. Для новичка важнейшее здесь: инкапсуляция, наследование, полиморфизм, остальное можно просто просмотреть и возвращаться к материалу по мере накопления опыта. Профессионалу полезно прочитать внимательно все от начала до конца. Так что давайте засучим рукава и приступим к делу.</p> <p style="text-align: center; margin: 0px 113px;"><span class="f_Heading1">Объектно-ориентированное программирование (ООП</span><span class="f_Heading1">)</span></p> <p> </p> <p>Объекты – это крупнейшее достижение в современной технологии программирования. Смеем утверждать, что изобретение и практическая реализация объектов являются подвигом человеческого гения. Это не пустые слова: объекты позволили строить программу не из чудовищных по сложности процедур и функций, а из кирпичиков-объектов, заранее наделенных нужными свойствами. Самое приятное в этом то, что внутренняя сложность объектов скрыта от программиста, он просто пользуется готовым строительным материалом.</p> <p> </p> <p>Сейчас преимущества использования объектов очевидны для всех. Однако так было всегда. Сначала старая гвардия не поняла и не приняла объекты, поэтому они почти лет потихоньку развивались в различных языках, первыми из которых были Simula 67 и Smalltalk 72. Постепенно объектно-ориентированный подход нашел себе место и в более мощных языках: С++, Turbo Pascal 6.0/7.0, Modula, ADA и множестве других. Блестящим примером реализации объектов была библиотека Turbo Vision, предназначенная для построения пользовательского интерфейса DOS-программ.</p> <p> </p> <p>Полную победу объекты одержали после воцарения Windows: теперь без них в программировании просто не обойтись. Delphi – не исключение, она в своей основе является объектно-ориентированной и говорить о программировании без объектов про бессмысленно. Чтобы вы не рылись в других книгах, собирая информацию по крохам, мы не поленились и собрали в этой главе все, что нужно знать об объектах Delphi. Для новичка важнейшее здесь: инкапсуляция, наследование, полиморфизм, остальное можно просто просмотреть и возвращаться к материалу по мере накопления опыта. Профессионалу полезно прочитать внимательно все от начала до конца. Так что давайте засучим рукава и приступим к делу.</p> Игра отражений 2013-08-15T20:40:50+07:00 2013-08-15T20:40:50+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/sushchnost-oop/igra-otrazhenij.html Super User toto44@inbox.ru <p>Автор: Владимир Волосенков</p> <p> </p> <p>Музыку любите, а на инструменте неприличное слово нацарапали.</p> <p>"Республика ШКИД"</p> <p> </p> <p> </p> <p>Данный материал является независимым дополнением/исправлением к статье Дмитрия Логинова "ЯП, ОПП и т.д. и т.п. в свете безопасности программирования". Поводом к написанию явилось наличие в исходном материале множества неточностей и откровенно ложных сведений, вводящих в заблуждение неподготовленного читателя.</p> <p> </p> <p>Условно материал Дмитрия можно разделить на две части: историческую и непосредственно техническую. По исторической части у меня вопросов нет, и прочитал я ее с большим интересом. Целью данного материала является внесение ясности по техническим вопросам в меру моих скромных знаний.</p> <p>Исходный текст я буду приводить курсивом. Т.к. в статье в основном сравнивается C++ и Delphi, то вместо Pascal или Object Pascal будет использоваться сокращение ОР. Т.к. автор в своем повествовании не ограничивался сравнением только безопасности программирования в С++ и ОР, то я также позволю себе сравнения по всем аспектам. Конечно, только в рамках технических фактов.</p> <p> </p> <p>Кроме того, в скобках иногда будут встречаться комментарии за подписью КоТ. Это замечания одного непрофессионального программиста по поводу моих и Дмитрия размышлений. Пишет он в С++ и исключительно под Linux, называет себя не иначе, как глупым ламером. Впрочем, исходя хотя бы из того, что обычно настоящие ламеры себя таковыми не считают, его высказывания весьма интересны и часто к месту. Итак, приступим.</p> <p> </p> <p>Сразу замечу, что размер страницы памяти для процессоров Intel и MIPS составляет 4К, а для Alpha - 8K (а не 2 и 4К соответственно).</p> <p> </p> <p>Начнем с принципиальных отличий в модели обработки исключений в С++ от Делфи. И какие это порождает гадости (КоТ: почему именно гадости?). В первую очередь, Борланд ввел некоторые ограничения на перегенерацию собственных исключений. Вырезка из Help:</p> <p>1) You cannot rethrow an operating system exception once the catch frame has been exited and have it be caught by intervening VCL catch frames.</p> <p>2) You cannot rethrow an operating system exception once the catch frame has been exited and have it be caught by intervening operating system catch frames.</p> <p>3) You cannot use "throw"(аналог Делфийского raise) to reraise an exception that was caught within VCL code.</p> <p> </p> <p>Приведенная автором вырезка в Delphi Help отсутствует. Да и с какой стати там будет указываться ключевое слово "throw" из С++? Более всего это похоже на вырезку из хелпа C++ Builder. Соответственно и ограничения на работу с более мощной моделью исключений ОР, используемой в VCL (доказательства будут ниже). Выводы делаем сами…</p> <p> </p> <p>Рассматривая модель ООП в Делфях и модель ООП в С++, легко прийти к выводу, что функционально модель С++ шире, и поэтому Борландовский Буилдер легко "глотает" делфийский VCL.</p> <p> </p> <p>Используя модель ООП С++, создать, к примеру, среду Delphi или библиотеку VCL невозможно в принципе (если не касаться разработки новых компиляторов). Это было неоднократно доказано в дискуссиях с другими фанатами С++. Как ограничения выступают отсутствие классовых ссылок, виртуальных конструкторов и ущербная модель RTTI в С++. Не буду утверждать, как работает C++ Builder, но подозреваю, что ключевые моменты работы среды с компонентами написаны на ОР.</p> <p> </p> <p>Думаю, если бы С++ позволял написать VCL, то Delphi пришлось бы сейчас "глотать" чужой код. Но пока все наоборот. Кстати, Borland имела прекрасную возможность пересмотреть свои воззрения на языковую основу VCL при разработке Kylix (этот проект включает и ОР и С++). Однако революции не произошло. Революция уже случилась в 95-м году с выходом Delphi 1 :)</p> <p> </p> <p>В С++ классы могут находиться в любой памяти, из перечисленных выше трех [статическая, стек, динамическая].</p> <p> </p> <p>(КоТ: Никакого плюса не вижу, говорю как С++ - программер. Мало геморроя с распределением динамической памяти, так еще и со всеми другими. Из-за этого я на линух от доса перешел - кстати. И вообще, на мой (ламерский) взгляд, распределение памяти - вопрос не к языку, а к мемори-модели операционной системы.)</p> <p> </p> <p>В Делфи классы (объекты) могут располагаться только в динамической памяти</p> <p> </p> <p>Что, безусловно, добавляет той самой безопасности программирования. К примеру, функция может вернуть ссылку на объект в стеке, который уже уничтожен. (КоТ: такие ошибки у меня часто были в досовском паскале. Именно тогда я привык инициализировать все переменные в процессе декларирования.) Если Дмитрий интересовался вопросами сборки мусора, то не мне ему объяснять, что сделать это в одной динамической памяти куда легче.</p> <p> </p> <p>Из этого вытекает следующее отличие. Все конструкторы и деструкторы классов Паскаля вызываются явно.</p> <p>object := TMyObject.Create. // где-то в начале</p> <p>//....</p> <p>object.Free; // где-то в конце</p> <p>С одной стороны хорошо. Все ясно, как никогда. Но это специфика Паскаля заставляет программера делать уйму работы, и порой ошибаться (КоТ: а что, С++ прямо так вот и гарантирует безошибочность?) Частенько бывает необходимо иметь "неявный" вызов или конструктор "по умолчанию". Конструктор класса С++, например, вызывается как только встречается описание экземпляра (переменной) класса. И, соответственно, деструктор вызовется, как только класс "выйдет из области видимости".</p> <p> </p> <p>(КоТ: опять подмена терминов. Т.е. банально нечестная игра. Справедливей, имхо, сказать, что в определенных задачах приходится не надеяться на механизм порождения классов дельфы. Но ведь и в С++ есть точно такие же ситуации - где-то ты можешь положиться на язык (компилятор), где-то - не можешь. Так в чем же преимущество?)</p> <p> </p> <p>Не нужно преувеличивать количество работы программера. Вызвать конструктор и деструктор совсем не сложно. К тому же, компоненты на форме, например, создаются и уничтожаются автоматически, что очень облегчает жизнь новичкам. При уничтожении компонента ссылка на него в обязательном порядке обнуляется компонентом-владельцем.</p> <p> </p> <p>А что касается области видимости класса и времени жизни, то это элементарно организуется использованием интерфейсов. Всю работу по подсчету количества ссылок и автоматическому менеджменту памяти возьмет на себя Delphi. (КоТ: кстати, в том же С++ такой же механизм я сам организовывал часов за восемь. Не скажу, что просто и легко, но возможно. Минус - лишний геморрой, плюс - можешь сделать сам, какой нужно, с точностью до битовых полей и регистров.) В Delphi этот механизм также может быть легко реализован по-своему.</p> <p> </p> <p>К тому же, такая форма конструирования имеет под собой четкую логическую основу. Она напрямую ориентированна на использование классовых ссылок, когда вместо статического указания типа (TMyObject) используется переменная типа "тип класса":</p> <p>TComponentClass = class of TComponent; //ссылка на класс</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> CreateAny(AType: TComponentClass): TComponent;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := AType.Create(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">…</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Form1.InsertComponent(CreateAny(TButton));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Создали кнопку</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Form1.InsertComponent(CreateAny(Edit1.ClassType));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Создали еще одно поле редактирования</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Скажем прямо, такие решения в С++ недоступны. В качестве лирического отступления можно сказать, что именно на этом основана работа Delphi IDE с любым компонентом.</p> <p> </p> <p>Вас не удивляло, что Delphi способна не то что без перекомпиляции, а даже без перезапуска брать внешние, абсолютно не знакомые ей классы (компоненты, которые можно инсталлировать хоть каждые 5 минут, тип которых, конечно, неизвестен) и строить на их основе другие классы (формы и т.д.) в run-time (для разработчика design-time)?</p> <p> </p> <p>(КоТ: круто, конечно)</p> <p> </p> <p>Очень занимательный вопрос, скажу я вам. Прикиньте, как бы вы реализовали это в своем приложении. Механизм должен быть очень универсальным, работающим для любого компонента. Компоненты поставляются, например, в виде DLL (или packages - разновидность DLL). Тут никакая RTTI в чистом виде не поможет. Применительно к этой задаче даже шаблоны С++ абсолютно бесполезны, т.к. они являются механизмом compile-time only.</p> <p> </p> <p>Секрет заключается в механизме классовых ссылок, которые фактически являются ссылками на VMT класса. Классовые ссылки регистрируются в пакетах с помощью процедуры Register. Ну и без виртуальных конструкторов, конечно, здесь тоже каши не сваришь.</p> <p> </p> <p>Ну теперь самое интересное - динамическая память. Тут еще проще - у указателей конструкторов и деструкторов нет. Но, повторюсь, это у встроенных типов. Чтобы вызвать конструктор у указателя надо воспользоваться оператором new. В случае же удаления - оператором delete.</p> <p> </p> <p>TComplex* c; // переменная указатель на тип TComplex - ниче не вызывается.</p> <p> </p> <p>(КоТ: ну кто же в софтине будет САМ создавать указатель на пустое место? Зачем? Чтобы stack error'ом по хоботу получить? Объявил переменную - инициализируй!!! Вот так:</p> <p>TСomplex* c=new TComplex(1,1)</p> <p>// "а будешь делать не так, надеру уши" (с) Зеф, "Обитаемый остров")</p> <p> </p> <p>c = new TComplex(1,1); // выделяется память под TComplex и вызывается его конструктор с параметрами.</p> <p>delete c; // освобождаем память предварительно вызвав деструктор Tcomplex</p> <p> </p> <p>Вот здесь работа с классами похожа на Делфийскую работу. Похожа-то, похожа - да не совсем.</p> <p>. (КоТ: на CENSORED похожа, да и работы я здесь не вижу что-то.)</p> <p> </p> <p>Во-первых: как вы успели заметить new и delete - это операторы. Значит их можно переопределять (КоТ: кстати, НЕ ВСЯКИЙ оператор С++ переопределяется). Значит, где захочу - там и будут лежать мои классы. Так можно организовать несколько куч, даже не имея "много-кучевого" менеджера ОС. Я позже опишу, как это влияет на безопасность</p> <p> </p> <p>Странно, но Дмитрию не известно, что управление памятью классов в ОР реализовано даже не с помощью операторов, а гораздо красивее - на уровне TObject, виртуальными (!) методами NewInstance и FreeInstance. Таким образом, абсолютно ЛЮБОЙ класс может переопределить эти методы для осуществления желания "где хочу - там и буду лежать". Соответственно организуется и "многокучность".</p> <p> </p> <p>Во-вторых: здесь всплывает понятие "ВРЕМЯ ЖИЗНИ КЛАССА" и то, как обрабатываются исключения в конструкторах и деструкторах. Рассмотрим это поближе. В Делфи время жизни класса таково:</p> <p>Рождение: Класс начинает свое существование сразу ПОСЛЕ окончания работы КОНСТРУКТОРА(вызов AfterConstruction).</p> <p>Смерть: Класс заканчивает свое существование сразу ПОСЛЕ окончания работы ДЕСТРУКТОРА(вызов BeforeDestruction).</p> <p> </p> <p>Неправильно. Before он на то и Before, чтобы отрабатывать ДО вызова деструктора. И это вовсе не значит, что класс уже уничтожен. Для справки: BeforeDestruction введен для того, чтобы создатель класса был уверен, что необходимые действия перед его уничтожением будут выполнены всегда, независимо от того, вызовут или нет его потомки унаследованный деструктор. По поводу AfterConstruction разговор будет чуть позже.</p> <p> </p> <p>Кроме того, и конструкторы и деструкторы в ОР имеют приятную особенность (и далеко не одну). Они могут вызываться как обычные методы. Для этого в них передается неявный параметр. Не путать с неявным Self или this. Кстати, Self в классовых методах ОР является классовой ссылкой, а не объектной.</p> <p> </p> <p>Так что вопросы рождения и смерти в ОР далеко не так тривиальны. Впрочем, самые интересные подробности еще впереди.</p> <p> </p> <p>В С++ немножечко по другому:</p> <p>Рождение: Сразу ПЕРЕД телом конструктора.</p> <p>Смерть: Сразу ПОСЛЕ тела деструктора.</p> <p>Это несколько меняет работу с конструкторами/деструкторами родителями и конструкторами/деструкторами членами. Вот С++:</p> <p>class TChild : public TMama,TPapa{ // :o)</p> <p>TMemberOne member_1_;</p> <p>TMembarTwo member_2_;</p> <p>public:</p> <p>TChild() { cout&lt;&lt;"TChild created!"; }</p> <p>}</p> <p> </p> <p>Порядок конструкторов будет следующий: TMama, TPapa, TMemberOne, TMemberTwo и только потом вызовется ТЕЛО конструктора TChild. Это логично и похоже на правду. (КоТ: немножко беременной быть можно? Это похоже на правду, или это правда? Разницу чувствуете?) Действительно, когда мы можем получить доступ к методам и полям(переменным класса) родителей и классов-членов(конкретных классов)? Мы можем получить этот доступ только, когда они сконструированы. И это лучше оставить на совести компилятора, чем надеяться на программера.</p> <p> </p> <p>Вообще типичной идеологией компилятора С++ считается: "Ну, парень, если ты хочешь сделать именно так, делай, а я умываю руки". А тут такая удивительная забота о программере! Только вот она в данном случае совсем не к месту, по крайней мере, в таком виде. Как контраст - конструкторы ОР.</p> <p> </p> <p>Допустим, у нас есть иерархия классов A -&gt; B -&gt; C. Мы конструируем класс С. Действительно, в С++ последовательность конструирования будет A -&gt; B -&gt; C. И никак иначе.</p> <p> </p> <p>Теперь признайтесь, когда вы пишите конструктор в ОР, вы ведь первым делом указываете вызов inherited. Да? В этом случае последовательность конструирования абсолютно аналогична. Но! Стоит вам убрать inherited, и Delphi будет конструировать класс C в последовательности C -&gt; B -&gt; A. Неплохо для начала, но это еще цветочки.</p> <p> </p> <p>Незаметное inherited дает вам полный контроль над тем КАК, КОГДА и КАКИЕ конструкторы будут вызываться (и будут ли вызываться вообще, ведь inherited можно и в if засунуть). Нет никаких ограничений на расположение inherited в теле конструктора. А ведь его еще можно дополнить именем конкретного конструктора предка с указанием нужных параметров. Ну и, конечно, можно вызывать собственные конструкторы. (КоТ: это здорово, однако).</p> <p> </p> <p>Таким образом, сначала, например, может отработать часть конструктора С, затем конструкторы предков, затем оставшаяся часть конструктора С. Для чего все это?</p> <p> </p> <p>Прозаический пример. В конструкторе С создается некоторый объект (аллокатор памяти, например), который используется для работы в конструкторе предка B. Другой наследник, класс D, может создавать совершенно другой объект. Создание этого объекта можно вынести в виртуальную функцию, которую вызывать перед inherited.</p> <p> </p> <p>Да, такие возможности используются не слишком часто, но им есть реальное применение. Показательно, что подобный подход нереализуем в С++ никакими способами. Он никогда не даст создать что-то ПЕРЕД работой конструктора предка.</p> <p> </p> <p>(КоТ: сорри, сир! Переопределив new под это дело (кстати, одно из упражнений в каком-то С++-учебнике), вполне возможно и вызвать. Только потом приходится delete лечить - он-то базируется на стандартных умолчаниях. То есть, данных объекта нет, и объекту адрес не выделен, но VMT его есть. В библиотеке или там где еще, не суть. И к этой VMT можно добраться через разную там… гм… CENSORED Плюс дельфы в откровенности доступа ко всем VMT проекта, независимо, созданы ли объекты соответствующих классов).</p> <p> </p> <p>Как правило, на этом месте фанаты С++ начинают кричать, что это де нелогично, так быть не должно… Но на самом деле нет ничего плохого в том, что конструктор использует в своей работе виртуальные принципы. Никто не утверждает, что экземпляр станет объектом С или В раньше, чем он станет объектом А. Конструкторы всего лишь выполняют свою работу, не важно в каком порядке.</p> <p> </p> <p>(КоТ: От слабости кричать. Т.к. это, безусловно, бонус дельфе перед С++, но и С++-модель определенные преимущества все-таки имеет).</p> <p> </p> <p>Более того, вызов указанной виртуальной функции совершенно бесполезен. Почему? В С++ при работе каждого из конструкторов A, B, C таблица виртуальных методов VMT будет соответствовать именно тому классу, к которому принадлежит конструктор. Т.е. вызов ЛЮБЫХ виртуальных методов в конструкторе С++ теряет всякий смысл, т.к. не является виртуальным (будет вызван соответствующий метод для класса А или В, а не для С). То же касается и деструкторов С++.</p> <p> </p> <p>В ОР при работе любого из конструкторов предков VMT всегда соответствует РЕАЛЬНОМУ создаваемому классу, т.е. классу С. Вызовы виртуальных методов будут правильными. В принципе, это может создать опасную ситуацию, когда в данном виртуальном методе какой-то из наследников подразумевает, что класс уже полностью сконструирован. Именно для разрешения этой проблемы и существует виртуальный метод AfterConstruction.</p> <p> </p> <p>Теперь мы четко видим, что конструкторы ОР обладают НАМНОГО большей гибкостью и мощью. Конечно, при условии, что программист понимает, что делает. (КоТ: при условии, что программист понимает, что делает, и С++ не так уж плох ;-) А это не так уж и сложно. По крайней мере, практика показывает, что эти конструкторы не доставляют никаких хлопот программистам. А значит, увеличение мощи не уменьшило "безопасности программирования" :) Продолжим.</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> E: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span><span class="f_CodeExample" style="color: #000000;"> A,B </span><span class="f_CodeExample" style="color: #000080;">{</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> C* c_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> D* d_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> public: </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> E(); // реализацию см.ниже</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> ~E() { delete d_; delete c_; }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> E::E() </span><span class="f_CodeExample" style="color: #000080;">// конструктор класса E</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> : A(</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">), B(</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">), c_( new C ), d_( new D ) </span><span class="f_CodeExample" style="color: #000080;">// список инициализации</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ //начало тела конструктора</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> cout&lt;&lt;"Constructor body";</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> }</span><span class="f_CodeExample" style="color: #000080;">// конец тела конструктора</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> catch(...)</span><span class="f_CodeExample" style="color: #000080;">{ // ловим любое исключение</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> A::~A();</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> B::~B();</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> delete c_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> delete d_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> }</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p>Непривычное написание, не так ли? Да, в Делфях нельзя ВЕСЬ процесс конструирования поместить в блок try except.</p> <p> </p> <p>Неправильно! Скорее можно сказать, что в ОР нельзя НЕ поместить весь процесс конструирования в блок try…except. При вызове конструктора ОР как классового (статического, в терминах С++) метода (т.е. через классовую ссылку) блок try…except устанавливается АВТОМАТИЧЕСКИ. При возникновении любого необработанного исключения в конструкторе автоматически вызывается деструктор. Это, однако, не мешает вписать в тело конструктора свои блоки обработки исключений, в том числе и для полной, безопасной обработки некоторых их типов.</p> <p> </p> <p>Здесь уместно более подробно осветить различия в способах вызова конструкторов ОР. Как я уже говорил, конструктору компилятором неявно передается параметр, который говорит, что он вызывается как классовый или как обычный метод.</p> <p> </p> <p>В случае классового метода:</p> <p>устанавливается блок try…except;</p> <p>вызывается виртуальный метод NewInstance, выделяющий память под экземпляр класса. В случае переопределения Вами этого метода:</p> <p>размер экземпляра можно получить методом InstanceSize;</p> <p>память нужно очистить методом InitInstance;</p> <p>отрабатывает тело конструктора;</p> <p>вызывается виртуальный метод AfterConstruction.</p> <p>В случае обычного метода выполняется только тело конструктора. Блок try…except НЕ устанавливается. Так вызываются все собственные конструкторы и конструкторы предков из тела какого-либо конструктора класса (они все равно попадут в установленный блок обработки исключений). Конструктор может быть вызван где угодно. Главное - использовать объектную ссылку (Self.Create), а не классовую. Условно, реальный код конструктора мог бы выглядеть так:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TSomething.Create(IsClassRef: boolean): TSomething;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> IsClassRef </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self := TSomthing.NewInstance;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> InitInstance(Self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.Create(False); </span><span class="f_CodeExample" style="color: #000080;">// Тело конструктора,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// написанное разработчиком</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.AfterConstruction;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">except</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.Destroy; </span><span class="f_CodeExample" style="color: #000080;">// Если что - харакири :)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.Create(False); </span><span class="f_CodeExample" style="color: #000080;">// Тело конструктора</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p>Аналогичная песня с деструкторами. Но здесь обойдемся без лишних объяснений:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TSomething.Destroy(Deallocate: boolean);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Deallocate </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.BeforeDestruction;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Self.Destroy(False);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Deallocate </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.CleanupInstance;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.FreeInstance;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p>Еще раз замечу, что это чисто гипотетический код, создаваемый компилятором, а не реализация конкретного класса. Конечно, в нем нет никаких рекурсивных вызовов. Продолжим.</p> <p> </p> <p>Но как же быть с динамическими ресурсами? Спросите вы. Все очень просто:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> E::E() </span><span class="f_CodeExample" style="color: #000080;">// конструктор класса E</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> : A(</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">), B(</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">), c_( NULL ), d_( NULL ) </span><span class="f_CodeExample" style="color: #000080;">// список инициализации</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ //начало тела конструктора</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> try{ </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> c_ = new C;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> d_ = new D;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> cout&lt;&lt;"Constructor body";</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> catch(...)</span><span class="f_CodeExample" style="color: #000080;">{</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> if(c_) delete C;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> if(d_) delete D;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> throw;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> } </span><span class="f_CodeExample" style="color: #000080;">// конец тела конструктора</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> catch(...)</span><span class="f_CodeExample" style="color: #000080;">{ // ловим любое исключение</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> throw E_ErrorCreate();</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> }</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p>Видно, что я использовал блок try...catch только для "перевода" одного исключения в другое. И назначение этого блока только такое и никакого другого. Использование его в других целях может привести к гадостям (КоТ: если ножом кухонным неправильно пользоваться, это МОЖЕТ привести даже к смерти… Но ведь не обязательно же приводит! Так претензии к ножу (языку), или к кривым рукам?) ,поэтому в некоторых С++ компиляторах (фирмы Борланд например) эта возможность от греха подальше убрана. Вы еще не заскучали?</p> <p> </p> <p>Нет, Дмитрий, с Вами не соскучишься :)</p> <p> </p> <p>Здесь хочу лишь заметить, что в ОР нет необходимости чистить ресурсы в конструкторе. На это есть деструктор! (КоТ: Вот!!!) Логично, не так ли? Зачем плодить двойной код. А вот конструкции вида</p> <p>if Assigned(MyObject1) then</p> <p>FreeAndNil(MyObject1);</p> <p>if Assigned(MyObject2) then</p> <p>FreeAndNil(MyObject2);</p> <p>ОЧЕНЬ рекомендуется использовать именно в деструкторе. Это хороший стиль. (КоТ: что да, то да.) Конструкция аналогичная if (c_) delete c_ (кстати, здесь была ошибка).</p> <p> </p> <p>(КоТ: с != 0 бывает, т.к NULL-тип машинно-зависимый. Но пустой указатель где-то представлен, напр, отрицательным числом. Если мне понадобилось, я бы писал</p> <p>if (С ! = NULL) // что надо сделать с С</p> <p>хотя Страуструп и советует использовать 0 вместо NULL - в третьей редакции книги. В первой, помнится, советовал обратное ;)</p> <p> </p> <p>Ведь деструктор может быть вызван в любой момент работы конструктора, и часть ресурсов будет неинициализирована.</p> <p> </p> <p>Привел я этот пример не для демонстрации возможностей блока try...catch, а для того чтобы показать как С++ сам делает безопасным процесс "конструирования" класса. В Делфи все это ложиться на хрупкие плЭчи программера.</p> <p>(КоТ: "Врать не надо по телефону" (с) Булгаков)</p> <p> </p> <p>Теперь мы видим, кто действительно "сам делает безопасным процесс конструирования класса", а кто перекладывает все это на чьи-то "хрупкие плЭчи".</p> <p> </p> <p>Кстати о Делфях, я там не нашел аналог функции С++ - uncaught_exception() - показывает статус стека исключений. Благодаря этой функции ваш деструктор знает - нормальное это "устранение" класса или не нормальное. По-моему, очень даже пользительно.</p> <p> </p> <p>Что значит ненормальное устранение класса? Может, мы еще будем считать возникновение исключения ненормальной ситуацией? Между прочим, на исключениях вполне можно выстроить логику работы класса или библиотеки. В ОР этому, кстати, очень способствуют такие преимущества модели исключений перед ANSI C++, как наличие общего предка исключений (и то, что это вообще классы, а не абы что) и наличие блока try…finally (ну это просто добавляет удобств по сравнению с try…catch(…){ throw; })</p> <p> </p> <p>Поэтому не совсем понятно, зачем понадобилась некая функция uncaught_exception(). Зачем лезть в идеологию работы исключений со своим уставом? Ведь они как раз и избавляют разработчика от чрезмерного применения if. Это еще называется реактивной моделью программирования. Но, раз есть спрос, то есть и предложение:</p> <p>ExceptAddr function - returns the address at which the current exception was raised.</p> <p>ExceptObject function - returns a reference to the object associated with the current exception.</p> <p>ExceptProc variable - points to the lowest-level RTL exception handler.</p> <p>Фича в том, что оператор new уже выделил память для экземпляра класса TObject, а тут ррраз! И исключение! Что делает С++? Он тут же освободит память - не надо ставить блок try...catch. Все сделает С++. Ну, как говориться, приятная неожиданность.</p> <p> </p> <p>(КоТ: это стандарт, и кто не знает его, как может говорить, что знает С++?)</p> <p> </p> <p>Ну, это только для тех, кто не очень хорошо знает ОР и С++. Впрочем, такие "детские" неожиданности не избавляют программера в С++ от необходимости защиты динамических ресурсов. В ОР же в это время можно попить пива ;)</p> <p> </p> <p>Я не привожу примеры реализации более полезных УМНЫХ указателей, реализующих сборку мусора и правильную работу с ресурсами вообще.</p> <p> </p> <p>Судя по всему, автор прочитал книгу Джефа Элджера "C++", испестренную идеями УМНЫХ, ВЕДУЩИХ, ГЕНИАЛЬНЫХ указателей и сборки мусора. Здесь хочу заметить, что я иногда читаю книги с карандашом в руке. Это очень хорошая, умная (КоТ: ведущая и гениальная ;-) книга про С++. Только во время ее чтения, постоянно задумываешься, а как можно сделать тоже самое в ОР. В результате после прочтения книга превратилась в записную книжку, испестренную замечаниями о том, насколько проще и красивее выглядела бы в ОР большая часть предлагаемых решений. Для интересующихся - основная идея в использовании свойств и интерфейсов.</p> <p> </p> <p>1) Работа с несколькими "собственными" кучами. Например, все покупатели складываются в одну кучу. А поступаемые товары в другую… Как видите осталось только реализовать менеджер кучи, что в рамках С++ вещь простая и ведущая себя незаметно (как встроенная фича). Можно так извернуться в Делфях? Нет</p> <p> </p> <p>(КоТ: Если можно проще и лучше, так изворачиваться-то нафиг?)</p> <p> </p> <p>Мы уже выяснили, что можно. И как-то изворачиванием это и не назовешь. Обычная работа. Хочешь, переопределяй работу с памятью на уровне классов, хочешь, глобальный менеджер памяти напиши.</p> <p> </p> <p>2) Помимо "многокучности", оператор new предоставляет вам возможность "виртуального" размещения объекта. Например в файле, в Сети, где вашей душеньке будет угодно. Это тоже недоступно в Делфях.</p> <p> </p> <p>(КоТ: Это и в С++ без корбы тоже не особенно хорошо получается, кстати. И опять же, нафига? чтобы без спроса прога в своп лазила? Или в инет звонила?)</p> <p> </p> <p>Откуда такая категоричность? Возможностей "виртуального" размещения у ОР ничуть не меньше. Или операционная система предоставляет для программ на С++ особые механизмы работы с файлами, с сетью и т.д.?</p> <p> </p> <p>Кстати о преобразовании типов. Делфи обязан безопасному преобразованию типов(as и is) C++, а точнее шаблону dynamic_cast.</p> <p> </p> <p>(КоТ: Страуструп: "как правило, НЕБЕЗОПАСНО (выделено мной - КоТ) использовать указатель, преобразованный или приведенный с помощью функций …_cast к типу, отличному от типа объекта, на который он указывает.") Да, а в ОР эта вещь абсолютно безопасна…</p> <p> </p> <p>Не уверен, что кто-то кому-то обязан, тем более шаблону. У ОР всегда была и остается система RTTI, намного превосходящая возможности С++. Да и вообще, RTTI - это обобщенный языковой механизм. При чем здесь конкретные реализации?</p> <p> </p> <p>Правда в Делфях такое же ограничение на множественное наследование, как и в Яве. Один класс должен быть интерфейсным.</p> <p> </p> <p>Что за терминология? Дмитрий, наверное, имел в виду, что в списке предков класса ДОЛЖЕН быть указан один класс, и МОЖЕТ быть указано сколько угодно интерфейсов.</p> <p> </p> <p>Дело в том, что в Делфи тип class реализован через одно очень загадочное место. Связано это с большой нелюбовью паскаля к памяти</p> <p> </p> <p>(КоТ: это БЫЛО в ДОСе, десять лет назад, но ведь с тех пор воды утекло - !!!)</p> <p> </p> <p>Можно, конечно, и так сказать. Все в мире относительно. Но я до сих пор встречал очень мало людей, достаточно глубоко знающих устройство классов в Delphi, точнее мне доводилось только читать их труды. И статью Дмитрия тяжело отнести к таким трудам. И почему он решил, что ОР не любит память?</p> <p> </p> <p>Тип указатель в паскале создан только для того, чтобы указывать на что-то в динамической памяти(куче). Он создан, как шлюз между статической памятью паскаля и кучей. Странно, но зачем-то разработчики языка оставили возможность приводить целое к указателю (КоТ: к дождю, может быть? ;-)</p> <p> </p> <p>Ни разу не доводилось слышать об ограничении указателей ОР на работу только с кучей. Возможность же приводить целое к указателю позволяет "двигаться" по памяти (не думаю, что это секрет для Дмитрия). Кстати, для указателей на строки допустимы операции "+" и "-" (в том числе в комбинации с целыми) без приведения типов.</p> <p> </p> <p>Такое понятие как ссылка не знакомо паскалю</p> <p> </p> <p>(КоТ: тогда в 6.0 под ДОС я работал не с ссылками… а с чем???)</p> <p> </p> <p>Ссылка в терминологии ОР - это типизированный указатель. А используя термины С++ (КоТ: Страуструп: "Ссылка является альтернативным именем объекта.") ссылкой в ОР являются формальные параметры методов, объявленные с использованием var или out (возможно кто-то не знал, out - то же, что и var, только работает исключительно на возврат значения). Кроме того, чистой воды ссылками являются объектные переменные (Button1: TButton).</p> <p> </p> <p>Если вы пишите класс "комплексное число", а затем решаете создать массив чисел, то array [1..10] of TComplex; будет на самом деле занимать в памяти 4*10 байт плюс выравнивание. Т.о. вы может быть хотели именно массив ТОЛЬКО КОМПЛЕКСНЫХ чисел, а не указателей на них. Но вместо этого, после инициализации, у вас будет израсходовано (4*10 + 10*sizeof(TComplex)) байт памяти. Короче сами считайте</p> <p> </p> <p>Действительно, использовать классы ОР в массивах не очень удобно. Есть несколько более экономичных решений:</p> <p>1) Можно организовать свой менеджмент памяти для TComplex, размещая экземпляры в памяти подряд (например, в заранее выделенном пуле), и работу, скажем, на основе динамического массива. Не самое простое решение, но весьма эффективное и красивое (КоТ: Кстати, активно применяется в С++-модели).</p> <p>2) Можно вместо классов использовать записи record, организовав их в массив, являющийся свойством по умолчанию какого-то класса:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TItem = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">record</span><span class="f_CodeExample" style="color: #000000;"> …</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TArray = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Items[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: integer]: TItem</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetItem</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetItem;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">default</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Это будет самое экономичное решение, т.к. каждый экземпляр любого класса имел бы как минимум ссылку на таблицу VMT. А запись содержит только необходимые данные. Вся же логика работы - в классе TArray.</p> <p>3) Можно использовать старые "объекты" Паскаля вместо "классов": TComplex = object … end; И массив таких объектов будет содержать сами объекты, а не ссылки на них. Это будет самое оригинальное решение. Кстати, на таких объектах построена библиотека KOL (https://xcl.cjb.net/) - аналог VCL. Размер EXE файлов с использованием этой библиотеки начинается от 4.5К (если не изменяет склероз :)</p> <p>Одним словом, проблема в разработчике, а не в языке. (КоТ: Вот!!!)</p> <p> </p> <p>Паскаль маленький язык и это не недостаток. (КоТ: Уф!. Ну сколько можно говорить о паскале 10-летней давности?) ?) Его не замечаешь, когда пишешь прогу большую или маленькую. (КоТ: это высшая похвала паскалю вообще. Лучшая одежда - та, которой не замечаешь.) Почему? (КоТ: Потому, что это хороший язык.)</p> <p> </p> <p>Потому что Паскаль от Борланд специальный язык, т.е. предназначен для узкой области. Узкая - это не значит, что программ мало, просто цели в этой области отличаются не намного.</p> <p> </p> <p>(КоТ: "С++ создавался для того, чтобы ИЗБАВИТЬ автора и его друзей ОТ ПРОГРАММИРОВАНИЯ НА АССЕМБЛЕРЕ" - (с) Бьерн Страуструп. Дельфа, возможно, создавалась для того, чтобы избавить автора от программирования на паскале, который вообще создавался изначально для ОБУЧЕНИЯ ПОНЯТИЯМ информатики. Оба эти языка свои цели выполнили с блеском. Ну так о чем же спор, цели-то разные?)</p> <p> </p> <p>Не знаю, может быть ОР и маленький язык. Однако я оцениваю свои знания ОР не более, чем на 60-70% (хотя меня как-то угораздило сдать экзамен на сертификат Brainbench Certified Master Delphi Programmer :), не включая сюда VCL или среду Delphi, разговор только о самом языке. Если охватить все, то я вообще ничего не знаю. Поэтому мне даже как-то неловко заниматься здесь исправлениями. Я считаю, что для этого необходим куда больший кругозор. Но пока за эту задачу никто не взялся. Видимо настоящим профессионалам просто не до этого.</p> <p> </p> <p>По поводу узости области применения. До последнего времени я считал, что единственное, что нельзя делать в Delphi - это писать драйвера (ОР тут ни причем, это не языковое ограничение). Но недавно натолкнулся на пример создания в Delphi 3 драйвера VxD. Что еще? Игрушки, сетевые сервисы, системные утилиты, распределенные базы данных, научные программы, средства мультимедиа в Delphi пишут и очень успешно. Так о чем речь?</p> <p> </p> <p>Поэтому резонно было бы выбрать язык, который необходим только для склеивания компонентов или их написания. За все остальное отвечает среда.</p> <p> </p> <p>После таких утверждений становится странно, как человек позволяет себе критиковать продукт, о котором имеет лишь зачаточное представление. За что "все остальное" отвечает среда? В виде списка, пожалуйста.</p> <p> </p> <p>Delphi IDE - это, по большому счету, лишь оболочка, набор зацепок к возможностям библиотеки VCL и шикарный пример использования возможностей языка. Это продукт, тратящий наименьшее количество усилий для выполнения одной и той же работы в сравнении с аналогами. Ведь в лице библиотеки VCL он в design-time использует тот же самый код, который работает в готовом приложении. Для сохранения спроектированной формы со всеми компонентами в ресурс Delphi достаточно одной строчки кода!</p> <p> </p> <p>И потом, "склеивание" и "написание" компонент - вещи по своей сложности абсолютно разные. Visual Basic тоже хорошо склеивает COM-компоненты, только вот с их написанием у VB как-то не очень… То, что ОР позволяет легко и непринужденно создавать и склеивать любые компоненты говорит лишь о его мощности, продуктивности и универсальности. Совершенно очевидно, что сегодня ОР по этому показателю не имеет не то что конкурентов, а даже толковых аналогов.</p> <p> </p> <p>VCL не является языковым расширением Паскаля - это "ОО" библиотека. Транспортом же между такими библиотеками и отдельными компонентами выступает некая переделка СОМ от Борланд.</p> <p> </p> <p>Да, VCL - вещь самостоятельная, пока она строится на ОР. Далее автор, похоже, говорит о RTTI. Но причем здесь транспорт между библиотеками и отдельными компонентами? Библиотека - понятие чисто условное. Каждый написанный мной компонент становится полноправной частью VCL. Правильнее, наверно, говорить о транспорте между компонентами и их пользователями, в частности средой Delphi IDE.</p> <p> </p> <p>К вопросу о переделках. Delphi начинала разрабатываться где-то в 92-93 году. Трудно говорить, кто кого переделал. Да это и не важно. Важно то, что компонент Delphi в полной мере обладает обоими механизмами.</p> <p> </p> <p>И опять же отбросьте этот транспорт, который не является частью языка, и от Делфи ничего не останется. (КоТ: Отбрось Gdb\Gtk, STL - что останется от милого нашему сердцу С++?) Поэтому Делфи очень гармоничная со своими недостатками среда для разработки GUI приложений под винды.</p> <p> </p> <p>Да, RTTI - незаметная, но ключевая для Delphi технология. А вот с тем, что она не является частью языка можно крепко поспорить. Достаточно вспомнить операторы AS и IS, которые целиком базируются на RTTI. Да и от TObject никуда не убежишь. Попробуй скажи, что это не часть языка. А ведь основное содержание TObject - реализация RTTI.</p> <p> </p> <p>Кроме того, Delphi идеально подходит не только для создания GUI приложений, но и консольных, и приложений без визуального интерфейса вообще (например, сервисы Windows NT). К счастью компоненты Delphi не ставят во главу угла визуальность/невизуальность. Это абсолютно универсальные в применении классы. Уже поэтому Delphi разительно отличается от, например, MSVC++, где в основе слова "Visual" лежит наличие у компонента оконного идентификатора и множество маловразумительных макросов и комментариев по тексту, которые нельзя (!) редактировать. Вот где действительно безопасный язык! Ведь программист может все испортить :)</p> <p> </p> <p>По поводу недостатков можно сказать лишь то, что вряд ли у конкурирующих с Delphi продуктов их меньше. А вообще, давайте взглянем на Delphi 6 и Kylix. Уверен, что сюрпризов там будет более чем достаточно.</p> <p>(Кот: я очень надеюсь, что у нас научатся, наконец, считать "Итого", а не только недостатки и достоинства отдельно).</p> <p> </p> <p>Похоже, Дмитрий применительно к безопасности программирования рассматривал только те моменты, которые, по его мнению, хорошо смотрелись в С++ в сравнении с ОР. Здесь, кстати, стоит упомянуть такие преимущества С++ над ОР, как возможность понижать видимость членов класса, а также указание const при объявлении метода, что гарантирует неизменность атрибутов объекта при вызове метода.</p> <p> </p> <p>Однако не стоит забывать, что ОР является языком, который действительно ставит во главу угла безопасность практически во всем. Можно долго перечислять все его тонкости, избавляющие программера от головной боли и рутиной работы. Как пример, можно привести директиву implements для свойств (делегирование реализации) или объявление глобальных переменных в разделе threadvar для поддержки многопоточности, или замечательную реализацию работы со строками и динамическими массивами на уровне компилятора. Очень важное для безопасности программирования свойство - объявление новых типов.</p> <p> </p> <p>Гради Буч: "К сожалению, конструкция typedef не определяет нового типа данных и не обеспечивает его защиты. Например, следующее описание в С++:</p> <p>typedef int Count;</p> <p>просто вводит синоним для примитивного типа int."</p> <p> </p> <p>В ОР же мы можем создать абсолютно новый тип. Для этого надо применить ключевое слово type:</p> <p>type</p> <p>Count = type int64; // другой тип</p> <p>Alias = int64; // синоним</p> <p>Типы Count и int64 уже не будут совместимы без приведения типов.</p> <p> </p> <p>А вот пример стандартизованной фичи компилятора (соответственно и языка) С++:</p> <p>long FileSize = 256 * 1024;</p> <p> </p> <p>В 16-битном компиляторе вы в результате получите 0. Очень приятный сюрприз! А дело в том, что 256 и 1024 по отдельности попадают в int (2 байта), а их произведение уже в long (4 байта). Однако стандарт С++ как раз в том и заключается, что произведение будет также помещено в int. И уже только после этого произойдет присвоение к long. Соответственно туда попадает только младшая часть произведения, которая равна нулю. Спасает написание в форме 256 * 1024L. На 32 битах все будет нормально, т.к. размеры типов int и long совпадают (4 байта).</p> <p> </p> <p>Некоторые начинают вяло возражать, что такие вещи нужно помнить, что это, мол, нормально. Однако в эту проблему (обнаружили ее случайно) конкретно уперлись два программера на С++ с очень хорошим опытом работы и в течение получаса не смогли ее решить. С ходу помог только действительно матерый эксперт С++. Ну, и как это выглядит с точки зрения безопасности программирования?</p> <p>(КоТ: плохо выглядит).</p> <p> </p> <p>А как "эстетичны" в каждом header'е С++ конструкции типа:</p> <p>#ifndef _MYHEADER_H</p> <p>#define _MYHEADER_H</p> <p>… body of the header …</p> <p>#endif</p> <p> </p> <p>Получается, я вместо компилятора должен следить, чтобы в проекте оказалась только одна копия каждого файла.</p> <p> </p> <p>Кстати, особенности ОР как языка обеспечивают не только безопасность программирования, но и безопасность полученного софта, как таковую. К примеру, более половины дыр в безопасности программ отраженных в Bugtraq возникают из-за проблемы переполнения буфера. А эта проблема является визитной карточкой С/С++. Дошло до того, что выпускаются специальные пакеты, которые патчят исходники С++. Как один из вариантов решения проблем безопасности предлагают писать на Pascal…</p> <p> </p> <p>После всего, что я тут наговорил, может возникнуть мысль: "А почему же тогда Борланд двигает Делфи?". "И почему VCL написан на паскале, а не на С++?". Резонно. Мыслям вообще свойственно появляться в головах человеков.</p> <p> </p> <p>Нет, мысль возникает не такая. С этим все ясно и так, VCL и Delphi не могут быть написаны ни на чем другом (можно, конечно, на С++ написать компилятор ОР, что вполне реализуемо, и потом в нем все делать, но ведь разработчика такой способ явно не устроит).</p> <p> </p> <p>Возникает другая мысль. Почему уровень знаний ОР у очень многих программистов так удручающе низок (КоТ: С С++ ситуация ничуть не лучше. Груда книг всяких, прости господи, пересмешников. А если прочитать 1 (один) раз Страуструпа, множество вопросов просто отпадет). Понятно, что литература у нас в основном "для чайников". Но иногда надо хотя бы help читать. Похоже считается делом чести начитаться умных книжек "с примерами приложений на С++", а для Delphi, мол, можно ограничиться знанием Object Inspector'а.</p> <p> </p> <p>При этом многие такие программисты почему-то считают для себя возможным критиковать возможности ОР. Может быть потому, что Delphi дала им возможность быстро и легко воплотить свои идеи? А потом вдруг что-то не получилось… И вот, виновата Delphi. Можно с уверенностью сказать, что С++ такому программисту все равно не поможет.</p> <p> </p> <p>Кажется беда Delphi как раз в том, что за внешней простотой многие не могут разглядеть ее истинные возможности. Да и решения об использовании конкретного языка принимаются зачастую на уровне руководства, которое вообще ничего не видит, кроме финансовых показателей дяди Билли.</p> <p> </p> <p>(КоТ: за что я вообще и выбрал линух - это система людей, имеющих роскошь на рынок в некоторых местах вообще плевать. Хотя от рынка, конечно уйти нельзя. Да и зачем? В умеренных дозах рынок - это очень хорошо.)</p> <p> </p> <p>Для любящих спорить. Не стоит критиковать какие-то возможности продукта, не до конца в них разобравшись. Современные языки слишком многогранны, чтобы один человек досконально знал хотя бы два языка. Я лично не уверен, что все мои рассуждения на 100% достоверны, но старался, как мог. Поэтому буду рад техническим исправлениям.</p> <p>"Портос, если Вы говорите глупости, то делайте это, пожалуйста, только от своего имени"</p> <p> </p> <p>P.S. Красота драгоценного камня, как известно, зависит не только от породы, но и от мастерства огранщика. Только тогда обычный белый свет превращается в нем в причудливую игру разноцветных искр. Так что учите матчасть, и Delphi вас не подведет :)</p> <p> </p> <p>(КоТ: Два слова напоследок - не удержался. Я полагаю, что С++, что дельфа - языки одного уровня, но разных подуровней. Бессмысленно их сравнивать вообще. С++ старше - хотя бы поэтому дельфа лучше, т.к написана на его крови, если можно так сказать.</p> <p>Но дельфа все-таки следующее поколение языков. Стоит ли сравнивать сына с отцом, и чему удивляться? Уже народ типами не оперирует, уже оперирует свойствами и объектами. Кто даст хороший язык для этого, тот и выиграет.</p> <p>А что до С++ - учите матчасть… И не хуже будет, чем в дельфе. ;)</p> <p> </p> <p>P.P.S. Да, в конце концов, все измеряется способностями конкретного "юзера" языка. Хочется верить, что эта статья поможет кому-нибудь сделать очередной шаг на длинном пути от "чайника" к "профи".</p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p>https://delphiworld.narod</p> <p>DelphiWorld 6.0</p> <p>Автор: Владимир Волосенков</p> <p> </p> <p>Музыку любите, а на инструменте неприличное слово нацарапали.</p> <p>"Республика ШКИД"</p> <p> </p> <p> </p> <p>Данный материал является независимым дополнением/исправлением к статье Дмитрия Логинова "ЯП, ОПП и т.д. и т.п. в свете безопасности программирования". Поводом к написанию явилось наличие в исходном материале множества неточностей и откровенно ложных сведений, вводящих в заблуждение неподготовленного читателя.</p> <p> </p> <p>Условно материал Дмитрия можно разделить на две части: историческую и непосредственно техническую. По исторической части у меня вопросов нет, и прочитал я ее с большим интересом. Целью данного материала является внесение ясности по техническим вопросам в меру моих скромных знаний.</p> <p>Исходный текст я буду приводить курсивом. Т.к. в статье в основном сравнивается C++ и Delphi, то вместо Pascal или Object Pascal будет использоваться сокращение ОР. Т.к. автор в своем повествовании не ограничивался сравнением только безопасности программирования в С++ и ОР, то я также позволю себе сравнения по всем аспектам. Конечно, только в рамках технических фактов.</p> <p> </p> <p>Кроме того, в скобках иногда будут встречаться комментарии за подписью КоТ. Это замечания одного непрофессионального программиста по поводу моих и Дмитрия размышлений. Пишет он в С++ и исключительно под Linux, называет себя не иначе, как глупым ламером. Впрочем, исходя хотя бы из того, что обычно настоящие ламеры себя таковыми не считают, его высказывания весьма интересны и часто к месту. Итак, приступим.</p> <p> </p> <p>Сразу замечу, что размер страницы памяти для процессоров Intel и MIPS составляет 4К, а для Alpha - 8K (а не 2 и 4К соответственно).</p> <p> </p> <p>Начнем с принципиальных отличий в модели обработки исключений в С++ от Делфи. И какие это порождает гадости (КоТ: почему именно гадости?). В первую очередь, Борланд ввел некоторые ограничения на перегенерацию собственных исключений. Вырезка из Help:</p> <p>1) You cannot rethrow an operating system exception once the catch frame has been exited and have it be caught by intervening VCL catch frames.</p> <p>2) You cannot rethrow an operating system exception once the catch frame has been exited and have it be caught by intervening operating system catch frames.</p> <p>3) You cannot use "throw"(аналог Делфийского raise) to reraise an exception that was caught within VCL code.</p> <p> </p> <p>Приведенная автором вырезка в Delphi Help отсутствует. Да и с какой стати там будет указываться ключевое слово "throw" из С++? Более всего это похоже на вырезку из хелпа C++ Builder. Соответственно и ограничения на работу с более мощной моделью исключений ОР, используемой в VCL (доказательства будут ниже). Выводы делаем сами…</p> <p> </p> <p>Рассматривая модель ООП в Делфях и модель ООП в С++, легко прийти к выводу, что функционально модель С++ шире, и поэтому Борландовский Буилдер легко "глотает" делфийский VCL.</p> <p> </p> <p>Используя модель ООП С++, создать, к примеру, среду Delphi или библиотеку VCL невозможно в принципе (если не касаться разработки новых компиляторов). Это было неоднократно доказано в дискуссиях с другими фанатами С++. Как ограничения выступают отсутствие классовых ссылок, виртуальных конструкторов и ущербная модель RTTI в С++. Не буду утверждать, как работает C++ Builder, но подозреваю, что ключевые моменты работы среды с компонентами написаны на ОР.</p> <p> </p> <p>Думаю, если бы С++ позволял написать VCL, то Delphi пришлось бы сейчас "глотать" чужой код. Но пока все наоборот. Кстати, Borland имела прекрасную возможность пересмотреть свои воззрения на языковую основу VCL при разработке Kylix (этот проект включает и ОР и С++). Однако революции не произошло. Революция уже случилась в 95-м году с выходом Delphi 1 :)</p> <p> </p> <p>В С++ классы могут находиться в любой памяти, из перечисленных выше трех [статическая, стек, динамическая].</p> <p> </p> <p>(КоТ: Никакого плюса не вижу, говорю как С++ - программер. Мало геморроя с распределением динамической памяти, так еще и со всеми другими. Из-за этого я на линух от доса перешел - кстати. И вообще, на мой (ламерский) взгляд, распределение памяти - вопрос не к языку, а к мемори-модели операционной системы.)</p> <p> </p> <p>В Делфи классы (объекты) могут располагаться только в динамической памяти</p> <p> </p> <p>Что, безусловно, добавляет той самой безопасности программирования. К примеру, функция может вернуть ссылку на объект в стеке, который уже уничтожен. (КоТ: такие ошибки у меня часто были в досовском паскале. Именно тогда я привык инициализировать все переменные в процессе декларирования.) Если Дмитрий интересовался вопросами сборки мусора, то не мне ему объяснять, что сделать это в одной динамической памяти куда легче.</p> <p> </p> <p>Из этого вытекает следующее отличие. Все конструкторы и деструкторы классов Паскаля вызываются явно.</p> <p>object := TMyObject.Create. // где-то в начале</p> <p>//....</p> <p>object.Free; // где-то в конце</p> <p>С одной стороны хорошо. Все ясно, как никогда. Но это специфика Паскаля заставляет программера делать уйму работы, и порой ошибаться (КоТ: а что, С++ прямо так вот и гарантирует безошибочность?) Частенько бывает необходимо иметь "неявный" вызов или конструктор "по умолчанию". Конструктор класса С++, например, вызывается как только встречается описание экземпляра (переменной) класса. И, соответственно, деструктор вызовется, как только класс "выйдет из области видимости".</p> <p> </p> <p>(КоТ: опять подмена терминов. Т.е. банально нечестная игра. Справедливей, имхо, сказать, что в определенных задачах приходится не надеяться на механизм порождения классов дельфы. Но ведь и в С++ есть точно такие же ситуации - где-то ты можешь положиться на язык (компилятор), где-то - не можешь. Так в чем же преимущество?)</p> <p> </p> <p>Не нужно преувеличивать количество работы программера. Вызвать конструктор и деструктор совсем не сложно. К тому же, компоненты на форме, например, создаются и уничтожаются автоматически, что очень облегчает жизнь новичкам. При уничтожении компонента ссылка на него в обязательном порядке обнуляется компонентом-владельцем.</p> <p> </p> <p>А что касается области видимости класса и времени жизни, то это элементарно организуется использованием интерфейсов. Всю работу по подсчету количества ссылок и автоматическому менеджменту памяти возьмет на себя Delphi. (КоТ: кстати, в том же С++ такой же механизм я сам организовывал часов за восемь. Не скажу, что просто и легко, но возможно. Минус - лишний геморрой, плюс - можешь сделать сам, какой нужно, с точностью до битовых полей и регистров.) В Delphi этот механизм также может быть легко реализован по-своему.</p> <p> </p> <p>К тому же, такая форма конструирования имеет под собой четкую логическую основу. Она напрямую ориентированна на использование классовых ссылок, когда вместо статического указания типа (TMyObject) используется переменная типа "тип класса":</p> <p>TComponentClass = class of TComponent; //ссылка на класс</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> CreateAny(AType: TComponentClass): TComponent;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := AType.Create(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">…</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Form1.InsertComponent(CreateAny(TButton));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Создали кнопку</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Form1.InsertComponent(CreateAny(Edit1.ClassType));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// Создали еще одно поле редактирования</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Скажем прямо, такие решения в С++ недоступны. В качестве лирического отступления можно сказать, что именно на этом основана работа Delphi IDE с любым компонентом.</p> <p> </p> <p>Вас не удивляло, что Delphi способна не то что без перекомпиляции, а даже без перезапуска брать внешние, абсолютно не знакомые ей классы (компоненты, которые можно инсталлировать хоть каждые 5 минут, тип которых, конечно, неизвестен) и строить на их основе другие классы (формы и т.д.) в run-time (для разработчика design-time)?</p> <p> </p> <p>(КоТ: круто, конечно)</p> <p> </p> <p>Очень занимательный вопрос, скажу я вам. Прикиньте, как бы вы реализовали это в своем приложении. Механизм должен быть очень универсальным, работающим для любого компонента. Компоненты поставляются, например, в виде DLL (или packages - разновидность DLL). Тут никакая RTTI в чистом виде не поможет. Применительно к этой задаче даже шаблоны С++ абсолютно бесполезны, т.к. они являются механизмом compile-time only.</p> <p> </p> <p>Секрет заключается в механизме классовых ссылок, которые фактически являются ссылками на VMT класса. Классовые ссылки регистрируются в пакетах с помощью процедуры Register. Ну и без виртуальных конструкторов, конечно, здесь тоже каши не сваришь.</p> <p> </p> <p>Ну теперь самое интересное - динамическая память. Тут еще проще - у указателей конструкторов и деструкторов нет. Но, повторюсь, это у встроенных типов. Чтобы вызвать конструктор у указателя надо воспользоваться оператором new. В случае же удаления - оператором delete.</p> <p> </p> <p>TComplex* c; // переменная указатель на тип TComplex - ниче не вызывается.</p> <p> </p> <p>(КоТ: ну кто же в софтине будет САМ создавать указатель на пустое место? Зачем? Чтобы stack error'ом по хоботу получить? Объявил переменную - инициализируй!!! Вот так:</p> <p>TСomplex* c=new TComplex(1,1)</p> <p>// "а будешь делать не так, надеру уши" (с) Зеф, "Обитаемый остров")</p> <p> </p> <p>c = new TComplex(1,1); // выделяется память под TComplex и вызывается его конструктор с параметрами.</p> <p>delete c; // освобождаем память предварительно вызвав деструктор Tcomplex</p> <p> </p> <p>Вот здесь работа с классами похожа на Делфийскую работу. Похожа-то, похожа - да не совсем.</p> <p>. (КоТ: на CENSORED похожа, да и работы я здесь не вижу что-то.)</p> <p> </p> <p>Во-первых: как вы успели заметить new и delete - это операторы. Значит их можно переопределять (КоТ: кстати, НЕ ВСЯКИЙ оператор С++ переопределяется). Значит, где захочу - там и будут лежать мои классы. Так можно организовать несколько куч, даже не имея "много-кучевого" менеджера ОС. Я позже опишу, как это влияет на безопасность</p> <p> </p> <p>Странно, но Дмитрию не известно, что управление памятью классов в ОР реализовано даже не с помощью операторов, а гораздо красивее - на уровне TObject, виртуальными (!) методами NewInstance и FreeInstance. Таким образом, абсолютно ЛЮБОЙ класс может переопределить эти методы для осуществления желания "где хочу - там и буду лежать". Соответственно организуется и "многокучность".</p> <p> </p> <p>Во-вторых: здесь всплывает понятие "ВРЕМЯ ЖИЗНИ КЛАССА" и то, как обрабатываются исключения в конструкторах и деструкторах. Рассмотрим это поближе. В Делфи время жизни класса таково:</p> <p>Рождение: Класс начинает свое существование сразу ПОСЛЕ окончания работы КОНСТРУКТОРА(вызов AfterConstruction).</p> <p>Смерть: Класс заканчивает свое существование сразу ПОСЛЕ окончания работы ДЕСТРУКТОРА(вызов BeforeDestruction).</p> <p> </p> <p>Неправильно. Before он на то и Before, чтобы отрабатывать ДО вызова деструктора. И это вовсе не значит, что класс уже уничтожен. Для справки: BeforeDestruction введен для того, чтобы создатель класса был уверен, что необходимые действия перед его уничтожением будут выполнены всегда, независимо от того, вызовут или нет его потомки унаследованный деструктор. По поводу AfterConstruction разговор будет чуть позже.</p> <p> </p> <p>Кроме того, и конструкторы и деструкторы в ОР имеют приятную особенность (и далеко не одну). Они могут вызываться как обычные методы. Для этого в них передается неявный параметр. Не путать с неявным Self или this. Кстати, Self в классовых методах ОР является классовой ссылкой, а не объектной.</p> <p> </p> <p>Так что вопросы рождения и смерти в ОР далеко не так тривиальны. Впрочем, самые интересные подробности еще впереди.</p> <p> </p> <p>В С++ немножечко по другому:</p> <p>Рождение: Сразу ПЕРЕД телом конструктора.</p> <p>Смерть: Сразу ПОСЛЕ тела деструктора.</p> <p>Это несколько меняет работу с конструкторами/деструкторами родителями и конструкторами/деструкторами членами. Вот С++:</p> <p>class TChild : public TMama,TPapa{ // :o)</p> <p>TMemberOne member_1_;</p> <p>TMembarTwo member_2_;</p> <p>public:</p> <p>TChild() { cout&lt;&lt;"TChild created!"; }</p> <p>}</p> <p> </p> <p>Порядок конструкторов будет следующий: TMama, TPapa, TMemberOne, TMemberTwo и только потом вызовется ТЕЛО конструктора TChild. Это логично и похоже на правду. (КоТ: немножко беременной быть можно? Это похоже на правду, или это правда? Разницу чувствуете?) Действительно, когда мы можем получить доступ к методам и полям(переменным класса) родителей и классов-членов(конкретных классов)? Мы можем получить этот доступ только, когда они сконструированы. И это лучше оставить на совести компилятора, чем надеяться на программера.</p> <p> </p> <p>Вообще типичной идеологией компилятора С++ считается: "Ну, парень, если ты хочешь сделать именно так, делай, а я умываю руки". А тут такая удивительная забота о программере! Только вот она в данном случае совсем не к месту, по крайней мере, в таком виде. Как контраст - конструкторы ОР.</p> <p> </p> <p>Допустим, у нас есть иерархия классов A -&gt; B -&gt; C. Мы конструируем класс С. Действительно, в С++ последовательность конструирования будет A -&gt; B -&gt; C. И никак иначе.</p> <p> </p> <p>Теперь признайтесь, когда вы пишите конструктор в ОР, вы ведь первым делом указываете вызов inherited. Да? В этом случае последовательность конструирования абсолютно аналогична. Но! Стоит вам убрать inherited, и Delphi будет конструировать класс C в последовательности C -&gt; B -&gt; A. Неплохо для начала, но это еще цветочки.</p> <p> </p> <p>Незаметное inherited дает вам полный контроль над тем КАК, КОГДА и КАКИЕ конструкторы будут вызываться (и будут ли вызываться вообще, ведь inherited можно и в if засунуть). Нет никаких ограничений на расположение inherited в теле конструктора. А ведь его еще можно дополнить именем конкретного конструктора предка с указанием нужных параметров. Ну и, конечно, можно вызывать собственные конструкторы. (КоТ: это здорово, однако).</p> <p> </p> <p>Таким образом, сначала, например, может отработать часть конструктора С, затем конструкторы предков, затем оставшаяся часть конструктора С. Для чего все это?</p> <p> </p> <p>Прозаический пример. В конструкторе С создается некоторый объект (аллокатор памяти, например), который используется для работы в конструкторе предка B. Другой наследник, класс D, может создавать совершенно другой объект. Создание этого объекта можно вынести в виртуальную функцию, которую вызывать перед inherited.</p> <p> </p> <p>Да, такие возможности используются не слишком часто, но им есть реальное применение. Показательно, что подобный подход нереализуем в С++ никакими способами. Он никогда не даст создать что-то ПЕРЕД работой конструктора предка.</p> <p> </p> <p>(КоТ: сорри, сир! Переопределив new под это дело (кстати, одно из упражнений в каком-то С++-учебнике), вполне возможно и вызвать. Только потом приходится delete лечить - он-то базируется на стандартных умолчаниях. То есть, данных объекта нет, и объекту адрес не выделен, но VMT его есть. В библиотеке или там где еще, не суть. И к этой VMT можно добраться через разную там… гм… CENSORED Плюс дельфы в откровенности доступа ко всем VMT проекта, независимо, созданы ли объекты соответствующих классов).</p> <p> </p> <p>Как правило, на этом месте фанаты С++ начинают кричать, что это де нелогично, так быть не должно… Но на самом деле нет ничего плохого в том, что конструктор использует в своей работе виртуальные принципы. Никто не утверждает, что экземпляр станет объектом С или В раньше, чем он станет объектом А. Конструкторы всего лишь выполняют свою работу, не важно в каком порядке.</p> <p> </p> <p>(КоТ: От слабости кричать. Т.к. это, безусловно, бонус дельфе перед С++, но и С++-модель определенные преимущества все-таки имеет).</p> <p> </p> <p>Более того, вызов указанной виртуальной функции совершенно бесполезен. Почему? В С++ при работе каждого из конструкторов A, B, C таблица виртуальных методов VMT будет соответствовать именно тому классу, к которому принадлежит конструктор. Т.е. вызов ЛЮБЫХ виртуальных методов в конструкторе С++ теряет всякий смысл, т.к. не является виртуальным (будет вызван соответствующий метод для класса А или В, а не для С). То же касается и деструкторов С++.</p> <p> </p> <p>В ОР при работе любого из конструкторов предков VMT всегда соответствует РЕАЛЬНОМУ создаваемому классу, т.е. классу С. Вызовы виртуальных методов будут правильными. В принципе, это может создать опасную ситуацию, когда в данном виртуальном методе какой-то из наследников подразумевает, что класс уже полностью сконструирован. Именно для разрешения этой проблемы и существует виртуальный метод AfterConstruction.</p> <p> </p> <p>Теперь мы четко видим, что конструкторы ОР обладают НАМНОГО большей гибкостью и мощью. Конечно, при условии, что программист понимает, что делает. (КоТ: при условии, что программист понимает, что делает, и С++ не так уж плох ;-) А это не так уж и сложно. По крайней мере, практика показывает, что эти конструкторы не доставляют никаких хлопот программистам. А значит, увеличение мощи не уменьшило "безопасности программирования" :) Продолжим.</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> E: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span><span class="f_CodeExample" style="color: #000000;"> A,B </span><span class="f_CodeExample" style="color: #000080;">{</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> C* c_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> D* d_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> public: </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> E(); // реализацию см.ниже</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> ~E() { delete d_; delete c_; }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> E::E() </span><span class="f_CodeExample" style="color: #000080;">// конструктор класса E</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> : A(</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">), B(</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">), c_( new C ), d_( new D ) </span><span class="f_CodeExample" style="color: #000080;">// список инициализации</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ //начало тела конструктора</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> cout&lt;&lt;"Constructor body";</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> }</span><span class="f_CodeExample" style="color: #000080;">// конец тела конструктора</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> catch(...)</span><span class="f_CodeExample" style="color: #000080;">{ // ловим любое исключение</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> A::~A();</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> B::~B();</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> delete c_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> delete d_;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> }</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p>Непривычное написание, не так ли? Да, в Делфях нельзя ВЕСЬ процесс конструирования поместить в блок try except.</p> <p> </p> <p>Неправильно! Скорее можно сказать, что в ОР нельзя НЕ поместить весь процесс конструирования в блок try…except. При вызове конструктора ОР как классового (статического, в терминах С++) метода (т.е. через классовую ссылку) блок try…except устанавливается АВТОМАТИЧЕСКИ. При возникновении любого необработанного исключения в конструкторе автоматически вызывается деструктор. Это, однако, не мешает вписать в тело конструктора свои блоки обработки исключений, в том числе и для полной, безопасной обработки некоторых их типов.</p> <p> </p> <p>Здесь уместно более подробно осветить различия в способах вызова конструкторов ОР. Как я уже говорил, конструктору компилятором неявно передается параметр, который говорит, что он вызывается как классовый или как обычный метод.</p> <p> </p> <p>В случае классового метода:</p> <p>устанавливается блок try…except;</p> <p>вызывается виртуальный метод NewInstance, выделяющий память под экземпляр класса. В случае переопределения Вами этого метода:</p> <p>размер экземпляра можно получить методом InstanceSize;</p> <p>память нужно очистить методом InitInstance;</p> <p>отрабатывает тело конструктора;</p> <p>вызывается виртуальный метод AfterConstruction.</p> <p>В случае обычного метода выполняется только тело конструктора. Блок try…except НЕ устанавливается. Так вызываются все собственные конструкторы и конструкторы предков из тела какого-либо конструктора класса (они все равно попадут в установленный блок обработки исключений). Конструктор может быть вызван где угодно. Главное - использовать объектную ссылку (Self.Create), а не классовую. Условно, реальный код конструктора мог бы выглядеть так:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TSomething.Create(IsClassRef: boolean): TSomething;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> IsClassRef </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self := TSomthing.NewInstance;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> InitInstance(Self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.Create(False); </span><span class="f_CodeExample" style="color: #000080;">// Тело конструктора,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// написанное разработчиком</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.AfterConstruction;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">except</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.Destroy; </span><span class="f_CodeExample" style="color: #000080;">// Если что - харакири :)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.Create(False); </span><span class="f_CodeExample" style="color: #000080;">// Тело конструктора</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p>Аналогичная песня с деструкторами. Но здесь обойдемся без лишних объяснений:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TSomething.Destroy(Deallocate: boolean);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Deallocate </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.BeforeDestruction;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Self.Destroy(False);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Deallocate </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.CleanupInstance;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Self.FreeInstance;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p>Еще раз замечу, что это чисто гипотетический код, создаваемый компилятором, а не реализация конкретного класса. Конечно, в нем нет никаких рекурсивных вызовов. Продолжим.</p> <p> </p> <p>Но как же быть с динамическими ресурсами? Спросите вы. Все очень просто:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> E::E() </span><span class="f_CodeExample" style="color: #000080;">// конструктор класса E</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">try</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> : A(</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">), B(</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">), c_( NULL ), d_( NULL ) </span><span class="f_CodeExample" style="color: #000080;">// список инициализации</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ //начало тела конструктора</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> try{ </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> c_ = new C;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> d_ = new D;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> cout&lt;&lt;"Constructor body";</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> catch(...)</span><span class="f_CodeExample" style="color: #000080;">{</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> if(c_) delete C;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> if(d_) delete D;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> throw;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> } </span><span class="f_CodeExample" style="color: #000080;">// конец тела конструктора</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> catch(...)</span><span class="f_CodeExample" style="color: #000080;">{ // ловим любое исключение</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> throw E_ErrorCreate();</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> }</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p>Видно, что я использовал блок try...catch только для "перевода" одного исключения в другое. И назначение этого блока только такое и никакого другого. Использование его в других целях может привести к гадостям (КоТ: если ножом кухонным неправильно пользоваться, это МОЖЕТ привести даже к смерти… Но ведь не обязательно же приводит! Так претензии к ножу (языку), или к кривым рукам?) ,поэтому в некоторых С++ компиляторах (фирмы Борланд например) эта возможность от греха подальше убрана. Вы еще не заскучали?</p> <p> </p> <p>Нет, Дмитрий, с Вами не соскучишься :)</p> <p> </p> <p>Здесь хочу лишь заметить, что в ОР нет необходимости чистить ресурсы в конструкторе. На это есть деструктор! (КоТ: Вот!!!) Логично, не так ли? Зачем плодить двойной код. А вот конструкции вида</p> <p>if Assigned(MyObject1) then</p> <p>FreeAndNil(MyObject1);</p> <p>if Assigned(MyObject2) then</p> <p>FreeAndNil(MyObject2);</p> <p>ОЧЕНЬ рекомендуется использовать именно в деструкторе. Это хороший стиль. (КоТ: что да, то да.) Конструкция аналогичная if (c_) delete c_ (кстати, здесь была ошибка).</p> <p> </p> <p>(КоТ: с != 0 бывает, т.к NULL-тип машинно-зависимый. Но пустой указатель где-то представлен, напр, отрицательным числом. Если мне понадобилось, я бы писал</p> <p>if (С ! = NULL) // что надо сделать с С</p> <p>хотя Страуструп и советует использовать 0 вместо NULL - в третьей редакции книги. В первой, помнится, советовал обратное ;)</p> <p> </p> <p>Ведь деструктор может быть вызван в любой момент работы конструктора, и часть ресурсов будет неинициализирована.</p> <p> </p> <p>Привел я этот пример не для демонстрации возможностей блока try...catch, а для того чтобы показать как С++ сам делает безопасным процесс "конструирования" класса. В Делфи все это ложиться на хрупкие плЭчи программера.</p> <p>(КоТ: "Врать не надо по телефону" (с) Булгаков)</p> <p> </p> <p>Теперь мы видим, кто действительно "сам делает безопасным процесс конструирования класса", а кто перекладывает все это на чьи-то "хрупкие плЭчи".</p> <p> </p> <p>Кстати о Делфях, я там не нашел аналог функции С++ - uncaught_exception() - показывает статус стека исключений. Благодаря этой функции ваш деструктор знает - нормальное это "устранение" класса или не нормальное. По-моему, очень даже пользительно.</p> <p> </p> <p>Что значит ненормальное устранение класса? Может, мы еще будем считать возникновение исключения ненормальной ситуацией? Между прочим, на исключениях вполне можно выстроить логику работы класса или библиотеки. В ОР этому, кстати, очень способствуют такие преимущества модели исключений перед ANSI C++, как наличие общего предка исключений (и то, что это вообще классы, а не абы что) и наличие блока try…finally (ну это просто добавляет удобств по сравнению с try…catch(…){ throw; })</p> <p> </p> <p>Поэтому не совсем понятно, зачем понадобилась некая функция uncaught_exception(). Зачем лезть в идеологию работы исключений со своим уставом? Ведь они как раз и избавляют разработчика от чрезмерного применения if. Это еще называется реактивной моделью программирования. Но, раз есть спрос, то есть и предложение:</p> <p>ExceptAddr function - returns the address at which the current exception was raised.</p> <p>ExceptObject function - returns a reference to the object associated with the current exception.</p> <p>ExceptProc variable - points to the lowest-level RTL exception handler.</p> <p>Фича в том, что оператор new уже выделил память для экземпляра класса TObject, а тут ррраз! И исключение! Что делает С++? Он тут же освободит память - не надо ставить блок try...catch. Все сделает С++. Ну, как говориться, приятная неожиданность.</p> <p> </p> <p>(КоТ: это стандарт, и кто не знает его, как может говорить, что знает С++?)</p> <p> </p> <p>Ну, это только для тех, кто не очень хорошо знает ОР и С++. Впрочем, такие "детские" неожиданности не избавляют программера в С++ от необходимости защиты динамических ресурсов. В ОР же в это время можно попить пива ;)</p> <p> </p> <p>Я не привожу примеры реализации более полезных УМНЫХ указателей, реализующих сборку мусора и правильную работу с ресурсами вообще.</p> <p> </p> <p>Судя по всему, автор прочитал книгу Джефа Элджера "C++", испестренную идеями УМНЫХ, ВЕДУЩИХ, ГЕНИАЛЬНЫХ указателей и сборки мусора. Здесь хочу заметить, что я иногда читаю книги с карандашом в руке. Это очень хорошая, умная (КоТ: ведущая и гениальная ;-) книга про С++. Только во время ее чтения, постоянно задумываешься, а как можно сделать тоже самое в ОР. В результате после прочтения книга превратилась в записную книжку, испестренную замечаниями о том, насколько проще и красивее выглядела бы в ОР большая часть предлагаемых решений. Для интересующихся - основная идея в использовании свойств и интерфейсов.</p> <p> </p> <p>1) Работа с несколькими "собственными" кучами. Например, все покупатели складываются в одну кучу. А поступаемые товары в другую… Как видите осталось только реализовать менеджер кучи, что в рамках С++ вещь простая и ведущая себя незаметно (как встроенная фича). Можно так извернуться в Делфях? Нет</p> <p> </p> <p>(КоТ: Если можно проще и лучше, так изворачиваться-то нафиг?)</p> <p> </p> <p>Мы уже выяснили, что можно. И как-то изворачиванием это и не назовешь. Обычная работа. Хочешь, переопределяй работу с памятью на уровне классов, хочешь, глобальный менеджер памяти напиши.</p> <p> </p> <p>2) Помимо "многокучности", оператор new предоставляет вам возможность "виртуального" размещения объекта. Например в файле, в Сети, где вашей душеньке будет угодно. Это тоже недоступно в Делфях.</p> <p> </p> <p>(КоТ: Это и в С++ без корбы тоже не особенно хорошо получается, кстати. И опять же, нафига? чтобы без спроса прога в своп лазила? Или в инет звонила?)</p> <p> </p> <p>Откуда такая категоричность? Возможностей "виртуального" размещения у ОР ничуть не меньше. Или операционная система предоставляет для программ на С++ особые механизмы работы с файлами, с сетью и т.д.?</p> <p> </p> <p>Кстати о преобразовании типов. Делфи обязан безопасному преобразованию типов(as и is) C++, а точнее шаблону dynamic_cast.</p> <p> </p> <p>(КоТ: Страуструп: "как правило, НЕБЕЗОПАСНО (выделено мной - КоТ) использовать указатель, преобразованный или приведенный с помощью функций …_cast к типу, отличному от типа объекта, на который он указывает.") Да, а в ОР эта вещь абсолютно безопасна…</p> <p> </p> <p>Не уверен, что кто-то кому-то обязан, тем более шаблону. У ОР всегда была и остается система RTTI, намного превосходящая возможности С++. Да и вообще, RTTI - это обобщенный языковой механизм. При чем здесь конкретные реализации?</p> <p> </p> <p>Правда в Делфях такое же ограничение на множественное наследование, как и в Яве. Один класс должен быть интерфейсным.</p> <p> </p> <p>Что за терминология? Дмитрий, наверное, имел в виду, что в списке предков класса ДОЛЖЕН быть указан один класс, и МОЖЕТ быть указано сколько угодно интерфейсов.</p> <p> </p> <p>Дело в том, что в Делфи тип class реализован через одно очень загадочное место. Связано это с большой нелюбовью паскаля к памяти</p> <p> </p> <p>(КоТ: это БЫЛО в ДОСе, десять лет назад, но ведь с тех пор воды утекло - !!!)</p> <p> </p> <p>Можно, конечно, и так сказать. Все в мире относительно. Но я до сих пор встречал очень мало людей, достаточно глубоко знающих устройство классов в Delphi, точнее мне доводилось только читать их труды. И статью Дмитрия тяжело отнести к таким трудам. И почему он решил, что ОР не любит память?</p> <p> </p> <p>Тип указатель в паскале создан только для того, чтобы указывать на что-то в динамической памяти(куче). Он создан, как шлюз между статической памятью паскаля и кучей. Странно, но зачем-то разработчики языка оставили возможность приводить целое к указателю (КоТ: к дождю, может быть? ;-)</p> <p> </p> <p>Ни разу не доводилось слышать об ограничении указателей ОР на работу только с кучей. Возможность же приводить целое к указателю позволяет "двигаться" по памяти (не думаю, что это секрет для Дмитрия). Кстати, для указателей на строки допустимы операции "+" и "-" (в том числе в комбинации с целыми) без приведения типов.</p> <p> </p> <p>Такое понятие как ссылка не знакомо паскалю</p> <p> </p> <p>(КоТ: тогда в 6.0 под ДОС я работал не с ссылками… а с чем???)</p> <p> </p> <p>Ссылка в терминологии ОР - это типизированный указатель. А используя термины С++ (КоТ: Страуструп: "Ссылка является альтернативным именем объекта.") ссылкой в ОР являются формальные параметры методов, объявленные с использованием var или out (возможно кто-то не знал, out - то же, что и var, только работает исключительно на возврат значения). Кроме того, чистой воды ссылками являются объектные переменные (Button1: TButton).</p> <p> </p> <p>Если вы пишите класс "комплексное число", а затем решаете создать массив чисел, то array [1..10] of TComplex; будет на самом деле занимать в памяти 4*10 байт плюс выравнивание. Т.о. вы может быть хотели именно массив ТОЛЬКО КОМПЛЕКСНЫХ чисел, а не указателей на них. Но вместо этого, после инициализации, у вас будет израсходовано (4*10 + 10*sizeof(TComplex)) байт памяти. Короче сами считайте</p> <p> </p> <p>Действительно, использовать классы ОР в массивах не очень удобно. Есть несколько более экономичных решений:</p> <p>1) Можно организовать свой менеджмент памяти для TComplex, размещая экземпляры в памяти подряд (например, в заранее выделенном пуле), и работу, скажем, на основе динамического массива. Не самое простое решение, но весьма эффективное и красивое (КоТ: Кстати, активно применяется в С++-модели).</p> <p>2) Можно вместо классов использовать записи record, организовав их в массив, являющийся свойством по умолчанию какого-то класса:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TItem = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">record</span><span class="f_CodeExample" style="color: #000000;"> …</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TArray = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Items[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: integer]: TItem</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetItem</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetItem;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">default</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Это будет самое экономичное решение, т.к. каждый экземпляр любого класса имел бы как минимум ссылку на таблицу VMT. А запись содержит только необходимые данные. Вся же логика работы - в классе TArray.</p> <p>3) Можно использовать старые "объекты" Паскаля вместо "классов": TComplex = object … end; И массив таких объектов будет содержать сами объекты, а не ссылки на них. Это будет самое оригинальное решение. Кстати, на таких объектах построена библиотека KOL (https://xcl.cjb.net/) - аналог VCL. Размер EXE файлов с использованием этой библиотеки начинается от 4.5К (если не изменяет склероз :)</p> <p>Одним словом, проблема в разработчике, а не в языке. (КоТ: Вот!!!)</p> <p> </p> <p>Паскаль маленький язык и это не недостаток. (КоТ: Уф!. Ну сколько можно говорить о паскале 10-летней давности?) ?) Его не замечаешь, когда пишешь прогу большую или маленькую. (КоТ: это высшая похвала паскалю вообще. Лучшая одежда - та, которой не замечаешь.) Почему? (КоТ: Потому, что это хороший язык.)</p> <p> </p> <p>Потому что Паскаль от Борланд специальный язык, т.е. предназначен для узкой области. Узкая - это не значит, что программ мало, просто цели в этой области отличаются не намного.</p> <p> </p> <p>(КоТ: "С++ создавался для того, чтобы ИЗБАВИТЬ автора и его друзей ОТ ПРОГРАММИРОВАНИЯ НА АССЕМБЛЕРЕ" - (с) Бьерн Страуструп. Дельфа, возможно, создавалась для того, чтобы избавить автора от программирования на паскале, который вообще создавался изначально для ОБУЧЕНИЯ ПОНЯТИЯМ информатики. Оба эти языка свои цели выполнили с блеском. Ну так о чем же спор, цели-то разные?)</p> <p> </p> <p>Не знаю, может быть ОР и маленький язык. Однако я оцениваю свои знания ОР не более, чем на 60-70% (хотя меня как-то угораздило сдать экзамен на сертификат Brainbench Certified Master Delphi Programmer :), не включая сюда VCL или среду Delphi, разговор только о самом языке. Если охватить все, то я вообще ничего не знаю. Поэтому мне даже как-то неловко заниматься здесь исправлениями. Я считаю, что для этого необходим куда больший кругозор. Но пока за эту задачу никто не взялся. Видимо настоящим профессионалам просто не до этого.</p> <p> </p> <p>По поводу узости области применения. До последнего времени я считал, что единственное, что нельзя делать в Delphi - это писать драйвера (ОР тут ни причем, это не языковое ограничение). Но недавно натолкнулся на пример создания в Delphi 3 драйвера VxD. Что еще? Игрушки, сетевые сервисы, системные утилиты, распределенные базы данных, научные программы, средства мультимедиа в Delphi пишут и очень успешно. Так о чем речь?</p> <p> </p> <p>Поэтому резонно было бы выбрать язык, который необходим только для склеивания компонентов или их написания. За все остальное отвечает среда.</p> <p> </p> <p>После таких утверждений становится странно, как человек позволяет себе критиковать продукт, о котором имеет лишь зачаточное представление. За что "все остальное" отвечает среда? В виде списка, пожалуйста.</p> <p> </p> <p>Delphi IDE - это, по большому счету, лишь оболочка, набор зацепок к возможностям библиотеки VCL и шикарный пример использования возможностей языка. Это продукт, тратящий наименьшее количество усилий для выполнения одной и той же работы в сравнении с аналогами. Ведь в лице библиотеки VCL он в design-time использует тот же самый код, который работает в готовом приложении. Для сохранения спроектированной формы со всеми компонентами в ресурс Delphi достаточно одной строчки кода!</p> <p> </p> <p>И потом, "склеивание" и "написание" компонент - вещи по своей сложности абсолютно разные. Visual Basic тоже хорошо склеивает COM-компоненты, только вот с их написанием у VB как-то не очень… То, что ОР позволяет легко и непринужденно создавать и склеивать любые компоненты говорит лишь о его мощности, продуктивности и универсальности. Совершенно очевидно, что сегодня ОР по этому показателю не имеет не то что конкурентов, а даже толковых аналогов.</p> <p> </p> <p>VCL не является языковым расширением Паскаля - это "ОО" библиотека. Транспортом же между такими библиотеками и отдельными компонентами выступает некая переделка СОМ от Борланд.</p> <p> </p> <p>Да, VCL - вещь самостоятельная, пока она строится на ОР. Далее автор, похоже, говорит о RTTI. Но причем здесь транспорт между библиотеками и отдельными компонентами? Библиотека - понятие чисто условное. Каждый написанный мной компонент становится полноправной частью VCL. Правильнее, наверно, говорить о транспорте между компонентами и их пользователями, в частности средой Delphi IDE.</p> <p> </p> <p>К вопросу о переделках. Delphi начинала разрабатываться где-то в 92-93 году. Трудно говорить, кто кого переделал. Да это и не важно. Важно то, что компонент Delphi в полной мере обладает обоими механизмами.</p> <p> </p> <p>И опять же отбросьте этот транспорт, который не является частью языка, и от Делфи ничего не останется. (КоТ: Отбрось Gdb\Gtk, STL - что останется от милого нашему сердцу С++?) Поэтому Делфи очень гармоничная со своими недостатками среда для разработки GUI приложений под винды.</p> <p> </p> <p>Да, RTTI - незаметная, но ключевая для Delphi технология. А вот с тем, что она не является частью языка можно крепко поспорить. Достаточно вспомнить операторы AS и IS, которые целиком базируются на RTTI. Да и от TObject никуда не убежишь. Попробуй скажи, что это не часть языка. А ведь основное содержание TObject - реализация RTTI.</p> <p> </p> <p>Кроме того, Delphi идеально подходит не только для создания GUI приложений, но и консольных, и приложений без визуального интерфейса вообще (например, сервисы Windows NT). К счастью компоненты Delphi не ставят во главу угла визуальность/невизуальность. Это абсолютно универсальные в применении классы. Уже поэтому Delphi разительно отличается от, например, MSVC++, где в основе слова "Visual" лежит наличие у компонента оконного идентификатора и множество маловразумительных макросов и комментариев по тексту, которые нельзя (!) редактировать. Вот где действительно безопасный язык! Ведь программист может все испортить :)</p> <p> </p> <p>По поводу недостатков можно сказать лишь то, что вряд ли у конкурирующих с Delphi продуктов их меньше. А вообще, давайте взглянем на Delphi 6 и Kylix. Уверен, что сюрпризов там будет более чем достаточно.</p> <p>(Кот: я очень надеюсь, что у нас научатся, наконец, считать "Итого", а не только недостатки и достоинства отдельно).</p> <p> </p> <p>Похоже, Дмитрий применительно к безопасности программирования рассматривал только те моменты, которые, по его мнению, хорошо смотрелись в С++ в сравнении с ОР. Здесь, кстати, стоит упомянуть такие преимущества С++ над ОР, как возможность понижать видимость членов класса, а также указание const при объявлении метода, что гарантирует неизменность атрибутов объекта при вызове метода.</p> <p> </p> <p>Однако не стоит забывать, что ОР является языком, который действительно ставит во главу угла безопасность практически во всем. Можно долго перечислять все его тонкости, избавляющие программера от головной боли и рутиной работы. Как пример, можно привести директиву implements для свойств (делегирование реализации) или объявление глобальных переменных в разделе threadvar для поддержки многопоточности, или замечательную реализацию работы со строками и динамическими массивами на уровне компилятора. Очень важное для безопасности программирования свойство - объявление новых типов.</p> <p> </p> <p>Гради Буч: "К сожалению, конструкция typedef не определяет нового типа данных и не обеспечивает его защиты. Например, следующее описание в С++:</p> <p>typedef int Count;</p> <p>просто вводит синоним для примитивного типа int."</p> <p> </p> <p>В ОР же мы можем создать абсолютно новый тип. Для этого надо применить ключевое слово type:</p> <p>type</p> <p>Count = type int64; // другой тип</p> <p>Alias = int64; // синоним</p> <p>Типы Count и int64 уже не будут совместимы без приведения типов.</p> <p> </p> <p>А вот пример стандартизованной фичи компилятора (соответственно и языка) С++:</p> <p>long FileSize = 256 * 1024;</p> <p> </p> <p>В 16-битном компиляторе вы в результате получите 0. Очень приятный сюрприз! А дело в том, что 256 и 1024 по отдельности попадают в int (2 байта), а их произведение уже в long (4 байта). Однако стандарт С++ как раз в том и заключается, что произведение будет также помещено в int. И уже только после этого произойдет присвоение к long. Соответственно туда попадает только младшая часть произведения, которая равна нулю. Спасает написание в форме 256 * 1024L. На 32 битах все будет нормально, т.к. размеры типов int и long совпадают (4 байта).</p> <p> </p> <p>Некоторые начинают вяло возражать, что такие вещи нужно помнить, что это, мол, нормально. Однако в эту проблему (обнаружили ее случайно) конкретно уперлись два программера на С++ с очень хорошим опытом работы и в течение получаса не смогли ее решить. С ходу помог только действительно матерый эксперт С++. Ну, и как это выглядит с точки зрения безопасности программирования?</p> <p>(КоТ: плохо выглядит).</p> <p> </p> <p>А как "эстетичны" в каждом header'е С++ конструкции типа:</p> <p>#ifndef _MYHEADER_H</p> <p>#define _MYHEADER_H</p> <p>… body of the header …</p> <p>#endif</p> <p> </p> <p>Получается, я вместо компилятора должен следить, чтобы в проекте оказалась только одна копия каждого файла.</p> <p> </p> <p>Кстати, особенности ОР как языка обеспечивают не только безопасность программирования, но и безопасность полученного софта, как таковую. К примеру, более половины дыр в безопасности программ отраженных в Bugtraq возникают из-за проблемы переполнения буфера. А эта проблема является визитной карточкой С/С++. Дошло до того, что выпускаются специальные пакеты, которые патчят исходники С++. Как один из вариантов решения проблем безопасности предлагают писать на Pascal…</p> <p> </p> <p>После всего, что я тут наговорил, может возникнуть мысль: "А почему же тогда Борланд двигает Делфи?". "И почему VCL написан на паскале, а не на С++?". Резонно. Мыслям вообще свойственно появляться в головах человеков.</p> <p> </p> <p>Нет, мысль возникает не такая. С этим все ясно и так, VCL и Delphi не могут быть написаны ни на чем другом (можно, конечно, на С++ написать компилятор ОР, что вполне реализуемо, и потом в нем все делать, но ведь разработчика такой способ явно не устроит).</p> <p> </p> <p>Возникает другая мысль. Почему уровень знаний ОР у очень многих программистов так удручающе низок (КоТ: С С++ ситуация ничуть не лучше. Груда книг всяких, прости господи, пересмешников. А если прочитать 1 (один) раз Страуструпа, множество вопросов просто отпадет). Понятно, что литература у нас в основном "для чайников". Но иногда надо хотя бы help читать. Похоже считается делом чести начитаться умных книжек "с примерами приложений на С++", а для Delphi, мол, можно ограничиться знанием Object Inspector'а.</p> <p> </p> <p>При этом многие такие программисты почему-то считают для себя возможным критиковать возможности ОР. Может быть потому, что Delphi дала им возможность быстро и легко воплотить свои идеи? А потом вдруг что-то не получилось… И вот, виновата Delphi. Можно с уверенностью сказать, что С++ такому программисту все равно не поможет.</p> <p> </p> <p>Кажется беда Delphi как раз в том, что за внешней простотой многие не могут разглядеть ее истинные возможности. Да и решения об использовании конкретного языка принимаются зачастую на уровне руководства, которое вообще ничего не видит, кроме финансовых показателей дяди Билли.</p> <p> </p> <p>(КоТ: за что я вообще и выбрал линух - это система людей, имеющих роскошь на рынок в некоторых местах вообще плевать. Хотя от рынка, конечно уйти нельзя. Да и зачем? В умеренных дозах рынок - это очень хорошо.)</p> <p> </p> <p>Для любящих спорить. Не стоит критиковать какие-то возможности продукта, не до конца в них разобравшись. Современные языки слишком многогранны, чтобы один человек досконально знал хотя бы два языка. Я лично не уверен, что все мои рассуждения на 100% достоверны, но старался, как мог. Поэтому буду рад техническим исправлениям.</p> <p>"Портос, если Вы говорите глупости, то делайте это, пожалуйста, только от своего имени"</p> <p> </p> <p>P.S. Красота драгоценного камня, как известно, зависит не только от породы, но и от мастерства огранщика. Только тогда обычный белый свет превращается в нем в причудливую игру разноцветных искр. Так что учите матчасть, и Delphi вас не подведет :)</p> <p> </p> <p>(КоТ: Два слова напоследок - не удержался. Я полагаю, что С++, что дельфа - языки одного уровня, но разных подуровней. Бессмысленно их сравнивать вообще. С++ старше - хотя бы поэтому дельфа лучше, т.к написана на его крови, если можно так сказать.</p> <p>Но дельфа все-таки следующее поколение языков. Стоит ли сравнивать сына с отцом, и чему удивляться? Уже народ типами не оперирует, уже оперирует свойствами и объектами. Кто даст хороший язык для этого, тот и выиграет.</p> <p>А что до С++ - учите матчасть… И не хуже будет, чем в дельфе. ;)</p> <p> </p> <p>P.P.S. Да, в конце концов, все измеряется способностями конкретного "юзера" языка. Хочется верить, что эта статья поможет кому-нибудь сделать очередной шаг на длинном пути от "чайника" к "профи".</p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p>https://delphiworld.narod</p> <p>DelphiWorld 6.0</p> Краеугольные камни ООП 2013-08-15T20:30:22+07:00 2013-08-15T20:30:22+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/sushchnost-oop/kraeugolnye-kamni-oop.html Super User toto44@inbox.ru <p><span class="f_Heading1">КРАЕУГОЛЬНЫЕ КАМНИ ООП</span></p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">ФОРМУЛА ОБЪЕКТА</span></p> <p class="p_Heading1"> </p> <p>Авторы надеются, что читатель помнит кое-что из второй главы и такие понятия, как тип данных, процедура, функция, запись для него не в новинку. Это прекрасно. Та вот, в конце 60-х годов кому-то пришло в голову объединить эти понятия и то, что получилось, назвать объектом. Рассмотрение данных в неразрывной связи с методами их обработки позволило вывести формулу объекта:</p> <p style="text-align: center;">Объект = Данные + Операции</p> <p style="text-align: center;"> </p> <p>На основании этой формулы была разработана методология объектно-ориентированного программирования (ООП).</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">ПРИРОДА ОБЪЕКТА</span></p> <p> </p> <p>Об объектах можно думать как о полезных существах, которые «живут» в вашей программе и коллективно решают некоторую прикладную задачу. Вы, как Демиург, лепите этих существ, распределяете между ними обязанности и устанавливаете правила их взаимодействия.</p> <p>В общем случае каждый объект «помнит» необходимую информацию, «умеет» выполнять некоторый набор действий и характеризуется набором свойств. То, что объект «помнит», хранится в его полях. То, что объект «умеет делать», реализуется в виде его внутренних процедур и функций, называемых методами. Свойства объектов аналогичны свойствам, которые мы наблюдаем у обычных предметов. Значения свойств можно устанавливать и читать. Программно свойства реализуются через поля и методы.</p> <p> </p> <p>Например, объект «кнопка» имеет свойство «цвет». Значение цвета кнопка запоминает в одном из своих полей. При изменении значения свойства «цвет» вызывается метод, который перерисовывает кнопку.</p> <p> </p> <p>Кстати, этот пример позволяет сделать важный вывод: свойства имеют первостепенное значение для программиста, использующего объект. Чтобы понять суть и назначение объекта, вы обязательно должны знать его свойства, иногда — методы, очень редко — поля (объект и сам знает, что с ними делать).</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">ОБЪЕКТЫ И КОМПОНЕНТЫ</span></p> <p>Когда прикладные программы создавались для операционной системы MS-DOS и были консольно-ориентированными, объекты казались пределом развития программирования, поскольку были идеальным средством разбиения сложных задач на простые подзадачи. Однако с появлением графических систем, в частности Windows, программирование пользовательского интерфейса резко усложнилось. Программист в какой-то мере стал дизайнером, а визуальная компоновка и увязка элементов пользовательского интерфейса (кнопок, меток, строк редактора) начали отнимать основную часть времени. И тогда программистам пришла в голову идея визуализировать объекты, объединив программную часть объекта с его видимым представлением на экране дисплея в одно целое. То, что получилось в результате, было названо компонентом.</p> <p>Компоненты в Delphi — это особые объекты, которые являются строительными кирпичиками среды визуальной разработки и приспособлены к визуальной установке свойств. Чтобы превратить объект в компонент, первый разрабатывается по определенным правилам, а затем помещается в Палитру Компонентов. Конструируя приложение, вы берете компоненты из Палитры Компонентов, располагаете на форме и устанавливаете их свойства в окне Инспектора Объектов. Внешне все выглядит просто, но чтобы достичь такой простоты, потребовалось создать механизмы, обеспечивающие функционирование объектов-компонентов уже на этапе проектирования приложения! Все это было придумано и блестяще реализовано в среде Delphi. Таким образом, компонентный подход значительно упростил создание приложений с графическим пользовательским интерфейсом и дал толчок развитию новой индустрии компонентов.</p> <p>В данной главе мы рассмотрим лишь вопросы создания и использования объектов, Чуть позже мы научим вас превращать объекты в компоненты.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">КЛАССЫ ОБЪЕКТОВ</span></p> <p>Каждый объект всегда принадлежит некоторому классу. Класс — это обобщенное (абстрактное) описание множества однотипных объектов. Объекты являются конкретными представителями своего класса, их принято называть экземплярами класса. Например, класс СОБАКИ — понятие абстрактное, а экземпляр этого класса МОЙ ПЕС БОБИК — понятие конкретное.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">ТРИ КИТА ООП</span></p> <p>Весь мир ООП держится на трех китах: инкапсуляции, наследовании и полиморфизме. Для начала о них надо иметь только самое общее представление.</p> <p> </p> <p>Наблюдаемое в объектах объединение данных и операций в одно целое было обозначено термином <span style="font-weight: bold;">инкапсуляция</span> (первый кит ООП). Применение инкапсуляции сделало объекты похожими на маленькие программные модули и обеспечило сокрытие их внутреннего устройства. Для объектов появилось понятие интерфейса, что значительно повысило их надежность и целостность.</p> <p> </p> <p>Второй кит ООП — <span style="font-weight: bold;">наследование</span>. Этот простой принцип означает, что если вы хотите создать новый класс, лишь немногим отличающийся от того, что уже существует, то нет необходимости в переписывании заново всех полей, методов и свойств. Вы объявляете, что новый класс является потомком (или дочерним классом) имеющегося класса, называемого предком (или родительским классом), и добавляете к нему новые поля, методы и свойства. Иными словами добавляется то, что нужно для перехода от общего к частному. Процесс порождения новых классов на основе других классов называется наследованием. Новые классы имеют как унаследованные признаки, так и, возможно, новые. Например, класс СОБАКИ унаследовал многие свойства своих предков — ВОЛКОВ.</p> <p> </p> <p>Третий кит — это <span style="font-weight: bold;">полиморфизм</span>. Он означает, что в производных классах вы можете изменять работу уже существующих в базовом классе методов. При этом весь программный код, управляющий объектами родительского класса, пригоден для управления объектами дочернего класса без всякой модификации. Например, вы можете породить новый класс кнопок с рельефной надписью, переопределив метод отрисовки кнопки. Новую кнопку можно «подсунуть» вместо стандартной в какую-нибудь подпрограмму, вызывающую отрисовку кнопки. При этом подпрограмма «думает», что работает со стандартной кнопкой, но на самом деле кнопка принадлежит производному классу и отображается в новом стиле.</p> <p>Пока достаточно самого поверхностного понимания всех приведенных выше понятий, ниже мы рассмотрим их подробнее и покажем, как они реализованы в Delphi.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">КЛАССЫ</span></p> <p>Delphi поддерживает две модели представления объектов — старую и новую. Старая модель существует лишь для совместимости с более ранними версиями компилятора, в частности с Borland Pascal 7.0, поэтому мы не будем ее рассматривать. Все, что сказано ниже, относится к новой модели представления объектов, более мощной и богатой по своим возможностям.</p> <p> </p> <p>Для поддержки ООП в язык Object Pascal введены объектные типы данных, с помощью которых одновременно описываются данные и операции над ними. Объектные типы называют классами, а их экземпляры — <span style="font-weight: bold;">объектами</span>.</p> <p> </p> <p>Классы объектов определяются в секции <span style="font-weight: bold;">type</span> глобального блока. Описание класса начинается словом <span style="font-weight: bold;">class</span> и заканчивается словом <span style="font-weight: bold;">end</span>. По форме объявления классы похожи на обычные записи, но помимо полей данных могут содержать объявления пользовательских процедур и функций. Такие процедуры и функции обобщенно называют методами, они предназначены для выполнения над объектами различных операций.</p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Приведем пример объявления класса:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span> <span class="f_CodeExample" style="font-style: italic; color: #000080;">{ измеритель дискового пространства}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DriveLetter: Char; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ буква дискового накопителя}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PercentCritical: Integer; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ критический процент свободного пространства}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Заголовки методов, следующие за списком полей, играют роль предварительных</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> (forward) </span><span style="font-family: 'Times New Roman'; color: #000000;">объявлений. Программный код методов помещается ниже определения класса и будет приведен позже.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Класс обычно описывает сущность, моделируемую в программе. Например, класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge </span><span style="font-family: 'Times New Roman'; color: #000000;">описывает измеритель дискового ресурса. Класс содержит два поля:</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> DriveLetter</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> буква находящегося под наблюдением накопителя, и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> PercentCritical</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> процент свободного пространства на диске, с которым работает программа. Когда объем свободных ресурсов снижается до этого порога, пользователю выдается звуковое предупреждение. Функция </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">GetPercentFree</span><span style="font-family: 'Times New Roman'; color: #000000;"> определена как метод работы над любым объектом класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> и возвращает процент свободного пространства на диске. Процедура</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> служит для проверки состояния ресурса и выдачи звукового предупреждения.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Обратите внимание, что приведенное выше описание является не чем иным, как декларацией интерфейса для управления объектами класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Реализация методов </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">GetPercentFree и CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> отсутствует, но для создания и использования экземпляров класса она пока и не нужна. В этом как раз и состоит сила инкапсуляции, Которая делает объекты аналогичными программным модулям. Для использования модуля необходимо изучить лишь его интерфейсную часть, раздел реализации для этого изучать не требуется. Поэтому дальше от описания класса мы перейдем не к реализации методов, а к созданию на их основе объектов.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">ОБЪЕКТЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Чтобы от описания класса перейти к объекту, следует выполнить соответствующее объявление в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> var:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> DiskGauge: TDiskGauge;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">При работе с обычными типами данных этого объявления было бы достаточно для получения экземпляра типа. Однако объекты в Delphi являются динамическими данными, т.е. распределяются в «куче» (heap). Поэтому переменная</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> DiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это просто </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">ссылка на экземпляр объекта,</span><span style="font-family: 'Times New Roman'; color: #000000;"> которого физически еще не существует. Чтобы </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">сконструировать</span><span style="font-family: 'Times New Roman'; color: #000000;"> объект класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> и </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">связать</span><span style="font-family: 'Times New Roman'; color: #000000;"> с ним переменную</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> DiskGauge, </span><span style="font-family: 'Times New Roman'; color: #000000;">нужно в текст программы поместить следующий оператор (statement):</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge: = TDiskGauge.Create;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 16px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Create</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это так называемый </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">конструктор</span><span style="font-family: 'Times New Roman'; color: #000000;"> объекта; он всегда присутствует в классе и служит для создания и инициализации экземпляров. К сведению профессионалов заметим, что в памяти выделяется место только для полей объекта. Методы, так же как и обычные процедуры и функции, помещаются в область кода программы; они умеют работать с любыми экземплярами своего класса и в памяти никогда не дублируются,</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">После создания объект можно использовать в программе </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> читать и устанавливать его поля, вызывать методы. Доступ к полям и методам объекта происходит с помощью уточненных имен, например:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge.DriveLetter: = </span><span class="f_CodeExample" style="color: #ff0000;">'С'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge. PercentCritical: = </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge.CheckStatus;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Кроме того, как и при работе с записями, допустимо использование оператора with, например:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> DiskGauge </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DriveLetter: = </span><span class="f_CodeExample" style="color: #ff0000;">'С'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PercentCritical: = </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Если наступает время, когда объект становится не нужен в программе, он должен быть удален вызовом специального метода</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Destroy,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge.Destroy;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 16px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Destroy </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это так называемый </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">деструктор</span><span style="font-family: 'Times New Roman'; color: #000000;"> объекта; он присутствует в классе наряду с конструктором и служит для удаления объекта из динамической памяти. После вызова деструктора переменная</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> DiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> становится </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">несвязанной</span><span style="font-family: 'Times New Roman'; color: #000000;"> и не должна использоваться для доступа к полям и методам уже несуществующего объекта. Чтобы отличать в программе связанные объектные переменные от несвязанных, последние следует инициализировать значением</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> nil.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Например, в следующем фрагменте обращение к деструктору</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Destroy</span><span style="font-family: 'Times New Roman'; color: #000000;"> выполняется только в том случае, если объект реально существует.</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge: = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> DiskGauge &lt;&gt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> DiskGauge.Destroy;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 11px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Вызов деструктора для несуществующих объектов недопустим и при выполнении программы приведет к ошибке. Чтобы избавить программистов от лишних ошибок, в объекты ввели предопределенный метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Free,</span><span style="font-family: 'Times New Roman'; color: #000000;"> который следует вызывать вместо деструктора. Метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Free</span><span style="font-family: 'Times New Roman'; color: #000000;"> сам вызывает деструктор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Destroy,</span><span style="font-family: 'Times New Roman'; color: #000000;"> но только в том случае, если значение объектной переменной не равно nil. Поэтому последнюю строчку в приведенном выше примере можно переписать следующим образом:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge.Free;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 11px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Значение одной объектной переменной можно присвоить другой. При этом объект не копируется в памяти, а вторая переменная просто связывается с тем же объектом, что и первая:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGaugel, DiskGauge2: TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Переменные DiskGauge1 и DiskGauge2 не связаны с объектом}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge1: = TDiskGauge.Create;</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Переменная DiskGauge1 связана с объектом, а DiskGauge2 — нет}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge2: = DiskGauge1;</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Обе переменные связаны с одним объектом}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge2.Free; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Объект удален, переменные DiskGauge1 и DiskGauge2 с ним не связаны}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Объекты могут выступать в программе не только в качестве переменных, но также элементов массивов, полей записей, параметров процедур и функций. Кроме того, они могут служить полями других объектов. Во всех этих случаях программист фактически оперирует указателями на экземпляры объектов в динамической памяти. Следовательно, объекты априори приспособлены для создания сложных динамических структур данных, таких как списки и деревья. Указатели на объекты для этого не нужны.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В некоторых случаях требуется, чтобы объекты разных классов содержали ссылки друг на друга. Возникает проблема: объявление первого класса будет содержать ссылку на еще не определенный класс. Она решается с помощью упреждающего объявления.</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TGaugeList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ предварительное объявление класса TGaugeList }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> Owner: TGaugeList;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TGaugeList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> Gauges: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">array</span><span class="f_CodeExample" style="color: #000000;"> [</span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">..</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #000000;">] </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Первое объявление класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TGaugeList</span><span style="font-family: 'Times New Roman'; color: #000000;"> называется </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">предварительным</span><span style="font-family: 'Times New Roman'; color: #000000;"> (от англ. forward). Оно необходимо для того, чтобы компилятор нормально воспринял объявление поля Owner в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Итак, вы уже имеете некоторое представление об объектах, перейдем теперь к вопросу реализации их методов.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">МЕТОДЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Процедуры и функции, предназначенные для выполнения над объектами действий, называются </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">методами.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Предварительное объявление методов выполняется при описании класса в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> interface</span><span style="font-family: 'Times New Roman'; color: #000000;"> модуля, а их программный код записывается в секции </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">implementation.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Однако в отличие от обычных процедур и функций заголовки методов должны иметь уточненные имена, т.е. содержать наименование класса. Приведем, например, возможную реализацию методов в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.GetPercentFree: Integer; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ uses SysUtils; }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var </span><span class="f_CodeExample" style="color: #000000;">Drive: Byte;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Drive := Ord(DriveLetter) - Ord(</span><span class="f_CodeExample" style="color: #ff0000;">'A'</span><span class="f_CodeExample" style="color: #000000;">) + </span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := DiskFree(Drive) * </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">div</span><span class="f_CodeExample" style="color: #000000;"> DiskSize(Drive);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.CheckStatus; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ uses Windows; }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree &lt;= PercentCritical</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;"> then</span><span class="f_CodeExample" style="color: #000000;"> Beep;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 28px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Обратите внимание, что внутри методов обращения к полям и другим методам выполняются как к обычным переменным и подпрограммам без уточнения экземпляра объекта. Такое упрощение достигается путем использования в пределах метода псевдопеременной </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Self</span><span style="font-family: 'Times New Roman'; color: #000000;"> (стандартный идентификатор). Физически</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Self</span><span style="font-family: 'Times New Roman'; color: #000000;"> представляет собой дополнительный неявный параметр, передаваемый в метод при вызове. Этот параметр и указывает экземпляр объекта, к которому данный метод применяется. Чтобы пояснить сказанное, перепишем метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus,</span><span style="font-family: 'Times New Roman'; color: #000000;"> представив его в виде обычной процедуры:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge_CheckStatus (Self: TDiskGauge);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> Self </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree &lt;= PercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Beep;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 8px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Согласитесь, что метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> выглядит более предпочтительно, чем процедура </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TDiskGauge_CheckStatus.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Практика показывает, что псевдопеременная</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Self</span><span style="font-family: 'Times New Roman'; color: #000000;"> редко используется в явном виде. Ее необходимо применять только тогда, когда при написании метода может возникнуть какая-либо двусмысленность для компилятора, например при использовании одинаковых имен и для локальных переменных, и для полей объекта.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Если выполнить метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge.CheckStatus;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 11px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">то произойдет проверка состояния дискового ресурса. При этом неявный параметр Self будет содержать значение переменной</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> DiskGauge.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Такой вызов реализуется обычными средствами процедурного программирования приблизительно так:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge_CheckStatus(DiskGauge);</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 11px;"> </p> <p style="margin: 0px 0px 0px 11px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">КОНСТРУКТОРЫ И ДЕСТРУКТОРЫ</span></p> <p style="margin: 0px 0px 0px 5px;"><span style="font-family: 'Times New Roman'; color: #000000;">Особой разновидностью методов являются </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">конструкторы</span><span style="font-family: 'Times New Roman'; color: #000000;"> и </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">деструкторы.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Напомним, что конструкторы создают, а деструкторы </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> разрушают объекты. Создание объекта включает выделение памяти под экземпляр и инициализацию его полей, а разрушение </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> очистку полей и освобождение памяти.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Очевидно, что выполняемые при инициализации и деинициализации действия специфичны для каждого конкретного класса объектов. По этой причине Object Pascal позволяет </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">переопределить</span><span style="font-family: 'Times New Roman'; color: #000000;"> стандартные конструктор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Create</span><span style="font-family: 'Times New Roman'; color: #000000;"> и деструктор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Destroy</span><span style="font-family: 'Times New Roman'; color: #000000;"> для выполнения любых полезных действий. Можно даже определить несколько конструкторов и деструкторов (имена им назначает сам программист), чтобы обеспечить различные способы создания и разрушения объектов.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Объявление конструкторов и деструкторов похоже на объявление обычных методов с той лишь разницей, что вместо зарезервированного слова procedure (или function) используются слова constructor и destructor:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> DriveLetter: Char;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PercentCritical: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Приведем их возможную реализацию:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DriveLetter := </span><span class="f_CodeExample" style="color: #ff0000;">'C'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PercentCritical := </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Разрушение встроенных объектов и освобождение динамических данных}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Конструктор иногда имеет параметры, в которых передаются исходные значения полей объекта. Если объект содержит встроенные объекты или другие динамические данные, то конструктор </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это как раз то место, где их нужно создавать.</span></p> <p style="text-indent: -19px; margin: 0px 27px 0px 19px;"><span style="font-family: 'Times New Roman'; color: #000000;">Конструктор применяется к классу или к объекту. Если он применяется к классу</span></p> <p style="text-indent: -19px; margin: 0px 27px 0px 19px;"> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge: = TDiskGauge.Create;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 27px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">то выполняется следующая последовательность действий:</span></p> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 44px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">в динамической памяти выделяется место для нового объекта;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 44px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">выделенная память заполняется нулями; в результате все числовые поля и поля порядкового типа приобретают нулевые значения, строковые поля становятся пустыми, а поля, содержащие указатели и объекты, получают значение</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> nil;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 44px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">затем выполняются заданные программистом действия конструктора;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 44px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">ссылка на созданный объект возвращается в качестве значения конструктора; тип возвращаемого значения совпадает с типом класса, использованного при вызове (в нашем примере это тип</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge).</span></td> </tr> </tbody> </table> </div> <p style="text-indent: -24px; margin: 0px 0px 0px 68px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Если конструктор применяется к объекту (</span><span style="font-family: 'Courier New'; color: #000000; font-size: 10pt;">DiskGauge.Create;)</span><span style="font-family: 'Times New Roman'; color: #000000;">то новый объект не создается, а происходит переинициализация полей существующего. В этом случае конструктор не возвращает никакого значения.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Деструктор уничтожает объект, к которому применяется (</span><span style="font-family: 'Courier New'; color: #000000; font-size: 10pt;">DiskGauge.Destroy;)</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В результате:</span></p> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 40px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">выполняется заданный программистом код деинициализации;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 40px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">освобождается занимаемая объектом динамическая память.</span></td> </tr> </tbody> </table> </div> <p><span style="font-family: 'Times New Roman'; color: #000000;">В теле деструктора обычно должны уничтожаться встроенные объекты и динамические данные, созданные конструктором.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">СВОЙСТВА</span></p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">ПОНЯТИЕ СВОЙСТВА</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Помимо полей и методов в объектах существуют </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">свойства.</span><span style="font-family: 'Times New Roman'; color: #000000;"> При работе с объектом свойства выглядят как поля: они принимают значения и участвуют в выражениях. Но в отличие от полей свойства не занимают места в памяти, а операции их чтения и записи ассоциируются с обычными полями или методами. Это позволяет создавать необходимые побочные эффекты при обращении к свойствам. Например, присваивание свойству</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Visible</span><span style="font-family: 'Times New Roman'; color: #000000;"> значения</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> True</span><span style="font-family: 'Times New Roman'; color: #000000;"> вызовет отображение графического объекта на экране, а значения</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> False</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> его исчезновение.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Объявление свойства выполняется с помощью зарезервированного слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> property,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical (Percent: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentCritical: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FpercentCritical</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">После слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> read</span><span style="font-family: 'Times New Roman'; color: #000000;"> указывается поле или метод, к которому происходит обращение при чтении значения свойства, а после слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> write</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> поле или метод, к которому происходит обращение при записи значения свойства. Например, чтение свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> PercentCritical </span><span style="font-family: 'Times New Roman'; color: #000000;">заменяется на чтение поля</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> FPercentCritical,</span><span style="font-family: 'Times New Roman'; color: #000000;"> а установка свойства </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> на вызов метода </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">SetPercentCritical.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Чтобы имена свойств не совпадали с именами полей, последние принято писать с буквы F (от англ. field).</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Атрибуты read и write называются спецификаторами доступа. Если один из них опущен, то значение свойства можно либо только читать (задан спецификатор read), либо только записывать (задан спецификатор write). В следующем примере объявлено свойство, значение которого можно только читать:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentFree: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 28px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Обращение к свойствам выглядит в программе как обращение к полям:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge: TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">A : Integer;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">А := DiskGauge.PercentCritical;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ эквивалентно А := DiskGauge.FPercentCritical;}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge.PercentCritical := A + </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ эквивалентно DiskGauge.SetPercentCritical(A + 10);}</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Однако в отличие от полей свойства не имеют адреса в памяти, поэтому к ним запрещено применять операцию @. Кроме того, их нельзя передавать в var-параметрах процедур и функций.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Технология объектно-ориентированного программирования в Delphi предписывает избегать прямого обращения к полям, создавая вместо этого соответствующие свойства. Это упорядочивает работу с объектами, изолируя их данные от непосредственной модификации. В будущем внутренняя структура класса, которая иногда является достаточно сложной, может быть изменена с целью повышения эффективности работы программы. При этом потребуется переработать только методы чтения и записи значений свойств; внешний интерфейс класса не изменится.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">МЕТОДЫ ПОЛУЧЕНИЯ И УСТАНОВКИ СВОЙСТВ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы чтения и записи свойств подчиняются определенным правилам. Метод чтения свойства </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это всегда функция, возвращающая значение того же типа, что и тип свойства. Метод записи свойства </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это обязательно процедура, принимающая параметр того же типа, что и тип свойства. В остальном это обычные методы объекта. Примерами методов чтения и записи свойств являются</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPercentFree и SetPercentCritical в</span><span style="font-family: 'Times New Roman'; color: #000000;"> классе </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TDiskGauge:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FPercentCritical: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical (Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentFree: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentCritical: Integer</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Использование методов для получения и установки свойств позволяет проверить корректность значения свойства, сделать дополнительные вычисления, установить значения зависимых полей и т.д. Например, в методе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> SetPercentCritical</span><span style="font-family: 'Times New Roman'; color: #000000;"> целесообразно сделать проверку на то, что устанавливаемое значение находится в диапазоне от 0 до 100:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.SetPercentCritical (Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> (Value &gt;= </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">and</span><span class="f_CodeExample" style="color: #000000;"> (Value &lt; </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #000000;">)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> FpercentCritical := Value;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">МЕТОДЫ, ОБСЛУЖИВАЮЩИЕ НЕСКОЛЬКО СВОЙСТВ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">0дин и тот же метод может использоваться для получения (установки) значений нескольких свойств одного типа. В этом случае каждому свойству назначается целочисленный индекс, который передается в метод первым параметром. В следующем примере методы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Get и Set</span><span style="font-family: 'Times New Roman'; color: #000000;"> обслуживают три свойства:</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GaugeA, GaugeB и GaugeC:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TGaugeList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FGauges: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">array</span><span class="f_CodeExample" style="color: #000000;"> [</span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">..</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #000000;">] </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Get (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer): TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;"> (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer; Value: TDiskGauge);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> GaugeA: TDiskGauge </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> Get </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> GaugeB: TDiskGauge </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> Get </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> GaugeC: TDiskGauge </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> Get </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TGaugeList.Get (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer): TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FGauges [</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">];</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TGaugeList.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;"> (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer; Value: TDiskGauge);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FGauges [</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">] := Value;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Обращения к свойствам</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GaugeA, GaugeB и GaugeC</span><span style="font-family: 'Times New Roman'; color: #000000;"> заменяются на соответствующие Вызовы методов</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Get и Set:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GaugeList: TGaugeList;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge: TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GaugeList.GaugeC := DiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ эквивалентно GaugeList.Set (2, DiskGauge) }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GaugeList.GaugeC.CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ эквивалентно GaugeList.Get(2).CheckStatus }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">СВОЙСТВА-МАССИВЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Кроме обычных свойств в объектах существуют свойства-массивы (array properties), </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">Свойство-массив </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это индексированное множество свойств. В виде свойства-массива удобно, например, представить множество измерителей ресурсов в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TGaugeList</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TGaugeList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Gauges[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer]: TdiskGauge</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> Get </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 16px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Обратите внимание, что методы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Get</span><span style="font-family: 'Times New Roman'; color: #000000;"> и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Set</span><span style="font-family: 'Times New Roman'; color: #000000;"> обслуживают и свойство-массив Gauges, и индексированные свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GaugeA, GaugeB и GaugeC.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Если в описании обычных свойств могут участвовать поля, то в описании свойств-массивов разрешено использовать только методы.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Основная выгода от применения свойств-массивов </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> возможность выполнения итераций с помощью цикла</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> for,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GaugeList: TGaugeList;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">I: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> I := </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> GaugeList </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #000000;"> Gauges [I] .CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 13px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Свойства-массивы могут быть многомерными. В этом случае методы чтения и записи их элементов имеют столько же индексных параметров соответствующего типа, что и массив.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Свойства-массивы имеют два важных отличия от обычных массовов:</span></p> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 10px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="9"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">их индексы не ограничиваются диапазоном и могуптаеть-любой тип-данных, а не только</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Integer;</span><span style="font-family: 'Times New Roman'; color: #000000;"> например, можно создать свойство-массив, в котором индексами будут строки; обращение к такому свойству могло бы выглядеть так:</span></td> </tr> </tbody> </table> </div> <p style="margin: 0px 160px 0px 19px;"><span style="font-family: 'Courier New'; color: #000000; font-size: 10pt;">GaugeList.Gauges['GaugeA'] := DiskGauge;</span></p> <p><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">• </span><span style="font-family: 'Times New Roman'; color: #000000;">операции над свойством-массивом в целом запрещены; разрешены операции только с его элементами.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">СВОЙСТВО-МАССИВ КАК ОСНОВНОЕ СВОЙСТВО ОБЪЕКТА</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Свойство-массив можно сделать основным свойством объектов данного класса. Для этого в его описание добавляется слово</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> default:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TGaugeList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Gauges [</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer]: TdiskGauge</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> Get </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">default</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Такое объявление свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Gauges</span><span style="font-family: 'Times New Roman'; color: #000000;"> позволяет рассматривать сам объект класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TGaugeList </span><span style="font-family: 'Times New Roman'; color: #000000;">как массив и опускать имя свойства-массива при обращении к нему из программы, например:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var </span><span class="f_CodeExample" style="color: #000000;">GaugeList: TGaugeList;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> I: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> I := </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #000000;"> GaugeList [I] := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ эквивалентно GaugeList.Gauges[I] := nil; }</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt;">Следует помнить, что только свойства-массивы могут быть основными свойствами объектов; для обычных свойств это недопустимо.</span></p> <p><span class="f_Heading1">КРАЕУГОЛЬНЫЕ КАМНИ ООП</span></p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">ФОРМУЛА ОБЪЕКТА</span></p> <p class="p_Heading1"> </p> <p>Авторы надеются, что читатель помнит кое-что из второй главы и такие понятия, как тип данных, процедура, функция, запись для него не в новинку. Это прекрасно. Та вот, в конце 60-х годов кому-то пришло в голову объединить эти понятия и то, что получилось, назвать объектом. Рассмотрение данных в неразрывной связи с методами их обработки позволило вывести формулу объекта:</p> <p style="text-align: center;">Объект = Данные + Операции</p> <p style="text-align: center;"> </p> <p>На основании этой формулы была разработана методология объектно-ориентированного программирования (ООП).</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">ПРИРОДА ОБЪЕКТА</span></p> <p> </p> <p>Об объектах можно думать как о полезных существах, которые «живут» в вашей программе и коллективно решают некоторую прикладную задачу. Вы, как Демиург, лепите этих существ, распределяете между ними обязанности и устанавливаете правила их взаимодействия.</p> <p>В общем случае каждый объект «помнит» необходимую информацию, «умеет» выполнять некоторый набор действий и характеризуется набором свойств. То, что объект «помнит», хранится в его полях. То, что объект «умеет делать», реализуется в виде его внутренних процедур и функций, называемых методами. Свойства объектов аналогичны свойствам, которые мы наблюдаем у обычных предметов. Значения свойств можно устанавливать и читать. Программно свойства реализуются через поля и методы.</p> <p> </p> <p>Например, объект «кнопка» имеет свойство «цвет». Значение цвета кнопка запоминает в одном из своих полей. При изменении значения свойства «цвет» вызывается метод, который перерисовывает кнопку.</p> <p> </p> <p>Кстати, этот пример позволяет сделать важный вывод: свойства имеют первостепенное значение для программиста, использующего объект. Чтобы понять суть и назначение объекта, вы обязательно должны знать его свойства, иногда — методы, очень редко — поля (объект и сам знает, что с ними делать).</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">ОБЪЕКТЫ И КОМПОНЕНТЫ</span></p> <p>Когда прикладные программы создавались для операционной системы MS-DOS и были консольно-ориентированными, объекты казались пределом развития программирования, поскольку были идеальным средством разбиения сложных задач на простые подзадачи. Однако с появлением графических систем, в частности Windows, программирование пользовательского интерфейса резко усложнилось. Программист в какой-то мере стал дизайнером, а визуальная компоновка и увязка элементов пользовательского интерфейса (кнопок, меток, строк редактора) начали отнимать основную часть времени. И тогда программистам пришла в голову идея визуализировать объекты, объединив программную часть объекта с его видимым представлением на экране дисплея в одно целое. То, что получилось в результате, было названо компонентом.</p> <p>Компоненты в Delphi — это особые объекты, которые являются строительными кирпичиками среды визуальной разработки и приспособлены к визуальной установке свойств. Чтобы превратить объект в компонент, первый разрабатывается по определенным правилам, а затем помещается в Палитру Компонентов. Конструируя приложение, вы берете компоненты из Палитры Компонентов, располагаете на форме и устанавливаете их свойства в окне Инспектора Объектов. Внешне все выглядит просто, но чтобы достичь такой простоты, потребовалось создать механизмы, обеспечивающие функционирование объектов-компонентов уже на этапе проектирования приложения! Все это было придумано и блестяще реализовано в среде Delphi. Таким образом, компонентный подход значительно упростил создание приложений с графическим пользовательским интерфейсом и дал толчок развитию новой индустрии компонентов.</p> <p>В данной главе мы рассмотрим лишь вопросы создания и использования объектов, Чуть позже мы научим вас превращать объекты в компоненты.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">КЛАССЫ ОБЪЕКТОВ</span></p> <p>Каждый объект всегда принадлежит некоторому классу. Класс — это обобщенное (абстрактное) описание множества однотипных объектов. Объекты являются конкретными представителями своего класса, их принято называть экземплярами класса. Например, класс СОБАКИ — понятие абстрактное, а экземпляр этого класса МОЙ ПЕС БОБИК — понятие конкретное.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">ТРИ КИТА ООП</span></p> <p>Весь мир ООП держится на трех китах: инкапсуляции, наследовании и полиморфизме. Для начала о них надо иметь только самое общее представление.</p> <p> </p> <p>Наблюдаемое в объектах объединение данных и операций в одно целое было обозначено термином <span style="font-weight: bold;">инкапсуляция</span> (первый кит ООП). Применение инкапсуляции сделало объекты похожими на маленькие программные модули и обеспечило сокрытие их внутреннего устройства. Для объектов появилось понятие интерфейса, что значительно повысило их надежность и целостность.</p> <p> </p> <p>Второй кит ООП — <span style="font-weight: bold;">наследование</span>. Этот простой принцип означает, что если вы хотите создать новый класс, лишь немногим отличающийся от того, что уже существует, то нет необходимости в переписывании заново всех полей, методов и свойств. Вы объявляете, что новый класс является потомком (или дочерним классом) имеющегося класса, называемого предком (или родительским классом), и добавляете к нему новые поля, методы и свойства. Иными словами добавляется то, что нужно для перехода от общего к частному. Процесс порождения новых классов на основе других классов называется наследованием. Новые классы имеют как унаследованные признаки, так и, возможно, новые. Например, класс СОБАКИ унаследовал многие свойства своих предков — ВОЛКОВ.</p> <p> </p> <p>Третий кит — это <span style="font-weight: bold;">полиморфизм</span>. Он означает, что в производных классах вы можете изменять работу уже существующих в базовом классе методов. При этом весь программный код, управляющий объектами родительского класса, пригоден для управления объектами дочернего класса без всякой модификации. Например, вы можете породить новый класс кнопок с рельефной надписью, переопределив метод отрисовки кнопки. Новую кнопку можно «подсунуть» вместо стандартной в какую-нибудь подпрограмму, вызывающую отрисовку кнопки. При этом подпрограмма «думает», что работает со стандартной кнопкой, но на самом деле кнопка принадлежит производному классу и отображается в новом стиле.</p> <p>Пока достаточно самого поверхностного понимания всех приведенных выше понятий, ниже мы рассмотрим их подробнее и покажем, как они реализованы в Delphi.</p> <p> </p> <p class="p_Heading1"><span class="f_Heading1">КЛАССЫ</span></p> <p>Delphi поддерживает две модели представления объектов — старую и новую. Старая модель существует лишь для совместимости с более ранними версиями компилятора, в частности с Borland Pascal 7.0, поэтому мы не будем ее рассматривать. Все, что сказано ниже, относится к новой модели представления объектов, более мощной и богатой по своим возможностям.</p> <p> </p> <p>Для поддержки ООП в язык Object Pascal введены объектные типы данных, с помощью которых одновременно описываются данные и операции над ними. Объектные типы называют классами, а их экземпляры — <span style="font-weight: bold;">объектами</span>.</p> <p> </p> <p>Классы объектов определяются в секции <span style="font-weight: bold;">type</span> глобального блока. Описание класса начинается словом <span style="font-weight: bold;">class</span> и заканчивается словом <span style="font-weight: bold;">end</span>. По форме объявления классы похожи на обычные записи, но помимо полей данных могут содержать объявления пользовательских процедур и функций. Такие процедуры и функции обобщенно называют методами, они предназначены для выполнения над объектами различных операций.</p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Приведем пример объявления класса:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span> <span class="f_CodeExample" style="font-style: italic; color: #000080;">{ измеритель дискового пространства}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DriveLetter: Char; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ буква дискового накопителя}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PercentCritical: Integer; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ критический процент свободного пространства}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Заголовки методов, следующие за списком полей, играют роль предварительных</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> (forward) </span><span style="font-family: 'Times New Roman'; color: #000000;">объявлений. Программный код методов помещается ниже определения класса и будет приведен позже.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Класс обычно описывает сущность, моделируемую в программе. Например, класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge </span><span style="font-family: 'Times New Roman'; color: #000000;">описывает измеритель дискового ресурса. Класс содержит два поля:</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> DriveLetter</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> буква находящегося под наблюдением накопителя, и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> PercentCritical</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> процент свободного пространства на диске, с которым работает программа. Когда объем свободных ресурсов снижается до этого порога, пользователю выдается звуковое предупреждение. Функция </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">GetPercentFree</span><span style="font-family: 'Times New Roman'; color: #000000;"> определена как метод работы над любым объектом класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> и возвращает процент свободного пространства на диске. Процедура</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> служит для проверки состояния ресурса и выдачи звукового предупреждения.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Обратите внимание, что приведенное выше описание является не чем иным, как декларацией интерфейса для управления объектами класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Реализация методов </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">GetPercentFree и CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> отсутствует, но для создания и использования экземпляров класса она пока и не нужна. В этом как раз и состоит сила инкапсуляции, Которая делает объекты аналогичными программным модулям. Для использования модуля необходимо изучить лишь его интерфейсную часть, раздел реализации для этого изучать не требуется. Поэтому дальше от описания класса мы перейдем не к реализации методов, а к созданию на их основе объектов.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">ОБЪЕКТЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Чтобы от описания класса перейти к объекту, следует выполнить соответствующее объявление в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> var:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #000000;"> DiskGauge: TDiskGauge;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">При работе с обычными типами данных этого объявления было бы достаточно для получения экземпляра типа. Однако объекты в Delphi являются динамическими данными, т.е. распределяются в «куче» (heap). Поэтому переменная</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> DiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это просто </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">ссылка на экземпляр объекта,</span><span style="font-family: 'Times New Roman'; color: #000000;"> которого физически еще не существует. Чтобы </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">сконструировать</span><span style="font-family: 'Times New Roman'; color: #000000;"> объект класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> и </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">связать</span><span style="font-family: 'Times New Roman'; color: #000000;"> с ним переменную</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> DiskGauge, </span><span style="font-family: 'Times New Roman'; color: #000000;">нужно в текст программы поместить следующий оператор (statement):</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge: = TDiskGauge.Create;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 16px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Create</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это так называемый </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">конструктор</span><span style="font-family: 'Times New Roman'; color: #000000;"> объекта; он всегда присутствует в классе и служит для создания и инициализации экземпляров. К сведению профессионалов заметим, что в памяти выделяется место только для полей объекта. Методы, так же как и обычные процедуры и функции, помещаются в область кода программы; они умеют работать с любыми экземплярами своего класса и в памяти никогда не дублируются,</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">После создания объект можно использовать в программе </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> читать и устанавливать его поля, вызывать методы. Доступ к полям и методам объекта происходит с помощью уточненных имен, например:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge.DriveLetter: = </span><span class="f_CodeExample" style="color: #ff0000;">'С'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge. PercentCritical: = </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge.CheckStatus;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Кроме того, как и при работе с записями, допустимо использование оператора with, например:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> DiskGauge </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DriveLetter: = </span><span class="f_CodeExample" style="color: #ff0000;">'С'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PercentCritical: = </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Если наступает время, когда объект становится не нужен в программе, он должен быть удален вызовом специального метода</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Destroy,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge.Destroy;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 16px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Destroy </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это так называемый </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">деструктор</span><span style="font-family: 'Times New Roman'; color: #000000;"> объекта; он присутствует в классе наряду с конструктором и служит для удаления объекта из динамической памяти. После вызова деструктора переменная</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> DiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> становится </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">несвязанной</span><span style="font-family: 'Times New Roman'; color: #000000;"> и не должна использоваться для доступа к полям и методам уже несуществующего объекта. Чтобы отличать в программе связанные объектные переменные от несвязанных, последние следует инициализировать значением</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> nil.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Например, в следующем фрагменте обращение к деструктору</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Destroy</span><span style="font-family: 'Times New Roman'; color: #000000;"> выполняется только в том случае, если объект реально существует.</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge: = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> DiskGauge &lt;&gt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> DiskGauge.Destroy;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 11px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Вызов деструктора для несуществующих объектов недопустим и при выполнении программы приведет к ошибке. Чтобы избавить программистов от лишних ошибок, в объекты ввели предопределенный метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Free,</span><span style="font-family: 'Times New Roman'; color: #000000;"> который следует вызывать вместо деструктора. Метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Free</span><span style="font-family: 'Times New Roman'; color: #000000;"> сам вызывает деструктор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Destroy,</span><span style="font-family: 'Times New Roman'; color: #000000;"> но только в том случае, если значение объектной переменной не равно nil. Поэтому последнюю строчку в приведенном выше примере можно переписать следующим образом:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge.Free;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 11px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Значение одной объектной переменной можно присвоить другой. При этом объект не копируется в памяти, а вторая переменная просто связывается с тем же объектом, что и первая:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGaugel, DiskGauge2: TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Переменные DiskGauge1 и DiskGauge2 не связаны с объектом}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge1: = TDiskGauge.Create;</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Переменная DiskGauge1 связана с объектом, а DiskGauge2 — нет}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge2: = DiskGauge1;</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Обе переменные связаны с одним объектом}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge2.Free; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{Объект удален, переменные DiskGauge1 и DiskGauge2 с ним не связаны}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Объекты могут выступать в программе не только в качестве переменных, но также элементов массивов, полей записей, параметров процедур и функций. Кроме того, они могут служить полями других объектов. Во всех этих случаях программист фактически оперирует указателями на экземпляры объектов в динамической памяти. Следовательно, объекты априори приспособлены для создания сложных динамических структур данных, таких как списки и деревья. Указатели на объекты для этого не нужны.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В некоторых случаях требуется, чтобы объекты разных классов содержали ссылки друг на друга. Возникает проблема: объявление первого класса будет содержать ссылку на еще не определенный класс. Она решается с помощью упреждающего объявления.</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TGaugeList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ предварительное объявление класса TGaugeList }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> Owner: TGaugeList;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TGaugeList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> Gauges: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">array</span><span class="f_CodeExample" style="color: #000000;"> [</span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">..</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #000000;">] </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Первое объявление класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TGaugeList</span><span style="font-family: 'Times New Roman'; color: #000000;"> называется </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">предварительным</span><span style="font-family: 'Times New Roman'; color: #000000;"> (от англ. forward). Оно необходимо для того, чтобы компилятор нормально воспринял объявление поля Owner в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Итак, вы уже имеете некоторое представление об объектах, перейдем теперь к вопросу реализации их методов.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">МЕТОДЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Процедуры и функции, предназначенные для выполнения над объектами действий, называются </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">методами.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Предварительное объявление методов выполняется при описании класса в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> interface</span><span style="font-family: 'Times New Roman'; color: #000000;"> модуля, а их программный код записывается в секции </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">implementation.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Однако в отличие от обычных процедур и функций заголовки методов должны иметь уточненные имена, т.е. содержать наименование класса. Приведем, например, возможную реализацию методов в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.GetPercentFree: Integer; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ uses SysUtils; }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var </span><span class="f_CodeExample" style="color: #000000;">Drive: Byte;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Drive := Ord(DriveLetter) - Ord(</span><span class="f_CodeExample" style="color: #ff0000;">'A'</span><span class="f_CodeExample" style="color: #000000;">) + </span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := DiskFree(Drive) * </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">div</span><span class="f_CodeExample" style="color: #000000;"> DiskSize(Drive);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.CheckStatus; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ uses Windows; }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree &lt;= PercentCritical</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;"> then</span><span class="f_CodeExample" style="color: #000000;"> Beep;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 28px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Обратите внимание, что внутри методов обращения к полям и другим методам выполняются как к обычным переменным и подпрограммам без уточнения экземпляра объекта. Такое упрощение достигается путем использования в пределах метода псевдопеременной </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Self</span><span style="font-family: 'Times New Roman'; color: #000000;"> (стандартный идентификатор). Физически</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Self</span><span style="font-family: 'Times New Roman'; color: #000000;"> представляет собой дополнительный неявный параметр, передаваемый в метод при вызове. Этот параметр и указывает экземпляр объекта, к которому данный метод применяется. Чтобы пояснить сказанное, перепишем метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus,</span><span style="font-family: 'Times New Roman'; color: #000000;"> представив его в виде обычной процедуры:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge_CheckStatus (Self: TDiskGauge);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> Self </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree &lt;= PercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Beep;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 8px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Согласитесь, что метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> выглядит более предпочтительно, чем процедура </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TDiskGauge_CheckStatus.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Практика показывает, что псевдопеременная</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Self</span><span style="font-family: 'Times New Roman'; color: #000000;"> редко используется в явном виде. Ее необходимо применять только тогда, когда при написании метода может возникнуть какая-либо двусмысленность для компилятора, например при использовании одинаковых имен и для локальных переменных, и для полей объекта.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Если выполнить метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge.CheckStatus;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 11px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">то произойдет проверка состояния дискового ресурса. При этом неявный параметр Self будет содержать значение переменной</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> DiskGauge.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Такой вызов реализуется обычными средствами процедурного программирования приблизительно так:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge_CheckStatus(DiskGauge);</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 11px;"> </p> <p style="margin: 0px 0px 0px 11px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">КОНСТРУКТОРЫ И ДЕСТРУКТОРЫ</span></p> <p style="margin: 0px 0px 0px 5px;"><span style="font-family: 'Times New Roman'; color: #000000;">Особой разновидностью методов являются </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">конструкторы</span><span style="font-family: 'Times New Roman'; color: #000000;"> и </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">деструкторы.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Напомним, что конструкторы создают, а деструкторы </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> разрушают объекты. Создание объекта включает выделение памяти под экземпляр и инициализацию его полей, а разрушение </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> очистку полей и освобождение памяти.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Очевидно, что выполняемые при инициализации и деинициализации действия специфичны для каждого конкретного класса объектов. По этой причине Object Pascal позволяет </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">переопределить</span><span style="font-family: 'Times New Roman'; color: #000000;"> стандартные конструктор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Create</span><span style="font-family: 'Times New Roman'; color: #000000;"> и деструктор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Destroy</span><span style="font-family: 'Times New Roman'; color: #000000;"> для выполнения любых полезных действий. Можно даже определить несколько конструкторов и деструкторов (имена им назначает сам программист), чтобы обеспечить различные способы создания и разрушения объектов.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Объявление конструкторов и деструкторов похоже на объявление обычных методов с той лишь разницей, что вместо зарезервированного слова procedure (или function) используются слова constructor и destructor:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> DriveLetter: Char;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PercentCritical: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Приведем их возможную реализацию:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DriveLetter := </span><span class="f_CodeExample" style="color: #ff0000;">'C'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PercentCritical := </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Разрушение встроенных объектов и освобождение динамических данных}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Конструктор иногда имеет параметры, в которых передаются исходные значения полей объекта. Если объект содержит встроенные объекты или другие динамические данные, то конструктор </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это как раз то место, где их нужно создавать.</span></p> <p style="text-indent: -19px; margin: 0px 27px 0px 19px;"><span style="font-family: 'Times New Roman'; color: #000000;">Конструктор применяется к классу или к объекту. Если он применяется к классу</span></p> <p style="text-indent: -19px; margin: 0px 27px 0px 19px;"> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge: = TDiskGauge.Create;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 27px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">то выполняется следующая последовательность действий:</span></p> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 44px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">в динамической памяти выделяется место для нового объекта;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 44px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">выделенная память заполняется нулями; в результате все числовые поля и поля порядкового типа приобретают нулевые значения, строковые поля становятся пустыми, а поля, содержащие указатели и объекты, получают значение</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> nil;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 44px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">затем выполняются заданные программистом действия конструктора;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 44px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">ссылка на созданный объект возвращается в качестве значения конструктора; тип возвращаемого значения совпадает с типом класса, использованного при вызове (в нашем примере это тип</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge).</span></td> </tr> </tbody> </table> </div> <p style="text-indent: -24px; margin: 0px 0px 0px 68px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Если конструктор применяется к объекту (</span><span style="font-family: 'Courier New'; color: #000000; font-size: 10pt;">DiskGauge.Create;)</span><span style="font-family: 'Times New Roman'; color: #000000;">то новый объект не создается, а происходит переинициализация полей существующего. В этом случае конструктор не возвращает никакого значения.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Деструктор уничтожает объект, к которому применяется (</span><span style="font-family: 'Courier New'; color: #000000; font-size: 10pt;">DiskGauge.Destroy;)</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В результате:</span></p> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 40px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">выполняется заданный программистом код деинициализации;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 40px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">освобождается занимаемая объектом динамическая память.</span></td> </tr> </tbody> </table> </div> <p><span style="font-family: 'Times New Roman'; color: #000000;">В теле деструктора обычно должны уничтожаться встроенные объекты и динамические данные, созданные конструктором.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">СВОЙСТВА</span></p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">ПОНЯТИЕ СВОЙСТВА</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Помимо полей и методов в объектах существуют </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">свойства.</span><span style="font-family: 'Times New Roman'; color: #000000;"> При работе с объектом свойства выглядят как поля: они принимают значения и участвуют в выражениях. Но в отличие от полей свойства не занимают места в памяти, а операции их чтения и записи ассоциируются с обычными полями или методами. Это позволяет создавать необходимые побочные эффекты при обращении к свойствам. Например, присваивание свойству</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Visible</span><span style="font-family: 'Times New Roman'; color: #000000;"> значения</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> True</span><span style="font-family: 'Times New Roman'; color: #000000;"> вызовет отображение графического объекта на экране, а значения</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> False</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> его исчезновение.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Объявление свойства выполняется с помощью зарезервированного слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> property,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical (Percent: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentCritical: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FpercentCritical</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">После слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> read</span><span style="font-family: 'Times New Roman'; color: #000000;"> указывается поле или метод, к которому происходит обращение при чтении значения свойства, а после слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> write</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> поле или метод, к которому происходит обращение при записи значения свойства. Например, чтение свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> PercentCritical </span><span style="font-family: 'Times New Roman'; color: #000000;">заменяется на чтение поля</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> FPercentCritical,</span><span style="font-family: 'Times New Roman'; color: #000000;"> а установка свойства </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> на вызов метода </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">SetPercentCritical.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Чтобы имена свойств не совпадали с именами полей, последние принято писать с буквы F (от англ. field).</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Атрибуты read и write называются спецификаторами доступа. Если один из них опущен, то значение свойства можно либо только читать (задан спецификатор read), либо только записывать (задан спецификатор write). В следующем примере объявлено свойство, значение которого можно только читать:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentFree: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 28px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Обращение к свойствам выглядит в программе как обращение к полям:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge: TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">A : Integer;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">А := DiskGauge.PercentCritical;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ эквивалентно А := DiskGauge.FPercentCritical;}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge.PercentCritical := A + </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ эквивалентно DiskGauge.SetPercentCritical(A + 10);}</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Однако в отличие от полей свойства не имеют адреса в памяти, поэтому к ним запрещено применять операцию @. Кроме того, их нельзя передавать в var-параметрах процедур и функций.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Технология объектно-ориентированного программирования в Delphi предписывает избегать прямого обращения к полям, создавая вместо этого соответствующие свойства. Это упорядочивает работу с объектами, изолируя их данные от непосредственной модификации. В будущем внутренняя структура класса, которая иногда является достаточно сложной, может быть изменена с целью повышения эффективности работы программы. При этом потребуется переработать только методы чтения и записи значений свойств; внешний интерфейс класса не изменится.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">МЕТОДЫ ПОЛУЧЕНИЯ И УСТАНОВКИ СВОЙСТВ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы чтения и записи свойств подчиняются определенным правилам. Метод чтения свойства </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это всегда функция, возвращающая значение того же типа, что и тип свойства. Метод записи свойства </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это обязательно процедура, принимающая параметр того же типа, что и тип свойства. В остальном это обычные методы объекта. Примерами методов чтения и записи свойств являются</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPercentFree и SetPercentCritical в</span><span style="font-family: 'Times New Roman'; color: #000000;"> классе </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TDiskGauge:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FPercentCritical: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical (Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentFree: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentCritical: Integer</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Использование методов для получения и установки свойств позволяет проверить корректность значения свойства, сделать дополнительные вычисления, установить значения зависимых полей и т.д. Например, в методе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> SetPercentCritical</span><span style="font-family: 'Times New Roman'; color: #000000;"> целесообразно сделать проверку на то, что устанавливаемое значение находится в диапазоне от 0 до 100:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.SetPercentCritical (Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> (Value &gt;= </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">and</span><span class="f_CodeExample" style="color: #000000;"> (Value &lt; </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #000000;">)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> FpercentCritical := Value;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">МЕТОДЫ, ОБСЛУЖИВАЮЩИЕ НЕСКОЛЬКО СВОЙСТВ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">0дин и тот же метод может использоваться для получения (установки) значений нескольких свойств одного типа. В этом случае каждому свойству назначается целочисленный индекс, который передается в метод первым параметром. В следующем примере методы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Get и Set</span><span style="font-family: 'Times New Roman'; color: #000000;"> обслуживают три свойства:</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GaugeA, GaugeB и GaugeC:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TGaugeList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FGauges: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">array</span><span class="f_CodeExample" style="color: #000000;"> [</span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">..</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #000000;">] </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> Get (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer): TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;"> (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer; Value: TDiskGauge);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> GaugeA: TDiskGauge </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> Get </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> GaugeB: TDiskGauge </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> Get </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> GaugeC: TDiskGauge </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">index</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> Get </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TGaugeList.Get (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer): TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := FGauges [</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">];</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TGaugeList.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;"> (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer; Value: TDiskGauge);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FGauges [</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">] := Value;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Обращения к свойствам</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GaugeA, GaugeB и GaugeC</span><span style="font-family: 'Times New Roman'; color: #000000;"> заменяются на соответствующие Вызовы методов</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Get и Set:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GaugeList: TGaugeList;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DiskGauge: TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GaugeList.GaugeC := DiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ эквивалентно GaugeList.Set (2, DiskGauge) }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GaugeList.GaugeC.CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ эквивалентно GaugeList.Get(2).CheckStatus }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">СВОЙСТВА-МАССИВЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Кроме обычных свойств в объектах существуют свойства-массивы (array properties), </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">Свойство-массив </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> это индексированное множество свойств. В виде свойства-массива удобно, например, представить множество измерителей ресурсов в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TGaugeList</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TGaugeList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Gauges[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer]: TdiskGauge</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> Get </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 16px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Обратите внимание, что методы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Get</span><span style="font-family: 'Times New Roman'; color: #000000;"> и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Set</span><span style="font-family: 'Times New Roman'; color: #000000;"> обслуживают и свойство-массив Gauges, и индексированные свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GaugeA, GaugeB и GaugeC.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Если в описании обычных свойств могут участвовать поля, то в описании свойств-массивов разрешено использовать только методы.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Основная выгода от применения свойств-массивов </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> возможность выполнения итераций с помощью цикла</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> for,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GaugeList: TGaugeList;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">I: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> I := </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> GaugeList </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #000000;"> Gauges [I] .CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 13px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Свойства-массивы могут быть многомерными. В этом случае методы чтения и записи их элементов имеют столько же индексных параметров соответствующего типа, что и массив.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Свойства-массивы имеют два важных отличия от обычных массовов:</span></p> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 10px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="9"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">•</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">их индексы не ограничиваются диапазоном и могуптаеть-любой тип-данных, а не только</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Integer;</span><span style="font-family: 'Times New Roman'; color: #000000;"> например, можно создать свойство-массив, в котором индексами будут строки; обращение к такому свойству могло бы выглядеть так:</span></td> </tr> </tbody> </table> </div> <p style="margin: 0px 160px 0px 19px;"><span style="font-family: 'Courier New'; color: #000000; font-size: 10pt;">GaugeList.Gauges['GaugeA'] := DiskGauge;</span></p> <p><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #000000; font-size: 10pt;">• </span><span style="font-family: 'Times New Roman'; color: #000000;">операции над свойством-массивом в целом запрещены; разрешены операции только с его элементами.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">СВОЙСТВО-МАССИВ КАК ОСНОВНОЕ СВОЙСТВО ОБЪЕКТА</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Свойство-массив можно сделать основным свойством объектов данного класса. Для этого в его описание добавляется слово</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> default:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TGaugeList = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Gauges [</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer]: TdiskGauge</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> Get </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Set</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">default</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Такое объявление свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Gauges</span><span style="font-family: 'Times New Roman'; color: #000000;"> позволяет рассматривать сам объект класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TGaugeList </span><span style="font-family: 'Times New Roman'; color: #000000;">как массив и опускать имя свойства-массива при обращении к нему из программы, например:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var </span><span class="f_CodeExample" style="color: #000000;">GaugeList: TGaugeList;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> I: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> I := </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000080;">2</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #000000;"> GaugeList [I] := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ эквивалентно GaugeList.Gauges[I] := nil; }</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt;">Следует помнить, что только свойства-массивы могут быть основными свойствами объектов; для обычных свойств это недопустимо.</span></p> Метаклассы 2013-08-15T20:36:07+07:00 2013-08-15T20:36:07+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/sushchnost-oop/metaklassy.html Super User toto44@inbox.ru <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">МЕТАКЛАССЫ</span></p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">ССЫЛКИ НА КЛАССЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Язык Object Pascal позволяет рассматривать классы как своего рода объекты, которыми можно манипулировать в программе. Такая возможность рождает новое понятие </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">класс класса;</span><span style="font-family: 'Times New Roman'; color: #000000;"> его принято обозначать термином </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">метакласс.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Для поддержки метаклассов введен специальный тип данных </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">ссылка на класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> (class reference). Он описывается с помощью словосочетания </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">class of,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGaugeClass = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Переменная типа</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGaugeClass</span><span style="font-family: 'Times New Roman'; color: #000000;"> объявляется в программе обычным образом:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ClassRef: TResourceGaugeClass;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Значениями переменной</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> ClassRef</span><span style="font-family: 'Times New Roman'; color: #000000;"> могут быть класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> и все порожденные от него классы. Допустимы, например, следующие операторы:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ClassRef := TResourceGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ClassRef := TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ClassRef := TMemoryGauge;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">По аналогии с тем, как для всех классов существует общий предок</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TObject,</span><span style="font-family: 'Times New Roman'; color: #000000;"> у ссылок на классы существует базовый тип</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TCIass:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> TCIass = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TObject;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Переменная типа </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TCIass</span><span style="font-family: 'Times New Roman'; color: #000000;"> может ссылаться на любой класс.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Практическая ценность ссылок на классы состоит в возможности создавать программные модули, работающие с любыми классами объектов, даже с теми, которые еще не разработаны.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">МЕТОДЫ КЛАССОВ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Метаклассы привели к возникновению нового типа методов </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> методов класса. </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">Метод класса</span><span style="font-family: 'Times New Roman'; color: #000000;"> оперирует не экземпляром объекта, а непосредственно классом. Он объявляется как обычный метод, но перед словом</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> procedure</span><span style="font-family: 'Times New Roman'; color: #000000;"> или</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> function</span><span style="font-family: 'Times New Roman'; color: #000000;"> записывается зарезервированное слово</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> class,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetClassName : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Псевдопараметр</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Self,</span><span style="font-family: 'Times New Roman'; color: #000000;"> передаваемый в метод класса, содержит не ссылку на объект, а ссылку на класс, поэтому в теле метода нельзя обращаться к полям, методам и свойствам объекта. Зато можно вызывать другие методы класса, например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.GetClassName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := ClassName;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> ClassName</span><span style="font-family: 'Times New Roman'; color: #000000;"> объявлен в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TObject</span><span style="font-family: 'Times New Roman'; color: #000000;"> и возвращает имя класса, к которому применяется. Очевидно, что надуманный метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetClassName</span><span style="font-family: 'Times New Roman'; color: #000000;"> просто дублирует эту функциональность для класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> и всех его наследников.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы класса применимы и к классам, и к объектам. В обоих случаях в параметре</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Self </span><span style="font-family: 'Times New Roman'; color: #000000;">передается ссылка на класс объекта. Пример:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Gauge: TResourceGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">S: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Вызов метода с помощью ссылки на класс }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">S := TDiskGauge.GetClassName; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ S получит значение 'TDiskGauge' }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Gauge := TDiskGauge.Create(</span><span class="f_CodeExample" style="color: #ff0000;">'С'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Вызов метода с помощью ссылки на объект }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">S := Gauge.GetClassName; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ S получит значение 'TDiskGauge' }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы классов могут быть виртуальными. Например, в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TObject</span><span style="font-family: 'Times New Roman'; color: #000000;"> определен виртуальный метод класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Newlnstance.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Он служит для распределения памяти под объект и автоматически вызывается конструктором. Его можно перекрыть в своем классе, чтобы обеспечить нестандартный способ выделения памяти для экземпляров. Метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Newlnstance должен</span><span style="font-family: 'Times New Roman'; color: #000000;"> перекрываться вместе с другим методом</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Freelnstance,</span><span style="font-family: 'Times New Roman'; color: #000000;"> который автоматически вызывается из деструктора и служит для освобождения памяти. Добавим, что размер памяти, требуемый для экземпляра, можно узнать вызовом предопределенного метода класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> InstanceSize.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">ВИРТУАЛЬНЫЕ КОНСТРУКТОРЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Особая мощь ссылок на классы проявляется в сочетании с виртуальными конструкторами. Виртуальный конструктор объявляется с ключевым словом</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> virtual.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Вызов виртуального конструктора происходит по фактическому значению ссылки на класс, а не по ее формальному типу. Это позволяет создавать объекты, классы которых неизвестны на этапе компиляции. Механизм виртуальных конструкторов применяется в Delphi при создании форм и компонентов.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">На этом закончим изучение теории объектно-ориентированного программирования и в качестве практики рассмотрим несколько широко используемых инструментальных классов Delphi. Разберитесь с их назначением и работой. Это поможет глубже понять ООП и пригодится на будущее.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">КЛАССЫ ОБЩЕГО НАЗНАЧЕНИЯ В DELPHI</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Как показывает практика, в большинстве задач приходится использовать однотипные структуры данных: списки, массивы, множества и т.д. От задачи к задаче изменяются только их элементы, а методы работы сохраняются. Например, для любого списка нужны процедуры вставки и удаления элементов. В связи с этим возникает естественное желание решить задачу «в общем виде», т.е. создать универсальные средства для управления основными структурами данных. Эта идея не нова. Она давно пришла в голову разработчикам инструментальных пакетов, которые быстро наплодили множество вспомогательных библиотек. Эти библиотеки содержали классы объектов для работы со списками, коллекциями (динамические массивы с переменным количеством элементов), словарями (коллекции, индексированные строками) и другими «абстрактными» структурами. Для Delphi тоже разработаны аналогичные классы объектов. Их большая часть сосредоточена в модуле </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Classes</span><span style="font-family: 'Times New Roman'; color: #000000;">. Наиболее нужными для вас являются списки строк (</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStringList</span><span style="font-family: 'Times New Roman'; color: #000000;">) и потоки (</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TSream</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">THandleSream</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TFileStream</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TMemoryStream</span><span style="font-family: 'Times New Roman'; color: #000000;"> и </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TBIobStream</span><span style="font-family: 'Times New Roman'; color: #000000;">). Рассмотрим кратко их назначение и применение.</span></p> <p> </p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">КЛАССЫ ДЛЯ ПРЕДСТАВЛЕНИЯ СПИСКА СТРОК</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Для работы со списками строк служат классы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings и TStringList. </span><span style="font-family: 'Times New Roman'; color: #000000;">Они используются в библиотеке VCL повсеместно и имеют гораздо большую универсальность, чем та, что можно почерпнуть из их названия. Классы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings </span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStringList</span><span style="font-family: 'Times New Roman'; color: #000000;"> служат для представления не просто списка строк, а списка элементов, каждый из которых представляет собой пару строка-объект. Если со строками не ассоциированы объекты, получается обычный список строк.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Класс </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> используется визуальными компонентами и является абстрактным. Он не имеет собственных средств хранения строк и определяет лишь интерфейс для работы с элементами. Класс </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStringList</span><span style="font-family: 'Times New Roman'; color: #000000;"> является наследником </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> и служит для организации списков строк, которые используются отдельно от управляющих элементов. Объекты </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStringList</span><span style="font-family: 'Times New Roman'; color: #000000;"> хранят строки и объекты в динамической памяти.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Свойства класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> описаны ниже.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Count: Integer</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> число элементов в списке.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Strings[lndex: Integer]: string</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> обеспечивает доступ к массиву строк по индексу. Первая строка имеет индекс, равный 0. Свойство</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Strings</span><span style="font-family: 'Times New Roman'; color: #000000;"> является основным свойством объекта.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Objects[lndex: Integer]: TObject </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> обеспечивает доступ к массиву объектов. Свойства </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Strings</span><span style="font-family: 'Times New Roman'; color: #000000;"> и </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Objects</span><span style="font-family: 'Times New Roman'; color: #000000;"> позволяют использовать объект</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> как хранилище строк и ассоциированных с ними объектов произвольных классов.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Text: string</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> позволяет интерпретировать список строк как одну большую строку, в которой элементы разделены символами #13#10 (возврат каретки и перевод строки),</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Наследники класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> иногда используются для хранения строк вида Имя=3начение, в частности, строк INI-файлов (см. гл. 6). Для удобной работы со строками такой структуры в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> дополнительно имеются следующие свойства.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Names[lndex: Integer]: string</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> обеспечивает доступ к той части строки, в которой содержится имя.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Values[const Name: string]: string</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> обеспечивает доступ к той части строки, в которой содержится значение. Указывая вместо</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Name</span><span style="font-family: 'Times New Roman'; color: #000000;"> ту часть строки, которая находится слева от знака равенства, вы получаете ту часть, что находится справа.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Управление элементами списка осуществляется с помощью следующих методов:</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Add(const S: string): Integer</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> добавляет новую строку </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">S</span><span style="font-family: 'Times New Roman'; color: #000000;"> в список и возвращает ее позицию. Новая строка добавляется в конец списка.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Add0bject(const S: string; AObject: TObject): Integer</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> добавляет в список строку </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">S</span><span style="font-family: 'Times New Roman'; color: #000000;"> и ассоциированный с ней объект</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> AObject.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Возвращает индекс пары строка</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;">объект.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">AddStrings(Strings: TStrings)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> добавляет группу строк в существующий список. </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Append(const S: string)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> делает то же, что и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Add,</span><span style="font-family: 'Times New Roman'; color: #000000;"> но не возвращает значения. </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Clear</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> удаляет из списка все элементы.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Delete(lndex: Integer)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> удаляет строку и ассоциированный с ней объект. Метод </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Delete</span><span style="font-family: 'Times New Roman'; color: #000000;">, так же как метод </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Clear</span><span style="font-family: 'Times New Roman'; color: #000000;">, не разрушает объектов, т.е. не вызывает у них деструктор. Об этом вы должны позаботиться сами.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Equals(Strings: TStrings): Boolean</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> возвращает</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> True,</span><span style="font-family: 'Times New Roman'; color: #000000;"> если список строк в точности равен тому, что передан в параметре</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Strings.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Exchange(lndex1, lndex2: Integer)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> меняет два элемента местами.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">GetText:</span><span style="font-family: 'Times New Roman'; color: #000000;"> PChar </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> возвращает все строки списка в виде одной большой нуль-терминированной строки.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">lndex0f(const S: string): Integer</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> возвращает позицию строки </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">S</span><span style="font-family: 'Times New Roman'; color: #000000;"> в списке. Если заданная строка в списке отсутствует, функция возвращает значение </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;">1.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">lndexOfName(const Name: string): Integer</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> возвращает позицию строки, которая имеет вид Имя=3начение и содержит в себе Имя, равное</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Name.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">lndexOfObject(AObject: TObject): Integer</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> возвращает позицию объекта</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> AObject</span><span style="font-family: 'Times New Roman'; color: #000000;"> в массиве</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Objects.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Если заданный объект в списке отсутствует, функция возвращает значение </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;">1.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">lnsert(lndex: Integer; const S: string)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> вставляет в список строку </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">S</span><span style="font-family: 'Times New Roman'; color: #000000;"> в позицию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Index.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">lnsert0bject(lndex: Integer; const S: string; AObject: TObject)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> вставляет в список строку </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">S</span><span style="font-family: 'Times New Roman'; color: #000000;"> и ассоциированный с ней объект</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> AObject</span><span style="font-family: 'Times New Roman'; color: #000000;"> в позицию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Index.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">LoadFromFile(const FileName: string)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> загружает строки списка из текстового файла.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">LoadFromStream(Stream: TStream)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> загружает строки списка из потока данных (см. ниже).</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Move(Curlndex, Newlndex: Integer)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> изменяет позицию элемента (пары строка-объект) в списке.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">SaveToFile(const FileName: string)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> сохраняет строки списка в текстовом файле.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">SaveToStream(Stream: TStream)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> сохраняет строки списка в потоке данных.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">SetText(Text: PChar)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> загружает строки списка из одной большой нуль-терминированной строки.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Класс </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStringList</span><span style="font-family: 'Times New Roman'; color: #000000;"> добавляет к</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> несколько дополнительных свойств и методов, а также два свойства-события для уведомления об изменениях в списке. Они описаны ниже.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Свойства:</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Duplicates: TDuplicates</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> определяет, разрешено ли использовать дублированные строки в списке. Свойство может принимать следующие значения:</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> duplgnore</span><span style="font-family: 'Times New Roman'; color: #000000;"> (дубликаты игнорируются),</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> dupAccept</span><span style="font-family: 'Times New Roman'; color: #000000;"> (дубликаты разрешены), dupError (дубликаты запрещены, попытка добавить в список дубликат вызывает ошибку).</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Sorted: Boolean</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> если имеет значение</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> True,</span><span style="font-family: 'Times New Roman'; color: #000000;"> то строки автоматически сортируются в алфавитном порядке.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы:</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Find(const S: string; var Index: Integer): Boolean</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> выполняет поиск строки </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">S</span><span style="font-family: 'Times New Roman'; color: #000000;"> в списке строк. Если строка найдена,</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Find</span><span style="font-family: 'Times New Roman'; color: #000000;"> помещает ее позицию в переменную, переданную в параметре</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Index,</span><span style="font-family: 'Times New Roman'; color: #000000;"> и возвращает</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> True.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Sort</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> сортирует строки в алфавитном порядке.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">События:</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">OnChange: TNotifyEvent</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> указывает на обработчик события, который выполнится при изменении содержимого списка. Событие</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> OnChange</span><span style="font-family: 'Times New Roman'; color: #000000;"> генерируется после того, как были сделаны изменения.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">OnChanging: TNotifyEvent</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> указывает на обработчик события, который выполнится при изменении содержимого списка. Событие</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> OnChanging</span><span style="font-family: 'Times New Roman'; color: #000000;"> генерируется перед тем, как будут сделаны изменения.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Ниже приводится фрагмент программы, демонстрирующий создание списка строк и манипулирование его элементами:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Items: TStrings;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">I: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Создание списка }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Items := TStringList.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Items.Add(</span><span class="f_CodeExample" style="color: #ff0000;">'Туризм'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Items.Add(</span><span class="f_CodeExample" style="color: #ff0000;">'Наука'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Items.Insert(</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Бизнес'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Работа со списком }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> I := </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> Items. Count - </span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Items[I] := Uppercase(Items [I]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Удаление списка }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Items.Free;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">КЛАССЫ ДЛЯ ПРЕДСТАВЛЕНИЯ ПОТОКА ДАННЫХ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В Delphi существует иерархия классов для хранения и последовательного ввода-вывода данных. Классы этой иерархии называются </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">потоками.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Потоки лучше всего представлять как файлы. Классы потоков обеспечивают различное физическое представление данных:</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">файл на диске, раздел оперативной памяти, поле в таблице базы данных (см. табл. 1).</span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">Таблица 1.</span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">Класс Описание </span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">TStream </span><span style="font-family: 'Arial'; color: #000000; font-size: 10pt;">Абстрактный поток, от которого наследуются все остальные. Свойства и методы класса TStream образуют базовый интерфейс потоковых объектов. </span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">THandleStream </span><span style="font-family: 'Arial'; color: #000000; font-size: 10pt;">Поток, который хранит свои данные в файле. Для чтения-записи файла используется дескриптор (handle), поэтому поток называется дескрипторным. Дескриптор - это номер открытого файла в операционной системе. Его возвращают низкоуровневые функции создания и открытия файла. </span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">TFileStream </span><span style="font-family: 'Arial'; color: #000000; font-size: 10pt;">Поток, который хранит свои данные в файле. Отличается от ThandleStream тем, что сам открывает (создает) файл по имени, переданному в конструктор. </span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">TMemoryStream </span><span style="font-family: 'Arial'; color: #000000; font-size: 10pt;">Поток, который хранит свои данные в оперативной памяти. Моделирует работу с файлом. Используется для хранения промежуточных результатов, когда файловый поток не подходит из-за низкой скорости передачи данных. </span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">TResourceStream </span><span style="font-family: 'Arial'; color: #000000; font-size: 10pt;">Поток, обеспечивающий доступ к ресурсам в Windows-приложении. </span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">TBIobStream </span><span style="font-family: 'Arial'; color: #000000; font-size: 10pt;">Обеспечивает последовательный доступ к большим полям таблиц в базах данных. </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Потоки широко применяются в библиотеке VCL и наверняка вам понадобятся. Поэтому ниже кратко перечислены их общие ключевые свойства и методы.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Общие свойства:</span></p> <p style="margin: 0px 200px 0px 0px;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Position: Longint</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> текущая позиция чтения-записи.</span></p> <p style="margin: 0px 200px 0px 0px;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Size: Longint</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> текущий размер потока в байтах.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Общие методы:</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">CopyFrom(Source: TStream; Count: Longint): Longint</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> копирует</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт из потока</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Source</span><span style="font-family: 'Times New Roman'; color: #000000;"> в свой поток.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Read(var Buffer; Count: Longint): Longint</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> читает</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт из потока в буфер</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Buffer, </span><span style="font-family: 'Times New Roman'; color: #000000;">продвигает текущую позицию на</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт вперед и возвращает число прочитанных байт. Если значение функции меньше значения</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count,</span><span style="font-family: 'Times New Roman'; color: #000000;"> то в результате чтения был достигнут конец потока.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">ReadBuffer(var Buffer; Count: Longint)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> читает из потока</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт в буфер</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Buffer</span><span style="font-family: 'Times New Roman'; color: #000000;"> и продвигает текущую позицию на</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт вперед. Если выполняется попытка чтения за концом потока, то генерируется ошибка.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Seek(0ffset: Longint; Origin: Word): Longint</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> продвигает текущую позицию в потоке на Offset байт относительно позиции, заданной параметром</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Origin.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Параметр</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Origin </span><span style="font-family: 'Times New Roman'; color: #000000;">может иметь одно из следующих значений: 0 </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> смещение задается относительно начала потока; 1 </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> смещение задается относительно текущей позиции в потоке; 2 </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> смещение задается относительно конца потока.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Write(const Buffer; Count: Longint): Longint</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> записывает в поток</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт из буфера</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Buffer,</span><span style="font-family: 'Times New Roman'; color: #000000;"> продвигает текущую позицию на</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт вперед и возвращает реально записанное количество байт. Если значение функции отличается от значения</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count,</span><span style="font-family: 'Times New Roman'; color: #000000;"> то при записи была ошибка.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">WriteBuffer(const Buffer; Count: Longint)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> записывает в поток</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт из буфера </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Buffer</span><span style="font-family: 'Times New Roman'; color: #000000;"> и продвигает текущую позицию на</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт вперед. Если по какой-либо причине невозможно записать все байты буфера, то генерируется ошибка.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Ниже приводится фрагмент программы, демонстрирующий создание файлового потока и запись в него строки:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream: TStream;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">S: AnsiString;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StrLen: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Создание файлового потока }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream := TFileStream.Create(</span><span class="f_CodeExample" style="color: #ff0000;">'Sample.Dat'</span><span class="f_CodeExample" style="color: #000000;">, fmCreate);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Запись в поток некоторой строки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StrLen := Length(S) * SizeOf(Char);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Write</span><span class="f_CodeExample" style="color: #000000;"> (StrLen, SizeOf (Integer) ) ; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ запись длины строки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Write</span><span class="f_CodeExample" style="color: #000000;"> (S, StrLen); </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ запись символов строки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Закрытие потока }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream.Free;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">итоги</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Теперь для вас нет секретов в мире ООП. Вы на достаточно серьезном уровне познакомились с объектами и их свойствами; узнали, как объекты создаются, используются и уничтожаются. Если не все удалось запомнить сразу </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> не беда. Возвращайтесь к материалам главы по мере решения стоящих перед вами задач, и работа с объектами станет простой, естественной и даже приятной. Когда вы добьетесь понимания того, как работает один объект, то автоматически поймете, как работают все остальные. Теперь мы рассмотрим то, с чем вы встретитесь очень скоро </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> ошибки программирования.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">МЕТАКЛАССЫ</span></p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">ССЫЛКИ НА КЛАССЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Язык Object Pascal позволяет рассматривать классы как своего рода объекты, которыми можно манипулировать в программе. Такая возможность рождает новое понятие </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">класс класса;</span><span style="font-family: 'Times New Roman'; color: #000000;"> его принято обозначать термином </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">метакласс.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Для поддержки метаклассов введен специальный тип данных </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">ссылка на класс</span><span style="font-family: 'Times New Roman'; color: #000000;"> (class reference). Он описывается с помощью словосочетания </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">class of,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGaugeClass = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Переменная типа</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGaugeClass</span><span style="font-family: 'Times New Roman'; color: #000000;"> объявляется в программе обычным образом:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ClassRef: TResourceGaugeClass;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Значениями переменной</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> ClassRef</span><span style="font-family: 'Times New Roman'; color: #000000;"> могут быть класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> и все порожденные от него классы. Допустимы, например, следующие операторы:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ClassRef := TResourceGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ClassRef := TDiskGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ClassRef := TMemoryGauge;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">По аналогии с тем, как для всех классов существует общий предок</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TObject,</span><span style="font-family: 'Times New Roman'; color: #000000;"> у ссылок на классы существует базовый тип</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TCIass:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span><span class="f_CodeExample" style="color: #000000;"> TCIass = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TObject;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Переменная типа </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TCIass</span><span style="font-family: 'Times New Roman'; color: #000000;"> может ссылаться на любой класс.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Практическая ценность ссылок на классы состоит в возможности создавать программные модули, работающие с любыми классами объектов, даже с теми, которые еще не разработаны.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">МЕТОДЫ КЛАССОВ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Метаклассы привели к возникновению нового типа методов </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> методов класса. </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">Метод класса</span><span style="font-family: 'Times New Roman'; color: #000000;"> оперирует не экземпляром объекта, а непосредственно классом. Он объявляется как обычный метод, но перед словом</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> procedure</span><span style="font-family: 'Times New Roman'; color: #000000;"> или</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> function</span><span style="font-family: 'Times New Roman'; color: #000000;"> записывается зарезервированное слово</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> class,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetClassName : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Псевдопараметр</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Self,</span><span style="font-family: 'Times New Roman'; color: #000000;"> передаваемый в метод класса, содержит не ссылку на объект, а ссылку на класс, поэтому в теле метода нельзя обращаться к полям, методам и свойствам объекта. Зато можно вызывать другие методы класса, например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.GetClassName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := ClassName;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> ClassName</span><span style="font-family: 'Times New Roman'; color: #000000;"> объявлен в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TObject</span><span style="font-family: 'Times New Roman'; color: #000000;"> и возвращает имя класса, к которому применяется. Очевидно, что надуманный метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetClassName</span><span style="font-family: 'Times New Roman'; color: #000000;"> просто дублирует эту функциональность для класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> и всех его наследников.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы класса применимы и к классам, и к объектам. В обоих случаях в параметре</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Self </span><span style="font-family: 'Times New Roman'; color: #000000;">передается ссылка на класс объекта. Пример:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Gauge: TResourceGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">S: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Вызов метода с помощью ссылки на класс }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">S := TDiskGauge.GetClassName; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ S получит значение 'TDiskGauge' }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Gauge := TDiskGauge.Create(</span><span class="f_CodeExample" style="color: #ff0000;">'С'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Вызов метода с помощью ссылки на объект }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">S := Gauge.GetClassName; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ S получит значение 'TDiskGauge' }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы классов могут быть виртуальными. Например, в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TObject</span><span style="font-family: 'Times New Roman'; color: #000000;"> определен виртуальный метод класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Newlnstance.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Он служит для распределения памяти под объект и автоматически вызывается конструктором. Его можно перекрыть в своем классе, чтобы обеспечить нестандартный способ выделения памяти для экземпляров. Метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Newlnstance должен</span><span style="font-family: 'Times New Roman'; color: #000000;"> перекрываться вместе с другим методом</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Freelnstance,</span><span style="font-family: 'Times New Roman'; color: #000000;"> который автоматически вызывается из деструктора и служит для освобождения памяти. Добавим, что размер памяти, требуемый для экземпляра, можно узнать вызовом предопределенного метода класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> InstanceSize.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">ВИРТУАЛЬНЫЕ КОНСТРУКТОРЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Особая мощь ссылок на классы проявляется в сочетании с виртуальными конструкторами. Виртуальный конструктор объявляется с ключевым словом</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> virtual.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Вызов виртуального конструктора происходит по фактическому значению ссылки на класс, а не по ее формальному типу. Это позволяет создавать объекты, классы которых неизвестны на этапе компиляции. Механизм виртуальных конструкторов применяется в Delphi при создании форм и компонентов.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">На этом закончим изучение теории объектно-ориентированного программирования и в качестве практики рассмотрим несколько широко используемых инструментальных классов Delphi. Разберитесь с их назначением и работой. Это поможет глубже понять ООП и пригодится на будущее.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">КЛАССЫ ОБЩЕГО НАЗНАЧЕНИЯ В DELPHI</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Как показывает практика, в большинстве задач приходится использовать однотипные структуры данных: списки, массивы, множества и т.д. От задачи к задаче изменяются только их элементы, а методы работы сохраняются. Например, для любого списка нужны процедуры вставки и удаления элементов. В связи с этим возникает естественное желание решить задачу «в общем виде», т.е. создать универсальные средства для управления основными структурами данных. Эта идея не нова. Она давно пришла в голову разработчикам инструментальных пакетов, которые быстро наплодили множество вспомогательных библиотек. Эти библиотеки содержали классы объектов для работы со списками, коллекциями (динамические массивы с переменным количеством элементов), словарями (коллекции, индексированные строками) и другими «абстрактными» структурами. Для Delphi тоже разработаны аналогичные классы объектов. Их большая часть сосредоточена в модуле </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Classes</span><span style="font-family: 'Times New Roman'; color: #000000;">. Наиболее нужными для вас являются списки строк (</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStringList</span><span style="font-family: 'Times New Roman'; color: #000000;">) и потоки (</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TSream</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">THandleSream</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TFileStream</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TMemoryStream</span><span style="font-family: 'Times New Roman'; color: #000000;"> и </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TBIobStream</span><span style="font-family: 'Times New Roman'; color: #000000;">). Рассмотрим кратко их назначение и применение.</span></p> <p> </p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">КЛАССЫ ДЛЯ ПРЕДСТАВЛЕНИЯ СПИСКА СТРОК</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Для работы со списками строк служат классы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings и TStringList. </span><span style="font-family: 'Times New Roman'; color: #000000;">Они используются в библиотеке VCL повсеместно и имеют гораздо большую универсальность, чем та, что можно почерпнуть из их названия. Классы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings </span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStringList</span><span style="font-family: 'Times New Roman'; color: #000000;"> служат для представления не просто списка строк, а списка элементов, каждый из которых представляет собой пару строка-объект. Если со строками не ассоциированы объекты, получается обычный список строк.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Класс </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> используется визуальными компонентами и является абстрактным. Он не имеет собственных средств хранения строк и определяет лишь интерфейс для работы с элементами. Класс </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStringList</span><span style="font-family: 'Times New Roman'; color: #000000;"> является наследником </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> и служит для организации списков строк, которые используются отдельно от управляющих элементов. Объекты </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStringList</span><span style="font-family: 'Times New Roman'; color: #000000;"> хранят строки и объекты в динамической памяти.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Свойства класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> описаны ниже.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Count: Integer</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> число элементов в списке.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Strings[lndex: Integer]: string</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> обеспечивает доступ к массиву строк по индексу. Первая строка имеет индекс, равный 0. Свойство</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Strings</span><span style="font-family: 'Times New Roman'; color: #000000;"> является основным свойством объекта.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Objects[lndex: Integer]: TObject </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> обеспечивает доступ к массиву объектов. Свойства </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Strings</span><span style="font-family: 'Times New Roman'; color: #000000;"> и </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Objects</span><span style="font-family: 'Times New Roman'; color: #000000;"> позволяют использовать объект</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> как хранилище строк и ассоциированных с ними объектов произвольных классов.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Text: string</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> позволяет интерпретировать список строк как одну большую строку, в которой элементы разделены символами #13#10 (возврат каретки и перевод строки),</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Наследники класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> иногда используются для хранения строк вида Имя=3начение, в частности, строк INI-файлов (см. гл. 6). Для удобной работы со строками такой структуры в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> дополнительно имеются следующие свойства.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Names[lndex: Integer]: string</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> обеспечивает доступ к той части строки, в которой содержится имя.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Values[const Name: string]: string</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> обеспечивает доступ к той части строки, в которой содержится значение. Указывая вместо</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Name</span><span style="font-family: 'Times New Roman'; color: #000000;"> ту часть строки, которая находится слева от знака равенства, вы получаете ту часть, что находится справа.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Управление элементами списка осуществляется с помощью следующих методов:</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Add(const S: string): Integer</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> добавляет новую строку </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">S</span><span style="font-family: 'Times New Roman'; color: #000000;"> в список и возвращает ее позицию. Новая строка добавляется в конец списка.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Add0bject(const S: string; AObject: TObject): Integer</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> добавляет в список строку </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">S</span><span style="font-family: 'Times New Roman'; color: #000000;"> и ассоциированный с ней объект</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> AObject.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Возвращает индекс пары строка</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;">объект.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">AddStrings(Strings: TStrings)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> добавляет группу строк в существующий список. </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Append(const S: string)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> делает то же, что и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Add,</span><span style="font-family: 'Times New Roman'; color: #000000;"> но не возвращает значения. </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Clear</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> удаляет из списка все элементы.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Delete(lndex: Integer)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> удаляет строку и ассоциированный с ней объект. Метод </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Delete</span><span style="font-family: 'Times New Roman'; color: #000000;">, так же как метод </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Clear</span><span style="font-family: 'Times New Roman'; color: #000000;">, не разрушает объектов, т.е. не вызывает у них деструктор. Об этом вы должны позаботиться сами.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Equals(Strings: TStrings): Boolean</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> возвращает</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> True,</span><span style="font-family: 'Times New Roman'; color: #000000;"> если список строк в точности равен тому, что передан в параметре</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Strings.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Exchange(lndex1, lndex2: Integer)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> меняет два элемента местами.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">GetText:</span><span style="font-family: 'Times New Roman'; color: #000000;"> PChar </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> возвращает все строки списка в виде одной большой нуль-терминированной строки.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">lndex0f(const S: string): Integer</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> возвращает позицию строки </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">S</span><span style="font-family: 'Times New Roman'; color: #000000;"> в списке. Если заданная строка в списке отсутствует, функция возвращает значение </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;">1.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">lndexOfName(const Name: string): Integer</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> возвращает позицию строки, которая имеет вид Имя=3начение и содержит в себе Имя, равное</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Name.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">lndexOfObject(AObject: TObject): Integer</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> возвращает позицию объекта</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> AObject</span><span style="font-family: 'Times New Roman'; color: #000000;"> в массиве</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Objects.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Если заданный объект в списке отсутствует, функция возвращает значение </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;">1.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">lnsert(lndex: Integer; const S: string)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> вставляет в список строку </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">S</span><span style="font-family: 'Times New Roman'; color: #000000;"> в позицию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Index.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">lnsert0bject(lndex: Integer; const S: string; AObject: TObject)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> вставляет в список строку </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">S</span><span style="font-family: 'Times New Roman'; color: #000000;"> и ассоциированный с ней объект</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> AObject</span><span style="font-family: 'Times New Roman'; color: #000000;"> в позицию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Index.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">LoadFromFile(const FileName: string)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> загружает строки списка из текстового файла.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">LoadFromStream(Stream: TStream)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> загружает строки списка из потока данных (см. ниже).</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Move(Curlndex, Newlndex: Integer)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> изменяет позицию элемента (пары строка-объект) в списке.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">SaveToFile(const FileName: string)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> сохраняет строки списка в текстовом файле.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">SaveToStream(Stream: TStream)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> сохраняет строки списка в потоке данных.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">SetText(Text: PChar)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> загружает строки списка из одной большой нуль-терминированной строки.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Класс </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TStringList</span><span style="font-family: 'Times New Roman'; color: #000000;"> добавляет к</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TStrings</span><span style="font-family: 'Times New Roman'; color: #000000;"> несколько дополнительных свойств и методов, а также два свойства-события для уведомления об изменениях в списке. Они описаны ниже.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Свойства:</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Duplicates: TDuplicates</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> определяет, разрешено ли использовать дублированные строки в списке. Свойство может принимать следующие значения:</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> duplgnore</span><span style="font-family: 'Times New Roman'; color: #000000;"> (дубликаты игнорируются),</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> dupAccept</span><span style="font-family: 'Times New Roman'; color: #000000;"> (дубликаты разрешены), dupError (дубликаты запрещены, попытка добавить в список дубликат вызывает ошибку).</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Sorted: Boolean</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> если имеет значение</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> True,</span><span style="font-family: 'Times New Roman'; color: #000000;"> то строки автоматически сортируются в алфавитном порядке.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы:</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Find(const S: string; var Index: Integer): Boolean</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> выполняет поиск строки </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">S</span><span style="font-family: 'Times New Roman'; color: #000000;"> в списке строк. Если строка найдена,</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Find</span><span style="font-family: 'Times New Roman'; color: #000000;"> помещает ее позицию в переменную, переданную в параметре</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Index,</span><span style="font-family: 'Times New Roman'; color: #000000;"> и возвращает</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> True.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Sort</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> сортирует строки в алфавитном порядке.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">События:</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">OnChange: TNotifyEvent</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> указывает на обработчик события, который выполнится при изменении содержимого списка. Событие</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> OnChange</span><span style="font-family: 'Times New Roman'; color: #000000;"> генерируется после того, как были сделаны изменения.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">OnChanging: TNotifyEvent</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> указывает на обработчик события, который выполнится при изменении содержимого списка. Событие</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> OnChanging</span><span style="font-family: 'Times New Roman'; color: #000000;"> генерируется перед тем, как будут сделаны изменения.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Ниже приводится фрагмент программы, демонстрирующий создание списка строк и манипулирование его элементами:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Items: TStrings;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">I: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Создание списка }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Items := TStringList.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Items.Add(</span><span class="f_CodeExample" style="color: #ff0000;">'Туризм'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Items.Add(</span><span class="f_CodeExample" style="color: #ff0000;">'Наука'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Items.Insert(</span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Бизнес'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Работа со списком }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">for</span><span class="f_CodeExample" style="color: #000000;"> I := </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">to</span><span class="f_CodeExample" style="color: #000000;"> Items. Count - </span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Items[I] := Uppercase(Items [I]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Удаление списка }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Items.Free;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">КЛАССЫ ДЛЯ ПРЕДСТАВЛЕНИЯ ПОТОКА ДАННЫХ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В Delphi существует иерархия классов для хранения и последовательного ввода-вывода данных. Классы этой иерархии называются </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">потоками.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Потоки лучше всего представлять как файлы. Классы потоков обеспечивают различное физическое представление данных:</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">файл на диске, раздел оперативной памяти, поле в таблице базы данных (см. табл. 1).</span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">Таблица 1.</span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">Класс Описание </span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">TStream </span><span style="font-family: 'Arial'; color: #000000; font-size: 10pt;">Абстрактный поток, от которого наследуются все остальные. Свойства и методы класса TStream образуют базовый интерфейс потоковых объектов. </span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">THandleStream </span><span style="font-family: 'Arial'; color: #000000; font-size: 10pt;">Поток, который хранит свои данные в файле. Для чтения-записи файла используется дескриптор (handle), поэтому поток называется дескрипторным. Дескриптор - это номер открытого файла в операционной системе. Его возвращают низкоуровневые функции создания и открытия файла. </span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">TFileStream </span><span style="font-family: 'Arial'; color: #000000; font-size: 10pt;">Поток, который хранит свои данные в файле. Отличается от ThandleStream тем, что сам открывает (создает) файл по имени, переданному в конструктор. </span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">TMemoryStream </span><span style="font-family: 'Arial'; color: #000000; font-size: 10pt;">Поток, который хранит свои данные в оперативной памяти. Моделирует работу с файлом. Используется для хранения промежуточных результатов, когда файловый поток не подходит из-за низкой скорости передачи данных. </span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">TResourceStream </span><span style="font-family: 'Arial'; color: #000000; font-size: 10pt;">Поток, обеспечивающий доступ к ресурсам в Windows-приложении. </span></p> <p><span style="font-family: 'Arial'; color: #000000; font-size: 10pt; font-weight: bold;">TBIobStream </span><span style="font-family: 'Arial'; color: #000000; font-size: 10pt;">Обеспечивает последовательный доступ к большим полям таблиц в базах данных. </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Потоки широко применяются в библиотеке VCL и наверняка вам понадобятся. Поэтому ниже кратко перечислены их общие ключевые свойства и методы.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Общие свойства:</span></p> <p style="margin: 0px 200px 0px 0px;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Position: Longint</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> текущая позиция чтения-записи.</span></p> <p style="margin: 0px 200px 0px 0px;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Size: Longint</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> текущий размер потока в байтах.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Общие методы:</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">CopyFrom(Source: TStream; Count: Longint): Longint</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> копирует</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт из потока</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Source</span><span style="font-family: 'Times New Roman'; color: #000000;"> в свой поток.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Read(var Buffer; Count: Longint): Longint</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> читает</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт из потока в буфер</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Buffer, </span><span style="font-family: 'Times New Roman'; color: #000000;">продвигает текущую позицию на</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт вперед и возвращает число прочитанных байт. Если значение функции меньше значения</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count,</span><span style="font-family: 'Times New Roman'; color: #000000;"> то в результате чтения был достигнут конец потока.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">ReadBuffer(var Buffer; Count: Longint)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> читает из потока</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт в буфер</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Buffer</span><span style="font-family: 'Times New Roman'; color: #000000;"> и продвигает текущую позицию на</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт вперед. Если выполняется попытка чтения за концом потока, то генерируется ошибка.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Seek(0ffset: Longint; Origin: Word): Longint</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> продвигает текущую позицию в потоке на Offset байт относительно позиции, заданной параметром</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Origin.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Параметр</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Origin </span><span style="font-family: 'Times New Roman'; color: #000000;">может иметь одно из следующих значений: 0 </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> смещение задается относительно начала потока; 1 </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> смещение задается относительно текущей позиции в потоке; 2 </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> смещение задается относительно конца потока.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Write(const Buffer; Count: Longint): Longint</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> записывает в поток</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт из буфера</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Buffer,</span><span style="font-family: 'Times New Roman'; color: #000000;"> продвигает текущую позицию на</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт вперед и возвращает реально записанное количество байт. Если значение функции отличается от значения</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count,</span><span style="font-family: 'Times New Roman'; color: #000000;"> то при записи была ошибка.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">WriteBuffer(const Buffer; Count: Longint)</span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> записывает в поток</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт из буфера </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Buffer</span><span style="font-family: 'Times New Roman'; color: #000000;"> и продвигает текущую позицию на</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Count</span><span style="font-family: 'Times New Roman'; color: #000000;"> байт вперед. Если по какой-либо причине невозможно записать все байты буфера, то генерируется ошибка.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Ниже приводится фрагмент программы, демонстрирующий создание файлового потока и запись в него строки:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream: TStream;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">S: AnsiString;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StrLen: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Создание файлового потока }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream := TFileStream.Create(</span><span class="f_CodeExample" style="color: #ff0000;">'Sample.Dat'</span><span class="f_CodeExample" style="color: #000000;">, fmCreate);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Запись в поток некоторой строки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StrLen := Length(S) * SizeOf(Char);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Write</span><span class="f_CodeExample" style="color: #000000;"> (StrLen, SizeOf (Integer) ) ; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ запись длины строки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Write</span><span class="f_CodeExample" style="color: #000000;"> (S, StrLen); </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ запись символов строки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ Закрытие потока }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream.Free;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">итоги</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Теперь для вас нет секретов в мире ООП. Вы на достаточно серьезном уровне познакомились с объектами и их свойствами; узнали, как объекты создаются, используются и уничтожаются. Если не все удалось запомнить сразу </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> не беда. Возвращайтесь к материалам главы по мере решения стоящих перед вами задач, и работа с объектами станет простой, естественной и даже приятной. Когда вы добьетесь понимания того, как работает один объект, то автоматически поймете, как работают все остальные. Теперь мы рассмотрим то, с чем вы встретитесь очень скоро </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> ошибки программирования.</span></p> Наследование 2013-08-15T20:34:52+07:00 2013-08-15T20:34:52+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/sushchnost-oop/nasledovanie.html Super User toto44@inbox.ru <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">НАСЛЕДОВАНИЕ</span></p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">ПОНЯТИЕ НАСЛЕДОВАНИЯ</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Классы инкапсулируют (т.е. включают в себя) поля, методы и свойства; это их первая черта. Следующая не менее важная черта классов </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> способность </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">наследовать</span><span style="font-family: 'Times New Roman'; color: #000000;"> поля, методы и свойства других классов. Чтобы пояснить сущность наследования, обратимся к примеру с измерителями ресурсов.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> описывает измеритель дискового ресурса и непригоден для измерения ресурса другого типа, например оперативной памяти. С появлением измерителя оперативной памяти нужен новый класс объектов:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMemoryGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FPercentCritical: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical (Value: Integer) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentFree: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentCritical: Integer</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Поля, методы и свойства класса </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TMemoryGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> аналогичны тем, что определены</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">классе </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;">. Отличие состоит в отсутствии поля </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">DriveLetter</span><span style="font-family: 'Times New Roman'; color: #000000;"> и другой реализации конструктора </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Create</span><span style="font-family: 'Times New Roman'; color: #000000;"> и метода </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">GetPercentFree</span><span style="font-family: 'Times New Roman'; color: #000000;">. Если в будущем появится класс, описывающий измеритель ресурса какого-то нового типа, то придется снова определять общие для всех классов поля, методы и свойства. Чтобы избавиться от дублирования атрибутов при определении новых классов, воспользуемся механизмом наследования. Прежде всего выделим атрибуты, общие для всех измерителей ресурсов, в отдельный класс </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;">:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FPercentCritical: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical (Value: Integer) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentFree : Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentCritical: Integer</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FPercentCritical := </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.SetPercentCritical (Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> (Value &gt;= </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">and</span><span class="f_CodeExample" style="color: #000000;"> (Value &lt; </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical := Value;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree &lt;= FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Beep;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">При реализации класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> ничего не известно о том, что в действительности представляет собой ресурс, поэтому функция</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPercentFree</span><span style="font-family: 'Times New Roman'; color: #000000;"> возвращает нуль. Очевидно, что создавать объекты класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> не имеет смысла. Для чего тогда нужен класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge?</span><span style="font-family: 'Times New Roman'; color: #000000;"> Ответ: чтобы на его основе </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">породить</span><span style="font-family: 'Times New Roman'; color: #000000;"> два других класса </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge и TMemoryGauge,</span><span style="font-family: 'Times New Roman'; color: #000000;"> описывающих конкретные виды измерителей ресурсов, </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> измеритель диска и измеритель памяти:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TResourceGauge)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DriveLetter: Char;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create (ADriveLetter: Char) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMemoryGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TResourceGauge)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Классы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge и TMemoryGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> определены как </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">наследники</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> (об этом говорит имя в скобках после слова </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">class</span><span style="font-family: 'Times New Roman'; color: #000000;">). Они автоматически включают в себя все описания, сделанные в классе </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> и добавляют к ним некоторые новые. В результате формируется следующее </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">дерево классов</span><span style="font-family: 'Times New Roman'; color: #000000;"> (рис. 1):</span></p> <p> </p> <p style="text-align: center;"><img src="https://delphi-hlp.ru/embim1697.gif" alt="" hspace="1" vspace="1" width="203" height="94" /></p> <p style="text-align: center;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Рисунок 1</span></p> <p style="text-align: center;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Класс, который наследует атрибуты другого класса, называется порожденным классом или </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">потомком.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Естественно, что класс, от которого происходит наследование, выступает в роли базового, или </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">предка.</span><span style="font-family: 'Times New Roman'; color: #000000;"> В примере класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> является непосредственным потомком класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Если от</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> породить новый класс, то он тоже будет потомком</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge,</span><span style="font-family: 'Times New Roman'; color: #000000;"> но уже не таким близким, как</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Очень важно, что в отношениях наследования любой класс может иметь только одного непосредственного предка и сколь угодно много потомков. Поэтому все связанные отношением наследования классы образуют </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">иерархию.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Примером иерархии классов является библиотека Visual Component Library (VCL); с ее помощью в Delphi обеспечивается разработка Windows-приложений.</span></p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">ПРЕДОК ПО УМОЛЧАНИЮ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В языке Object Pascal существует предопределенный класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TObject,</span><span style="font-family: 'Times New Roman'; color: #000000;"> который служит неявным предком тех классов, для которых предок не указан. Это означает, что объявление</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>эквивалентно следующему:</p> <p style="margin: 0px 0px 0px 19px;"> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TObject)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TObject</span><span style="font-family: 'Times New Roman'; color: #000000;"> выступает корнем любой иерархии классов. Он содержит ряд методов, которые по наследству передаются всем остальным классам. Среди них конструктор </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Create,</span><span style="font-family: 'Times New Roman'; color: #000000;"> деструктор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Destroy,</span><span style="font-family: 'Times New Roman'; color: #000000;"> процедура</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Free</span><span style="font-family: 'Times New Roman'; color: #000000;"> и некоторые другие методы.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Таким образом, полная иерархия классов для измерителей ресурсов выглядит так (рис. 2):</span></p> <p> </p> <p style="text-align: center;"><img src="https://delphi-hlp.ru/embim1698.gif" alt="" hspace="1" vspace="1" width="203" height="144" /></p> <p style="text-align: center;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Рисунок 2</span></p> <p style="text-align: center;"> </p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">ПЕРЕКРЫТИЕ АТРИБУТОВ В НАСЛЕДНИКАХ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В механизме наследования можно условно выделить три основных момента:</span></p> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 24px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="14"><span style="font-family: 'Wingdings'; color: #000000; font-size: 10pt;">§</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">наследование полей;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 24px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="14"><span style="font-family: 'Wingdings'; color: #000000; font-size: 10pt;">§</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">наследование свойств;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 24px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="14"><span style="font-family: 'Wingdings'; color: #000000; font-size: 10pt;">§</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">наследование методов.</span></td> </tr> </tbody> </table> </div> <p><span style="font-family: 'Times New Roman'; color: #000000;">Любой порожденный класс наследует от родительского все поля данных, поэтому классы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge и TMemoryGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> автоматически содержат поле</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> FPercentCritical,</span><span style="font-family: 'Times New Roman'; color: #000000;"> объявленное в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Доступ к полям предка осуществляется по имени, как если бы они были определены в порожденном классе. В наследниках можно определять новые поля, но их имена должны отличаться от имен полей предка.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Наследование свойств и методов имеет свои особенности.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Свойство базового класса можно </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">перекрыть</span><span style="font-family: 'Times New Roman'; color: #000000;"> (от англ. override) в производном классе, например чтобы добавить ему новый атрибут доступа или связать с другим полем или методом.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Метод базового класса тоже можно перекрыть в производном классе, например чтобы изменить логику его работы. Обратимся, например, к классам</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge и TMemoryGauge. </span><span style="font-family: 'Times New Roman'; color: #000000;">В них методы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> SetPercentCritical и CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> унаследованы от</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge,</span><span style="font-family: 'Times New Roman'; color: #000000;"> так как логика их работы не зависит от типа ресурса. А вот метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPercentFree</span><span style="font-family: 'Times New Roman'; color: #000000;"> перекрыт, так как способ вычисления процента свободного пространства специфичен для диска и оперативной памяти:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Drive: Byte;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Drive := Ord(DriveLetter) - Ord(</span><span class="f_CodeExample" style="color: #ff0000;">'A'</span><span class="f_CodeExample" style="color: #000000;">) + </span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := DiskFree(Drive) * </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">div</span><span class="f_CodeExample" style="color: #000000;"> DiskSize(Drive) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TMemoryGauge.GetPercentFree: Integer; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ uses Windows; }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MemoryStatus: TMemoryStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MemoryStatus.dwLength := SizeOf(MemoryStatus);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GlobalMemoryStatus(MemoryStatus);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #000000;"> - MemoryStatus.dwMemoryLoad;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> перекрыт еще и конструктор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Create.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Это необходимо для инициализации дополнительного поля</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> DriveLetter:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.Create (ADriveLetter: Char) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DriveLetter := ADriveLetter;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Как видно из примера, в наследнике можно вызвать перекрытый метод предка, указав перед именем метода зарезервированное слово</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> inherited.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Кстати, данный пример демонстрирует важный принцип реализации конструкторов: сначала вызывается конструктор предка, а затем инициализируются дополнительные поля данных. В деструкторах применяется обратная последовательность действий: сначала разрушаются данные, недоступные предку, а затем вызывается унаследованный деструктор.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">СОВМЕСТИМОСТЬ ОБЪЕКТОВ РАЗЛИЧНЫХ КЛАССОВ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Для классов, связанных отношением наследования, вводится новое правило совместимости типов. Вместо объекта базового класса можно подставить объект любого производного класса. Обратное неверно. Например, переменной типа</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> можно присвоить значение переменной типа</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">R: TResourceGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">R := TDiskGauge.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Объектная переменная R </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">формально</span><span style="font-family: 'Times New Roman'; color: #000000;"> имеет тип</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge,</span><span style="font-family: 'Times New Roman'; color: #000000;"> а </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">фактически</span><span style="font-family: 'Times New Roman'; color: #000000;"> связана с экземпляром класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Правило совместимости классов чаще всего применяется при передаче объектов в параметрах процедур и функций. Например, если процедура работает с объектом класса </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TResourceGauge,</span><span style="font-family: 'Times New Roman'; color: #000000;"> то вместо него можно передать объект класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> или </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TMemoryGauge.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">КОНТРОЛЬ И ПРЕОБРАЗОВАНИЕ ТИПОВ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Поскольку реальный экземпляр объекта может оказаться наследником класса, указанного при описании объектной переменной или параметра, бывает необходимо проверить, к какому классу принадлежит объект на самом деле. Чтобы программист мог выполнять такого рода проверки, каждый объект хранит информацию о своем классе. В Object Pascal существуют операторы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> is и as,</span><span style="font-family: 'Times New Roman'; color: #000000;"> с помощью которых выполняется соответственно </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">проверка на тип</span><span style="font-family: 'Times New Roman'; color: #000000;"> (type checking) и </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">преобразование к типу</span><span style="font-family: 'Times New Roman'; color: #000000;"> (type casting).</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Например, чтобы выяснить, принадлежит ли некоторый объект</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Obj,</span><span style="font-family: 'Times New Roman'; color: #000000;"> объявленный в программе как</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Obj: TObject;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">к классу</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> или его наследнику, следует записать</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Obj </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">is</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ да, принадлежит }</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Для преобразования объекта к нужному типу используется оператор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> as,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> Obj </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #000000;"> CheckStatus;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Стоит отметить, что для объектов применим и обычный способ приведения типа:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge(Obj ) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #000000;"> CheckStatus;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Вариант с оператором as лучше, поскольку безопасен. Он генерирует ошибку (точнее, исключительную ситуацию) при выполнении программы (run-time error), если реальный экземпляр объекта</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Obj</span><span style="font-family: 'Times New Roman'; color: #000000;"> несовместим с классом</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Забегая вперед, скажем, что ошибку приведения типа можно обработать и таким образом избежать досрочного завершения приложения.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">ВИРТУАЛЬНЫЕ МЕТОДЫ</span></p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">ПОНЯТИЕ ВИРТУАЛЬНОГО МЕТОДА</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Все методы, которые до сих пор рассматривались, имеют одну общую черту </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> все они </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">статические.</span><span style="font-family: 'Times New Roman'; color: #000000;"> При обращении к статическому методу компилятор точно знает класс, которому данный метод принадлежит. Поэтому, например, обращение к статическому методу </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">GetPereentFree</span><span style="font-family: 'Times New Roman'; color: #000000;"> в методе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> компилируется в вызов</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge.GetPercentFree:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetPereentFree &lt;= FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Beep;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ if TResourceGauge.GetPereentFree &lt;= FPercentCritical then Beep; }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> работает неправильно в наследниках</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge,</span><span style="font-family: 'Times New Roman'; color: #000000;"> так как внутри него вызов перекрытого метода</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPereentFree</span><span style="font-family: 'Times New Roman'; color: #000000;"> не происходит. Конечно, в классах </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TDiskGauge и TMemoryGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> можно продублировать все методы и свойства, которые прямо или косвенно вызывают</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPereentFree,</span><span style="font-family: 'Times New Roman'; color: #000000;"> но при этом теряются преимущества наследования. ООП предлагает изящное решение этой проблемы </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPereentFree </span><span style="font-family: 'Times New Roman'; color: #000000;">всего-навсего объявляется </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">виртуальным:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPereentFree: Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В производных классах виртуальный метод перекрывается с использованием ключевого слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> override.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Перекрытый метод должен иметь точно такой же формат (список параметров, а для функций еще и тип возвращаемого значения), что и перекрываемый:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TResourceGauge)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMemoryGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TResourceGauge)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Суть виртуальных методов в том, что они вызываются по фактическому типу экземпляра, а не по формальному типу, записанному в программе. Поэтому после сделанных изменений метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> будет работать так, как ожидает программист:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree &lt;= FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Beep;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ if «фактический класс&gt;.GetPercentFree &lt;= FpercentCritical then Beep; }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Работа виртуальных методов основана на механизме позднего связывания (late binding). В отличие </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">от раннего связывания</span><span style="font-family: 'Times New Roman'; color: #000000;"> (early binding), характерного для статических методов, </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">позднее связывание</span><span style="font-family: 'Times New Roman'; color: #000000;"> основано на вычислении адреса вызываемого метода при выполнении программы. Метод вычисляется по хранящемуся в каждом объекте описателю типа.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Благодаря механизму наследования и виртуальным методам, в Delphi реализуется такая концепция ООП как полиморфизм. Полиморфизм существенно облегчает труд программиста, так как обеспечивает повторное использование кода уже написанных методов.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">АБСТРАКТНЫЕ ВИРТУАЛЬНЫЕ МЕТОДЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt;">При построении иерархии часто возникает ситуация, когда работа виртуального метода в базовом классе неизвестна и наполняется содержанием только в наследниках. Так случилось, например, с методом</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt; font-weight: bold;"> GetPercentFree,</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt;"> который в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt;"> состоит всего из одного оператора:</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt; font-weight: bold;"> Result := 0.</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt;"> Конечно, тело метода можно сделать пустым или почти пустым (так мы и поступили), но лучше воспользоваться директивой</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt; font-weight: bold;"> abstract:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree : Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">abstract</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Директива</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> abstract</span><span style="font-family: 'Times New Roman'; color: #000000;"> записывается после слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> virtual</span><span style="font-family: 'Times New Roman'; color: #000000;"> и исключает необходимость написания кода виртуального метода для данного класса. Такой метод называется </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">абстрактным,</span><span style="font-family: 'Times New Roman'; color: #000000;"> т.е. подразумевает конкретное логическое действие, а не способ его реализации. Абстрактные виртуальные методы часто используются при создании классов-полуфабрикатов. Свою реализацию такие методы получают в законченных наследниках.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">ДИНАМИЧЕСКИЕ МЕТОДЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Разновидностью виртуальных методов являются так называемые </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">динамические методы.</span><span style="font-family: 'Times New Roman'; color: #000000;"> При их объявлении вместо слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> virtual</span><span style="font-family: 'Times New Roman'; color: #000000;"> записывается ключевое слово</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> dynamic, </span><span style="font-family: 'Times New Roman'; color: #000000;">например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">dynamic</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">abstract</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В наследниках динамические методы перекрываются так же, как и виртуальные, т.е. с помощью зарезервированного слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> override.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Семантически динамические и виртуальные методы идентичны. Различие состоит только в механизме их вызова. Методы, объявленные с директивой </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">virtual</span><span style="font-family: 'Times New Roman'; color: #000000;">, вызываются максимально быстро, но платой за это является большой размер системных таблиц, с помощью которых происходит их диспетчеризация. Размер этих таблиц начинает сказываться с увеличением числа классов в иерархии. Методы, объявленные с директивой </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">dynamic</span><span style="font-family: 'Times New Roman'; color: #000000;">, вызываются несколько дольше, но при этом таблицы диспетчирования имеют более компактный вид, что способствует экономии памяти. Таким образом, программисту предоставляются два способа оптимизации объектов: по скорости работы (</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">virtual</span><span style="font-family: 'Times New Roman'; color: #000000;">) или по объему памяти (</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">dynamic</span><span style="font-family: 'Times New Roman'; color: #000000;">).</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">МЕТОДЫ ОБРАБОТКИ СООБЩЕНИЙ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Специализированной формой динамических методов являются </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">методы обработки сообщений.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Они объявляются с помощью ключевого слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> message</span><span style="font-family: 'Times New Roman'; color: #000000;">, за которым следует целочисленная константа </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">номер сообщения,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyControl = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TWinControl)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> WMPaint (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Message</span><span class="f_CodeExample" style="color: #000000;">: TWMPaint) ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">message</span><span class="f_CodeExample" style="color: #000000;"> WM_PAINT;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы обработки сообщений всегда имеют формат процедуры и содержат единственный </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">var</span><span style="font-family: 'Times New Roman'; color: #000000;">-параметр. При перекрытии метода его название и имя параметра не имеют значения. Вызовом соответствующего обработчика занимается метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Dispatch,</span><span style="font-family: 'Times New Roman'; color: #000000;"> наследуемый из класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TObject.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы обработки сообщений применяются внутри библиотеки VCL для обработки сообщений Windows и редко нужны ее пользователям, т.е. нам с вами.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">КЛАССЫ В ПРОГРАММНЫХ МОДУЛЯХ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Классы очень удобно собирать в модули. При этом их описание помещается в секцию </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">interface,</span><span style="font-family: 'Times New Roman'; color: #000000;"> а код методов </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> в секцию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> implementation.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Создавая модули классов, нужно придерживаться следующих правил:</span></p> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 24px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Wingdings'; color: #000000; font-size: 8pt;">q</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">все классы, предназначенные для использования за пределами модуля, следует определять в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> interface;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 24px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Wingdings'; color: #000000; font-size: 8pt;">q</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">описание классов, предназначенных для употребления внутри модуля, следует располагать в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> implementation;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 24px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Wingdings'; color: #000000; font-size: 8pt;">q</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">если модуль В использует модуль</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> А,</span><span style="font-family: 'Times New Roman'; color: #000000;"> то в модуле В можно определять классы, порожденные от классов модуля А.</span></td> </tr> </tbody> </table> </div> <p><span style="font-family: 'Times New Roman'; color: #000000;">Соберем рассмотренные ранее классы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge, TDiskGauge и TmemoryGauge </span><span style="font-family: 'Times New Roman'; color: #000000;">в отдельный модуль Resgauge:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> Resgauge;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FPercentCritical: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical(Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">abstract</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentFree: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentCritical: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TResourceGauge)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DriveLetter: Char;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree : Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create (ADriveLetter: Char) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMemoryGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> (TResourceGauge)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SysUtils, Windows;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ TResourceGauge }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FPercentCritical := </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.SetPercentCritical(Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> (Value &gt;= </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">and</span><span class="f_CodeExample" style="color: #000000;"> (Value &lt; </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical := Value;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> PercentFree &lt;= PercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Beep;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ TDiskGauge }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.Create (ADriveLetter: Char) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DriveLetter := ADriveLetter;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Drive: Byte;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Drive := Ord (DriveLetter) - Ord(</span><span class="f_CodeExample" style="color: #ff0000;">'A'</span><span class="f_CodeExample" style="color: #000000;">) + </span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := DiskFree(Drive) * </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">div</span><span class="f_CodeExample" style="color: #000000;"> DiskSize(Drive) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ TMemoryGauge }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TMemoryGauge.GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MemoryStatus: TMemoryStatus ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MemoryStatus.dwLength := SizeOf(MemoryStatus);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GlobalMemoryStatus(MemoryStatus);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #000000;"> - MemoryStatus.dwMemoryLoad;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Как можно заметить, в описании классов присутствуют новые слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> private, protected </span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> public.</span><span style="font-family: 'Times New Roman'; color: #000000;"> С их помощью регулируется видимость частей класса для других модулей и основной программы. Назначение каждой директивы поясняется ниже.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">ВИДИМОСТЬ АТРИБУТОВ ОБЪЕКТА</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Программист имеет возможность ограничить видимость атрибутов класса для других программистов (и для себя в том числе). Для этого служат директивы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> private, protected, public, published, automated</span><span style="font-family: 'Times New Roman'; color: #000000;"> (последние две директивы не используется в модуле</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Resgauge).</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Private.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Все, что объявлено в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> private,</span><span style="font-family: 'Times New Roman'; color: #000000;"> недоступно за пределами модуля. Секция </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">private</span><span style="font-family: 'Times New Roman'; color: #000000;"> позволяет скрыть те поля и методы, которые относятся к так называемым особенностям реализации. Например, в этой секции объявлены поле</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> FPercentCritical</span><span style="font-family: 'Times New Roman'; color: #000000;"> и метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> SetPercentCritical.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Public.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Поля, методы и свойства, объявленные в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> public,</span><span style="font-family: 'Times New Roman'; color: #000000;"> не имеют никаких ограничений на использование, т.е. всегда видны за пределами модуля. Все, что помещается в секцию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> public,</span><span style="font-family: 'Times New Roman'; color: #000000;"> служит для манипуляций с объектами и составляет программный интерфейс класса. Например, в этой секции объявлены конструктор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Create,</span><span style="font-family: 'Times New Roman'; color: #000000;"> процедура</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus,</span><span style="font-family: 'Times New Roman'; color: #000000;"> свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> PercentFree и PercentCritical.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Protected.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Поля, методы и свойства, объявленные в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> protected,</span><span style="font-family: 'Times New Roman'; color: #000000;"> видны за пределами модуля только потомкам данного класса; остальным частям программы они не видны. Так же как и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> private,</span><span style="font-family: 'Times New Roman'; color: #000000;"> директива</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> protected</span><span style="font-family: 'Times New Roman'; color: #000000;"> позволяет скрыть особенности реализации класса, но в отличие от нее разрешает другим программистам порождать новые классы и обращаться к полям, методам и свойствам, которые составляют так называемый интерфейс разработчика. В эту секцию обычно помещаются виртуальные методы чтения и записи свойств. Примером такого метода является</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPercentFree.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Published.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Устанавливает правила видимости те же, что и директива</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> public.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Особенность состоит в том, что для элементов, помещенных в секцию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> published,</span><span style="font-family: 'Times New Roman'; color: #000000;"> компилятор генерирует информацию о типе, которая позволяет превращать объекты в компоненты визуальной среды разработки. Секцию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> published</span><span style="font-family: 'Times New Roman'; color: #000000;"> разрешено использовать только тогда, когда для самого класса или его предка включена директива компилятора</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> $TYPEINFO.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Automated.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Устанавливает правила видимости те же, что и директива</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> public.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Директива</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> automated</span><span style="font-family: 'Times New Roman'; color: #000000;"> используется в наследниках класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TAutoObject</span><span style="font-family: 'Times New Roman'; color: #000000;"> при создании серверов OLE Automation. Для помещенных в эту секцию методов и свойств компилятор генерирует специальную информацию о типе, которая обеспечивает их видимость за пределами приложения.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Перечисленные секции могут чередоваться в объявлении класса в произвольном порядке, однако в пределах секции сначала следует описание полей, а потом методов и свойств. Если в определении класса</span><span style="font-family: 'Times New Roman'; color: #000000;">нет ключевых слов</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> private, protected, public, published </span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> automated,</span><span style="font-family: 'Times New Roman'; color: #000000;"> то для</span><span style="font-family: 'Times New Roman'; color: #000000;">обычных классов всем полям, методам и свойствам приписывается атрибут видимости</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> public, </span><span style="font-family: 'Times New Roman'; color: #000000;">а для тех классов, что порождены от классов VCL </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> атрибут видимости</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> published.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Заметим, что внутри модуля не действуют никакие ограничения видимости на атрибуты реализованного в модуле класса. Это, кстати, отличается от соглашений, принятых в других языках программирования, в частности в C++.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">УКАЗАТЕЛИ НА МЕТОДЫ ОБЪЕКТОВ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В Object Pascal существуют процедурные типы данных для методов объектов. Внешне объявление процедурного типа для метода отличается от обычного словосочетанием </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">of object,</span><span style="font-family: 'Times New Roman'; color: #000000;"> записанным после прототипа процедуры или функции:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TFewResourcesEvent = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> (Sender: TObject) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">object</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Переменная такого типа называется </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">указателем на метод</span><span style="font-family: 'Times New Roman'; color: #000000;"> (method pointer). Она занимает в памяти 8 байт и хранит одновременно ссылку на объект и адрес его метода:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OnFewResources: TFewResourcesEvent = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы объектов, объявленные по приведенному выше шаблону, становятся совместимы по типу с переменной</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> OnFewResources.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Tform1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FewResources (Sender: TObject) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Form1: Tform1;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p style="text-indent: -19px; margin: 0px 0px 0px 19px;"><span style="font-family: 'Times New Roman'; color: #000000;">Ecли переменную </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">OnFewResources</span><span style="font-family: 'Times New Roman'; color: #000000;"> связать с методом </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">FewResources</span><span style="font-family: 'Times New Roman'; color: #000000;"> объекта </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Form1</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OnFewResources:= Form1.FewResources;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">и переписать метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus,</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.CheckStatus ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> PercentFree &lt;= PercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Assigned(OnFewResources) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> OnFewResources(Self) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">то выдача предупреждения о нехватке ресурсов будет переадресована (говорят еще </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">делегирована)</span><span style="font-family: 'Times New Roman'; color: #000000;"> методу</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> FewResources</span><span style="font-family: 'Times New Roman'; color: #000000;"> объекта</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Form1</span><span style="font-family: 'Times New Roman'; color: #000000;">. Обратите внимание, что вызов метода через указатель происходит лишь в том случае, если указатель не равен</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> nil.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Эта проверка выполняется с помощью стандартной функции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Assigned,</span><span style="font-family: 'Times New Roman'; color: #000000;"> которая возвращает </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">True</span><span style="font-family: 'Times New Roman'; color: #000000;">, если ее аргумент является связанным указателем.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Делегирование позволяет сосредоточить в одном объекте обработку событий, возникающих в других объектах. Это избавляет программиста от необходимости порождать многочисленные классы-наследники и перекрывать в них виртуальные методы. Делегирование широко применяется в Delphi. Например, все компоненты делегируют обработку своих событий форме, на которой они находятся.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">НАСЛЕДОВАНИЕ</span></p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">ПОНЯТИЕ НАСЛЕДОВАНИЯ</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Классы инкапсулируют (т.е. включают в себя) поля, методы и свойства; это их первая черта. Следующая не менее важная черта классов </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> способность </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">наследовать</span><span style="font-family: 'Times New Roman'; color: #000000;"> поля, методы и свойства других классов. Чтобы пояснить сущность наследования, обратимся к примеру с измерителями ресурсов.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> описывает измеритель дискового ресурса и непригоден для измерения ресурса другого типа, например оперативной памяти. С появлением измерителя оперативной памяти нужен новый класс объектов:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMemoryGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FPercentCritical: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical (Value: Integer) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentFree: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentCritical: Integer</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Поля, методы и свойства класса </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TMemoryGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> аналогичны тем, что определены</span><span style="font-family: 'Times New Roman'; color: #000000;">в</span><span style="font-family: 'Times New Roman'; color: #000000;">классе </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;">. Отличие состоит в отсутствии поля </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">DriveLetter</span><span style="font-family: 'Times New Roman'; color: #000000;"> и другой реализации конструктора </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Create</span><span style="font-family: 'Times New Roman'; color: #000000;"> и метода </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">GetPercentFree</span><span style="font-family: 'Times New Roman'; color: #000000;">. Если в будущем появится класс, описывающий измеритель ресурса какого-то нового типа, то придется снова определять общие для всех классов поля, методы и свойства. Чтобы избавиться от дублирования атрибутов при определении новых классов, воспользуемся механизмом наследования. Прежде всего выделим атрибуты, общие для всех измерителей ресурсов, в отдельный класс </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;">:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FPercentCritical: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical (Value: Integer) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentFree : Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentCritical: Integer</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FPercentCritical := </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.SetPercentCritical (Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> (Value &gt;= </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">and</span><span class="f_CodeExample" style="color: #000000;"> (Value &lt; </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical := Value;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree &lt;= FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Beep;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">При реализации класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> ничего не известно о том, что в действительности представляет собой ресурс, поэтому функция</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPercentFree</span><span style="font-family: 'Times New Roman'; color: #000000;"> возвращает нуль. Очевидно, что создавать объекты класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> не имеет смысла. Для чего тогда нужен класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge?</span><span style="font-family: 'Times New Roman'; color: #000000;"> Ответ: чтобы на его основе </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">породить</span><span style="font-family: 'Times New Roman'; color: #000000;"> два других класса </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge и TMemoryGauge,</span><span style="font-family: 'Times New Roman'; color: #000000;"> описывающих конкретные виды измерителей ресурсов, </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> измеритель диска и измеритель памяти:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TResourceGauge)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DriveLetter: Char;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create (ADriveLetter: Char) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMemoryGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TResourceGauge)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Классы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge и TMemoryGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> определены как </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">наследники</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> (об этом говорит имя в скобках после слова </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">class</span><span style="font-family: 'Times New Roman'; color: #000000;">). Они автоматически включают в себя все описания, сделанные в классе </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> и добавляют к ним некоторые новые. В результате формируется следующее </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">дерево классов</span><span style="font-family: 'Times New Roman'; color: #000000;"> (рис. 1):</span></p> <p> </p> <p style="text-align: center;"><img src="https://delphi-hlp.ru/embim1697.gif" alt="" hspace="1" vspace="1" width="203" height="94" /></p> <p style="text-align: center;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Рисунок 1</span></p> <p style="text-align: center;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Класс, который наследует атрибуты другого класса, называется порожденным классом или </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">потомком.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Естественно, что класс, от которого происходит наследование, выступает в роли базового, или </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">предка.</span><span style="font-family: 'Times New Roman'; color: #000000;"> В примере класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> является непосредственным потомком класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Если от</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> породить новый класс, то он тоже будет потомком</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge,</span><span style="font-family: 'Times New Roman'; color: #000000;"> но уже не таким близким, как</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Очень важно, что в отношениях наследования любой класс может иметь только одного непосредственного предка и сколь угодно много потомков. Поэтому все связанные отношением наследования классы образуют </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">иерархию.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Примером иерархии классов является библиотека Visual Component Library (VCL); с ее помощью в Delphi обеспечивается разработка Windows-приложений.</span></p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">ПРЕДОК ПО УМОЛЧАНИЮ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В языке Object Pascal существует предопределенный класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TObject,</span><span style="font-family: 'Times New Roman'; color: #000000;"> который служит неявным предком тех классов, для которых предок не указан. Это означает, что объявление</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>эквивалентно следующему:</p> <p style="margin: 0px 0px 0px 19px;"> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TObject)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Класс</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TObject</span><span style="font-family: 'Times New Roman'; color: #000000;"> выступает корнем любой иерархии классов. Он содержит ряд методов, которые по наследству передаются всем остальным классам. Среди них конструктор </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Create,</span><span style="font-family: 'Times New Roman'; color: #000000;"> деструктор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Destroy,</span><span style="font-family: 'Times New Roman'; color: #000000;"> процедура</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Free</span><span style="font-family: 'Times New Roman'; color: #000000;"> и некоторые другие методы.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Таким образом, полная иерархия классов для измерителей ресурсов выглядит так (рис. 2):</span></p> <p> </p> <p style="text-align: center;"><img src="https://delphi-hlp.ru/embim1698.gif" alt="" hspace="1" vspace="1" width="203" height="144" /></p> <p style="text-align: center;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Рисунок 2</span></p> <p style="text-align: center;"> </p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">ПЕРЕКРЫТИЕ АТРИБУТОВ В НАСЛЕДНИКАХ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В механизме наследования можно условно выделить три основных момента:</span></p> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 24px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="14"><span style="font-family: 'Wingdings'; color: #000000; font-size: 10pt;">§</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">наследование полей;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 24px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="14"><span style="font-family: 'Wingdings'; color: #000000; font-size: 10pt;">§</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">наследование свойств;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 24px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="14"><span style="font-family: 'Wingdings'; color: #000000; font-size: 10pt;">§</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">наследование методов.</span></td> </tr> </tbody> </table> </div> <p><span style="font-family: 'Times New Roman'; color: #000000;">Любой порожденный класс наследует от родительского все поля данных, поэтому классы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge и TMemoryGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> автоматически содержат поле</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> FPercentCritical,</span><span style="font-family: 'Times New Roman'; color: #000000;"> объявленное в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Доступ к полям предка осуществляется по имени, как если бы они были определены в порожденном классе. В наследниках можно определять новые поля, но их имена должны отличаться от имен полей предка.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Наследование свойств и методов имеет свои особенности.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Свойство базового класса можно </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">перекрыть</span><span style="font-family: 'Times New Roman'; color: #000000;"> (от англ. override) в производном классе, например чтобы добавить ему новый атрибут доступа или связать с другим полем или методом.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Метод базового класса тоже можно перекрыть в производном классе, например чтобы изменить логику его работы. Обратимся, например, к классам</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge и TMemoryGauge. </span><span style="font-family: 'Times New Roman'; color: #000000;">В них методы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> SetPercentCritical и CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> унаследованы от</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge,</span><span style="font-family: 'Times New Roman'; color: #000000;"> так как логика их работы не зависит от типа ресурса. А вот метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPercentFree</span><span style="font-family: 'Times New Roman'; color: #000000;"> перекрыт, так как способ вычисления процента свободного пространства специфичен для диска и оперативной памяти:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Drive: Byte;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Drive := Ord(DriveLetter) - Ord(</span><span class="f_CodeExample" style="color: #ff0000;">'A'</span><span class="f_CodeExample" style="color: #000000;">) + </span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := DiskFree(Drive) * </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">div</span><span class="f_CodeExample" style="color: #000000;"> DiskSize(Drive) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TMemoryGauge.GetPercentFree: Integer; </span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ uses Windows; }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MemoryStatus: TMemoryStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MemoryStatus.dwLength := SizeOf(MemoryStatus);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GlobalMemoryStatus(MemoryStatus);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #000000;"> - MemoryStatus.dwMemoryLoad;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> перекрыт еще и конструктор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Create.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Это необходимо для инициализации дополнительного поля</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> DriveLetter:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.Create (ADriveLetter: Char) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DriveLetter := ADriveLetter;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Как видно из примера, в наследнике можно вызвать перекрытый метод предка, указав перед именем метода зарезервированное слово</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> inherited.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Кстати, данный пример демонстрирует важный принцип реализации конструкторов: сначала вызывается конструктор предка, а затем инициализируются дополнительные поля данных. В деструкторах применяется обратная последовательность действий: сначала разрушаются данные, недоступные предку, а затем вызывается унаследованный деструктор.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">СОВМЕСТИМОСТЬ ОБЪЕКТОВ РАЗЛИЧНЫХ КЛАССОВ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Для классов, связанных отношением наследования, вводится новое правило совместимости типов. Вместо объекта базового класса можно подставить объект любого производного класса. Обратное неверно. Например, переменной типа</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> можно присвоить значение переменной типа</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">R: TResourceGauge;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">R := TDiskGauge.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Объектная переменная R </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">формально</span><span style="font-family: 'Times New Roman'; color: #000000;"> имеет тип</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge,</span><span style="font-family: 'Times New Roman'; color: #000000;"> а </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">фактически</span><span style="font-family: 'Times New Roman'; color: #000000;"> связана с экземпляром класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Правило совместимости классов чаще всего применяется при передаче объектов в параметрах процедур и функций. Например, если процедура работает с объектом класса </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TResourceGauge,</span><span style="font-family: 'Times New Roman'; color: #000000;"> то вместо него можно передать объект класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TDiskGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> или </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TMemoryGauge.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">КОНТРОЛЬ И ПРЕОБРАЗОВАНИЕ ТИПОВ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Поскольку реальный экземпляр объекта может оказаться наследником класса, указанного при описании объектной переменной или параметра, бывает необходимо проверить, к какому классу принадлежит объект на самом деле. Чтобы программист мог выполнять такого рода проверки, каждый объект хранит информацию о своем классе. В Object Pascal существуют операторы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> is и as,</span><span style="font-family: 'Times New Roman'; color: #000000;"> с помощью которых выполняется соответственно </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">проверка на тип</span><span style="font-family: 'Times New Roman'; color: #000000;"> (type checking) и </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">преобразование к типу</span><span style="font-family: 'Times New Roman'; color: #000000;"> (type casting).</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Например, чтобы выяснить, принадлежит ли некоторый объект</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Obj,</span><span style="font-family: 'Times New Roman'; color: #000000;"> объявленный в программе как</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Obj: TObject;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">к классу</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> или его наследнику, следует записать</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Obj </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">is</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ да, принадлежит }</span><span class="f_CodeExample" style="color: #000000;"> ;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Для преобразования объекта к нужному типу используется оператор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> as,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> Obj </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">as</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #000000;"> CheckStatus;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Стоит отметить, что для объектов применим и обычный способ приведения типа:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge(Obj ) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span><span class="f_CodeExample" style="color: #000000;"> CheckStatus;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Вариант с оператором as лучше, поскольку безопасен. Он генерирует ошибку (точнее, исключительную ситуацию) при выполнении программы (run-time error), если реальный экземпляр объекта</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Obj</span><span style="font-family: 'Times New Roman'; color: #000000;"> несовместим с классом</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Забегая вперед, скажем, что ошибку приведения типа можно обработать и таким образом избежать досрочного завершения приложения.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">ВИРТУАЛЬНЫЕ МЕТОДЫ</span></p> <p><span style="color: #000000; font-size: 11pt; font-weight: bold;">ПОНЯТИЕ ВИРТУАЛЬНОГО МЕТОДА</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Все методы, которые до сих пор рассматривались, имеют одну общую черту </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> все они </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">статические.</span><span style="font-family: 'Times New Roman'; color: #000000;"> При обращении к статическому методу компилятор точно знает класс, которому данный метод принадлежит. Поэтому, например, обращение к статическому методу </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">GetPereentFree</span><span style="font-family: 'Times New Roman'; color: #000000;"> в методе</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> компилируется в вызов</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge.GetPercentFree:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetPereentFree &lt;= FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Beep;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ if TResourceGauge.GetPereentFree &lt;= FPercentCritical then Beep; }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> работает неправильно в наследниках</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge,</span><span style="font-family: 'Times New Roman'; color: #000000;"> так как внутри него вызов перекрытого метода</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPereentFree</span><span style="font-family: 'Times New Roman'; color: #000000;"> не происходит. Конечно, в классах </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">TDiskGauge и TMemoryGauge</span><span style="font-family: 'Times New Roman'; color: #000000;"> можно продублировать все методы и свойства, которые прямо или косвенно вызывают</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPereentFree,</span><span style="font-family: 'Times New Roman'; color: #000000;"> но при этом теряются преимущества наследования. ООП предлагает изящное решение этой проблемы </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPereentFree </span><span style="font-family: 'Times New Roman'; color: #000000;">всего-навсего объявляется </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">виртуальным:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPereentFree: Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В производных классах виртуальный метод перекрывается с использованием ключевого слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> override.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Перекрытый метод должен иметь точно такой же формат (список параметров, а для функций еще и тип возвращаемого значения), что и перекрываемый:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TResourceGauge)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMemoryGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TResourceGauge)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Суть виртуальных методов в том, что они вызываются по фактическому типу экземпляра, а не по формальному типу, записанному в программе. Поэтому после сделанных изменений метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus</span><span style="font-family: 'Times New Roman'; color: #000000;"> будет работать так, как ожидает программист:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree &lt;= FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Beep;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ if «фактический класс&gt;.GetPercentFree &lt;= FpercentCritical then Beep; }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Работа виртуальных методов основана на механизме позднего связывания (late binding). В отличие </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">от раннего связывания</span><span style="font-family: 'Times New Roman'; color: #000000;"> (early binding), характерного для статических методов, </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">позднее связывание</span><span style="font-family: 'Times New Roman'; color: #000000;"> основано на вычислении адреса вызываемого метода при выполнении программы. Метод вычисляется по хранящемуся в каждом объекте описателю типа.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Благодаря механизму наследования и виртуальным методам, в Delphi реализуется такая концепция ООП как полиморфизм. Полиморфизм существенно облегчает труд программиста, так как обеспечивает повторное использование кода уже написанных методов.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">АБСТРАКТНЫЕ ВИРТУАЛЬНЫЕ МЕТОДЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt;">При построении иерархии часто возникает ситуация, когда работа виртуального метода в базовом классе неизвестна и наполняется содержанием только в наследниках. Так случилось, например, с методом</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt; font-weight: bold;"> GetPercentFree,</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt;"> который в классе</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt; font-weight: bold;"> TResourceGauge</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt;"> состоит всего из одного оператора:</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt; font-weight: bold;"> Result := 0.</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt;"> Конечно, тело метода можно сделать пустым или почти пустым (так мы и поступили), но лучше воспользоваться директивой</span><span style="font-family: 'Times New Roman'; color: #000000; font-size: 11pt; font-weight: bold;"> abstract:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree : Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">abstract</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Директива</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> abstract</span><span style="font-family: 'Times New Roman'; color: #000000;"> записывается после слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> virtual</span><span style="font-family: 'Times New Roman'; color: #000000;"> и исключает необходимость написания кода виртуального метода для данного класса. Такой метод называется </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">абстрактным,</span><span style="font-family: 'Times New Roman'; color: #000000;"> т.е. подразумевает конкретное логическое действие, а не способ его реализации. Абстрактные виртуальные методы часто используются при создании классов-полуфабрикатов. Свою реализацию такие методы получают в законченных наследниках.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">ДИНАМИЧЕСКИЕ МЕТОДЫ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Разновидностью виртуальных методов являются так называемые </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">динамические методы.</span><span style="font-family: 'Times New Roman'; color: #000000;"> При их объявлении вместо слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> virtual</span><span style="font-family: 'Times New Roman'; color: #000000;"> записывается ключевое слово</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> dynamic, </span><span style="font-family: 'Times New Roman'; color: #000000;">например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">dynamic</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">abstract</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В наследниках динамические методы перекрываются так же, как и виртуальные, т.е. с помощью зарезервированного слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> override.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Семантически динамические и виртуальные методы идентичны. Различие состоит только в механизме их вызова. Методы, объявленные с директивой </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">virtual</span><span style="font-family: 'Times New Roman'; color: #000000;">, вызываются максимально быстро, но платой за это является большой размер системных таблиц, с помощью которых происходит их диспетчеризация. Размер этих таблиц начинает сказываться с увеличением числа классов в иерархии. Методы, объявленные с директивой </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">dynamic</span><span style="font-family: 'Times New Roman'; color: #000000;">, вызываются несколько дольше, но при этом таблицы диспетчирования имеют более компактный вид, что способствует экономии памяти. Таким образом, программисту предоставляются два способа оптимизации объектов: по скорости работы (</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">virtual</span><span style="font-family: 'Times New Roman'; color: #000000;">) или по объему памяти (</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">dynamic</span><span style="font-family: 'Times New Roman'; color: #000000;">).</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">МЕТОДЫ ОБРАБОТКИ СООБЩЕНИЙ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Специализированной формой динамических методов являются </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">методы обработки сообщений.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Они объявляются с помощью ключевого слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> message</span><span style="font-family: 'Times New Roman'; color: #000000;">, за которым следует целочисленная константа </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">номер сообщения,</span><span style="font-family: 'Times New Roman'; color: #000000;"> например:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyControl = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TWinControl)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> WMPaint (</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Message</span><span class="f_CodeExample" style="color: #000000;">: TWMPaint) ; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">message</span><span class="f_CodeExample" style="color: #000000;"> WM_PAINT;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы обработки сообщений всегда имеют формат процедуры и содержат единственный </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">var</span><span style="font-family: 'Times New Roman'; color: #000000;">-параметр. При перекрытии метода его название и имя параметра не имеют значения. Вызовом соответствующего обработчика занимается метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Dispatch,</span><span style="font-family: 'Times New Roman'; color: #000000;"> наследуемый из класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TObject.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы обработки сообщений применяются внутри библиотеки VCL для обработки сообщений Windows и редко нужны ее пользователям, т.е. нам с вами.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">КЛАССЫ В ПРОГРАММНЫХ МОДУЛЯХ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Классы очень удобно собирать в модули. При этом их описание помещается в секцию </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">interface,</span><span style="font-family: 'Times New Roman'; color: #000000;"> а код методов </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> в секцию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> implementation.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Создавая модули классов, нужно придерживаться следующих правил:</span></p> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 24px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Wingdings'; color: #000000; font-size: 8pt;">q</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">все классы, предназначенные для использования за пределами модуля, следует определять в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> interface;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 24px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Wingdings'; color: #000000; font-size: 8pt;">q</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">описание классов, предназначенных для употребления внутри модуля, следует располагать в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> implementation;</span></td> </tr> </tbody> </table> </div> <div style="text-align: left; text-indent: 0px; margin: 0px 0px 0px 24px; padding: 0px;"> <table style="line-height: normal;" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr valign="baseline"> <td width="24"><span style="font-family: 'Wingdings'; color: #000000; font-size: 8pt;">q</span></td> <td><span style="font-family: 'Times New Roman'; color: #000000;">если модуль В использует модуль</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> А,</span><span style="font-family: 'Times New Roman'; color: #000000;"> то в модуле В можно определять классы, порожденные от классов модуля А.</span></td> </tr> </tbody> </table> </div> <p><span style="font-family: 'Times New Roman'; color: #000000;">Соберем рассмотренные ранее классы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TResourceGauge, TDiskGauge и TmemoryGauge </span><span style="font-family: 'Times New Roman'; color: #000000;">в отдельный модуль Resgauge:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> Resgauge;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TResourceGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FPercentCritical: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical(Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">virtual</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">abstract</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentFree: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> PercentCritical: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetPercentCritical;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDiskGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TResourceGauge)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DriveLetter: Char;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree : Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create (ADriveLetter: Char) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMemoryGauge = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;"> (TResourceGauge)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetPercentFree: Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SysUtils, Windows;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ TResourceGauge }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FPercentCritical := </span><span class="f_CodeExample" style="color: #000080;">10</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.SetPercentCritical(Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> (Value &gt;= </span><span class="f_CodeExample" style="color: #000080;">0</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">and</span><span class="f_CodeExample" style="color: #000000;"> (Value &lt; </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> FPercentCritical := Value;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.CheckStatus;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> PercentFree &lt;= PercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> Beep;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ TDiskGauge }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.Create (ADriveLetter: Char) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">DriveLetter := ADriveLetter;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TDiskGauge.GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Drive: Byte;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Drive := Ord (DriveLetter) - Ord(</span><span class="f_CodeExample" style="color: #ff0000;">'A'</span><span class="f_CodeExample" style="color: #000000;">) + </span><span class="f_CodeExample" style="color: #000080;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := DiskFree(Drive) * </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">div</span><span class="f_CodeExample" style="color: #000000;"> DiskSize(Drive) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="font-style: italic; color: #000080;">{ TMemoryGauge }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TMemoryGauge.GetPercentFree: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MemoryStatus: TMemoryStatus ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MemoryStatus.dwLength := SizeOf(MemoryStatus);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GlobalMemoryStatus(MemoryStatus);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := </span><span class="f_CodeExample" style="color: #000080;">100</span><span class="f_CodeExample" style="color: #000000;"> - MemoryStatus.dwMemoryLoad;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Как можно заметить, в описании классов присутствуют новые слова</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> private, protected </span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> public.</span><span style="font-family: 'Times New Roman'; color: #000000;"> С их помощью регулируется видимость частей класса для других модулей и основной программы. Назначение каждой директивы поясняется ниже.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">ВИДИМОСТЬ АТРИБУТОВ ОБЪЕКТА</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Программист имеет возможность ограничить видимость атрибутов класса для других программистов (и для себя в том числе). Для этого служат директивы</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> private, protected, public, published, automated</span><span style="font-family: 'Times New Roman'; color: #000000;"> (последние две директивы не используется в модуле</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Resgauge).</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Private.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Все, что объявлено в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> private,</span><span style="font-family: 'Times New Roman'; color: #000000;"> недоступно за пределами модуля. Секция </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">private</span><span style="font-family: 'Times New Roman'; color: #000000;"> позволяет скрыть те поля и методы, которые относятся к так называемым особенностям реализации. Например, в этой секции объявлены поле</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> FPercentCritical</span><span style="font-family: 'Times New Roman'; color: #000000;"> и метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> SetPercentCritical.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Public.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Поля, методы и свойства, объявленные в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> public,</span><span style="font-family: 'Times New Roman'; color: #000000;"> не имеют никаких ограничений на использование, т.е. всегда видны за пределами модуля. Все, что помещается в секцию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> public,</span><span style="font-family: 'Times New Roman'; color: #000000;"> служит для манипуляций с объектами и составляет программный интерфейс класса. Например, в этой секции объявлены конструктор</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Create,</span><span style="font-family: 'Times New Roman'; color: #000000;"> процедура</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus,</span><span style="font-family: 'Times New Roman'; color: #000000;"> свойства</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> PercentFree и PercentCritical.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Protected.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Поля, методы и свойства, объявленные в секции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> protected,</span><span style="font-family: 'Times New Roman'; color: #000000;"> видны за пределами модуля только потомкам данного класса; остальным частям программы они не видны. Так же как и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> private,</span><span style="font-family: 'Times New Roman'; color: #000000;"> директива</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> protected</span><span style="font-family: 'Times New Roman'; color: #000000;"> позволяет скрыть особенности реализации класса, но в отличие от нее разрешает другим программистам порождать новые классы и обращаться к полям, методам и свойствам, которые составляют так называемый интерфейс разработчика. В эту секцию обычно помещаются виртуальные методы чтения и записи свойств. Примером такого метода является</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> GetPercentFree.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Published.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Устанавливает правила видимости те же, что и директива</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> public.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Особенность состоит в том, что для элементов, помещенных в секцию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> published,</span><span style="font-family: 'Times New Roman'; color: #000000;"> компилятор генерирует информацию о типе, которая позволяет превращать объекты в компоненты визуальной среды разработки. Секцию</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> published</span><span style="font-family: 'Times New Roman'; color: #000000;"> разрешено использовать только тогда, когда для самого класса или его предка включена директива компилятора</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> $TYPEINFO.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Automated.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Устанавливает правила видимости те же, что и директива</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> public.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Директива</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> automated</span><span style="font-family: 'Times New Roman'; color: #000000;"> используется в наследниках класса</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> TAutoObject</span><span style="font-family: 'Times New Roman'; color: #000000;"> при создании серверов OLE Automation. Для помещенных в эту секцию методов и свойств компилятор генерирует специальную информацию о типе, которая обеспечивает их видимость за пределами приложения.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Перечисленные секции могут чередоваться в объявлении класса в произвольном порядке, однако в пределах секции сначала следует описание полей, а потом методов и свойств. Если в определении класса</span><span style="font-family: 'Times New Roman'; color: #000000;">нет ключевых слов</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> private, protected, public, published </span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> automated,</span><span style="font-family: 'Times New Roman'; color: #000000;"> то для</span><span style="font-family: 'Times New Roman'; color: #000000;">обычных классов всем полям, методам и свойствам приписывается атрибут видимости</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> public, </span><span style="font-family: 'Times New Roman'; color: #000000;">а для тех классов, что порождены от классов VCL </span><span style="font-family: 'Times New Roman'; color: #000000;">—</span><span style="font-family: 'Times New Roman'; color: #000000;"> атрибут видимости</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> published.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Заметим, что внутри модуля не действуют никакие ограничения видимости на атрибуты реализованного в модуле класса. Это, кстати, отличается от соглашений, принятых в других языках программирования, в частности в C++.</span></p> <p> </p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">УКАЗАТЕЛИ НА МЕТОДЫ ОБЪЕКТОВ</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">В Object Pascal существуют процедурные типы данных для методов объектов. Внешне объявление процедурного типа для метода отличается от обычного словосочетанием </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">of object,</span><span style="font-family: 'Times New Roman'; color: #000000;"> записанным после прототипа процедуры или функции:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TFewResourcesEvent = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> (Sender: TObject) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">object</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Переменная такого типа называется </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">указателем на метод</span><span style="font-family: 'Times New Roman'; color: #000000;"> (method pointer). Она занимает в памяти 8 байт и хранит одновременно ссылку на объект и адрес его метода:</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OnFewResources: TFewResourcesEvent = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Методы объектов, объявленные по приведенному выше шаблону, становятся совместимы по типу с переменной</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> OnFewResources.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Tform1 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FewResources (Sender: TObject) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Form1: Tform1;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p style="text-indent: -19px; margin: 0px 0px 0px 19px;"><span style="font-family: 'Times New Roman'; color: #000000;">Ecли переменную </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">OnFewResources</span><span style="font-family: 'Times New Roman'; color: #000000;"> связать с методом </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">FewResources</span><span style="font-family: 'Times New Roman'; color: #000000;"> объекта </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Form1</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OnFewResources:= Form1.FewResources;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">и переписать метод</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> CheckStatus,</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TResourceGauge.CheckStatus ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> PercentFree &lt;= PercentCritical </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> Assigned(OnFewResources) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span><span class="f_CodeExample" style="color: #000000;"> OnFewResources(Self) ;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 0px 0px 0px 19px;"> </p> <p><span style="font-family: 'Times New Roman'; color: #000000;">то выдача предупреждения о нехватке ресурсов будет переадресована (говорят еще </span><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">делегирована)</span><span style="font-family: 'Times New Roman'; color: #000000;"> методу</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> FewResources</span><span style="font-family: 'Times New Roman'; color: #000000;"> объекта</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Form1</span><span style="font-family: 'Times New Roman'; color: #000000;">. Обратите внимание, что вызов метода через указатель происходит лишь в том случае, если указатель не равен</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> nil.</span><span style="font-family: 'Times New Roman'; color: #000000;"> Эта проверка выполняется с помощью стандартной функции</span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;"> Assigned,</span><span style="font-family: 'Times New Roman'; color: #000000;"> которая возвращает </span><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">True</span><span style="font-family: 'Times New Roman'; color: #000000;">, если ее аргумент является связанным указателем.</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000;">Делегирование позволяет сосредоточить в одном объекте обработку событий, возникающих в других объектах. Это избавляет программиста от необходимости порождать многочисленные классы-наследники и перекрывать в них виртуальные методы. Делегирование широко применяется в Delphi. Например, все компоненты делегируют обработку своих событий форме, на которой они находятся.</span></p> Переназначения объектов 2013-08-15T20:38:37+07:00 2013-08-15T20:38:37+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/sushchnost-oop/perenaznacheniya-ob-ektov.html Super User toto44@inbox.ru <p><span style="font-style: italic; color: #000000;">Существует ли возможность переключения набора данных, используемого DBNavigator на набор данных активного элемента управления без из прямого указания?</span></p> <p> </p> <p><span style="color: #000000;">Все, что вы хотите, поместится в пару строк кода. Добавьте "TypInfo" в список используемых модулей и сделайте примерно следующее:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PropInfo: PPropInfo;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PropInfo := GetPropInfo(PTypeInfo(ActiveControl.ClassInfo), </span><span class="f_CodeExample" style="color: #ff0000;">'DataSource'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> (PropInfo &lt;&gt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">and</span><span class="f_CodeExample" style="color: #000000;"> (PropInfo^.PropType^.Kind = tkClass)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">and</span><span class="f_CodeExample" style="color: #000000;"> (GetTypeData(PropInfo^.PropType)^.ClassType = TDataSource) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DBNavigator1.DataSource := TDataSource(GetOrdProp(ActiveControl, PropInfo));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p><span style="color: #000000;">Некоторая избыточность в проверках гарантирует вам, что вам не попадется некий странный объект (от сторонних производителей компонентов, например), имеющий свойство DataSource, но не типа TDataSource.</span></p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от</span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> <p><span style="font-style: italic; color: #000000;">Существует ли возможность переключения набора данных, используемого DBNavigator на набор данных активного элемента управления без из прямого указания?</span></p> <p> </p> <p><span style="color: #000000;">Все, что вы хотите, поместится в пару строк кода. Добавьте "TypInfo" в список используемых модулей и сделайте примерно следующее:</span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PropInfo: PPropInfo;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PropInfo := GetPropInfo(PTypeInfo(ActiveControl.ClassInfo), </span><span class="f_CodeExample" style="color: #ff0000;">'DataSource'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">if</span><span class="f_CodeExample" style="color: #000000;"> (PropInfo &lt;&gt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">nil</span><span class="f_CodeExample" style="color: #000000;">)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">and</span><span class="f_CodeExample" style="color: #000000;"> (PropInfo^.PropType^.Kind = tkClass)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">and</span><span class="f_CodeExample" style="color: #000000;"> (GetTypeData(PropInfo^.PropType)^.ClassType = TDataSource) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DBNavigator1.DataSource := TDataSource(GetOrdProp(ActiveControl, PropInfo));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p><span style="color: #000000;">Некоторая избыточность в проверках гарантирует вам, что вам не попадется некий странный объект (от сторонних производителей компонентов, например), имеющий свойство DataSource, но не типа TDataSource.</span></p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от</span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> Сабклассинг и суперклассинг в Delphi для начинающих 2013-08-15T20:39:51+07:00 2013-08-15T20:39:51+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/sushchnost-oop/sabklassing-i-superklassing-v-delphi-dlya-nachinayushchikh.html Super User toto44@inbox.ru <p><span style="font-weight: bold;">"Сабклассинг и суперклассинг в Delphi для начинающих"</span></p> <p> </p> <p>В данной статье я постараюсь рассказать об использовании двух мощных средств технологии Windows API - сабклассинга и суперклассинга. Все примеры к статье были составлены мною. Вы найдете их в прикрепленном к статье файле.</p> <p> </p> <p><span style="font-weight: bold;">Сабклассинг</span></p> <p> </p> <p>Сабклассинг (subclassing) - контроль сообщений окон путем модификации оконной процедуры последних. Сабклассинг подразумевает использование изменённой оконной процедуры до оригинальной (а её можно вовсе и не использовать), позволяя нам создать сколь угодно заготовок оконных процедур для данного объекта. Хотя на практике обычно используется только одна.</p> <p> </p> <p><span style="font-weight: bold;">Оконная процедура</span></p> <p> </p> <p>Оконная процедура (window procedure) - специальная функция любого окна, имеющего дескриптор, которая принимает и обрабатывает все поступающие окну сообщения (от других программ или от Windows). Оконная процедура является косвенно вызываемой (callback) пользовательской (user-defined) функцией. Соответственно, реакцию на сообщения задаёт программист.</p> <p> </p> <p>Оконная процедура - самое существенное из всего того, что принадлежит окну, поэтому сабклассинг является очень мощной технологией, необходимой для полноценной работы с Windows API. Важно уметь правильно обрабатывать сообщения, чтобы использовать сабклассинг.</p> <p> </p> <p>Оконная процедура обычно назначается при создании окна, когда заполняется структура класса последнего TWndClass(Ex).</p> <p> </p> <p>Оконная процедура имеет такой прототип:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> XWindowProc(HWnd: THandle; Msg: Cardinal; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam, LParam: Integer): Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Где X - любой префикс (можно и опустить), по которому можно идентифицировать</p> <p>нужную оконную процедуру (например, Edit или New).</p> <p> </p> <p>Рассмотрим, какие параметры передаются при вызове оконной процедуры. В параметре HWnd передаётся дескриптор окна, классу которого принадлежит оконная процедура. В параметре Msg передаётся идентификатор поступившего сообщения. В параметрах WParam и LParam передаётся дополнительная информация, которая зависит от типа посланного сообщения.</p> <p> </p> <p>Возвращаемый функцией результат должен определить программист.</p> <p> </p> <p>Рекомендуется обрабатывать сообщения через оператор Case:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WM_DESTROY:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p>Чтобы сообщение не обрабатывалось оригинальной оконной процедурой, необходимо после своих действий осуществить выход из блока Case:</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WM_CLOSE:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBox(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'WM_CLOSE'</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Caption'</span><span class="f_CodeExample" style="color: #000000;">, MB_OK);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Осуществляем выход из текущей процедуры }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Exit;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p>Этот способ применяется также для того, чтобы функция DefWindowProc не обрабатывала сообщение. Данная функция предназначена для выполнения стандартных действий системы при поступлении очередного сообщения. В сабклассинге она практически не используется (её роль выполняет оригинальная оконная процедура, в которой, быть может, и находится вызов DefWindowProc).</p> <p> </p> <p>Для вызова оконной процедуры по её адресу используется функция CallWindowProc. По параметрам она аналогична любой оконной процедуре, но помимо этого она имеет еще один параметр, определяющий адрес требуемой оконной процедуры для вызова (параметр первый).</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Тип первого параметра представляет собой простой указатель }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TFarProc = Pointer; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TFNWndProc = TFarProc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> CallWindowProc(lpPrevWndFunc: TFNWndProc; HWnd: HWND; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam: Integer; LParam: Integer): Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Функция CallWindowProc позволяет нам, по сути, менять поведение окна, ведь мы можем сабклассировать его множество раз с сохранением адресов оконных процедур, а потом вызывать нужные оконные процедуры по надобности. Но на практике эта функция используется для вызова одной оригинальной оконной процедуры окна, которая была до его сабклассирования.</p> <p> </p> <p>После детального рассмотрения основ сабклассинга непосредственно перейдём к его реализации в Delphi.</p> <p> </p> <p>Примечание: суперклассинг, как один из видов сабклассинга, будет описан далее отдельно!</p> <p> </p> <p>Примечание: сабклассинг для окон, принадлежащих чужим процессам, в данной статье не рассматривается! В частности, для начинающих программистов он достаточно сложен.</p> <p> </p> <p>Основная функция сабклассирования окна: SetWindowLong. Вообще, эта функция предназначена для изменения определённого атрибута окна (функция может изменять атрибут как самого окна, так и атрибут его класса). Рассмотрим её параметры.</p> <p> </p> <p>Объявление функции:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> SetWindowLong(HWnd: HWND; nIndex: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">dwNewLong: LongInt): LongInt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Параметр HWnd определяет окно, с которым будет производиться работа. Параметр nIndex определяет индекс аттрибута, который мы хотим изменить. Пока нас будут интересовать значения GWL_WNDPROC и GWL_USERDATA. Первый индекс определяет, что изменения затронут оконную процедуру окна, второй - то, что будет изменена специальная внутренняя четырёхбайтовая переменная, которой обладает каждое окно. В ней удобно хранить адрес старой оконной процедуры при сабклассинге.</p> <p> </p> <p>Рассмотрим, как по шагам засабклассировать окно.</p> <p>Создаём заготовку новой оконной процедуры;</p> <p>Помещаем в переменную GWL_USERDATA адрес старой оконной процедуры;</p> <p>Изменяем адрес оконной процедуры на новый.</p> <p>Последние два действия можно объединить в одно, так как функция SetWindowLong возвращает предыдущее значение изменённого параметра.</p> <p> </p> <p>Далее я публикую примеры кода, в которых будут рассмотрены способы сабклассирования окон как средствами VCL, так и средствами WinAPI. Все примеры кода хорошо комментированы.</p> <p> </p> <p><span style="font-weight: bold;">Сабклассинг окон на VCL</span></p> <p> </p> <p>В VCL на компонентном уровне сабклассинг реализуется достаточно просто и быстро. Его использование предпочтительней, чем использование сабклассинга на WinAPI (разумеется, при программировании с VCL) - всегда, если возможно, делайте сабклассинг именно через VCL. Для сабклассирования оконного компонента необходимо расширить его функциональность путём добавления обработчика желаемого сообщения, либо через перекрытие оконной процедуры компонента.</p> <p> </p> <p>Ниже приведен пример сабклассирования компонента TEdit таким образом, чтобы последний не реагировал на вставку текста:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Unit</span><span class="f_CodeExample" style="color: #000000;"> UMain;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMainForm = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FormDestroy(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Новый класс с дополнительным методом,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> который вызвается при сообщении WM_PASTE }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TNewEdit = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Class</span><span class="f_CodeExample" style="color: #000000;">(TEdit)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Обработчик сообщения }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> WMCopy(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span><span class="f_CodeExample" style="color: #000000;"> Msg: TWMPaste); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Message</span><span class="f_CodeExample" style="color: #000000;"> WM_PASTE;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MainForm: TMainForm;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Экземпляр нового класса }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit: TNewEdit;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R *.dfm}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ TNewEdit }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> TNewEdit.WMCopy(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span><span class="f_CodeExample" style="color: #000000;"> Msg: TWMPaste);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Игнорируем сообщение }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Msg.Result := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> TMainForm.FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Создание и размещение компонента на форме }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit := TNewEdit.Create(Self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Parent := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Left := </span><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Top := </span><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Width := MainForm.Width - </span><span class="f_CodeExample" style="color: #800000;">23</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Следующий метод работать не будет }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.PasteFromClipboard;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> TMainForm.FormDestroy(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Free;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">. </span></p> </td> </tr> </tbody> </table> </div> <p>Таким образом, чтобы засабклассировать оконный компонент, нужно просто реализовать свой обработчик сообщений. Есть еще один способ, который заключается в модификации оконной процедуры компонента на VCL-уровне:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Unit</span><span class="f_CodeExample" style="color: #000000;"> UMain;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMainForm = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FormDestroy(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TNewEdit = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Class</span><span class="f_CodeExample" style="color: #000000;">(TEdit) </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Перекрытая оконная процедура компонента }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> WndProc(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span><span class="f_CodeExample" style="color: #000000;"> Msg: TMessage); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MainForm: TMainForm;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Экземпляр нового класса }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit: TNewEdit;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R *.dfm}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ TNewEdit }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> TNewEdit.WndProc(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span><span class="f_CodeExample" style="color: #000000;"> Msg: TMessage);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg.Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_PASTE:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Msg.Result := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Звуковой сигнал, оповещающий пользователя о</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> невозможности вставки текста }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBeep(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Выход после обработки необходим, чтобы</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> оригинальная оконная процедура не имела</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> возможности обработать WM_PASTE; в противном</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> случае вставка текста всё равно произойдёт }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Exit;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Не забывайте вызывать унаследованную оконную процедуру }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Inherited</span><span class="f_CodeExample" style="color: #000000;"> WndProc(Msg);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> TMainForm.FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Создание и размещение компонента на форме }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit := TNewEdit.Create(Self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Parent := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Left := </span><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Top := </span><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Width := MainForm.Width - </span><span class="f_CodeExample" style="color: #800000;">23</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Следующий метод работать не будет }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.PasteFromClipboard;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> TMainForm.FormDestroy(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Free;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">. </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Этот способ по функциональности ничем не отличается от первого (только озвучкой).</p> <p> </p> <p>Вот и всё! Думаю, что Вы разобрались в примерах и мы можем переходить к сабклассингу средствами Windows API. Ту часть кода примеров, которые не относятся к теме статьи, я снабдил краткими комментариями.</p> <p> </p> <p><span style="font-weight: bold;">Сабклассинг окон с помощью Windows API</span></p> <p> </p> <p>В следующем примере будет показано, как усовершенствовать кнопку (Button) и поле ввода (Edit). Вот список усовершенствований:</p> <p> </p> <p>1) Для кнопки: создать такую кнопку, которая при нажатии левой кнопки мыши отображала бы текущую дату;</p> <p>2) Для поля ввода: запретить контекстное меню; установить шрифт для текста синего цвета</p> <p> </p> <p>Разберем, как это выглядит в теории. Для создания кнопки, отображающей дату, мы должны получить текущую дату функцией GetLocalTime. В переданной функции структуре будет находиться текущая дата. Нас интересует только текущие час, минута и секунда. Мы преобразуем полученные значения в строковый формат и дополняем нулями слева, если это необходимо. После этого отображаем дату на кнопке, по срабатыванию таймера.</p> <p> </p> <p>Что касается поля ввода, то для запрета контекстного меню необходимо проигнорировать сообщение WM_CONTEXTMENU, после чего осуществить выход из оконной процедуры. Для изменения цвета текста необходимо использовать функция SetTextColor для контекста Edit'а. Этот контекст можно получить, обрабатывая сообщение WM_CTLCOLOREDIT (обратите внимание, что это сообщение посылается родительскому окну поля ввода). Данное сообщение посылается при каждой отрисовке Edit'а, передавая в параметре WParam контекст для рисования. Не следует забывать включить прозрачность фона функцией SetBkMode (хотя для нашего примера эта функция ничего не изменяет, попробуйте использовать другие цвета, чтобы убедиться в её надобности).</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Program</span><span class="f_CodeExample" style="color: #000000;"> SampleProject03;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R *.res}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R WinXP.res}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Messages,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SysUtils;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> InitCommonControls; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">External</span><span class="f_CodeExample" style="color: #ff0000;">'comctl32.dll'</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Const</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Идентификатор таймера }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">BtnTimer = </span><span class="f_CodeExample" style="color: #800000;">450</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Константы с заголовками дочерних окон }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StaticInfoText = </span><span class="f_CodeExample" style="color: #ff0000;">'Метка без сабклассирования'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">BtnText = </span><span class="f_CodeExample" style="color: #ff0000;">'Кнопка для сабклассирования'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Главное окно }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">HWnd: THandle;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Три дочерних компонента для сабклассирования }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Btn, Edit, InfoStatic: THandle; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Устанавливает для окна AWindow шрифт для контролов по умолчанию }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> SetDefFont(AWindow: THandle);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SendMessage(AWindow, WM_SETFONT, GetStockObject(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">DEFAULT</span><span class="f_CodeExample" style="color: #000000;">_GUI_FONT), </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Косвенно-вызваемая процедура сообщений таймера }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Эта процедура выполняется при каждом срабатывании таймера }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> BtnTimerProc(HWnd: THandle; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">IDEvent, DWTime: Cardinal); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Переменная, куда будет помещено текущее время }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Time: TSystemTime;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Для анализа времени }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Hour, Minute, Second: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Получаем время }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GetLocalTime(Time);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Инициализируем переменные }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Hour := IntToStr(Time.wHour);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Minute := IntToStr(Time.wMinute);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Second := IntToStr(Time.wSecond);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Добавляем нули при необходимости }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> Length(Hour) = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> Hour := </span><span class="f_CodeExample" style="color: #ff0000;">'0'</span><span class="f_CodeExample" style="color: #000000;"> + Hour;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> Length(Minute) = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> Minute := </span><span class="f_CodeExample" style="color: #ff0000;">'0'</span><span class="f_CodeExample" style="color: #000000;"> + Minute;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> Length(Second) = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> Second := </span><span class="f_CodeExample" style="color: #ff0000;">'0'</span><span class="f_CodeExample" style="color: #000000;"> + Second;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Отображаем дату }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SetWindowText(HWnd, PChar(Hour + </span><span class="f_CodeExample" style="color: #ff0000;">':'</span><span class="f_CodeExample" style="color: #000000;"> + Minute + </span><span class="f_CodeExample" style="color: #ff0000;">':'</span><span class="f_CodeExample" style="color: #000000;"> + Second));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Модифицированная оконная процедура поля ввода }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> EditWinProc(HWnd: THandle; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam, LParam: Integer): Cardinal; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Запрещаем показ контекстного меню }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_CONTEXTMENU:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBeep(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Exit;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Не забываем вызвать оригинальную оконную процедуру }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := CallWindowProc(Pointer(GetWindowLong(HWnd, GWL_USERDATA)),</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Hwnd, Msg, WParam, LParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Модифицированная оконная процедура кнопки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> BtnWinProc(HWnd: THandle; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam, LParam: Integer): Cardinal; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ При нажатии мыши запускаем таймер, интервал - 10 миллисекунд }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_LBUTTONDOWN: SetTimer(HWnd, BtnTimer, </span><span class="f_CodeExample" style="color: #800000;">10</span><span class="f_CodeExample" style="color: #000000;">, @BtnTimerProc);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ При отпускании мыши уничтожаем таймер }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_LBUTTONUP:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> KillTimer(HWnd, BtnTimer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Восстанавливаем прежний текст }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetWindowText(HWnd, BtnText); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Не забываем вызвать оригинальную оконную процедуру }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := CallWindowProc(Pointer(GetWindowLong(HWnd, GWL_USERDATA)),</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HWnd, Msg, WParam, LParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Оконная процедура главного окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> MainWinProc(HWnd: THandle; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam, LParam: Integer): Cardinal; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Конвертирует сроку PChar в String }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> StrPas(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Const</span><span class="f_CodeExample" style="color: #000000;"> AStr: PChar): </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := AStr;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Здесь будет произведено создание дочерних окон }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_CREATE:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> InfoStatic := CreateWindowEx(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Static'</span><span class="f_CodeExample" style="color: #000000;">, StaticInfoText,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WS_CHILD </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> WS_VISIBLE </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> SS_LEFT,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">270</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">16</span><span class="f_CodeExample" style="color: #000000;">, HWnd, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, HInstance, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetDefFont(InfoStatic);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Edit := CreateWindowEx(WS_EX_CLIENTEDGE, </span><span class="f_CodeExample" style="color: #ff0000;">'Edit'</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WS_CHILD </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> WS_VISIBLE </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> ES_LEFT,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">28</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">300</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">21</span><span class="f_CodeExample" style="color: #000000;">, HWnd, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, HInstance, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetDefFont(Edit);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Выделяем весь текст }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SendMessage(Edit, EM_SETSEL, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, -</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Далее делаем сабклассинг поля ввода }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetWindowLong(Edit, GWL_USERDATA,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetWindowLong(Edit, GWL_WNDPROC, LongInt(@EditWinProc)));</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Btn := CreateWindowEx(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Button'</span><span class="f_CodeExample" style="color: #000000;">, BtnText, WS_CHILD </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> WS_VISIBLE</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> BS_PUSHBUTTON, </span><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">52</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">300</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">25</span><span class="f_CodeExample" style="color: #000000;">, HWnd, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HInstance, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetDefFont(Btn); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Далее делаем сабклассинг кнопки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetWindowLong(Btn, GWL_USERDATA,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetWindowLong(Btn, GWL_WNDPROC, LongInt(@BtnWinProc)));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_KEYDOWN:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Закрытие окна по нажатию Enter'а }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> WParam = VK_RETURN </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> PostQuitMessage(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Данное сообщение посылается при отрисовке Edit'a;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> вы можете использовать переданный контекст для рисования</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> фона, либо для смены цвета текста; после завершения рисования</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> верните модифицированный контекст как результат сообщения и не</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> забудьте сделать выход из оконной процедуры, так как в противном</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> случае DefWindowProc снова разукрасит Edit в стандартный системный цвет }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_CTLCOLOREDIT:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Устанавливаем прозрачность фона }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetBkMode(WParam, TRANSPARENT);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Устанавливаем цвет шрифта }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetTextColor(WParam, </span><span class="f_CodeExample" style="color: #800000;">$FF0000</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Возвращаем нужный нам контекст }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := WParam;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Exit;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_DESTROY:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Выход для освобождения памяти }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PostQuitMessage(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Обработка всех остальных сообщений по умолчанию }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := DefWindowProc(HWnd, Msg, WParam, LParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> WinMain;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Msg: TMsg;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Оконный класс }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx: TWndClassEx;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Подготовка структуры класса окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ZeroMemory(@WndClassEx, SizeOf(WndClassEx));</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{************* Заполнение структуры нужными значениями ******************* }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Размер структуры }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.cbSize := SizeOf(TWndClassEx);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Имя класса окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.lpszClassName := </span><span class="f_CodeExample" style="color: #ff0000;">'SubclassSampleWnd'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Стиль класса, не окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.style := CS_VREDRAW </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> CS_HREDRAW;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Дескриптор программы (для доступа к сегменту данных) }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hInstance := HInstance;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Адрес оконной процедуры }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.lpfnWndProc := @MainWinProc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Иконки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hIcon := LoadIcon(HInstance, MakeIntResource(</span><span class="f_CodeExample" style="color: #ff0000;">'MAINICON'</span><span class="f_CodeExample" style="color: #000000;">));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hIconSm := LoadIcon(HInstance, MakeIntResource(</span><span class="f_CodeExample" style="color: #ff0000;">'MAINICON'</span><span class="f_CodeExample" style="color: #000000;">));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Курсор }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hCursor := LoadCursor(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, IDC_ARROW);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Кисть для заполнения фона }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hbrBackground := COLOR_BTNFACE + </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Меню }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.lpszMenuName := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Регистрация оконного класса в Windows }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> RegisterClassEx(WndClassEx) = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBox(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Невозможно зарегистрировать класс окна'</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Ошибка'</span><span class="f_CodeExample" style="color: #000000;">, MB_OK </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> MB_ICONHAND)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Создание окна по зарегистрированному классу }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HWnd := CreateWindowEx(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, WndClassEx.lpszClassName,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Subclassing Sample by Rrader'</span><span class="f_CodeExample" style="color: #000000;">, WS_OVERLAPPEDWINDOW </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">And</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> WS_BORDER</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">And</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> WS_MAXIMIZEBOX </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">And</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> WS_SIZEBOX,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT), </span><span class="f_CodeExample" style="color: #800000;">320</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">116</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HInstance, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> HWnd = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBox (</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Окно не создалось!'</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Ошибка'</span><span class="f_CodeExample" style="color: #000000;">, MB_OK </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> MB_ICONHAND)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Показ окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ShowWindow(HWnd, SW_SHOWNORMAL);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Обновление окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> UpdateWindow(HWnd); </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Цикл обработки сообщений }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">While</span><span class="f_CodeExample" style="color: #000000;"> GetMessage(Msg, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TranslateMessage(Msg);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DispatchMessage(Msg);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Выход по прерыванию цикла }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Halt(Msg.WParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">InitCommonControls;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Создание окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WinMain;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">. </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Все примеры очень простые, они должны дать Вам базовое представление о сабклассинге.</p> <p> </p> <p>Теперь можно переходить к суперклассингу.</p> <p> </p> <p><span style="font-weight: bold;">Суперклассинг</span></p> <p> </p> <p>Сабклассинг особенно удобен, когда дело касается изменения одного окна, класс которого не совпадает с другими окнами, подлежащими сабклассированию. А что, если нам нужно засабклассировать сотню Edit'ов? Сабклассинг здесь будет громоздким. Решением этой проблемы является суперклассинг.</p> <p> </p> <p>Суперклассинг (superclassing) - создание и регистрация нового класса окна в системе. После чего этот класс окна готов к использованию.</p> <p> </p> <p>VCL-суперклассинг мы рассматривать не будем. Думаю, Вам понятно, что реализация суперклассинга на VCL - это создание компонентов. При создании оконного компонента в Delphi вы неявно создаёте подобие суперкласса. После этого вы можете использовать хоть сотню таких компонентов (например, создать из них массив). Заметьте, что такой компонент будет, как правило не стандартным, например, кнопка TBitBtn. Чтобы Вам было понятней, почему это суперкласс, можете посмотреть имя класса окна компонента через любой сканер окон (я использовал InqSoft Window Scanner) - это имя будет совпадать с тем именем, которое обозначает имя компонента в Delphi (например, TBitBtn или TLabeledEdit). Из этого мы можем сделать вывод, что суперклассинг прекрасно прижился в Delphi и широко там используется.</p> <p> </p> <p>У каждого потомка класса TWinControl в Delphi есть метод CreateParams. Можете воспользоваться им, чтобы изменить название класса окна.</p> <p> </p> <p>Гораздо более интересен суперклассинг на WinAPI. Необходимо уметь его использовать.</p> <p> </p> <p>Рассмотрим, как по шагам создать суперкласс.</p> <p>Вызываем функцию GetClassInfoEx, чтобы получить информацию о классе окна, который мы будем далее модернизировать. Эта функция заполнит переданную ей запись TWndClassEx параметрами класса;</p> <p>Изменяем всё, что нам нужно в полученной записи. Нужно задать свое имя класса, размер структуры, а также дескриптор HInstance, также нас будет интересовать оконная процедура - мы также изменим её у класса;</p> <p>Регистрируем новый класс при помощи функции RegisterClassEx;</p> <p>По окончании работы программы освобождаем класс функцией UnregisterClass.</p> <p>Далее новый класс можно использовать. В примерах я буду делать простые изменения в классах окон.</p> <p> </p> <p>Давайте рассмотрим функции для суперклассинга более подробно.</p> <p> </p> <p>Суперклассинг начинается с функции GetClassInfoEx.</p> <p> </p> <p>Объявление функции:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> GetClassInfoEx(Instance: Cardinal; Classname: PChar; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span><span class="f_CodeExample" style="color: #000000;"> WndClass: TWndClassEx): LongBool; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Первый параметр функции - дескриптор приложения, которое создало класс. Если же Вы желаете модифицировать предопределённые класс окон Windows (например, классы 'Button', 'Edit', 'ListBox' и т. п.), то передайте нуль в параметре.</p> <p> </p> <p>Следующий параметр - собственно название интересующего Вас класса. Сюда можно передать атом (см. ниже)</p> <p> </p> <p>В последнем параметре передается структура типа TWndClassEx, в которую в случае успешного вызова функции будет помещена информация о классе.</p> <p> </p> <p>Когда информация о классе получена, можно изменить его (что обязательно к этому, сказано выше).</p> <p> </p> <p>После подготовки класса окна Вы регистрируете его в Windows с помощью функции RegisterClassEx.</p> <p> </p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> RegisterClassEx(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Const</span><span class="f_CodeExample" style="color: #000000;"> WndClass: TWndClassEx): Word; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p>Функция возвращает атом, который по сути есть числовое уникальное значение. Это будет идентификатор класса окна в системе.</p> <p> </p> <p>По завершению работы приложения желательно уничтожить класс. В противном случае - "утечка памяти".</p> <p>Для этого существует функция UnregisterClass:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> UnregisterClass(lpClassName: PChar; hInstance: Cardinal): LongBool; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Эта функция уничтожает класс окна из Windows, освобождая память, ранее под него выделенную.</p> <p> </p> <p>Первый параметр функции - имя класса для деинсталляции. Обратите внимание, что эта функция сможет уничтожить только класс, который был зарегистрирован приложением, чей дескриптор передан во втором параметре. Глобальные предопределённые классы (см. выше) Windows (например, класс Edit) не могут быть уничтожены. В первом параметре также разрешается передавать атом-идентификатор класса.</p> <p> </p> <p>Для полного ознакомления с суперклассингом следует обобщить знания о самом классе окна.</p> <p> </p> <p><span style="font-weight: bold;">Класс окна</span></p> <p>Вообще, класс окна - объемная тема. Мы рассмотрим её самые главные особенности.</p> <p> </p> <p>Класс окна (window class) - набор свойств, который используются как шаблон для создания окон. Класс окна всегда можно расширить, изменить. Давайте подробнее разберем атрибуты класса.</p> <p> </p> <p>Первый атрибут - имя класса. Оно позволяет отличать одни классы от других. Классы с одинаковыми именами считаются идентичными. После создания окна по классу это окно может подвергнуться сабклассингу. Сабклассинг не изменяет класс окна. Не делайте имена классов длиннее 64 символов.</p> <p> </p> <p>Второй атрибут - это адрес оконной процедуры для окна. Об оконной процедуре подробно рассказано выше.</p> <p> </p> <p>Третий атрибут - дескриптор приложения (или DLL), которое зарегистрировало класс.</p> <p> </p> <p>Четвёртый - курсор окна при создании.</p> <p> </p> <p>Пятый - дескриптор большой иконки для окна.</p> <p> </p> <p>Шестой - тоже дескриптор иконки, но маленькой. Этого атрибута нет у структуры типа TWndClass (поняли, в чем отличие TWndClass от TWndClassEx?).</p> <p> </p> <p>Седьмой - дескриптор кисти, которой будет зарисована клиентская область окна.</p> <p> </p> <p>Восьмой - дескриптор меню, которое присваивается окну при создании.</p> <p> </p> <p>Девятый - стили класса (см. ниже)</p> <p> </p> <p>Десятый - дополнительная память, выделяемая классу (тип Integer).</p> <p> </p> <p>Одиннадцатый - дополнительная память (Integer), выделяемая под каждое окно класса.</p> <p> </p> <p>Напоследок рассмотрим стили класса. Стили класса - это комбинация значений, которые определяют поведение класса.</p> <p>Вот они:</p> <p> </p> <p>CS_BYTEALIGNCLIENT - выстраивает клиентскую часть окна на границу байта, что позволяет достичь большей производительности при отрисовке;</p> <p> </p> <p>CS_BYTEALIGNWINDOW - то же, что и CS_BYTEALIGNCLIENT, только увеличивает производительность при перемещении окна;</p> <p> </p> <p>CS_CLASSDC - создает контекст устройства, который разделяется между всеми наследниками этого класса - общий контекст для рисования;</p> <p> </p> <p>CS_DBLCLKS - разрешает обработку сообщений при двойном щелчке мыши;</p> <p> </p> <p>CS_GLOBALCLASS - разрешает создание окон с независимыми идентификаторами (HInstance) приложений. Создаётся глобальный класс. Если этот флаг не указан, то значение HInstance при создании окна должно быть таким же как и при регистрации класса RegisterClass(Ex).</p> <p> </p> <p>CS_HREDRAW - перерисовывает окно при его перемещении по горизонтали (и при изменении горизонтальных размеров);</p> <p> </p> <p>CS_VREDRAW - перерисовывает окно при его перемещении по вертикали (и при изменении вертикальных размеров);</p> <p> </p> <p>CS_NOCLOSE - убирает команду "Закрыть" из системного меню окна;</p> <p> </p> <p>CS_OWNDC - создает уникальный контекст устройства для каждого вновь создаваемого окна.</p> <p> </p> <p>На суперклассинг я публикую один пример, в котором на главном окне будет создано 10 "измененных" Edit'ов. Каждый такой Edit при клике на нём мышки уничтожит себя сам.</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Program</span><span class="f_CodeExample" style="color: #000000;"> SampleProject04;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R *.res}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R WinXP.res}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> InitCommonControls; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">External</span><span class="f_CodeExample" style="color: #ff0000;">'comctl32.dll'</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Главное окно }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">HWnd: THandle;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Массив Edit'ов }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edits: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Array</span><span class="f_CodeExample" style="color: #000000;">[</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">..</span><span class="f_CodeExample" style="color: #800000;">9</span><span class="f_CodeExample" style="color: #000000;">] </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span><span class="f_CodeExample" style="color: #000000;"> THandle;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Сюда будет помещено значение оригинальной оконной процедуры класса Edit }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OldProc: Pointer;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Устанавливает для окна AWindow шрифт для контролов по умолчанию }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> SetDefFont(AWindow: THandle);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SendMessage(AWindow, WM_SETFONT, GetStockObject(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">DEFAULT</span><span class="f_CodeExample" style="color: #000000;">_GUI_FONT), </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Модифицированная оконная процедура каждого поля ввода }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> EditWinProc(HWnd: THandle; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam, LParam: Integer): Cardinal; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Уничтожение Edit'а }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_LBUTTONDOWN: DestroyWindow(HWnd);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Вызов оригинальной оконной процедуры }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := CallWindowProc(OldProc,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HWnd, Msg, WParam, LParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Оконная процедура главного окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> MainWinProc(HWnd: THandle; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam, LParam: Integer): Cardinal; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TmpEdit: TWndClassEx;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">I: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Здесь будет произведено создание дочерних окон }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_CREATE:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Начало суперклассинга }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> GetClassInfoEx(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Edit'</span><span class="f_CodeExample" style="color: #000000;">, TmpEdit) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> Halt;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Запоминаем оконную процедуры для правильной работы окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> OldProc := TmpEdit.lpfnWndProc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Модификация класса }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TmpEdit.cbSize := SizeOf(TWndClassEx);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TmpEdit.lpfnWndProc := @EditWinProc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TmpEdit.lpszClassName := </span><span class="f_CodeExample" style="color: #ff0000;">'Sample04EditWindowClass'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TmpEdit.hInstance := GetModuleHandle(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Регистрация класса }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> RegisterClassEx(TmpEdit) = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> Halt;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Подготовка массива }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FillChar(Edits, SizeOf(Edits), </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">For</span><span class="f_CodeExample" style="color: #000000;"> I := Low(Edits) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">To</span><span class="f_CodeExample" style="color: #000000;"> High(Edits) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Edits[I] := CreateWindowEx(WS_EX_CLIENTEDGE,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Sample04EditWindowClass'</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Sample'</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WS_CHILD </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> WS_VISIBLE </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> ES_LEFT,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">28</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">300</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">21</span><span class="f_CodeExample" style="color: #000000;">, HWnd, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, HInstance, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetDefFont(Edits[I]); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_KEYDOWN:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Закрытие окна по нажатию Enter'а }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> WParam = VK_RETURN </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> PostQuitMessage(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_DESTROY:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Уничтожение классов}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> UnregisterClass(</span><span class="f_CodeExample" style="color: #ff0000;">'Sample04EditWindowClass'</span><span class="f_CodeExample" style="color: #000000;">, HInstance);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Выход для освобождения памяти }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PostQuitMessage(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Обработка всех остальных сообщений по умолчанию }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := DefWindowProc(HWnd, Msg, WParam, LParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> WinMain;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Msg: TMsg;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Оконный класс }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx: TWndClassEx;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Подготовка структуры класса окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ZeroMemory(@WndClassEx, SizeOf(WndClassEx));</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{************* Заполнение структуры нужными значениями ******************* }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Размер структуры }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.cbSize := SizeOf(TWndClassEx);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Имя класса окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.lpszClassName := </span><span class="f_CodeExample" style="color: #ff0000;">'SuperclassSampleWnd'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Стиль класса, не окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.style := CS_VREDRAW </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> CS_HREDRAW;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Дескриптор программы (для доступа к сегменту данных) }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hInstance := HInstance;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Адрес оконной процедуры }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.lpfnWndProc := @MainWinProc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Иконки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hIcon := LoadIcon(HInstance, MakeIntResource(</span><span class="f_CodeExample" style="color: #ff0000;">'MAINICON'</span><span class="f_CodeExample" style="color: #000000;">));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hIconSm := LoadIcon(HInstance, MakeIntResource(</span><span class="f_CodeExample" style="color: #ff0000;">'MAINICON'</span><span class="f_CodeExample" style="color: #000000;">));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Курсор }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hCursor := LoadCursor(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, IDC_ARROW);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Кисть для заполнения фона }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hbrBackground := COLOR_BTNFACE + </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Меню }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.lpszMenuName := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Регистрация оконного класса в Windows }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> RegisterClassEx(WndClassEx) = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBox(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Невозможно зарегистрировать класс окна'</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Ошибка'</span><span class="f_CodeExample" style="color: #000000;">, MB_OK </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> MB_ICONHAND)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Создание окна по зарегистрированному классу }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HWnd := CreateWindowEx(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, WndClassEx.lpszClassName,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Superclassing Sample by Rrader'</span><span class="f_CodeExample" style="color: #000000;">, WS_OVERLAPPEDWINDOW </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">And</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> WS_BORDER</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">And</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> WS_MAXIMIZEBOX </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">And</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> WS_SIZEBOX,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT), </span><span class="f_CodeExample" style="color: #800000;">320</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">116</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HInstance, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> HWnd = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBox (</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Окно не создалось!'</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Ошибка'</span><span class="f_CodeExample" style="color: #000000;">, MB_OK </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> MB_ICONHAND)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Показ окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ShowWindow(HWnd, SW_SHOWNORMAL);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Обновление окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> UpdateWindow(HWnd); </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Цикл обработки сообщений }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">While</span><span class="f_CodeExample" style="color: #000000;"> GetMessage(Msg, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TranslateMessage(Msg);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DispatchMessage(Msg);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Выход по прерыванию цикла }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Halt(Msg.WParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">InitCommonControls;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Создание окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WinMain;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Это</span><span style="font-family: 'Times New Roman'; color: #000000;">было</span><span style="font-family: 'Times New Roman'; color: #000000;">базовое</span><span style="font-family: 'Times New Roman'; color: #000000;">знакомство</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">сабклассингом</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">суперклассингом</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Надеюсь</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">материал</span><span style="font-family: 'Times New Roman'; color: #000000;">данной</span><span style="font-family: 'Times New Roman'; color: #000000;">статьи</span><span style="font-family: 'Times New Roman'; color: #000000;">поможет</span><span style="font-family: 'Times New Roman'; color: #000000;">Вам</span><span style="font-family: 'Times New Roman'; color: #000000;">при</span><span style="font-family: 'Times New Roman'; color: #000000;">программировании</span><span style="font-family: 'Times New Roman'; color: #000000;">!</span></p> <p style="margin: 7px 0px;"><br />Автор:Rrader</p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingrad</span></p> <p><span style="font-weight: bold;">"Сабклассинг и суперклассинг в Delphi для начинающих"</span></p> <p> </p> <p>В данной статье я постараюсь рассказать об использовании двух мощных средств технологии Windows API - сабклассинга и суперклассинга. Все примеры к статье были составлены мною. Вы найдете их в прикрепленном к статье файле.</p> <p> </p> <p><span style="font-weight: bold;">Сабклассинг</span></p> <p> </p> <p>Сабклассинг (subclassing) - контроль сообщений окон путем модификации оконной процедуры последних. Сабклассинг подразумевает использование изменённой оконной процедуры до оригинальной (а её можно вовсе и не использовать), позволяя нам создать сколь угодно заготовок оконных процедур для данного объекта. Хотя на практике обычно используется только одна.</p> <p> </p> <p><span style="font-weight: bold;">Оконная процедура</span></p> <p> </p> <p>Оконная процедура (window procedure) - специальная функция любого окна, имеющего дескриптор, которая принимает и обрабатывает все поступающие окну сообщения (от других программ или от Windows). Оконная процедура является косвенно вызываемой (callback) пользовательской (user-defined) функцией. Соответственно, реакцию на сообщения задаёт программист.</p> <p> </p> <p>Оконная процедура - самое существенное из всего того, что принадлежит окну, поэтому сабклассинг является очень мощной технологией, необходимой для полноценной работы с Windows API. Важно уметь правильно обрабатывать сообщения, чтобы использовать сабклассинг.</p> <p> </p> <p>Оконная процедура обычно назначается при создании окна, когда заполняется структура класса последнего TWndClass(Ex).</p> <p> </p> <p>Оконная процедура имеет такой прототип:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> XWindowProc(HWnd: THandle; Msg: Cardinal; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam, LParam: Integer): Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Где X - любой префикс (можно и опустить), по которому можно идентифицировать</p> <p>нужную оконную процедуру (например, Edit или New).</p> <p> </p> <p>Рассмотрим, какие параметры передаются при вызове оконной процедуры. В параметре HWnd передаётся дескриптор окна, классу которого принадлежит оконная процедура. В параметре Msg передаётся идентификатор поступившего сообщения. В параметрах WParam и LParam передаётся дополнительная информация, которая зависит от типа посланного сообщения.</p> <p> </p> <p>Возвращаемый функцией результат должен определить программист.</p> <p> </p> <p>Рекомендуется обрабатывать сообщения через оператор Case:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WM_DESTROY:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p>Чтобы сообщение не обрабатывалось оригинальной оконной процедурой, необходимо после своих действий осуществить выход из блока Case:</p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WM_CLOSE:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBox(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'WM_CLOSE'</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Caption'</span><span class="f_CodeExample" style="color: #000000;">, MB_OK);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Осуществляем выход из текущей процедуры }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Exit;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">; </span></p> </td> </tr> </tbody> </table> </div> <p>Этот способ применяется также для того, чтобы функция DefWindowProc не обрабатывала сообщение. Данная функция предназначена для выполнения стандартных действий системы при поступлении очередного сообщения. В сабклассинге она практически не используется (её роль выполняет оригинальная оконная процедура, в которой, быть может, и находится вызов DefWindowProc).</p> <p> </p> <p>Для вызова оконной процедуры по её адресу используется функция CallWindowProc. По параметрам она аналогична любой оконной процедуре, но помимо этого она имеет еще один параметр, определяющий адрес требуемой оконной процедуры для вызова (параметр первый).</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Тип первого параметра представляет собой простой указатель }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TFarProc = Pointer; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TFNWndProc = TFarProc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> CallWindowProc(lpPrevWndFunc: TFNWndProc; HWnd: HWND; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam: Integer; LParam: Integer): Integer; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Функция CallWindowProc позволяет нам, по сути, менять поведение окна, ведь мы можем сабклассировать его множество раз с сохранением адресов оконных процедур, а потом вызывать нужные оконные процедуры по надобности. Но на практике эта функция используется для вызова одной оригинальной оконной процедуры окна, которая была до его сабклассирования.</p> <p> </p> <p>После детального рассмотрения основ сабклассинга непосредственно перейдём к его реализации в Delphi.</p> <p> </p> <p>Примечание: суперклассинг, как один из видов сабклассинга, будет описан далее отдельно!</p> <p> </p> <p>Примечание: сабклассинг для окон, принадлежащих чужим процессам, в данной статье не рассматривается! В частности, для начинающих программистов он достаточно сложен.</p> <p> </p> <p>Основная функция сабклассирования окна: SetWindowLong. Вообще, эта функция предназначена для изменения определённого атрибута окна (функция может изменять атрибут как самого окна, так и атрибут его класса). Рассмотрим её параметры.</p> <p> </p> <p>Объявление функции:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> SetWindowLong(HWnd: HWND; nIndex: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">dwNewLong: LongInt): LongInt; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Параметр HWnd определяет окно, с которым будет производиться работа. Параметр nIndex определяет индекс аттрибута, который мы хотим изменить. Пока нас будут интересовать значения GWL_WNDPROC и GWL_USERDATA. Первый индекс определяет, что изменения затронут оконную процедуру окна, второй - то, что будет изменена специальная внутренняя четырёхбайтовая переменная, которой обладает каждое окно. В ней удобно хранить адрес старой оконной процедуры при сабклассинге.</p> <p> </p> <p>Рассмотрим, как по шагам засабклассировать окно.</p> <p>Создаём заготовку новой оконной процедуры;</p> <p>Помещаем в переменную GWL_USERDATA адрес старой оконной процедуры;</p> <p>Изменяем адрес оконной процедуры на новый.</p> <p>Последние два действия можно объединить в одно, так как функция SetWindowLong возвращает предыдущее значение изменённого параметра.</p> <p> </p> <p>Далее я публикую примеры кода, в которых будут рассмотрены способы сабклассирования окон как средствами VCL, так и средствами WinAPI. Все примеры кода хорошо комментированы.</p> <p> </p> <p><span style="font-weight: bold;">Сабклассинг окон на VCL</span></p> <p> </p> <p>В VCL на компонентном уровне сабклассинг реализуется достаточно просто и быстро. Его использование предпочтительней, чем использование сабклассинга на WinAPI (разумеется, при программировании с VCL) - всегда, если возможно, делайте сабклассинг именно через VCL. Для сабклассирования оконного компонента необходимо расширить его функциональность путём добавления обработчика желаемого сообщения, либо через перекрытие оконной процедуры компонента.</p> <p> </p> <p>Ниже приведен пример сабклассирования компонента TEdit таким образом, чтобы последний не реагировал на вставку текста:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Unit</span><span class="f_CodeExample" style="color: #000000;"> UMain;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMainForm = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FormDestroy(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Новый класс с дополнительным методом,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> который вызвается при сообщении WM_PASTE }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TNewEdit = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Class</span><span class="f_CodeExample" style="color: #000000;">(TEdit)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Обработчик сообщения }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> WMCopy(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span><span class="f_CodeExample" style="color: #000000;"> Msg: TWMPaste); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Message</span><span class="f_CodeExample" style="color: #000000;"> WM_PASTE;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MainForm: TMainForm;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Экземпляр нового класса }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit: TNewEdit;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R *.dfm}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ TNewEdit }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> TNewEdit.WMCopy(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span><span class="f_CodeExample" style="color: #000000;"> Msg: TWMPaste);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Игнорируем сообщение }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Msg.Result := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> TMainForm.FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Создание и размещение компонента на форме }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit := TNewEdit.Create(Self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Parent := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Left := </span><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Top := </span><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Width := MainForm.Width - </span><span class="f_CodeExample" style="color: #800000;">23</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Следующий метод работать не будет }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.PasteFromClipboard;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> TMainForm.FormDestroy(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Free;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">. </span></p> </td> </tr> </tbody> </table> </div> <p>Таким образом, чтобы засабклассировать оконный компонент, нужно просто реализовать свой обработчик сообщений. Есть еще один способ, который заключается в модификации оконной процедуры компонента на VCL-уровне:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Unit</span><span class="f_CodeExample" style="color: #000000;"> UMain;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages, SysUtils, Classes,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Graphics, Controls, Forms, Dialogs,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StdCtrls;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMainForm = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> FormDestroy(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TNewEdit = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Class</span><span class="f_CodeExample" style="color: #000000;">(TEdit) </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Перекрытая оконная процедура компонента }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> WndProc(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span><span class="f_CodeExample" style="color: #000000;"> Msg: TMessage); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MainForm: TMainForm;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Экземпляр нового класса }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit: TNewEdit;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R *.dfm}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ TNewEdit }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> TNewEdit.WndProc(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span><span class="f_CodeExample" style="color: #000000;"> Msg: TMessage);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg.Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_PASTE:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Msg.Result := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Звуковой сигнал, оповещающий пользователя о</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> невозможности вставки текста }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBeep(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Выход после обработки необходим, чтобы</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> оригинальная оконная процедура не имела</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> возможности обработать WM_PASTE; в противном</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> случае вставка текста всё равно произойдёт }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Exit;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Не забывайте вызывать унаследованную оконную процедуру }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Inherited</span><span class="f_CodeExample" style="color: #000000;"> WndProc(Msg);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> TMainForm.FormCreate(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Создание и размещение компонента на форме }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit := TNewEdit.Create(Self);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Parent := Self;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Left := </span><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Top := </span><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Width := MainForm.Width - </span><span class="f_CodeExample" style="color: #800000;">23</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Следующий метод работать не будет }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.PasteFromClipboard;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> TMainForm.FormDestroy(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edit.Free;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">. </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Этот способ по функциональности ничем не отличается от первого (только озвучкой).</p> <p> </p> <p>Вот и всё! Думаю, что Вы разобрались в примерах и мы можем переходить к сабклассингу средствами Windows API. Ту часть кода примеров, которые не относятся к теме статьи, я снабдил краткими комментариями.</p> <p> </p> <p><span style="font-weight: bold;">Сабклассинг окон с помощью Windows API</span></p> <p> </p> <p>В следующем примере будет показано, как усовершенствовать кнопку (Button) и поле ввода (Edit). Вот список усовершенствований:</p> <p> </p> <p>1) Для кнопки: создать такую кнопку, которая при нажатии левой кнопки мыши отображала бы текущую дату;</p> <p>2) Для поля ввода: запретить контекстное меню; установить шрифт для текста синего цвета</p> <p> </p> <p>Разберем, как это выглядит в теории. Для создания кнопки, отображающей дату, мы должны получить текущую дату функцией GetLocalTime. В переданной функции структуре будет находиться текущая дата. Нас интересует только текущие час, минута и секунда. Мы преобразуем полученные значения в строковый формат и дополняем нулями слева, если это необходимо. После этого отображаем дату на кнопке, по срабатыванию таймера.</p> <p> </p> <p>Что касается поля ввода, то для запрета контекстного меню необходимо проигнорировать сообщение WM_CONTEXTMENU, после чего осуществить выход из оконной процедуры. Для изменения цвета текста необходимо использовать функция SetTextColor для контекста Edit'а. Этот контекст можно получить, обрабатывая сообщение WM_CTLCOLOREDIT (обратите внимание, что это сообщение посылается родительскому окну поля ввода). Данное сообщение посылается при каждой отрисовке Edit'а, передавая в параметре WParam контекст для рисования. Не следует забывать включить прозрачность фона функцией SetBkMode (хотя для нашего примера эта функция ничего не изменяет, попробуйте использовать другие цвета, чтобы убедиться в её надобности).</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Program</span><span class="f_CodeExample" style="color: #000000;"> SampleProject03;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R *.res}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R WinXP.res}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Messages,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SysUtils;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> InitCommonControls; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">External</span><span class="f_CodeExample" style="color: #ff0000;">'comctl32.dll'</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Const</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Идентификатор таймера }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">BtnTimer = </span><span class="f_CodeExample" style="color: #800000;">450</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Константы с заголовками дочерних окон }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">StaticInfoText = </span><span class="f_CodeExample" style="color: #ff0000;">'Метка без сабклассирования'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">BtnText = </span><span class="f_CodeExample" style="color: #ff0000;">'Кнопка для сабклассирования'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Главное окно }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">HWnd: THandle;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Три дочерних компонента для сабклассирования }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Btn, Edit, InfoStatic: THandle; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Устанавливает для окна AWindow шрифт для контролов по умолчанию }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> SetDefFont(AWindow: THandle);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SendMessage(AWindow, WM_SETFONT, GetStockObject(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">DEFAULT</span><span class="f_CodeExample" style="color: #000000;">_GUI_FONT), </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Косвенно-вызваемая процедура сообщений таймера }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Эта процедура выполняется при каждом срабатывании таймера }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> BtnTimerProc(HWnd: THandle; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">IDEvent, DWTime: Cardinal); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Переменная, куда будет помещено текущее время }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Time: TSystemTime;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Для анализа времени }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Hour, Minute, Second: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Получаем время }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">GetLocalTime(Time);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Инициализируем переменные }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Hour := IntToStr(Time.wHour);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Minute := IntToStr(Time.wMinute);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Second := IntToStr(Time.wSecond);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Добавляем нули при необходимости }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> Length(Hour) = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> Hour := </span><span class="f_CodeExample" style="color: #ff0000;">'0'</span><span class="f_CodeExample" style="color: #000000;"> + Hour;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> Length(Minute) = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> Minute := </span><span class="f_CodeExample" style="color: #ff0000;">'0'</span><span class="f_CodeExample" style="color: #000000;"> + Minute;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> Length(Second) = </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> Second := </span><span class="f_CodeExample" style="color: #ff0000;">'0'</span><span class="f_CodeExample" style="color: #000000;"> + Second;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Отображаем дату }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SetWindowText(HWnd, PChar(Hour + </span><span class="f_CodeExample" style="color: #ff0000;">':'</span><span class="f_CodeExample" style="color: #000000;"> + Minute + </span><span class="f_CodeExample" style="color: #ff0000;">':'</span><span class="f_CodeExample" style="color: #000000;"> + Second));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Модифицированная оконная процедура поля ввода }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> EditWinProc(HWnd: THandle; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam, LParam: Integer): Cardinal; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Запрещаем показ контекстного меню }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_CONTEXTMENU:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBeep(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Exit;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Не забываем вызвать оригинальную оконную процедуру }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := CallWindowProc(Pointer(GetWindowLong(HWnd, GWL_USERDATA)),</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Hwnd, Msg, WParam, LParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Модифицированная оконная процедура кнопки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> BtnWinProc(HWnd: THandle; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam, LParam: Integer): Cardinal; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ При нажатии мыши запускаем таймер, интервал - 10 миллисекунд }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_LBUTTONDOWN: SetTimer(HWnd, BtnTimer, </span><span class="f_CodeExample" style="color: #800000;">10</span><span class="f_CodeExample" style="color: #000000;">, @BtnTimerProc);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ При отпускании мыши уничтожаем таймер }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_LBUTTONUP:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> KillTimer(HWnd, BtnTimer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Восстанавливаем прежний текст }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetWindowText(HWnd, BtnText); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Не забываем вызвать оригинальную оконную процедуру }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := CallWindowProc(Pointer(GetWindowLong(HWnd, GWL_USERDATA)),</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HWnd, Msg, WParam, LParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Оконная процедура главного окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> MainWinProc(HWnd: THandle; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam, LParam: Integer): Cardinal; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Конвертирует сроку PChar в String }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> StrPas(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Const</span><span class="f_CodeExample" style="color: #000000;"> AStr: PChar): </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := AStr;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Здесь будет произведено создание дочерних окон }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_CREATE:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> InfoStatic := CreateWindowEx(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Static'</span><span class="f_CodeExample" style="color: #000000;">, StaticInfoText,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WS_CHILD </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> WS_VISIBLE </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> SS_LEFT,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">270</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">16</span><span class="f_CodeExample" style="color: #000000;">, HWnd, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, HInstance, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetDefFont(InfoStatic);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Edit := CreateWindowEx(WS_EX_CLIENTEDGE, </span><span class="f_CodeExample" style="color: #ff0000;">'Edit'</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WS_CHILD </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> WS_VISIBLE </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> ES_LEFT,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">28</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">300</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">21</span><span class="f_CodeExample" style="color: #000000;">, HWnd, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, HInstance, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetDefFont(Edit);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Выделяем весь текст }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SendMessage(Edit, EM_SETSEL, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, -</span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Далее делаем сабклассинг поля ввода }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetWindowLong(Edit, GWL_USERDATA,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetWindowLong(Edit, GWL_WNDPROC, LongInt(@EditWinProc)));</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Btn := CreateWindowEx(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Button'</span><span class="f_CodeExample" style="color: #000000;">, BtnText, WS_CHILD </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> WS_VISIBLE</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> BS_PUSHBUTTON, </span><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">52</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">300</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">25</span><span class="f_CodeExample" style="color: #000000;">, HWnd, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HInstance, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetDefFont(Btn); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Далее делаем сабклассинг кнопки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetWindowLong(Btn, GWL_USERDATA,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetWindowLong(Btn, GWL_WNDPROC, LongInt(@BtnWinProc)));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_KEYDOWN:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Закрытие окна по нажатию Enter'а }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> WParam = VK_RETURN </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> PostQuitMessage(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Данное сообщение посылается при отрисовке Edit'a;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> вы можете использовать переданный контекст для рисования</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> фона, либо для смены цвета текста; после завершения рисования</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> верните модифицированный контекст как результат сообщения и не</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> забудьте сделать выход из оконной процедуры, так как в противном</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> случае DefWindowProc снова разукрасит Edit в стандартный системный цвет }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_CTLCOLOREDIT:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Устанавливаем прозрачность фона }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetBkMode(WParam, TRANSPARENT);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Устанавливаем цвет шрифта }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetTextColor(WParam, </span><span class="f_CodeExample" style="color: #800000;">$FF0000</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Возвращаем нужный нам контекст }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Result := WParam;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Exit;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_DESTROY:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Выход для освобождения памяти }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PostQuitMessage(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Обработка всех остальных сообщений по умолчанию }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := DefWindowProc(HWnd, Msg, WParam, LParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> WinMain;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Msg: TMsg;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Оконный класс }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx: TWndClassEx;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Подготовка структуры класса окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ZeroMemory(@WndClassEx, SizeOf(WndClassEx));</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{************* Заполнение структуры нужными значениями ******************* }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Размер структуры }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.cbSize := SizeOf(TWndClassEx);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Имя класса окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.lpszClassName := </span><span class="f_CodeExample" style="color: #ff0000;">'SubclassSampleWnd'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Стиль класса, не окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.style := CS_VREDRAW </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> CS_HREDRAW;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Дескриптор программы (для доступа к сегменту данных) }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hInstance := HInstance;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Адрес оконной процедуры }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.lpfnWndProc := @MainWinProc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Иконки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hIcon := LoadIcon(HInstance, MakeIntResource(</span><span class="f_CodeExample" style="color: #ff0000;">'MAINICON'</span><span class="f_CodeExample" style="color: #000000;">));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hIconSm := LoadIcon(HInstance, MakeIntResource(</span><span class="f_CodeExample" style="color: #ff0000;">'MAINICON'</span><span class="f_CodeExample" style="color: #000000;">));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Курсор }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hCursor := LoadCursor(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, IDC_ARROW);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Кисть для заполнения фона }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hbrBackground := COLOR_BTNFACE + </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Меню }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.lpszMenuName := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Регистрация оконного класса в Windows }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> RegisterClassEx(WndClassEx) = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBox(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Невозможно зарегистрировать класс окна'</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Ошибка'</span><span class="f_CodeExample" style="color: #000000;">, MB_OK </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> MB_ICONHAND)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Создание окна по зарегистрированному классу }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HWnd := CreateWindowEx(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, WndClassEx.lpszClassName,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Subclassing Sample by Rrader'</span><span class="f_CodeExample" style="color: #000000;">, WS_OVERLAPPEDWINDOW </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">And</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> WS_BORDER</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">And</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> WS_MAXIMIZEBOX </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">And</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> WS_SIZEBOX,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT), </span><span class="f_CodeExample" style="color: #800000;">320</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">116</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HInstance, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> HWnd = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBox (</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Окно не создалось!'</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Ошибка'</span><span class="f_CodeExample" style="color: #000000;">, MB_OK </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> MB_ICONHAND)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Показ окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ShowWindow(HWnd, SW_SHOWNORMAL);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Обновление окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> UpdateWindow(HWnd); </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Цикл обработки сообщений }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">While</span><span class="f_CodeExample" style="color: #000000;"> GetMessage(Msg, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TranslateMessage(Msg);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DispatchMessage(Msg);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Выход по прерыванию цикла }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Halt(Msg.WParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">InitCommonControls;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Создание окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WinMain;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">. </span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Все примеры очень простые, они должны дать Вам базовое представление о сабклассинге.</p> <p> </p> <p>Теперь можно переходить к суперклассингу.</p> <p> </p> <p><span style="font-weight: bold;">Суперклассинг</span></p> <p> </p> <p>Сабклассинг особенно удобен, когда дело касается изменения одного окна, класс которого не совпадает с другими окнами, подлежащими сабклассированию. А что, если нам нужно засабклассировать сотню Edit'ов? Сабклассинг здесь будет громоздким. Решением этой проблемы является суперклассинг.</p> <p> </p> <p>Суперклассинг (superclassing) - создание и регистрация нового класса окна в системе. После чего этот класс окна готов к использованию.</p> <p> </p> <p>VCL-суперклассинг мы рассматривать не будем. Думаю, Вам понятно, что реализация суперклассинга на VCL - это создание компонентов. При создании оконного компонента в Delphi вы неявно создаёте подобие суперкласса. После этого вы можете использовать хоть сотню таких компонентов (например, создать из них массив). Заметьте, что такой компонент будет, как правило не стандартным, например, кнопка TBitBtn. Чтобы Вам было понятней, почему это суперкласс, можете посмотреть имя класса окна компонента через любой сканер окон (я использовал InqSoft Window Scanner) - это имя будет совпадать с тем именем, которое обозначает имя компонента в Delphi (например, TBitBtn или TLabeledEdit). Из этого мы можем сделать вывод, что суперклассинг прекрасно прижился в Delphi и широко там используется.</p> <p> </p> <p>У каждого потомка класса TWinControl в Delphi есть метод CreateParams. Можете воспользоваться им, чтобы изменить название класса окна.</p> <p> </p> <p>Гораздо более интересен суперклассинг на WinAPI. Необходимо уметь его использовать.</p> <p> </p> <p>Рассмотрим, как по шагам создать суперкласс.</p> <p>Вызываем функцию GetClassInfoEx, чтобы получить информацию о классе окна, который мы будем далее модернизировать. Эта функция заполнит переданную ей запись TWndClassEx параметрами класса;</p> <p>Изменяем всё, что нам нужно в полученной записи. Нужно задать свое имя класса, размер структуры, а также дескриптор HInstance, также нас будет интересовать оконная процедура - мы также изменим её у класса;</p> <p>Регистрируем новый класс при помощи функции RegisterClassEx;</p> <p>По окончании работы программы освобождаем класс функцией UnregisterClass.</p> <p>Далее новый класс можно использовать. В примерах я буду делать простые изменения в классах окон.</p> <p> </p> <p>Давайте рассмотрим функции для суперклассинга более подробно.</p> <p> </p> <p>Суперклассинг начинается с функции GetClassInfoEx.</p> <p> </p> <p>Объявление функции:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> GetClassInfoEx(Instance: Cardinal; Classname: PChar; </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span><span class="f_CodeExample" style="color: #000000;"> WndClass: TWndClassEx): LongBool; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Первый параметр функции - дескриптор приложения, которое создало класс. Если же Вы желаете модифицировать предопределённые класс окон Windows (например, классы 'Button', 'Edit', 'ListBox' и т. п.), то передайте нуль в параметре.</p> <p> </p> <p>Следующий параметр - собственно название интересующего Вас класса. Сюда можно передать атом (см. ниже)</p> <p> </p> <p>В последнем параметре передается структура типа TWndClassEx, в которую в случае успешного вызова функции будет помещена информация о классе.</p> <p> </p> <p>Когда информация о классе получена, можно изменить его (что обязательно к этому, сказано выше).</p> <p> </p> <p>После подготовки класса окна Вы регистрируете его в Windows с помощью функции RegisterClassEx.</p> <p> </p> <p> </p> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> RegisterClassEx(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Const</span><span class="f_CodeExample" style="color: #000000;"> WndClass: TWndClassEx): Word; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p>Функция возвращает атом, который по сути есть числовое уникальное значение. Это будет идентификатор класса окна в системе.</p> <p> </p> <p>По завершению работы приложения желательно уничтожить класс. В противном случае - "утечка памяти".</p> <p>Для этого существует функция UnregisterClass:</p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> UnregisterClass(lpClassName: PChar; hInstance: Cardinal): LongBool; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p>Эта функция уничтожает класс окна из Windows, освобождая память, ранее под него выделенную.</p> <p> </p> <p>Первый параметр функции - имя класса для деинсталляции. Обратите внимание, что эта функция сможет уничтожить только класс, который был зарегистрирован приложением, чей дескриптор передан во втором параметре. Глобальные предопределённые классы (см. выше) Windows (например, класс Edit) не могут быть уничтожены. В первом параметре также разрешается передавать атом-идентификатор класса.</p> <p> </p> <p>Для полного ознакомления с суперклассингом следует обобщить знания о самом классе окна.</p> <p> </p> <p><span style="font-weight: bold;">Класс окна</span></p> <p>Вообще, класс окна - объемная тема. Мы рассмотрим её самые главные особенности.</p> <p> </p> <p>Класс окна (window class) - набор свойств, который используются как шаблон для создания окон. Класс окна всегда можно расширить, изменить. Давайте подробнее разберем атрибуты класса.</p> <p> </p> <p>Первый атрибут - имя класса. Оно позволяет отличать одни классы от других. Классы с одинаковыми именами считаются идентичными. После создания окна по классу это окно может подвергнуться сабклассингу. Сабклассинг не изменяет класс окна. Не делайте имена классов длиннее 64 символов.</p> <p> </p> <p>Второй атрибут - это адрес оконной процедуры для окна. Об оконной процедуре подробно рассказано выше.</p> <p> </p> <p>Третий атрибут - дескриптор приложения (или DLL), которое зарегистрировало класс.</p> <p> </p> <p>Четвёртый - курсор окна при создании.</p> <p> </p> <p>Пятый - дескриптор большой иконки для окна.</p> <p> </p> <p>Шестой - тоже дескриптор иконки, но маленькой. Этого атрибута нет у структуры типа TWndClass (поняли, в чем отличие TWndClass от TWndClassEx?).</p> <p> </p> <p>Седьмой - дескриптор кисти, которой будет зарисована клиентская область окна.</p> <p> </p> <p>Восьмой - дескриптор меню, которое присваивается окну при создании.</p> <p> </p> <p>Девятый - стили класса (см. ниже)</p> <p> </p> <p>Десятый - дополнительная память, выделяемая классу (тип Integer).</p> <p> </p> <p>Одиннадцатый - дополнительная память (Integer), выделяемая под каждое окно класса.</p> <p> </p> <p>Напоследок рассмотрим стили класса. Стили класса - это комбинация значений, которые определяют поведение класса.</p> <p>Вот они:</p> <p> </p> <p>CS_BYTEALIGNCLIENT - выстраивает клиентскую часть окна на границу байта, что позволяет достичь большей производительности при отрисовке;</p> <p> </p> <p>CS_BYTEALIGNWINDOW - то же, что и CS_BYTEALIGNCLIENT, только увеличивает производительность при перемещении окна;</p> <p> </p> <p>CS_CLASSDC - создает контекст устройства, который разделяется между всеми наследниками этого класса - общий контекст для рисования;</p> <p> </p> <p>CS_DBLCLKS - разрешает обработку сообщений при двойном щелчке мыши;</p> <p> </p> <p>CS_GLOBALCLASS - разрешает создание окон с независимыми идентификаторами (HInstance) приложений. Создаётся глобальный класс. Если этот флаг не указан, то значение HInstance при создании окна должно быть таким же как и при регистрации класса RegisterClass(Ex).</p> <p> </p> <p>CS_HREDRAW - перерисовывает окно при его перемещении по горизонтали (и при изменении горизонтальных размеров);</p> <p> </p> <p>CS_VREDRAW - перерисовывает окно при его перемещении по вертикали (и при изменении вертикальных размеров);</p> <p> </p> <p>CS_NOCLOSE - убирает команду "Закрыть" из системного меню окна;</p> <p> </p> <p>CS_OWNDC - создает уникальный контекст устройства для каждого вновь создаваемого окна.</p> <p> </p> <p>На суперклассинг я публикую один пример, в котором на главном окне будет создано 10 "измененных" Edit'ов. Каждый такой Edit при клике на нём мышки уничтожит себя сам.</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Program</span><span class="f_CodeExample" style="color: #000000;"> SampleProject04;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R *.res}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #0000ff;">{$R WinXP.res}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Windows, Messages;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> InitCommonControls; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">External</span><span class="f_CodeExample" style="color: #ff0000;">'comctl32.dll'</span><span class="f_CodeExample" style="color: #000000;">; </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Главное окно }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">HWnd: THandle;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Массив Edit'ов }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Edits: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Array</span><span class="f_CodeExample" style="color: #000000;">[</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">..</span><span class="f_CodeExample" style="color: #800000;">9</span><span class="f_CodeExample" style="color: #000000;">] </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span><span class="f_CodeExample" style="color: #000000;"> THandle;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Сюда будет помещено значение оригинальной оконной процедуры класса Edit }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">OldProc: Pointer;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Устанавливает для окна AWindow шрифт для контролов по умолчанию }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> SetDefFont(AWindow: THandle);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SendMessage(AWindow, WM_SETFONT, GetStockObject(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">DEFAULT</span><span class="f_CodeExample" style="color: #000000;">_GUI_FONT), </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Модифицированная оконная процедура каждого поля ввода }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> EditWinProc(HWnd: THandle; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam, LParam: Integer): Cardinal; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{Уничтожение Edit'а }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_LBUTTONDOWN: DestroyWindow(HWnd);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Вызов оригинальной оконной процедуры }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := CallWindowProc(OldProc,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HWnd, Msg, WParam, LParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Оконная процедура главного окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Function</span><span class="f_CodeExample" style="color: #000000;"> MainWinProc(HWnd: THandle; Msg: Cardinal;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WParam, LParam: Integer): Cardinal; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Stdcall</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TmpEdit: TWndClassEx;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">I: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Case</span><span class="f_CodeExample" style="color: #000000;"> Msg </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Of</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Здесь будет произведено создание дочерних окон }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_CREATE:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Начало суперклассинга }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> GetClassInfoEx(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Edit'</span><span class="f_CodeExample" style="color: #000000;">, TmpEdit) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> Halt;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Запоминаем оконную процедуры для правильной работы окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> OldProc := TmpEdit.lpfnWndProc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Модификация класса }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TmpEdit.cbSize := SizeOf(TWndClassEx);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TmpEdit.lpfnWndProc := @EditWinProc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TmpEdit.lpszClassName := </span><span class="f_CodeExample" style="color: #ff0000;">'Sample04EditWindowClass'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TmpEdit.hInstance := GetModuleHandle(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Регистрация класса }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> RegisterClassEx(TmpEdit) = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> Halt;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Подготовка массива }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FillChar(Edits, SizeOf(Edits), </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">For</span><span class="f_CodeExample" style="color: #000000;"> I := Low(Edits) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">To</span><span class="f_CodeExample" style="color: #000000;"> High(Edits) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Edits[I] := CreateWindowEx(WS_EX_CLIENTEDGE,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Sample04EditWindowClass'</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Sample'</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WS_CHILD </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> WS_VISIBLE </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> ES_LEFT,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #800000;">8</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">28</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">300</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">21</span><span class="f_CodeExample" style="color: #000000;">, HWnd, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, HInstance, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SetDefFont(Edits[I]); </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_KEYDOWN:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Закрытие окна по нажатию Enter'а }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> WParam = VK_RETURN </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span><span class="f_CodeExample" style="color: #000000;"> PostQuitMessage(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> WM_DESTROY:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Уничтожение классов}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> UnregisterClass(</span><span class="f_CodeExample" style="color: #ff0000;">'Sample04EditWindowClass'</span><span class="f_CodeExample" style="color: #000000;">, HInstance);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Выход для освобождения памяти }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> PostQuitMessage(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Обработка всех остальных сообщений по умолчанию }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := DefWindowProc(HWnd, Msg, WParam, LParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Procedure</span><span class="f_CodeExample" style="color: #000000;"> WinMain;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Var</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Msg: TMsg;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Оконный класс }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx: TWndClassEx;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Подготовка структуры класса окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">ZeroMemory(@WndClassEx, SizeOf(WndClassEx));</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{************* Заполнение структуры нужными значениями ******************* }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Размер структуры }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.cbSize := SizeOf(TWndClassEx);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Имя класса окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.lpszClassName := </span><span class="f_CodeExample" style="color: #ff0000;">'SuperclassSampleWnd'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Стиль класса, не окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.style := CS_VREDRAW </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> CS_HREDRAW;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Дескриптор программы (для доступа к сегменту данных) }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hInstance := HInstance;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Адрес оконной процедуры }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.lpfnWndProc := @MainWinProc;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Иконки }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hIcon := LoadIcon(HInstance, MakeIntResource(</span><span class="f_CodeExample" style="color: #ff0000;">'MAINICON'</span><span class="f_CodeExample" style="color: #000000;">));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hIconSm := LoadIcon(HInstance, MakeIntResource(</span><span class="f_CodeExample" style="color: #ff0000;">'MAINICON'</span><span class="f_CodeExample" style="color: #000000;">));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Курсор }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hCursor := LoadCursor(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, IDC_ARROW);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Кисть для заполнения фона }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.hbrBackground := COLOR_BTNFACE + </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Меню }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WndClassEx.lpszMenuName := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Регистрация оконного класса в Windows }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> RegisterClassEx(WndClassEx) = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBox(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Невозможно зарегистрировать класс окна'</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Ошибка'</span><span class="f_CodeExample" style="color: #000000;">, MB_OK </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> MB_ICONHAND)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Создание окна по зарегистрированному классу }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HWnd := CreateWindowEx(</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, WndClassEx.lpszClassName,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Superclassing Sample by Rrader'</span><span class="f_CodeExample" style="color: #000000;">, WS_OVERLAPPEDWINDOW </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">And</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> WS_BORDER</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">And</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> WS_MAXIMIZEBOX </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">And</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Not</span><span class="f_CodeExample" style="color: #000000;"> WS_SIZEBOX,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT), </span><span class="f_CodeExample" style="color: #800000;">320</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">116</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> HInstance, </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">NIL</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">If</span><span class="f_CodeExample" style="color: #000000;"> HWnd = </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Then</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> MessageBox (</span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #ff0000;">'Окно не создалось!'</span><span class="f_CodeExample" style="color: #000000;">,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #ff0000;">'Ошибка'</span><span class="f_CodeExample" style="color: #000000;">, MB_OK </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Or</span><span class="f_CodeExample" style="color: #000000;"> MB_ICONHAND)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Else</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Показ окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ShowWindow(HWnd, SW_SHOWNORMAL);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Обновление окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> UpdateWindow(HWnd); </span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Цикл обработки сообщений }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">While</span><span class="f_CodeExample" style="color: #000000;"> GetMessage(Msg, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">, </span><span class="f_CodeExample" style="color: #800000;">0</span><span class="f_CodeExample" style="color: #000000;">) </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TranslateMessage(Msg);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> DispatchMessage(Msg);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Выход по прерыванию цикла }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Halt(Msg.WParam);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">InitCommonControls;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Создание окна }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">WinMain;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p style="margin: 7px 0px;"><span style="font-family: 'Times New Roman'; color: #000000;">Это</span><span style="font-family: 'Times New Roman'; color: #000000;">было</span><span style="font-family: 'Times New Roman'; color: #000000;">базовое</span><span style="font-family: 'Times New Roman'; color: #000000;">знакомство</span><span style="font-family: 'Times New Roman'; color: #000000;">с</span><span style="font-family: 'Times New Roman'; color: #000000;">сабклассингом</span><span style="font-family: 'Times New Roman'; color: #000000;">и</span><span style="font-family: 'Times New Roman'; color: #000000;">суперклассингом</span><span style="font-family: 'Times New Roman'; color: #000000;">. </span><span style="font-family: 'Times New Roman'; color: #000000;">Надеюсь</span><span style="font-family: 'Times New Roman'; color: #000000;">, </span><span style="font-family: 'Times New Roman'; color: #000000;">материал</span><span style="font-family: 'Times New Roman'; color: #000000;">данной</span><span style="font-family: 'Times New Roman'; color: #000000;">статьи</span><span style="font-family: 'Times New Roman'; color: #000000;">поможет</span><span style="font-family: 'Times New Roman'; color: #000000;">Вам</span><span style="font-family: 'Times New Roman'; color: #000000;">при</span><span style="font-family: 'Times New Roman'; color: #000000;">программировании</span><span style="font-family: 'Times New Roman'; color: #000000;">!</span></p> <p style="margin: 7px 0px;"><br />Автор:Rrader</p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="color: #000000; font-weight: bold;">Взято с Vingrad</span></p> Сущность ООП 2013-08-15T20:37:40+07:00 2013-08-15T20:37:40+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/sushchnost-oop/sushchnost-oop.html Super User toto44@inbox.ru <p>Одна из вещей, которую вы могли бы захотеть реализовать - пользовательский интерфейс, предоставляющий доступ к файлу персональных данных. ООП предоставляет вам безусловно лучшие механизмы для его хранения, создания, и эксплуатации, делая эти вещи понятными и легкими для понимания.</p> <p> </p> <p>Вот как вы можете сделать это. Забудьте об диалоговом окне хотя бы на минуту и сконцентрируйтесь на создании файла персональных данных. Скажем, вы редактируете запись человека со следующими полями: First Name, Last Name, Age и Active. Скажем, вам нужны следующие операции при работе с записью: добавление, изменение, удаление и построение списка.</p> <p> </p> <p>Вам необходимо создать невизуальный объект доступа к файлу, инкапсулирующий вышеупомянутую функциональность. Это может выглядеть приблизительно так:</p> <p> </p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PPersonRecord = ^TPersonRecord;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TPersonRecord = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">record</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FirstName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">LastName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Age: Byte;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Active: Boolean;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TPersonFile = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TObject)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FFileName: TFileName;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FFile: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">file</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TPersonRec;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AFileName: TFileName);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> LoadRecord(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SaveRecord(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Add(NewPersonRecord: TPersonRecord);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Change(ChangedPersonRecord: TPersonRecord; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Delete(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> List(AStringList: TStringList);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Person[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer]: TPersonRecord </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> LoadRecord </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SaveRecord;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.Create(AFileName: TFileName);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">AssignFile(FFile, AFileName);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Reset(FFile, SizeOf(TPersonRec));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">New(FPersonRecord);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">CloseFile(FFile);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Dispose(FPersonRecord);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.LoadRecord(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer): PPersonRec;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ позиция файла в точке коррекции для чтения записи }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ ... }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.SaveRecord(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ позиция файла в точке коррекции для записи записи }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ ... }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.Add(NewPersonRecord: TPersonRecord);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ файл позиционируется в конец для записи записи }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ ... }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.Change(ChangedPersonRecord: TPersonRecord; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ именение TStatus ??? }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ позиция файла в точке коррекции для записи записи }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ ... }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.Delete(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ изменение TStatus ??? }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ позиция файла в точке коррекции для записи записи }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ ... }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.List(AStringList: TStringList);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ в цикле обходим все записи, пополняя AStringList??? }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p>OK, я надеюсь вы поняли мою идею. Вышеприведенный код взят мною из головы и, вероятно, несвободен от ошибок, поскольку я не до конца понял как работает тип file (для доступа к бинарному файлу я использую TFileStream), но идея следующая: инкапсуляция ваших функций работы с файлом в невизуальный объект как показано выше.</p> <p> </p> <p>Теперь вы можете начать думать о ваших диалогах. Вам необходимо создать диалог, у которого в обработчике события OnCreate была бы примерно такая строчка кода:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyPersonFile := TPersonFile.Create(</span><span class="f_CodeExample" style="color: #ff0000;">'c:\person.dat'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p>Естественно, вам необходим модуль, в котором вы объявляете TPersonFile в секции используемых модулей, а в классе формы необходимо поле с именем MyPersonFile. Вам также необходимо помнить об освобождении MyPersonFile в методе формы onClose. Я думаю вы сообразите как разместить в вашей программе необходимые элементы управления (менюшки, кнопки и прочие причиндалы), хотя бы для того, чтобы с помощью них можно было бы открыть файл.</p> <p> </p> <p>Теперь вы должны разместить на форме компоненты типа Edit, CheckBox и др., отображающие и позволяющие редактировать поля записи через свойство Record. Убедитесь в том, что вы поддерживаете должный порядок, и освобождаете объект (запись) после его создания и использования. Конечно, эту работу красивой не назовешь, но от нее вас никто еще не освобождал. Вот красота ООП:</p> <p> </p> <p>*После создания комбинации объект / форма диалога вся работа уже сделана.*</p> <p> </p> <p>Вот другая хорошая вещь:</p> <p> </p> <p>*Если вы изменяете ваш пользовательский интерфейс (например, при отказе от кучи диалогов или от использования Delphi (молчу-молчу)), ООП предоставляет вам простой и легкий в использовании способ переноса логики приложения, инкапсулированной в объекте TPersonFile.</p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p>https://delphiworld.narod</p> <p>DelphiWorld 6.0</p> <p>Одна из вещей, которую вы могли бы захотеть реализовать - пользовательский интерфейс, предоставляющий доступ к файлу персональных данных. ООП предоставляет вам безусловно лучшие механизмы для его хранения, создания, и эксплуатации, делая эти вещи понятными и легкими для понимания.</p> <p> </p> <p>Вот как вы можете сделать это. Забудьте об диалоговом окне хотя бы на минуту и сконцентрируйтесь на создании файла персональных данных. Скажем, вы редактируете запись человека со следующими полями: First Name, Last Name, Age и Active. Скажем, вам нужны следующие операции при работе с записью: добавление, изменение, удаление и построение списка.</p> <p> </p> <p>Вам необходимо создать невизуальный объект доступа к файлу, инкапсулирующий вышеупомянутую функциональность. Это может выглядеть приблизительно так:</p> <p> </p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">PPersonRecord = ^TPersonRecord;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TPersonRecord = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">record</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FirstName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">LastName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Age: Byte;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Active: Boolean;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TPersonFile = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TObject)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FFileName: TFileName;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FFile: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">file</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">of</span><span class="f_CodeExample" style="color: #000000;"> TPersonRec;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AFileName: TFileName);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> Destroy; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> LoadRecord(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SaveRecord(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Add(NewPersonRecord: TPersonRecord);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Change(ChangedPersonRecord: TPersonRecord; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Delete(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> List(AStringList: TStringList);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Person[</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer]: TPersonRecord </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> LoadRecord </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> SaveRecord;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.Create(AFileName: TFileName);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;">.Create;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">AssignFile(FFile, AFileName);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Reset(FFile, SizeOf(TPersonRec));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">New(FPersonRecord);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">destructor</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">CloseFile(FFile);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Dispose(FPersonRecord);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Destroy;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.LoadRecord(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer): PPersonRec;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ позиция файла в точке коррекции для чтения записи }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ ... }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.SaveRecord(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ позиция файла в точке коррекции для записи записи }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ ... }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.Add(NewPersonRecord: TPersonRecord);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ файл позиционируется в конец для записи записи }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ ... }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.Change(ChangedPersonRecord: TPersonRecord; </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">:</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ именение TStatus ??? }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ позиция файла в точке коррекции для записи записи }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ ... }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.Delete(</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Index</span><span class="f_CodeExample" style="color: #000000;">: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ изменение TStatus ??? }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ позиция файла в точке коррекции для записи записи }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ ... }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TPersonFile.List(AStringList: TStringList);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ в цикле обходим все записи, пополняя AStringList??? }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p>OK, я надеюсь вы поняли мою идею. Вышеприведенный код взят мною из головы и, вероятно, несвободен от ошибок, поскольку я не до конца понял как работает тип file (для доступа к бинарному файлу я использую TFileStream), но идея следующая: инкапсуляция ваших функций работы с файлом в невизуальный объект как показано выше.</p> <p> </p> <p>Теперь вы можете начать думать о ваших диалогах. Вам необходимо создать диалог, у которого в обработчике события OnCreate была бы примерно такая строчка кода:</p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">MyPersonFile := TPersonFile.Create(</span><span class="f_CodeExample" style="color: #ff0000;">'c:\person.dat'</span><span class="f_CodeExample" style="color: #000000;">);</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p>Естественно, вам необходим модуль, в котором вы объявляете TPersonFile в секции используемых модулей, а в классе формы необходимо поле с именем MyPersonFile. Вам также необходимо помнить об освобождении MyPersonFile в методе формы onClose. Я думаю вы сообразите как разместить в вашей программе необходимые элементы управления (менюшки, кнопки и прочие причиндалы), хотя бы для того, чтобы с помощью них можно было бы открыть файл.</p> <p> </p> <p>Теперь вы должны разместить на форме компоненты типа Edit, CheckBox и др., отображающие и позволяющие редактировать поля записи через свойство Record. Убедитесь в том, что вы поддерживаете должный порядок, и освобождаете объект (запись) после его создания и использования. Конечно, эту работу красивой не назовешь, но от нее вас никто еще не освобождал. Вот красота ООП:</p> <p> </p> <p>*После создания комбинации объект / форма диалога вся работа уже сделана.*</p> <p> </p> <p>Вот другая хорошая вещь:</p> <p> </p> <p>*Если вы изменяете ваш пользовательский интерфейс (например, при отказе от кучи диалогов или от использования Delphi (молчу-молчу)), ООП предоставляет вам простой и легкий в использовании способ переноса логики приложения, инкапсулированной в объекте TPersonFile.</p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p>https://delphiworld.narod</p> <p>DelphiWorld 6.0</p> Демонстрация DefineProperties 2013-08-19T16:43:08+07:00 2013-08-19T16:43:08+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/svojstva/demonstratsiya-defineproperties.html Super User toto44@inbox.ru <p><span style="color: #000000;">Хорошо, создайте на основе опубликованного ниже кода модуль PropDemo.pas и добавьте новый компонент в палитру компонентов. Расположите его на форме и сохраните ее. Затем посмотрите файл DFM каким-либо шестнадцатиричным редактором и проверьте наличие определенных свойств по их именованным тэгам. Вы можете также попробовать закрыть форму и модуль, а затем открыть его с помощью пункта меню File | Open file..., изменив тип файла в выпадающем списке на *.DFM.</span></p> <p> </p> <p><span style="color: #000000;">Mike Scott</span></p> <p><span style="color: #000000;">Mobius Ltd.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> PropDemo;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Демонстрация DefineProperties.Mike Scott, CIS 100140,2420. }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Forms, Dialogs;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDemoProps = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TComponent)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FStringThing: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FThing: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">record</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> i, j, k: integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> x, y: real;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ch: char;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ReadStringThing(Reader: TReader);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> WriteStringThing(Writer: TWriter);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ReadThing(Stream: TStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> WriteThing(Stream: TStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> DefineProperties(Filer: TFiler); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner: TComponent); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TDemoProps.Create(AOwner: TComponent);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ создайте любые данные, чтобы было что передать в поток}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FStringThing := </span><span class="f_CodeExample" style="color: #ff0000;">'Всем привет!'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> FThing </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> i := </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> j := </span><span class="f_CodeExample" style="color: #800000;">2</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> k := </span><span class="f_CodeExample" style="color: #800000;">3</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> x := PI;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> y := </span><span class="f_CodeExample" style="color: #800000;">180</span><span class="f_CodeExample" style="color: #000000;"> / PI;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ch := </span><span class="f_CodeExample" style="color: #ff0000;">'?'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDemoProps.ReadStringThing(Reader: TReader);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FStringThing := Reader.ReadString;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDemoProps.WriteStringThing(Writer: TWriter);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Writer.WriteString(FStringThing);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDemoProps.ReadThing(Stream: TStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream.ReadBuffer(FThing, sizeof(FThing));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDemoProps.WriteThing(Stream: TStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream.WriteBuffer(FThing, sizeof(FThing));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDemoProps.DefineProperties(Filer: TFiler);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> DefineProperties(Filer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Filer.DefineProperty(</span><span class="f_CodeExample" style="color: #ff0000;">'StringThing'</span><span class="f_CodeExample" style="color: #000000;">, ReadStringThing, WriteStringThing,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FStringThing &lt;&gt; </span><span class="f_CodeExample" style="color: #ff0000;">''</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Filer.DefineBinaryProperty(</span><span class="f_CodeExample" style="color: #ff0000;">'Thing'</span><span class="f_CodeExample" style="color: #000000;">, ReadThing, WriteThing, true);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Samples'</span><span class="f_CodeExample" style="color: #000000;">, [TDemoProps]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от</span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> <p><span style="color: #000000;">Хорошо, создайте на основе опубликованного ниже кода модуль PropDemo.pas и добавьте новый компонент в палитру компонентов. Расположите его на форме и сохраните ее. Затем посмотрите файл DFM каким-либо шестнадцатиричным редактором и проверьте наличие определенных свойств по их именованным тэгам. Вы можете также попробовать закрыть форму и модуль, а затем открыть его с помощью пункта меню File | Open file..., изменив тип файла в выпадающем списке на *.DFM.</span></p> <p> </p> <p><span style="color: #000000;">Mike Scott</span></p> <p><span style="color: #000000;">Mobius Ltd.</span></p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">unit</span><span class="f_CodeExample" style="color: #000000;"> PropDemo;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Демонстрация DefineProperties.Mike Scott, CIS 100140,2420. }</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">interface</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">uses</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Forms, Dialogs;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TDemoProps = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TComponent)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Private declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FStringThing: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FThing: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">record</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> i, j, k: integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> x, y: real;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ch: char;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ReadStringThing(Reader: TReader);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> WriteStringThing(Writer: TWriter);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> ReadThing(Stream: TStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> WriteThing(Stream: TStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Protected declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> DefineProperties(Filer: TFiler); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Public declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner: TComponent); </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">override</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">published</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ Published declarations }</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">implementation</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">constructor</span><span class="f_CodeExample" style="color: #000000;"> TDemoProps.Create(AOwner: TComponent);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Create(AOwner);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ создайте любые данные, чтобы было что передать в поток}</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FStringThing := </span><span class="f_CodeExample" style="color: #ff0000;">'Всем привет!'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">with</span><span class="f_CodeExample" style="color: #000000;"> FThing </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">do</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> i := </span><span class="f_CodeExample" style="color: #800000;">1</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> j := </span><span class="f_CodeExample" style="color: #800000;">2</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> k := </span><span class="f_CodeExample" style="color: #800000;">3</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> x := PI;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> y := </span><span class="f_CodeExample" style="color: #800000;">180</span><span class="f_CodeExample" style="color: #000000;"> / PI;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ch := </span><span class="f_CodeExample" style="color: #ff0000;">'?'</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDemoProps.ReadStringThing(Reader: TReader);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">FStringThing := Reader.ReadString;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDemoProps.WriteStringThing(Writer: TWriter);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Writer.WriteString(FStringThing);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDemoProps.ReadThing(Stream: TStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream.ReadBuffer(FThing, sizeof(FThing));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDemoProps.WriteThing(Stream: TStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Stream.WriteBuffer(FThing, sizeof(FThing));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TDemoProps.DefineProperties(Filer: TFiler);</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> DefineProperties(Filer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Filer.DefineProperty(</span><span class="f_CodeExample" style="color: #ff0000;">'StringThing'</span><span class="f_CodeExample" style="color: #000000;">, ReadStringThing, WriteStringThing,</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FStringThing &lt;&gt; </span><span class="f_CodeExample" style="color: #ff0000;">''</span><span class="f_CodeExample" style="color: #000000;">);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Filer.DefineBinaryProperty(</span><span class="f_CodeExample" style="color: #ff0000;">'Thing'</span><span class="f_CodeExample" style="color: #000000;">, ReadThing, WriteThing, true);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Register</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">RegisterComponents(</span><span class="f_CodeExample" style="color: #ff0000;">'Samples'</span><span class="f_CodeExample" style="color: #000000;">, [TDemoProps]);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">.</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p> </p> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из Советов по Delphi от</span><span style="color: #0000ff; font-size: 10pt; font-weight: bold; text-decoration: underline;">Валентина Озерова</span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Сборник Kuliba</span></p> Использование записей для хранения информации полей 2013-08-19T16:44:21+07:00 2013-08-19T16:44:21+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/svojstva/ispolzovanie-zapisej-dlya-khraneniya-informatsii-polej.html Super User toto44@inbox.ru <p> </p> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td> </td> </tr> </tbody> </table> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> You sometimes wish to store multiple information in a given class like </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> in the example: alltogether when it belongs together. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> Thus accessing this information from out of the class can be achieved </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> using property declaration. Its a good way to "clean your code" and </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> make it as "logic" as possible. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> You also may have to store or load information from your class using </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> file or stream technology. This can be done at once for the recorded </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> information from within the given class. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TPersonRecord = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Record</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FirstName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> LastName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> BirthDate: TDate;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TForm4 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Button1: TButton;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> fActualUser: TPersonRecord;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SaveActualUser(S: TFileStream); </span><span class="f_CodeExample" style="color: #000080;">// it's an example </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> LoadActualUser(S: TFileStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> FirstName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> fActualUser.FirstName</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> fActualUser.FirstName;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> LastName : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> fActualUser.LastName</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> fActualUser.LastName;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> BirthDate: TDate </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> fActualUser.BirthDate</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> fActualUser.BirthDate;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm4.SaveActualUser(S: TFileStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// All that stuff at once in your Stream </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">S.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Write</span><span class="f_CodeExample" style="color: #000000;">(fActualUser, SizeOf(fActualUser))</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm4.LoadActualUser(S: TFileStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// All that stuff at once back in your class </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">S.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Read</span><span class="f_CodeExample" style="color: #000000;">(fActualUser, SizeOf(fActualUser));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p>https://delphiworld.narod</p> <p>DelphiWorld 6.0</p> <p> </p> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td> </td> </tr> </tbody> </table> <div style="text-align: left; text-indent: 0px; margin: 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">{ </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> You sometimes wish to store multiple information in a given class like </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> in the example: alltogether when it belongs together. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> Thus accessing this information from out of the class can be achieved </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> using property declaration. Its a good way to "clean your code" and </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> make it as "logic" as possible. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> You also may have to store or load information from your class using </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> file or stream technology. This can be done at once for the recorded </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;"> information from within the given class. </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">}</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">type</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TPersonRecord = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Record</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> FirstName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> LastName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">String</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> BirthDate: TDate;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">End</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> TForm4 = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TForm)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> Button1: TButton;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> Button1Click(Sender: TObject);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">private</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> fActualUser: TPersonRecord;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SaveActualUser(S: TFileStream); </span><span class="f_CodeExample" style="color: #000080;">// it's an example </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> LoadActualUser(S: TFileStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;"> ...</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> FirstName: </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> fActualUser.FirstName</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> fActualUser.FirstName;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> LastName : </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">string</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> fActualUser.LastName</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> fActualUser.LastName;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> BirthDate: TDate </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> fActualUser.BirthDate</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> fActualUser.BirthDate;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm4.SaveActualUser(S: TFileStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// All that stuff at once in your Stream </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">S.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Write</span><span class="f_CodeExample" style="color: #000000;">(fActualUser, SizeOf(fActualUser))</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TForm4.LoadActualUser(S: TFileStream);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000080;">// All that stuff at once back in your class </span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">S.</span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">Read</span><span class="f_CodeExample" style="color: #000000;">(fActualUser, SizeOf(fActualUser));</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p> </p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p>https://delphiworld.narod</p> <p>DelphiWorld 6.0</p> Как скрыть свойства объекта? 2013-08-19T16:39:50+07:00 2013-08-19T16:39:50+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/svojstva/kak-skryt-svojstva-ob-ekta.html Super User toto44@inbox.ru <p><span style="color: #000000;">В иерархии VCL в большинстве случаев существует уровень объектов-"предшественников" (TCustomXXXX), в которых многие свойства скрыты. Для унаследованных от таких "предшественников" объектов можно "открывать" на выбор те или иные свойства. А как можно скрыть свойства, которые объявлены в published-области от Object Inspector'а, но при этом оставить возможность доступа во время работы программы? Решение состоит в объявлении свойства "по новой" в public-области. В примере скрытым будет у объекта TMyControl свойство Height. </span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyControl = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TWinControl)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetHeight(Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetHeight: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Height: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetHeight </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetHeight;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMyControl.SetHeight(Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Height := Value;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TMyControl.GetHeight;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Height;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> <p><span style="color: #000000;">В иерархии VCL в большинстве случаев существует уровень объектов-"предшественников" (TCustomXXXX), в которых многие свойства скрыты. Для унаследованных от таких "предшественников" объектов можно "открывать" на выбор те или иные свойства. А как можно скрыть свойства, которые объявлены в published-области от Object Inspector'а, но при этом оставить возможность доступа во время работы программы? Решение состоит в объявлении свойства "по новой" в public-области. В примере скрытым будет у объекта TMyControl свойство Height. </span></p> <p> </p> <div style="text-align: justify; text-indent: 0px; margin: 7px 0px; padding: 0px;"> <table style="border-bottom: #c0c0c0 1px solid; border-left: #000000 1px solid; background-color: #ffffc4; border-spacing: 0px; border-top: #000000 1px solid; border-right: #c0c0c0 1px solid;" border="1" cellspacing="0" cellpadding="5" bgcolor="#ffffc4"> <tbody> <tr align="left" valign="top"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p style="text-align: justify;"><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Code:</span></p> </td> </tr> <tr align="left"> <td style="border-bottom: #000000 1px solid; border-left: #c0c0c0 1px solid; border-top: #c0c0c0 1px solid; border-right: #000000 1px solid;"> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">TMyControl = </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">class</span><span class="f_CodeExample" style="color: #000000;">(TWinControl)</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">protected</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> SetHeight(Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> GetHeight: Integer;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">public</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">property</span><span class="f_CodeExample" style="color: #000000;"> Height: Integer </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">read</span><span class="f_CodeExample" style="color: #000000;"> GetHeight </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">write</span><span class="f_CodeExample" style="color: #000000;"> SetHeight;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">procedure</span><span class="f_CodeExample" style="color: #000000;"> TMyControl.SetHeight(Value: Integer);</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Height := Value;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> <p class="p_CodeExample"> </p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">function</span><span class="f_CodeExample" style="color: #000000;"> TMyControl.GetHeight;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">begin</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #000000;">Result := </span><span class="f_CodeExample" style="color: #008000; font-weight: bold;">inherited</span><span class="f_CodeExample" style="color: #000000;"> Height;</span></p> <p class="p_CodeExample"><span class="f_CodeExample" style="color: #008000; font-weight: bold;">end</span><span class="f_CodeExample" style="color: #000000;">;</span></p> </td> </tr> </tbody> </table> </div> Можно ли динамически изменять свойство owner компонента во время выполнения программы? 2013-08-19T16:42:05+07:00 2013-08-19T16:42:05+07:00 https://delphi-hlp.ru/index.php/ob-ektnoe-orientirovanie/svojstva/mozhno-li-dinamicheski-izmenyat-svojstvo-owner-komponenta-vo-vremya-vypolneniya-programmy.html Super User toto44@inbox.ru <p><span style="color: #000000;">Вы можете менять свойство "owner" и после создания компонента с помощью методов InsertComponent() и RemoveComponent(). </span></p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">DELPHI VCL FAQ</span><span style="font-style: italic; color: #000000;">Перевод с английского</span></p> <p><span style="color: #000000;">Подборку, перевод и адаптацию материала подготовил </span><span style="font-family: 'Times New Roman'; color: #0000ff; font-weight: bold; text-decoration: underline;">Aziz</span><span style="color: #000000;">(JINX)</span></p> <p><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">специально для </span>Королевства Дельфи</p> <p><span style="color: #000000;">Вы можете менять свойство "owner" и после создания компонента с помощью методов InsertComponent() и RemoveComponent(). </span></p> <p style="text-align: right;"><span style="font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', 'Arial'; color: #ff6600; font-size: 8pt; font-weight: bold;"> </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">Взято из </span></p> <p><span style="font-family: 'Times New Roman'; color: #000000; font-weight: bold;">DELPHI VCL FAQ</span><span style="font-style: italic; color: #000000;">Перевод с английского</span></p> <p><span style="color: #000000;">Подборку, перевод и адаптацию материала подготовил </span><span style="font-family: 'Times New Roman'; color: #0000ff; font-weight: bold; text-decoration: underline;">Aziz</span><span style="color: #000000;">(JINX)</span></p> <p><span style="font-style: italic; font-family: 'Times New Roman'; color: #000000;">специально для </span>Королевства Дельфи</p>