Последним шагом в разработке этого приложения у меня было создание истории по принципу FIFO. Реализация представлена ниже:
void TTextHist::LoadHistory(String fName)
{
hist->Items->BeginUpdate();
hist->Clear();
dataset->DisableControls();
TListItem* itm = hist->Items->Add();
int p = dataset->RecNo;
dataset->First();
int cur = -1;
for(int i=0;iCount;i++)
{
dataset->RecNo = history->Names[i].ToInt();
cur = dataset->RecNo;
TListItem* itm = hist->Items->Add();
itm->Caption = dataset->Fields->Fields[1]->AsString;
itm->SubItems->Add(dataset->Fields->Fields[0]->AsString);
itm->SubItems->Add(dataset->Fields->Fields[2]->AsString);
itm->Data = (void*)cur;
}
dataset->RecNo = p;
dataset->EnableControls();
hist->Items->EndUpdate();
}
Формат файла истории hist.inf выглядит следующим образом:
;номер книги=позиция полосы прокрутки 23=100
Занесение в историю выполняется при добавлении очередного TextView.
TForm* TTextMain::AddChild(String fName,String caption,int id)
{
TForm* child = NULL;
if(fName=="BOOKLIST")
child = new TBookList(this);
if(fName=="EDITBOOK")
child = new TEditBook(this);
if(fName=="TEXTHIST")
child = new TTextHist(this);
if(!child)
{
for(int i=0;iClassName())=="TTextView")
if(((TTextView*)MDIChildren[i])->id==id)
{
BringWindowToTop(MDIChildren[i]->Handle);
return 0;
};
child = new TTextView(this);
try
{
((TTextView*)child)->Output->Lines->LoadFromFile(fName);
}
catch(...)
{
delete child;
return 0;
}
((TTextView*)child)->id = id;
int x = history->IndexOfName(id);
if(x!=-1)
{
history->Exchange(0,x);
SendMessage(((TTextView*)child)->Output->Handle,
EM_LINESCROLL,0,history->Values[id].ToInt());
}
else
{
history->Insert(0,String(id)+"=0");
if(history->Count>count)
history->Delete(count);
}
}
Pages->Tabs->AddObject(caption,child);
Pages->TabIndex = Pages->Tabs->Count - 1;
child->Caption = caption;
child->Tag = Pages->Tabs->Count - 1;
child->OnActivate = (TNotifyEvent)&ChildShow;
return child;
}
Напомню, что принцип FIFO предполагает, что последний внесенный объект будет стоять на первом месте, а первый внесенный объект при этом удаляется. Вообще красивее было бы это реализовать в виде замкнутой очереди, но проще выглядит приведенный выше вариант.
Сохранение истории происходит при закрытии окна:
void __fastcall TTextMain::FormClose(TObject *Sender, TCloseAction &Action)
{
for(int i=0;iClassName())=="TTextView")
history->Values[((TTextView*)MDIChildren[i])->id] =
IntToStr(GetScrollPos(((TTextView*)MDIChildren[i])->Output->Handle,SB_VERT));
history->SaveToFile("hist.inf");
}
В данном случае перебором всех дочерних окон выбираются только относящиеся к типу TTextView. Для определения позиции полосы прокрутки используется стандартная WinAPI функция GetScrollPos.
Конечно, желательно взглянуть на это все целиком. Поэтому проект прилагается к шагу.