Шаг 84.
Библиотека OWL.
Поиск файлов

    На этом шаге мы рассмотрим реализацию поиска файлов средствами OWL.

    Студент 4 курса (2013-14 уч.год) Козлов Сергей реализовал поиск файлов средствами бибилиотеки OWL.

    Внешний вид приложения приведен на рисунке 1.


Рис.1. Внешний вид приложения

    Приведем текст программы с подробными комментариями.

    Основной файл pp.cpp.

//Поиск файлов
//Реализовать поиск файлов в выбранной папке(диске),
//удовлетворяющих заданному условию. Предусмотреть задание условия и место
//для вывода имен файлов вместе с путем доступа, а также выдачу
//диагностических сообщений.

#include <owl\applicat.h>
#include <owl\framewin.h>
#include <owl\radiobut.h>
#include <owl\edit.h>
#include <owl\listbox.h>
#include <owl\dc.h>
#include <windows.h>
//Подключить класс очереди
#include "och.cpp"

//Класс основного окна
class TWndw: public TFrameWindow
{
	private:
		// Переменные для хранения маски файлов и пути поиска соответсвенно
		char *maska,*put;
		// Переменная-очередь для хранения "дерева" папок
		name A;
		// Переменная для хранения количества найденных файлов
		unsigned long kol;
		// Функция для поиска файлов в папке
		void opr_files(char *);
		// Функция для формирования "дерева" папок
		void form_mas_papok();
	public:
		TWndw(TWindow *parent,const char far *title);
		~TWndw();
	protected:
		TEdit *edit1,*edit2;
		TListBox *listbox1;
		TStatic *label;
		void SetupWindow();
		void CmButton1();
		DECLARE_RESPONSE_TABLE(TWndw);
};

DEFINE_RESPONSE_TABLE1(TWndw,TFrameWindow)
	EV_COMMAND(ID_BUTTON_1,CmButton1),
END_RESPONSE_TABLE;

// TWndw::TWndw
// Это конструктор главного окна
TWndw::TWndw(TWindow *parent,const char far *title):TFrameWindow(parent,title)
{
	//Убрать границу окна
	Attr.Style&=!WS_BORDER;
	//Определяем положение окна
	Attr.X=20; Attr.Y=20;
	//Определяем размеры окна
	Attr.W=1000; Attr.H=600;
	//Создать управляющие элементы в окне
	new TStatic(this,-1,"Введите имя файла: ",20,20,140,30);
	edit1=new TEdit(this,ID_EDIT_1,"*.*",20,40,200,30,81);
	new TStatic(this,-1,"Введите директорию: ",20,80,150,30);
	edit2=new TEdit(this,ID_EDIT_2,"c:\\",20,100,200,30,81);
	new TButton(this,ID_BUTTON_1,"Найти",20,140,70,30);
	new TButton(this,ID_BUTTON_2,"Выход",100,140,70,30);
	listbox1=new TListBox(this,ID_LISTBOX_1,230,20,750,550);
	label=new TStatic(this,-1,"Всего найденных: ",20,500,140,30);
	//Выделить место в памяти для маски и пути
	maska=new char[81];
	put=new char[DLINA_PUTI];
}

//TWndw::~TWndw()
//Это деструктор главного окна
TWndw::~TWndw()
{
	//Возвратить зарезервированную память
	delete []maska;
	delete []put;
}

// TWndw::SetupWindow()
// Эта функция, переопределяющая функцию
// SetupWindow() базового класса, обеспечивает
// сервис по установке данного окна.
void TWndw::SetupWindow()
{
	// Вызвать SetupWindow() базового класса.
	TFrameWindow::SetupWindow();
}

// TWndw::opr_files(char *el)
// В этой функции определяются файлы в папке
// по заданной маске
void TWndw::opr_files(char *el)
{
	//Эта переменная типа структура
	//В ней хранится информация о файле (размер, атрибут, имя и т.д.)
	struct find_t ffblk;

	char *s=new char[DLINA_PUTI];
	strcpy(s,el); strcat(s,maska);
	//_dos_findfirst (s,_A_NORMAL||_A_RDONLY||_A_ARCH,&ffblk) ищет первый файл
	// по заданной маске с заданным аттрибутом.
	// Ели такой файл найден, фукнция возвращает 0
	int result=_dos_findfirst (s,_A_NORMAL||_A_RDONLY||_A_ARCH,&ffblk);

	while(result==0)
	{
	  strcpy(s,el); strcat(s,ffblk.name);
	  //Добавить в список найденный файл с полным путем
	  listbox1->AddString(s);
	  kol++;
	  // Аналогично _dos_findfirst, за исключеннием того,
	  // что она ищет следующий файл, удовлетворяющий тому же условию
	  result=_dos_findnext (&ffblk);
	}
	delete []s;
}

// TWndw::form_mas_papok()
// Функция формирует "дерево" папок
void TWndw::form_mas_papok()
{
	int result;
	struct find_t ffblk;
	char *s=new char[DLINA_PUTI];

	opr_files(A.GetEl()); strcpy(s,A.GetEl()); strcat(s,"*.*");
  
	//Аттрибут для нахождения папки _A_SUBDIR
	result=_dos_findfirst(s,_A_SUBDIR,&ffblk);
	while(result==0)
	{
   	
	// Нужно учесть, что есть две папки с именем "." и "..", их нужно исключить
		if ((ffblk.attrib==_A_SUBDIR)&&(ffblk.name[0]!='.'))
		{
			strcpy(s,A.GetEl()); strcat(s,ffblk.name);strcat(s,"\\");
			// Добавить в конец очереди
			A.add_el(s); 
		}
	  result=_dos_findnext(&ffblk);
	}
	delete []s;
	//Если очередь не пуста, удалить первый элемент
	if (!A.empty())A.del_el(); 
}

//TWndw::CmButton1()
//Функция-реакция нажатия на кнопку Найти
void TWndw::CmButton1()
{

	edit1->Copy(); maska=edit1->LockBuffer();
	edit2->Copy(); put=edit2->LockBuffer();

	kol=0; listbox1->ClearList();
	if((strlen(maska)!=0)&&(strlen(put)!=0))
	{
		if (put[strlen(put)-1]!='\\') strcat(put,"\\");

		//Добавить в очередь исходный путь
		A.add_el(put);
		//Пока очередь не будет пустой, вызываем form_mas_papok();
		while(!A.empty()) form_mas_papok();

		//Вывести соответсвующий результат поиска
		if (kol==0)listbox1->AddString("Поиск результатов не дал");

		char *s=new char[30],*s1=new char[11];
		itoa(kol,s1,10);
		strcpy(s,"Всего найденных: ");strcat(s,s1);
		label->SetText(s);
		delete []s; delete []s1;
	}
	else MessageBox("Введите все данные","ERROR",MB_OK);
}

//Класс приложения
class TApp:public TApplication
{
	public:
		TApp():TApplication(){}
		void InitMainWindow();
};

void TApp::InitMainWindow()
{
	TFrameWindow *wndw=new TWndw(0,"Поиск файлов");
	SetMainWindow(wndw);
}

int OwlMain(int,char *[])
{
	return TApp().Run();
}

    Файл och.cpp, содержащий описание класса очереди.

#include <iostream.h>
#include "pp.rc"

struct zveno
{
	 char el[DLINA_PUTI];
	 zveno *next;
};

class name
{
	private:
		zveno *nach,*konec;

	public:
		name(){nach=konec=NULL;}
		~name();
		int empty();
		char *GetEl(){return nach->el;}
		void add_el(char *);
		void del_el();
};

name::~name()
{
  while(!empty())del_el();
}

int name::empty()
{
	if (nach==NULL)return 1; else return 0;
}

void name::add_el(char *el)
{
	zveno *p=new(zveno); strcpy(p->el,el); p->next=NULL;
	if (empty())nach=p; else konec->next=p;
	konec=p;
}

void name::del_el()
{
	zveno *p=nach;
	//if (nach->next==NULL)konec=NULL;
	nach=nach->next; delete p;
}

    Файл ресурсов.

#include <string.h>

#define ID_EDIT_1 101
#define ID_EDIT_2 102
#define ID_BUTTON_1 103
#define ID_BUTTON_2 24310
#define ID_LISTBOX_1 104
#define ID_LABEL 105
#define DLINA_PUTI 1000
Текст этого приложения можно взять здесь.

    На следующем шаге мы рассмотрим приложение, используемое для замены иконок файла.




Предыдущий шаг Содержание Следующий шаг