БлогNot. Пожалуй, самый медленный "Проводник" в мире :)

Пожалуй, самый медленный "Проводник" в мире :)

... потому что написан он будет на Visual C++ 2010 (у меня сборка Express). Начнём с того, что создадим новый проект на C++/CLI (Файл - Создать - Проект - CLR - Приложение Windows Forms) и добавим на форму следующие компоненты:

  • ImageList, имя которого можно оставить по умолчанию. Добавим в него 3 иконки, отвечающие за показ файлов (индекс картинки 0), папок (индекс 1) и логических дисков (индекс 2).
  • Label под именем filePathLabel, там будем показывать путь к выбранной папке.
  • ListView с именем listViewFiles, он будет отвечать за вывод списка файлов. Поставим ему свойство View = LargeIcon, а LargeImageList = imageList1.

В классе формы сразу после директивы

#pragma endregion

пропишем статическое поле для хранения имени файла:

public: static String ^PathToFile = "";

а следом добавим тело метода, который будет выполнять основную работу по получению оглавлений дисков и папок:

public: void GetListFS() {
  //начало обновления(прорисовки) списка
  listViewFiles->BeginUpdate();
  listViewFiles->Items->Clear();
  if (PathToFile == "") { //если значение пути пустое, то...
                          //получаем имена логических дисков
   array <String ^> ^ strDrives = System::Environment::GetLogicalDrives();
   for each (String ^ strDrive in strDrives) {
	listViewFiles->Items->Add(strDrive, 2); 
   }
  }
  else  {
   try {
    //получаем список директорий
    array <String ^> ^ dirs = System::IO::Directory::GetDirectories(PathToFile);
    for each (String ^ s in dirs) {
     String ^ dirname = System::IO::Path::GetFileName(s);
     listViewFiles->Items->Add(dirname, 1);
    }
    //получаем список файлов
    array<String^> ^ files = System::IO::Directory::GetFiles(PathToFile, "*.*", System::IO::SearchOption::AllDirectories);
    for each (String ^ s in files) {
     String ^ filename = System::IO::Path::GetFileName(s);
     listViewFiles->Items->Add(filename, 0);
    }
   }
   catch  (...) {
    MessageBox::Show("Error", "", MessageBoxButtons::OK);
	return;
   }
  }
  //выводим полный путь к директории в которой находимся
  filePathLabel->Text = PathToFile;
  //конец обновления
  listViewFiles->EndUpdate();
}

Этот метод также нужно вызвать в конце конструктора формы, так что последний примет вид:

Form1(void)	{
  InitializeComponent();
  GetListFS();
}

В функции GetListFS мы пытаемся действовать грамотно - в начале вызывается метод BeginUpdate() списка представления, а в конце — EndUpdate(). Теперь со списком можно работать как угодно, метод перерисовки не будет лишний раз вызывается (теоретически). После начала обновления сразу же очищаем список от старых значений при помощи метода Clear() свойства Items.

Для получения списка папок по определенному пути файловой системы используем статический метод GetDirectories(), передав ему путь, по которому нужно получить содержимое. Метод возвращает список строк с именами путей. После этого используем статичный метод GetFileName() класса Path, чтобы получить только имя, а не весь путь целиком.

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

Чтобы можно было заходить внутрь папок, создадим обработчик события ItemActivate для компонента ListView (это событие происходит при активации элемента):

private: System::Void listViewFiles_ItemActivate(System::Object^  sender, System::EventArgs^  e) {
  if (listViewFiles->SelectedItems->Count == 0) return;
  ListViewItem ^ item = listViewFiles->SelectedItems[0];
  switch (item->ImageIndex) {
   case 1: {
    PathToFile += "\\" + item->Text;
    GetListFS();
    break;
   }               
   default: {
    PathToFile += item->Text;
    GetListFS();
    break;
   }
  }
}

Наконец, добавив на форму обычную кнопку button1, изменим её свойство Text на строку Up! и добавим ей следующий обработчик события Click:

private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
  System::IO::DirectoryInfo ^ dirinfo;
  try {
   dirinfo = System::IO::Directory::GetParent(PathToFile);
   PathToFile = dirinfo->ToString();
  }
  catch (...) {
   PathToFile = ""; 
  }
  GetListFS();
}

Думаю, ясно, что это будет возврат на уровень выше по дереву папок.

Теперь "файл-менеджером" можно насладиться в работе, у меня лично .NET Framework 4.5 в очередной раз вызвала отвращение своими дикими тормозами на вполне приличном "железе", так что улучшать и дополнять пример можете сами :)

 Скачать проект с примером (архив .zip с папкой проекта Visual C++ 2010) (36 Кб)

10.01.2014, 18:57 [9729 просмотров]


теги: программирование c++/cli

К этой статье пока нет комментариев, Ваш будет первым