M Y D E L P H I 7 . R U Самоучитель программирования  
 
  • Главная
  •  

     

    Пример использования списка указателей

    Рассмотрим использование списков указателей на примере приложения DemoList. При щелчке мышью на форме приложения отображается точка, которой присваивается порядковый номер. Одновременно координаты и номер точки записываются в соответствующие свойства создаваемого экземпляра класса TMypixel. Указатель на этот объект передается в новый элемент списка pixList.

    В результате после очистки формы всю последовательность точек можно восстановить, использовав указатели на объекты точек из списка.

    Список точек можно отсортировать по координате X в порядке возрастания.

    Листинг 7.1. Модуль главной формы проекта DemoList

    unit Main;

    interface

    uses

    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, 

    Dialogs, StdCtrls, Buttons;

    type

    TMainForm = class(TForm) 

    ListBtn: TBitBtn;

      ClearBtn: TBitBtn; 

    DelBtn: TBitBtn;

      SortBtn: TBitBtn;

    procedure FormCreate(Sender: TObject); 

    procedure FormClose(Sender: TObject; var Action: TCloseAction);

    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;

      Shift: TShiftState; X, Y: Integer);

    procedure ListBtnClick(Sender: TObject);

    procedure ClearBtnClick(Sender: TObject);

    procedure DelBtnClick(Sender: TObject);

    procedure SortBtnClick(Sender: TObject); 

    private

    PixList: TList;

    PixNum: Integer; public

    { Public declarations } 

    end;

    TMyPixel = class(TObject)

    FX: Integer;

    FY: Integer;

    FText: Integer;

    constructor Create(X, Y, Num: Integer);

    procedure SetPixel; 

    end;

    var

    MainForm: TMainForm;

    implementation

    {$R *.DFM}

    const PixColor = clRed;

    var CurPixel: TMyPixel;

    constructor TMyPixel.Create(X, Y, Num: Integer); 

    begin

    inherited Create;

    FX := X;

    FY := Y;

    FText := Num;

    SetPixel;

      end;

    procedure TMyPixel.SetPixel; 

    begin

    MainForm.Canvas.PolyLine([Point(FX, FY), Point(FX, FY)]);

    MainForm.Canvas.TextOut(FX +1, FY + 1, IntToStr(FText)); 

    end;

    function PixCompare(Iteml, Item2: Pointer): Integer;

    var Pixl, Pix2: TMyPixel;

    begin

    Pixl := Iteml;

    Pix2 := Item2;

    Result := Pixl.FX — Pix2.FX;

      end;

    procedure TMainForm.FormCreate(Sender: TObject);

     begin

    PixList := TList.Create;

    PixNum := 1; {Счетчик точек}

    Canvas.Pen.Color := PixColor; (Цвет точки}

    Canvas.Pen.Width := 3; {Размер точки}

    Canvas.Brush.Color := Color; (Цвет фона текста равен цвету формы}

     end;

    procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);

     begin

    PixList.Free;

      end;

    procedure TMainForm.FormMouseDown(Sender: TObject; Button: TMouseButton;

    Shift: TShiftState; X, Y: Integer); 

    begin

    PixList.Add(TMyPixel.Create(X, Y, PixNum));

    Inc(PixNum); 

    end;

    procedure TMainForm.ListBtnClick(Sender: TObject);

    var i: Integer;

    begin

    with PixList do

    for i := 0 to Count — 1 do

    begin

    CurPixel := Items[i]; CurPixel.SetPixel;

    end; end;

    procedure TMainForm.ClearBtnClick(Sender: TObject);

     begin

    Canvas.FillRect(Rect(0, 0, Width, Height));

      end;

    procedure TMainForm.DelBtnClick(Sender: TObject); 

    begin

    PixList.Clear;

    PixNum := 1;

      end;

    procedure TMainForm.SortBtnClick(Sender: TObject);

    var i: Integer;

    begin

    PixList.Sort(PixCompare);

    with PixList do

    for i := 0 to Count — 1 do TMyPixel(Items[i]).FText := i + 1; 

    end;

    end.

    Класс TMyPixel обеспечивает хранение координат точки и ее порядковый номер в серии. Эти параметры передаются в конструктор класса. Метод setPixel обеспечивает отрисовку точки на канве формы (см. гл. 10).

    Экземпляр класса создается для каждой новой точки при щелчке кнопкой мыши в методе-обработчике FormMouseDown. Здесь же указатель на новый объект сохраняется в создаваемом при помощи метода Add элементе списка PixList. Таким образом, программа "запоминает" расположение и порядок следования точек.

    Метод-обработчик ListBtnClick обеспечивает отображение точек. Для этого в цикле текущий указатель списка передается в переменную объектного типа curPixel, т. е. в этой переменной по очереди "побывают" все созданные объекты, указатели на которые хранятся в списке.

    Это сделано для того, чтобы получить доступ к свойствам объектов (непосредственно через указатель этого сделать нельзя). Второй способ приведения типа рассмотрен в методе-обработчике SortBtnClick.

    Перед вторичным отображением точек необходимо очистить поверхность формы. Эту операцию выполняет метод-обработчик clearBtnClick.

    Список точек можно отсортировать по координате X в порядке возрастания. Для этого в методе-обработчике SortBtnClick вызывается метод Sort списка PixList. В параметре метода (переменная процедурного типа) передается функция PixCompare, которая обеспечивает инкапсулированный в методе Sort механизм перебора элементов списка алгоритмом принятия решения о старшинстве двух соседних элементов.

    Если функция возвращает положительное число, то элемент item1 больше элемента item2. Если результат отрицательный, то item1 меньше, чем item2. Если элементы равны, функция должна возвращать ноль.

    В нашем случае сравнивались координаты X двух точек. В результате такой сортировки по возрастанию объекты оказались расположены так, что первый элемент списка указывает на объект с минимальной координатой X, а последний — на объект с максимальной координатой X.

    После сортировки осталось заново пронумеровать все точки. Это делает цикл в методе-обработчике SortBtnclick. Обратите внимание на примененный в этом случае способ приведения типа, обеспечивающий обращение к свойствам экземпляров класса TMypixel.

    Метод-обработчик DeiBtnClick обеспечивает полную очистку списка pixList.