Добавление и удаление перьев
-----------------------------------------------------------------
В последнем разделе вы отвечали на сообщения от Add Pen (До- бавить перо) и Del Pen (Удалить перо) изменением размера окна па- литры. Теперь настало время изменить эту реакцию и фактически до- бавлять или удалять перья из палитры, что в свою очередь указыва- ет окну палитры на необходимость изменения размера. Вместо вызова собственных методов Grow и Shrink методы объекта палитры AddPen и DeletePen должны вызывать соответственно, методы IDAdd и IDDel в TPenPalette.
procedure TPenPalette.IDAdd(var Msg: TMessage); begin Pens^.AddPen(CommonPen); end;
procedure TPenPalette.IDDel(var Msg: TMessage); begin Pens^.DeletePen; end;
Метод AddPen воспринимает передаваемое перо, копирует его в набор и отмечает перо, как текущее выбранное. Затем он разрешает кнопку Del Pen в окне палитры пера, запрещает кнопку Add Pen, ес- ли набор полон, и сообщает порождающему окну о необходимости уве- личения размера, чтобы поместить новое перо.
procedure TPenPic.AddPen(APen: PPen); begin CurrentPen := PenSet^.Count; with APen^ do PenSet^.Insert(New(PPen, Init(Style, With, Color))); with PPenPalette(Parent)^ do begin DelBtn^.Enable; if PenSet^.Count >= MaxPens tnen AddBtn^.Disable; Grow; end; end;
Примечание: Чтобы использовать преимущества средств, специфических для TPenPAlette, TPenPic может выполнять при- ведение типа поля Parent. Большинство оконных объектов не связаны так жестко с конкретным порождающим типом, и поэто- му не должны делать никаких предположений относительно типа порождающих их окон.
Метод DeletePen по существу изменяет действия AddPen на об- ратные. При наличии выбранного в палитре пера оно удаляется из набора, а набор уплотняется таким образом, чтобы перья размеща- лись непрерывно. Затем он указывает, что в данный момент выбран- ных перьев нет (поскольку выбранное перо только что удалено) и запрещает командную кнопку Del Pen, так как Del Pen работает с выбранным пером. Далее он разрешает кнопку Add Pen, поскольку удаление пера автоматически освобождает место для по крайней мере еще одного пера. Наконец, он сообщает порождающему окну на необ- ходимость уменьшения его размера (так выводить теперь нужно мень- ше перьев).
procedure TPenPic.DeletePen; begin if CurrentPen > -1 then begin PenSet^.AtFree(CurrentPen); PenSet^.Pack; CurrentPen := -1; with PPenPelette(Parent)^ do begin AddBtn^.Enable; DelBtn^.Disable; Shrink; end; end; end;
Заметим, что AddPen и DeletePen используют преимущества того факта, что окна палитры пера для упрощения связи с методами имеет указатели на свои командные кнопки. Если бы TPenPalette не имел полей AddBtn и DelBtn, то объекту палитры пришлось бы искать их по идентификаторам и посылать им сообщения, либо нужно было бы послать сообщение порождающему окну, которое в свою очередь долж- но каким-то образом связываться с командными кнопками.