- Автор темы
- #1
Данная программа позволяет осуществлять поиск файлов по маске (в формате MS-DOS) в указанном пользователем каталоге, включая подкаталоги. После отображения списка найденных файлов, пользователь сможет осуществить следующие действия (файлы, над которыми производятся операции, должны быть предварительно выделены):
Домашнее задание
Реализовать приложение-справочник по автомобилям. Должны поддерживаться функции добавления, удаления, модификации, поиска, сохранения в файл и загрузки из файла информации.
- удалить выделенные файлы
- скопировать выделенные файлы в каталог, указанный пользователем
- перейти в каталог(-и), где находятся выделенные файлы
Код:
using System;
using System.Drawing;
using System.Windows.Forms;
// Работа с ресурсами
using System.Resources;
// Файлы
using System.IO;
// Регулярные выражения
using System.Text.RegularExpressions;
// Используется для работы с процессами, точнее для работы
// с функциями класса Process
// public static Process Start(string fileName); -
// позволяет запустить указанный процесс или процесс, ассоциированный с указанным файлом;
// public static Process Start(string fileName, string arguments); - тоже самое,
// во втором параметре передаются аргументы командной строки.
using System.Diagnostics;
// Работа с файлами, которые ищутся по вводимой маске
namespace CSharpApplication.SearchFileByMask
{
class Search : Form
{
// Строка для ввода пути
private TextBox Path;
// Строка для ввода маски
private TextBox Mask;
// Кнопка для вызова стандартного диалога выбора каталогов
private Button Browse;
// Кнопка поиска
private Button GoSearch;
// Флаг для поиска в подкаталогах указанного каталога
private CheckBox SubDir;
// Список найденных файлов
private ListBox FilesList;
// Приглашение для ввода маски
private Label MaskText;
// Приглашение для ввода пути
private Label PathText;
// Стандартный диалог выбора каталогов
private FolderBrowserDialog BrowserDialog;
// Меню верхнего уровня
private MainMenu TopMenu;
// Пункт "Выход"
private MenuItem menuItemExit;
// Выпадающее меню "Операции"
private MenuItem menuItemOperations;
// Пункт "Удалить выделенные файлы"
private MenuItem menuItemDelete;
// Пункт "Переместить выделенные файлы в ..."
private MenuItem menuItemMove;
// Пункт "Перейти к выделенным файлам"
private MenuItem menuItemGo;
static void Main()
{
// Запуск приложения
Application.Run(new Search());
}
/****************************************************************/
/* Данная функция ранее называлась InitializeComponent.
* Эту функцию создает редактор ресурсов, и, в принципе,
* для начала она кажется довольно удобной. Но после
* некоторого времени работы с редактором ресурсов автора данной
* программы стало безумно раздражать его помощь.
* Дело в том, что, как и большинство программ компании Microsoft,
* данный редактор стремится оказать максимально возможную помощь,
* после чего код функции дико разрастается из-за подробнейшего
* описания каждой мелочи (вспомните написания HTML-файлов в
* Microsoft Word). Поэтому после составления формы, автор
* переименовал функцию и подчистил написанный редактором код.
***************************************************************/
private void InitializeComponents()
{
// Класс для работы с менеджером ресурсов
ResourceManager resources = new ResourceManager(typeof(Search));
/*********************************************************/
/* Создание элементов управления
/*********************************************************/
this.PathText = new Label();
this.MaskText = new Label();
this.Path = new TextBox();
this.Mask = new TextBox();
this.FilesList = new ListBox();
this.Browse = new Button();
this.GoSearch = new Button();
this.SubDir = new CheckBox();
this.BrowserDialog = new FolderBrowserDialog();
this.TopMenu = new MainMenu();
this.menuItemOperations = new MenuItem();
this.menuItemExit = new MenuItem();
this.menuItemDelete = new MenuItem();
this.menuItemMove = new MenuItem();
this.menuItemGo = new MenuItem();
/* Замораживаем ресурсы.
* Это нужно для того, чтобы во время создания и
* расположения на форме элементов управления
* они не обрабатывали сообщений о собственных
* изменениях размеров, координат и т. д.
*/
this.SuspendLayout();
// В основном добавлено редактором ресурсов!!!
//
// PathText
//
// Авторазмер
this.PathText.AutoSize = true;
// Цвет текста
this.PathText.ForeColor = Color.Blue;
// Позиция
this.PathText.Location = new Point(0, 5);
// Имя
this.PathText.Name = "PathText";
// Переход по табуляции (для надписей не имеет смысла)
this.PathText.TabIndex = 0;
// Текст
this.PathText.Text = "Выберите каталог для поиска:";
//
// MaskText
//
this.MaskText.AutoSize = true;
this.MaskText.ForeColor = Color.Blue;
this.MaskText.Location = new Point(0, 40);
this.MaskText.Name = "MaskText";
this.MaskText.TabIndex = 1;
this.MaskText.Text = "Введите маску для файлов:";
//
// Path
//
// Привязка элемента к определенным сторонам формы -
// используется для сохранений пропорций элемента
// при изменении размеров формы
this.Path.Anchor = AnchorStyles.Top | AnchorStyles.Left
| AnchorStyles.Right;
this.Path.AutoSize = false;
this.Path.Location = new Point(0, 20);
this.Path.Name = "Path";
this.Path.Size = new Size(269, 20);
this.Path.TabIndex = 2;
this.Path.Text = "";
// Обработчик события изменения текста
this.Path.TextChanged += new EventHandler(this.OnPathChanged);
//
// Mask
//
this.Mask.Anchor = AnchorStyles.Top | AnchorStyles.Left
| AnchorStyles.Right;
this.Mask.Location = new Point(0, 55);
this.Mask.Name = "Mask";
this.Mask.Size = new Size(140, 20);
this.Mask.TabIndex = 4;
this.Mask.Text = "";
// Обработчик события нажатия клавиши
this.Mask.KeyDown += new KeyEventHandler(this.OnMaskKeyDown);
//
// FilesList
//
this.FilesList.Anchor = AnchorStyles.Top | AnchorStyles.Bottom
| AnchorStyles.Left | AnchorStyles.Right;
this.FilesList.Location = new Point(0, 85);
this.FilesList.Name = "FilesList";
// Режим мультивыборки (с зажатыми Control'ом или Shift'ом)
this.FilesList.SelectionMode = SelectionMode.MultiExtended;
this.FilesList.Size = new Size(301, 186);
this.FilesList.TabIndex = 7;
//
// Browse
//
this.Browse.Anchor = AnchorStyles.Top | AnchorStyles.Right;
this.Browse.ForeColor = Color.Blue;
this.Browse.Location = new Point(277, 20);
this.Browse.Name = "Browse";
this.Browse.Size = new Size(24, 23);
this.Browse.TabIndex = 3;
this.Browse.Text = "...";
// Обработчик нажатия кнопки
this.Browse.Click += new EventHandler(this.OnBrowseClick);
//
// GoSearch
//
this.GoSearch.Anchor = AnchorStyles.Top | AnchorStyles.Right;
this.GoSearch.Enabled = false;
this.GoSearch.ForeColor = Color.Blue;
this.GoSearch.Location = new Point(235, 55);
this.GoSearch.Name = "GoSearch";
this.GoSearch.Size = new Size(65, 23);
this.GoSearch.TabIndex = 6;
this.GoSearch.Text = "Поиск";
// Обработчик нажатия кнопки
this.GoSearch.Click += new EventHandler(this.OnSearchClick);
//
// SubDir
//
this.SubDir.Anchor = AnchorStyles.Top | AnchorStyles.Right;
this.SubDir.ForeColor = Color.Blue;
this.SubDir.Location = new Point(143, 50);
this.SubDir.Name = "SubDir";
this.SubDir.Size = new Size(95, 28);
this.SubDir.TabIndex = 5;
this.SubDir.Text = "Поиск в\nподкаталогах";
//
// BrowserDialog
//
// Надпись на диалоге в момент появления
this.BrowserDialog.Description = "Выбор каталога для поиска";
// Кнопка "Создать новую папку" выключена
this.BrowserDialog.ShowNewFolderButton = false;
//
// TopMenu
//
// Создание меню верхнего уровня
this.TopMenu.MenuItems.AddRange(new MenuItem[]
{
this.menuItemExit,
this.menuItemOperations
}
);
//
// menuItemExit
//
// Порядковый номер пункта меню в данном подменю
this.menuItemExit.Index = 0;
// Горячая комбинация клавиш
this.menuItemExit.Shortcut = Shortcut.CtrlX;
// Текст
this.menuItemExit.Text = "&Выход";
// Обработчик выбора пункта меню
this.menuItemExit.Click += new EventHandler(this.OnMenuExitClick);
//
// menuItemOperations
//
this.menuItemOperations.Index = 1;
this.menuItemOperations.MenuItems.AddRange(new MenuItem[]
{
this.menuItemDelete,
this.menuItemMove,
this.menuItemGo
}
);
this.menuItemOperations.Text = "&Операции";
// Обработчик, срабатывающий перед отображением выпадаюшего меню
this.menuItemOperations.Popup += new EventHandler(this.OnMenuPopup);
//
// menuItemDelete
//
this.menuItemDelete.Index = 0;
this.menuItemDelete.Text = "Удалить выделенные файлы";
this.menuItemDelete.Click += new EventHandler(menuItemDelete_Click);
//
// menuItemMove
//
this.menuItemMove.Index = 1;
this.menuItemMove.Text = "Переместить выделенные файлы в ...";
this.menuItemMove.Click += new EventHandler(menuItemMove_Click);
//
// menuItemGo
//
this.menuItemGo.Index = 2;
this.menuItemGo.Text = "Перейти к выделенным файлам";
this.menuItemGo.Click += new EventHandler(menuItemGo_Click);
// Создание контекстного меню на основе существующего подменю.
// Обратите внимание на то, что пункты меню, которые уже находятся
// в каком-либо подменю, нельзя добавлять куда-либо повторно.
// Поэтому указанные ниже пункты перед добавлением клонируются.
this.FilesList.ContextMenu =
new ContextMenu(new MenuItem[]
{
this.menuItemDelete.CloneMenu(),
this.menuItemMove.CloneMenu(),
this.menuItemGo.CloneMenu()
}
);
// Обработчик вызова контекстного меню для списка.
// Срабатывает при щелчке правой кнопкой мыши по элементу.
this.FilesList.ContextMenu.Popup += new EventHandler(this.OnMenuPopup);
// Обработчик двойного щелчка по списку
this.FilesList.DoubleClick += new EventHandler(FilesList_DoubleClick);
//
// Search
//
this.AutoScaleBaseSize = new Size(5, 13);
this.BackColor = SystemColors.Control;
this.ClientSize = new Size(302, 273);
// Добавляем элементы управления в коллекцию элементов формы
// (форма становится их родителем)
this.Controls.AddRange(new Control[]
{
this.GoSearch,
this.MaskText,
this.Browse,
this.FilesList,
this.Mask,
this.SubDir,
this.Path,
this.PathText}
);
// Вынимаем иконку из ресурсов и прибиваем к форме
this.Icon = ((Icon)(resources.GetObject("$this.Icon")));
// Натягиваем меню
this.Menu = this.TopMenu;
// Устанавливаем минимально возможный размер для формы
this.MinimumSize = new Size(300, 300);
this.Name = "Search";
// Позиция формы при первом отображении
this.StartPosition = FormStartPosition.CenterScreen;
this.Text = "Поиск файлов";
// Размораживаем элементы управления
this.ResumeLayout(false);
}
Search()
{
// Инициализируем форму и элементы управления на ней
InitializeComponents();
}
// Функция для инициализации поиска фалов по маске
private void StartSearch()
{
// Проверка корректности указанного пути
if(!Directory.Exists(Path.Text))
{
// Все плохо
MessageBox.Show("Каталог " + Path.Text + " открыть не удалось",
"Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// Дописываем слэш (если есть необходимость)
if(Path.Text[Path.Text.Length - 1] != '\\')
Path.Text += '\\';
// Если маска не указана
if(Mask.Text.Length == 0)
{
// Маска по умолчанию
Mask.Text = "*.*";
}
// Убираем лишние пробелы позади указанного пути
Path.Text = Path.Text.TrimEnd();
// Преобразуем введенную маску для файлов
// в регулярное выражение
// Заменяем . на \.
string RegMask = Mask.Text.Replace(".", @"\.");
// Заменяем ? на .
RegMask = RegMask.Replace("?", ".");
// Заменяем * на .*
RegMask = RegMask.Replace("*", ".*");
// Указываем, что требуется найти точное соответствие маске
RegMask = "^" + RegMask + "$";
// Создание объекта регулярного выражения
// на основе маски
Regex RegExpr = new Regex(RegMask, RegexOptions.IgnoreCase);
string PathToDirectory = Path.Text;
// Очистка содержимого списка
FilesList.Items.Clear();
// Запускаем функцию поиска
uint Count = FillListOfFiles(PathToDirectory, RegExpr);
MessageBox.Show("Количество файлов в каталоге \n" + Path.Text +
" , \nкоторые соответствуют маске, равно " + Count,
"Операция завершена", MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
// Функция, осуществляющая поиск файлов по указанной маске
private uint FillListOfFiles(string dir, Regex mask)
{
// Количество найденных элементов
uint Count = 0;
string [] names;
try
{
// Пытаемся получить список каталогов
// (а прав может и не быть :-( )
names = Directory.GetFiles(dir);
}
catch
{
// Закругляемся
return Count;
}
// Перебираем найденные элементы
foreach(string name in names)
{
// А подошла ли маска ?!!
if(mask.IsMatch(name))
{
// Добавляем файл в список
FilesList.Items.Add(name);
++Count;
}
}
// Если хочется войти глубже (просмотр подкаталогов)
if(this.SubDir.Checked)
{
// Получаем список имеющихся в наличии подкаталогов
string [] dirnames = Directory.GetDirectories(dir);
// Берем по одному
foreach(string dirname in dirnames)
{
// Запускаем функцию от него
Count += FillListOfFiles(dirname, mask);
}
}
// Возвращаем количество найденных файлов
return Count;
}
// Обрабатываем изменение текста в текстовом поле
private void OnPathChanged(object sender, EventArgs e)
{
// Удаляем ведущие пробелы
Path.Text = Path.Text.TrimStart();
// Нет текста?
if(Path.Text.Length == 0)
{
// Нет поиска!
GoSearch.Enabled = false;
}
else
{
// Кнопка гори!!!
GoSearch.Enabled = true;
}
}
// Обрабатываем вызов диалога выбора каталогов
private void OnBrowseClick(object sender, EventArgs e)
{
// Если введенный текст таки каталог
if(Directory.Exists(Path.Text))
{
// Добавляем слэш (при необходимости)
if(Path.Text[Path.Text.Length - 1] != '\\')
Path.Text += '\\';
// Выбираем введенный путь в качестве стартового для диалога
BrowserDialog.SelectedPath = Path.Text;
}
// Кнопка "Создать новую папку" для диалога отключена
BrowserDialog.ShowNewFolderButton = false;
// Отбражаем диалог и ждем чего будет
if(BrowserDialog.ShowDialog() == DialogResult.OK)
{
// Если user определился, то его выбор - наш выбор
Path.Text = BrowserDialog.SelectedPath;
}
}
// Нажали кнопку "Поиск"
private void OnSearchClick(object sender, EventArgs e)
{
StartSearch();
}
// Обрабатываем нажатия кнопок в поле для ввода маски
private void OnMaskKeyDown(object sender, KeyEventArgs e)
{
// Если нажали Enter и кнопка "Поиск" доступна
if(e.KeyCode == Keys.Enter && GoSearch.Enabled == true)
{
// Запускаем поиск
StartSearch();
}
}
// Пункт меню "Выход"
private void OnMenuExitClick(object sender, EventArgs e)
{
// Закрываемся
Close();
}
// Меню желает отобразиться
private void OnMenuPopup(object sender, EventArgs e)
{
// Приводимся к базовому классу
Menu menu = (Menu)sender;
// Если в списке нет веделенных файлов
if(FilesList.SelectedItems.Count == 0)
{
// Вырубаем пункты подменю
foreach(MenuItem mi in menu.MenuItems)
{
mi.Enabled = false;
}
}
else
{
// Оживляем пункты подменю
foreach(MenuItem mi in menu.MenuItems)
{
mi.Enabled = true;
}
}
}
// Желаем удалять выделенные файлы
private void menuItemDelete_Click(object sender, EventArgs e)
{
// Переспрашиваем
DialogResult Yes = MessageBox.Show("Вы уверены?", "Удаление файлов",
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
// Пользователь на все согласен
if(Yes == DialogResult.Yes)
{
// Считаем "смертничков"
int Count = FilesList.SelectedIndices.Count;
for(int i = Count - 1; i >= 0; i--)
{
// Удаляем файлы
File.Delete((string)FilesList.SelectedItems[i]);
// Удаляем запись из списка
FilesList.Items.RemoveAt(FilesList.SelectedIndices[i]);
}
}
}
// Желаем переместить файлы в сухое, прохладное место
private void menuItemMove_Click(object sender, EventArgs e)
{
// Даем шанс создать папку на ходу (в диалоге выбора каталогов)
BrowserDialog.ShowNewFolderButton = true;
string dir;
// Отображаем каталог
if(BrowserDialog.ShowDialog() == DialogResult.OK)
{
// Записываем выбранный путь
dir = BrowserDialog.SelectedPath;
}
else
// Не хочет - не надо
return;
// Считаем "эмигрантов"
int Count = FilesList.SelectedIndices.Count;
string name, path;
for(int i = Count - 1; i >= 0; i--)
{
// Получаем путь к файлу из списка
path = (string)FilesList.SelectedItems[i];
// Выкусываем имя файла
name = path.Substring(path.LastIndexOf('\\'));
// Перемещаем файл на новое место жительство
File.Move(path, dir + name);
// Удаляем следы пребывания файла в списке
FilesList.Items.RemoveAt(FilesList.SelectedIndices[i]);
}
}
// Желаем видеть место жительства файла и его соседей
private void menuItemGo_Click(object sender, EventArgs e)
{
// Считаем места, в которые надо заглянуть
int Count = FilesList.SelectedIndices.Count;
string oldpath = "", newpath;
for(int i = 0; i < Count; i++)
{
// Забираем путь из списка
newpath = (string)FilesList.SelectedItems[i];
// Откусываем имя файла
newpath = newpath.Substring(0, newpath.LastIndexOf('\\'));
// Если этот путь в списке посещений уже присутствует
if(newpath == oldpath)
continue;
// Осматриваем место жительства очередного файла
Process.Start("explorer.exe", newpath);
// Запоминаем где были в последний раз
oldpath = newpath;
}
}
// Есть желание запустить файл
private void FilesList_DoubleClick(object sender, EventArgs e)
{
// Считаем количество "желающих"
if(FilesList.SelectedIndices.Count == 0)
return;
// Запуск
Process.Start((string)FilesList.SelectedItem);
}
}
}
Домашнее задание
Реализовать приложение-справочник по автомобилям. Должны поддерживаться функции добавления, удаления, модификации, поиска, сохранения в файл и загрузки из файла информации.