Шаг 15 - Проект приложения CView

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

Конечно, желательно взглянуть на это все целиком. Поэтому проект прилагается к шагу.


Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Аванесов Самвел - 05.02.2004