Последним шагом в разработке этого приложения у меня было создание истории по принципу 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.
Конечно, желательно взглянуть на это все целиком. Поэтому проект прилагается к шагу.