Программирование - это просто
Advertisement
Главная arrow Уроки Delphi arrow Пишем на Delphi с применением COM-технологий arrow Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).
18.04.2024 г.
Главное меню
Главная
Интернет магазин
Программные продукты
Биржевые роботы
Искусственный интеллект
Математика и информатика
1С:Предприятие
Уроки C#
Уроки Delphi
Уроки программирования
Web-программирование
Дизайн и графика
Компьютер для блондинок
Исходники
Статьи
Платный раздел
Рассказы про компьютеры
Хитрости и секреты
Системный подход
Размышления
Наука для чайников
Друзья сайта
Excel-это не сложно
Все о финансах
.
Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown). Печать E-mail
Автор megabax   
04.10.2011 г.
New Page 1

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

Исходники к уроку можно скачать здесь.

Сегодня мы разберем пример практического применения интерфеса. Нет, это еще пока не COM, до него мы рано или поздно доберемся. Но сегодня мы, наконец то, продемонстрируем, как извлечь из интерфесов реальную пользу. И так, давайте напишем программу, демонстрирующую алгоритм сортировки. Поскольку нам может потребоваться сортировать совершенно разные объекты: строки, числа, да и вообще Бог знает что, объявим специальный сортировочный интерфейс, который будет содержать метод, предназначенный для сравнения объектов:

     ICompare=interface

        ['{6D7DEC57-1572-49A0-9287-3DE3EA4496BA}']

        function CompareWith(ACompare:ICompare; ASortBy:integer):Integer;

     end;

И реализуем простой алгоритм сортировки с применением этого интерфейса (подробнее об алгоритмах сортировки см. здесь):

procedure SortArray(var A:Array of IUnknown; ASortBy:integer);

var I,J:integer;

    temp:IUnknown;

begin

  for i:=Low(A) To High(A)-1 do

     for J:=I To High(A) do

       if (A[J] as ICompare).CompareWith(A[I] as ICompare, ASortBy)<0 then

         begin

           temp:=A[I];

           A[I]:=A[J];

           A[J]:=temp;

         end;

end;

Как вы заметили, алгоритм получился универсальный - мы можем использовать его для любых объектов, поддерживающих интерфейс ICompare. Создавая новый класс, мы просто реализуем у него метод CompareWith, отвечающий за сравнение объектов.

А теперь переходим к самим классам, которые мы будем сортировать. Для начала объявим класса TEmployee (информация о сотруднике):

     TEmployeeOrder=(eoName, eoSalary); //Перечисление порядковых номеров полей

 

     //Интерфейс доступа к полям сотрудника

     IEmployee=interface

         ['{D967D86A-D5D8-41FF-94DC-394B6D6D4659}']

         function GetName:string;

         function GetSalary:double;

     end;

 

     //Класс для хранения информации о сотруднике

     TEmployee=class(TInterfacedObject, IEmployee, ICompare)

     private

        FName:String;

        FSalary:double;

     public

        constructor Create(AName:string; ASalary:Double);

        function CompareWith(ACompare:ICompare; ASortBy:integer):integer;

        function GetName:string;

        function GetSalary:double;

     end;

Как видим, данный класс реализует два интерфейса ICompare - для сортировки и IEmployee - для доступа к полям информации о сотруднике. Теперь реализуем данный класс:

function TEmployee.CompareWith(ACompare:ICompare; ASortBy:Integer):integer;

var emp:IEmployee;

begin

  Result:=0;

  Emp:=ACompare as IEmployee;

  case ASortBy of

     Ord(eoName):Result:=CompareStr(FName, Emp.GetName);

     Ord(eoSalary):

        if FSalary<Emp.GetSalary then

           Result:=-1

        else if FSalary>Emp.GetSalary then

           Result:=1;

        else

           Result:=0;

        end;

end;

 

Constructor TEmployee.Create(AName:string; ASalary:Double);

begin

  Inherited Create;

  FName:=AName;

  FSalary:=ASalary;

end;

 

function TEmployee.GetName:string;

begin

  Result:=FName;

end;

 

function TEmployee.GetSalary:Double;

begin

 Result:=FSalary;

end;

Как видим, алгоритм сравнения довольно прост - в зависимости от параметра ASortBy мы сравниваем одно из полей информации о сотруднике.

Теперь, аналогичным образом объявим класс TInventoryItem для хранения информации о номенклатурных единицах производственного инвентаря:

    TInventoryItemOrder=(iioPartNumber, iioDescription, iioInStock);

 

    IInventoryItem=interface

        ['{496E2A60-A9BC-4214-9040-6E8CA926AC60}']

        function GetPartNumber: string;

        function GetDescription:string;

        function GetInStock:integer;

     end;

 

    TInventoryItem=class(TInterfacedObject, IInventoryItem, ICompare)

    private

        FPartNumber:string;

        FDescription:string;

        FInStock:integer;

    public

        constructor Create(APartNumber:string; ADescription:string; AinStock:integer);

        function CompareWith(ACompare:ICompare; ASortBy:integer):integer;

        function GetPartNumber:string;

        function GetDescription:string;

        function GetInStock:Integer;

    end;

И реализуем его:

function TInventoryItem.CompareWith(ACompare: ICompare; ASortBy:integer):integer;

var Inv:IInventoryItem; r:double;

begin

   Result:=0;

   Inv:=ACompare As IInventoryItem;

   case ASortBy of

      ord(iioPartNumber):Result:=CompareStr(FPartNumber,Inv.GetPartNumber);

      ord(iioDescription):Result:=CompareStr(FDescription,Inv.GetDescription);

      ord(iioInStock):Result:=FInStock-Inv.GetInStock;

   end;

end;

 

constructor TInventoryItem.Create(APartNumber:string; ADescription:string; AInStock:integer);

begin

   inherited Create;

   FPartNumber:=APartNumber;

   FDescription:=ADescription;

   FInStock:=AInStock;

end;

 

function TInventoryItem.GetPartNumber:string;

begin

  Result:=FPartNumber;

end;

 

function TInventoryItem.GetDescription:string;

begin

  Result:=FDescription;

end;

 

function TInventoryItem.GetInStock:integer;

begin

  Result:=FInStock;

end;

Теперь переходим к созданию тестового примера. И так, помещаем на форму TPageControl (закладка Win 32):

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

Создаем у него две страницы: "Bubble Sort" и "List View". На первую страницу кладем TListBox (закладка Standard):

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

А так же пару кнопок TButton:

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

В итоге первая страница формы  у нас должна выглядеть вот так:

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

На вторую закладку мы кладем TListView (закладка Win 32):

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

И редактируем у него колонки, как показано на скриншоте:

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

Что бы отредактировать колонки, щелкаем по объект правой кнопкой мыши и во всплывающем меню выбираем Columns Editor:

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

И в нем мы уже редактируем колонки:

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

Теперь возвращаемся к программированию. Для начала в классе формы объявим кое какие поля и методы в секции private:

  TSortDemoForm = class(TForm)

    PageControl1: TPageControl;

    TabSheet1: TTabSheet;

    TabSheet2: TTabSheet;

    btnByName: TButton;

    btnBySalary: TButton;

    lbEmployees: TListBox;

    lvInventory: TListView;

    procedure FormCreate(Sender: TObject);

    procedure btnByNameClick(Sender: TObject);

    procedure btnBySalaryClick(Sender: TObject);

    procedure lvInventoryColumnClick(Sender: TObject; Column: TListColumn);

    procedure lvInventoryCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer);

  private

    { Private declarations }

    FEmpArray:Array[1..MAX_EMPLOYEES] of IUnknown;

    FInvArray:Array[1..MAX_INVENTORYITEM] of IUnknown;

    procedure LoadListBox;

    procedure CreateInventoryItem(Index:integer; APartNo, ADescription:string;  AInStock:integer);

  public

    { Public declarations }

  end;

 

Теперь пишем обработчик нажатия кнопок сортировки:

procedure TSortDemoForm.btnByNameClick(Sender: TObject);

begin

  SortArray(FEmpArray, Ord(eoName));

  LoadListBox;

end;

 

procedure TSortDemoForm.btnBySalaryClick(Sender: TObject);

begin

  SortArray(FEmpArray, Ord(eoSalary));

  LoadListBox;

end;

Теперь нам нужно реализовать процедуру отображения массива сотрудников в списке значений:

procedure TSortDemoForm.LoadListBox;

var Index:integer;

    emp:IEmployee;

begin

  lbEmployees.Items.Clear;

  for Index:=1 to MAX_EMPLOYEES do

     begin

       Emp:=FEmpArray[index] As IEmployee;

       lbEmployees.Items.Add(Emp.GetName+' '+FloatToStrF(Emp.GetSalary,ffCurrency,8,2))

     end;

end;

Еще у нас на второй закладке есть таблица - компонент TListView. Во первых, что бы при нажатии на заголовок столбца происходила сортировка, нам нужно реализовать у этого компонента событие OnColumnClick:

procedure TSortDemoForm.lvInventoryColumnClick(Sender: TObject;  Column: TListColumn);

begin

  lvInventory.CustomSort(nil,Column.Index);

end;

Для реализации сортировки программируем событие OnCompare

procedure TSortDemoForm.lvInventoryCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer);

var I1,I2:IUnknown;

begin

  I1:=IUnknown(Item1.Data);

  I2:=IUnknown(Item2.Data);

  Compare:=(I1 AS ICompare).CompareWith((I2 AS ICompare), Data);

end;

И, наконец, последний штрих, событие формы OnCreate,  в нем мы заполняем массив сотрудников и строки компонента TListView:

procedure TSortDemoForm.FormCreate(Sender: TObject);

begin

  FEmpArray[1]:=TEmployee.Create('Иванов',10000);

  FEmpArray[2]:=TEmployee.Create('Петров',9000);

  FEmpArray[3]:=TEmployee.Create('Сидоров',12500);

  FEmpArray[4]:=TEmployee.Create('Воробьев',8500);

  FEmpArray[5]:=TEmployee.Create('Лебедев',21000);

  LoadListBox();

 

  CreateInventoryItem(1,'P5409','Widget',35);

  CreateInventoryItem(2,'X1234','Gadget',4);

  CreateInventoryItem(3,'J7749','Doodlad',17);

  CreateInventoryItem(4,'1A749','Table',2);

  CreateInventoryItem(5,'A2349','Mouse',1);

end;

Создает строку функция CreateInventoryItem:

procedure TSortDemoForm.CreateInventoryItem(Index:integer; APArtNo, ADescription:string; AInStock:integer);

var  ListItem:TListItem;

begin

  FInvArray[index]:=TInventoryItem.Create(APartNo,ADescription,AInStock);

  ListItem:=lvInventory.Items.Add;

  ListItem.Caption:=APartNo;

  ListItem.SubItems.Add(ADescription);

  ListItem.SubItems.Add(IntToStr(AInStock));

  ListItem.Data:=Pointer(FInvArray[index]);

end;

В этой функции мы заполняем данные столбца, а ссылку на объект TInventoryItem, который у нас будет сравниваться при сортировке в событии OnCompare, передаем компоненту TListView через поле Data.

Все, теперь можно запускать программу на тестирование:

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

Нажимаем на кнопу сортировки по имени (btnByName):

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

Сортировка по зарплате (btnBySalary):

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

Дальше переключаемся на List View:

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

Сортируем по Part #::

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

По Description:

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

По In Store:

Программирование COM в Delphi. Урок 5. Практическое применение интерфейсов (TListView, IUnknown).

Исходники к уроку можно скачать здесь..

(C) Шуравин Александр 

Последнее обновление ( 12.09.2013 г. )
 
« След.   Пред. »
 
© 2024 Программирование - это просто
Joomla! - свободное программное обеспечение, распространяемое по лицензии GNU/GPL.
Русская локализация © 2005-2008 Joom.Ru - Русский Дом Joomla!
Design by Mamboteam.com | Powered by Mambobanner.de
Я принимаю Яндекс.Деньги