Нашел в интернете вот это но как это реализовать не пойму.
(Нестандартный способ решения задачи применён и к алгоритму отмены и повтора действий пользователя. Создан специальный класс TBmpMemory, который хранит изображения в памяти. После каждого действия, будь то рисование прямоугольника или увеличение контрастности, изображение сохраняется в отдельной ячейке (Cell) динамического массива, длина которого равна числу возможных отмен + 1. Данный массив представляет собой двусвязный список. Тип каждой ячейки определён следующим образом:
PBitmapCell = ^TBitmapCell;
TBitmapCell = record
NextCell: PBitmapCell; // указатель на следующую ячейку
PrevCell: PBitmapCell; // указатель на предыдущую ячейку
Bitmap: TBitmap;
end;
Таким образом, каждый элемент списка имеет указатель на предыдущий и на следующий элемент. Указатель PrevCell первой ячейки указывает на последнюю, а указатель NextCell последней ячейки указывает на первую ячейку. Получается замкнутое кольцо без входа и выхода. Это сделано по той причине, что после отмены действия, для восстановления требуется то изображение, которое было отменено. Например: пользователь нарисовал круг, а затем линию. В первой ячейке записано изображение, которое было до рисования круга, во второй - после рисования круга, а в третьей - после рисования линии. После отмены последнего действия указатель перемещается на предыдущую ячейку (ячейка с кругом, но без линии):
procedure TBmpMemory.Undo(Bitmap: TBitmap);
begin
if CanUndo then begin
Dec(FNumUndo); //уменьшаем число возможных отмен
Bitmap.Assign(FActiveCell^.Bitmap); //передаём изображение с активной ячейки
FActiveCell := FActiveCell^.PrevCell;//переносим указатель на предыдущую ячейку
end;
end;
Если же пользователь передумал и решил вернуть нарисованное, то он может вызвать повтор последнего отменённого действия (если после отмены ничего не было сделано):
procedure TBmpMemory.Redo(Bitmap: TBitmap);
begin
if CanRedo then begin
Inc(FNumUndo); //увеличиваем число возможных отмен
FActiveCell := FActiveCell^.NextCell; //переносим указатель на следующую ячейку
Bitmap.Assign(FActiveCell^.NextCell^.Bitmap); //передаём изображение
//со следующей после активной ячейки, т. к. активная ячейка та,
//которая должна быть отменена
end;
end;)
RPI.su - самая большая русскоязычная база вопросов и ответов. Наш проект был реализован как продолжение популярного сервиса otvety.google.ru, который был закрыт и удален 30 апреля 2015 года. Мы решили воскресить полезный сервис Ответы Гугл, чтобы любой человек смог публично узнать ответ на свой вопрос у интернет сообщества.
Все вопросы, добавленные на сайт ответов Google, мы скопировали и сохранили здесь. Имена старых пользователей также отображены в том виде, в котором они существовали ранее. Только нужно заново пройти регистрацию, чтобы иметь возможность задавать вопросы, или отвечать другим.
Чтобы связаться с нами по любому вопросу О САЙТЕ (реклама, сотрудничество, отзыв о сервисе), пишите на почту [email protected]. Только все общие вопросы размещайте на сайте, на них ответ по почте не предоставляется.