Навигация
Категории
C++,C#,C [19]
Уроки по средам разработки приложений с использованием C,C++,C#, а также .Net, DirectX, OpenGL и других
Delphi [14]
Уроки работы в среде программирования Delphi
Basic [13]
Уроки разработки приложений в среде Basic
DirectX [8]
Уроки по работе с DirectX, включая Direct3D и другие инструменты
Web [7]
Уроки по "Веб-программированию"
JavaScript [12]
Уроки по кодингу в Java и JavaScript
XNA [9]
Статьи и уроки программирование в среде XNA C++&C#
Профиль
Статистика
Rambler's Top100

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Locations of visitors to this page
Главная » Статьи » Программирование » C++,C#,C

Пишем файл-браузер на C++
Поставим задачу расширения дизайна этих компонентов. Мы не будем менять их код. Мы создадим на форме три кнопки, DriveComboBox, FileListBox сделаем невидимыми, в заменим их
ComboBox и ListBox компонентами соответсвенно.

Сначала проиницилизируем ComboBox:
#define USER_PATH DriveComboBox1->Items->Count



Стандартные папки:
AnsiString SystemDir, WindowsDir, TempDir;
AnsiString MyDocumentsFolder ,Desktop;

...

 char specfolder[MAX_PATH];
 GetSystemDirectory(specfolder,100);
 SystemDir = specfolder;
 GetWindowsDirectory(specfolder,100);
 WindowsDir=specfolder;
 TempDir = WindowsDir+"\\Temp";
 SHGetSpecialFolderPath(Handle, specfolder, 0x0005, false);
 MyDocumentsFolder = specfolder;
 SHGetSpecialFolderPath(Handle, specfolder, 0x0000, false);
 Desktop = specfolder;



Теперь мы знаем местоположение и буквы дисков компьютера. Осталось заполнить полученными данными ComboBox.

Напишем специальную структуру, и создадим массив на её базе:
enum TPathType {ptDestkop, ptNetworkDrive , ptHardDisk, ptCdrom, ptFloppy, ptDisk,
      ptMyDocuments, ptWinSystem, ptWindows, ptWinTemp,
      ptUserDefined };

struct TPath {
  TPathType PathType; //Тип пути
  AnsiString DefDir;  //Каталог пути
  AnsiString Name;    //Имя пути
}StdPath[40];



Для определения типа пути по его каталогу и размещения полученных данных в массиве напишем функцию:
void AddUserPath(AnsiString DefDir, AnsiString Name, int PathID) {
   StdPath[PathID].Name = Name;
   StdPath[PathID].DefDir = DefDir;
   Form1->ComboBox1->Items->Add(DefDir+"  "+Name+"");
   if(DefDir.Length()==2) {
     switch(GetDriveType(DefDir.c_str()))  {
      case DRIVE_CDROM:
       StdPath[PathID].PathType = ptCdrom;
      return;
      case DRIVE_REMOTE:
       StdPath[PathID].PathType = ptNetworkDrive;
      return;
      case DRIVE_FIXED:
       StdPath[PathID].PathType = ptHardDisk;
      return;
      case DRIVE_REMOVABLE:
        StdPath[PathID].PathType = ptFloppy;
      return;
      default:
       StdPath[PathID].PathType = ptDisk;
      return;
     }
   }
   if(DefDir==MyDocumentsFolder) {
      StdPath[PathID].PathType = ptMyDocuments;
      return;
   }
   if(DefDir==SystemDir) {
      StdPath[PathID].PathType = ptWinSystem;
      return;
   }
   if(DefDir==WindowsDir) {
      StdPath[PathID].PathType = ptWindows;
      return;
   }
   if(DefDir==TempDir) {
      StdPath[PathID].PathType = ptWinTemp;
      return;
   }
   if(DefDir==Desktop) {
      StdPath[PathID].PathType = ptDestkop;
      return;
   }
   StdPath[PathID].PathType = ptUserDefined;
}



Благодаря функции GetDriveType мы узнаём тип данного диска.

Теперь мы можем проинициализировать ComboBox:
 for(int i=0; i<DriveComboBox1->Items->Count; i++) {
   AddUserPath(DriveComboBox1->Items->Strings[i].SubString(1,2),DriveComboBox1->Items->Strings[i].c_str()+3,i);
 }
 AddUserPath(SystemDir, "Системная папка", USER_PATH);
 AddUserPath(WindowsDir, "Папка Windows", USER_PATH+1);
 AddUserPath(TempDir, "Временные файлы", USER_PATH+2);
 AddUserPath(MyDocumentsFolder, "Мои документы", USER_PATH+3);
 AddUserPath(Desktop, "Рабочий стол", USER_PATH+4);



Для каждого типа пути нужна своя картинка. Проинициализируем её.
Мы разместим все картинки в папочке Interface. Каждому типу пути поставим в соответствие свою картинку:

AnsiString PathIconNames[] = {
  "Destkop.bmp",
  "NetDisk.bmp",
  "HardDisk.bmp",
  "CDDisk.bmp",
  "Floppy.bmp",
  "Disk.bmp",
  "Mydocs.bmp",
  "Winsys.bmp",
  "Windows.bmp",
  "WinTemp.bmp",
  "User.bmp"
};

Graphics::TBitmap* PathIcons[ptUserDefined+1];



Проинициализируем их:
 for(int i=0; i<ptUserDefined+1; i++) {
    PathIcons[i] = new Graphics::TBitmap();
    PathIcons[i]->LoadFromFile("interface\\" + PathIconNames[i]);
    PathIcons[i]->Transparent = true;
 }



И удалим:

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
 for(int i=0; i<ptUserDefined+1; i++) {
    delete PathIcons[i];
 }
}



Теперь самое интересное - отрисовка элементов ComboBox. Для этого свойство Style надо установить в csOwnerDrawFixed (только отрисовка), выбрать ItemHeight по размерам картинок (у меня было значение 24 для картинок 16 на 16), а событие OnDrawItem заполнить следующим кодом:
void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control, int Index,
      TRect &Rect, TOwnerDrawState State)
{
   ComboBox1->Canvas->FillRect(Rect);
   ComboBox1->Canvas->Draw(Rect.Left+4,Rect.Top+4, PathIcons[StdPath[Index].PathType]);
if(StdPath[Index].PathType>=ptNetworkDrive && StdPath[Index].PathType<=ptDisk) {
    ComboBox1->Canvas->TextOut(Rect.Left+48, Rect.Top+6, StdPath[Index].Name);
    ComboBox1->Canvas->TextOut(Rect.Left+28, Rect.Top+6, StdPath[Index].DefDir);
 }
else {
   ComboBox1->Canvas->TextOut(Rect.Left+28, Rect.Top+6, StdPath[Index].Name);
}
}



Половина дела сделанa. Теперь на очереди FileListBox.
Так как картинки из этого компонента нам не подходят, а TIcon не может менять размеры значка, мы опять всё пишем руками :)
Сначала напишем функцию SetPath. Онабудет вызываться при изменении текущей папки.

void SetPath(AnsiString NewPath) {
  if(DirectoryExists(NewPath)) {
   Path = NewPath;
   Form1->FileListBox1->Directory=Path;
   if(Form1->DirectoryListBox1->Directory!=Path) Form1->DirectoryListBox1->Directory=Path;
   Form1->ListBox1->Clear();
   Form1->ListBox1->Items->AddStrings(Form1->FileListBox1->Items);
  }
}


В конструктор добавится следующая строка: SetPath(MyDocumentsFolder); Теперь при стрте приложения текущей папкой будет "мои документы".
Наполнится кодом OnChange ComboBox'а:
void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
 SetPath(StdPath[ComboBox1->ItemIndex].DefDir);
}



Теперь осталось написать отрисовку элемента в ListBox. Установим Для этого свойство Style надо установить в lbOwnerDrawVariable (отрисовка и подготовка к отрисовке). Выполним подготовительные действия для значков: установим папку со значками и их размер:

int IconSize=16;
AnsiString IconsDir;

...

IconsDir = ExtractFilePath(Application->ExeName)+"\\interface\\files16\\";



Сама отрисовка:
 
void __fastcall TForm1::ListBox1DrawItem(TWinControl *Control, int Index,
      TRect &Rect, TOwnerDrawState State)
{
    HICON hTypeIcon;
    ListBox1->Canvas->Brush->Style = bsSolid;
    ListBox1->Canvas->Rectangle(Rect);
    ListBox1->Canvas->Brush->Style = bsClear;
    ListBox1->Canvas->TextOut(Rect.Left+IconSize+4,Rect.Top+Rect.Height()/2-10,ListBox1->Items->Strings[Index]);
    if(FileExists(IconsDir+AnsiLowerCase(ExtractFileExt(ListBox1->Items->Strings[Index]).SubString(2,3))+".ico")) { //Если есть значок для этого типа файлов грузим его, если нет то грузим default.ico.
        hTypeIcon = LoadImage(NULL, (IconsDir+AnsiLowerCase(ExtractFileExt(ListBox1->Items->Strings[Index]).SubString(2,3))+".ico").c_str(), IMAGE_ICON, IconSize, IconSize, LR_LOADFROMFILE);
    }
     else {
      hTypeIcon = LoadImage(NULL, "interface\\files16\\default.ico", IMAGE_ICON, IconSize, IconSize, LR_LOADFROMFILE);
     }
     DrawIconEx(ListBox1->Canvas->Handle, Rect.Left+2, Rect.Top+2, hTypeIcon, IconSize,IconSize, 0, NULL, DI_NORMAL);
     DestroyIcon(hTypeIcon);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListBox1MeasureItem(TWinControl *Control,
      int Index, int &Height)
{
    //Подготока к отрисовке
    ListBox1->Canvas->Pen->Color = 0xFAFAFA;
    if(ListBox1->ItemIndex == Index) { //Если этот элемент текущий
      ListBox1->Canvas->Brush->Color=clNavy;
    }
    else {
      ListBox1->Canvas->Brush->Color=clWhite;
    }

   Height = IconSize+4; //Высота элемента

}



Мы использовали функцию LoadImage. Это универсальная функция загрузки иконок, курсоров, битмапов из ресурса. Если использовать флаг LR_LOADFROMFILE, загрузка происходит из файла. Первыц параметр - Имя ресурса или путь к файлу. Второй параметр - тип картинки. Третий и четвёртый - размеры.

И, наконец, последний штрих, выбор размера значков. Для этого нам нужны три кнопки с заговками 16, 32 и 48


void __fastcall TForm1::Button1Click(TObject *Sender)
{
 IconSize=16;
 ListBox1->Repaint();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
 IconSize=32;
 ListBox1->Repaint();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
 IconSize=48;
 ListBox1->Repaint();
}



Файл-броузер готов!


Источник: http://файл,браузер,обозреватель,проводник,файл-браузер,файл-менеджер,пишем,создаем,программируем,в,visual
Категория: C++,C#,C | Добавил: gforcer (16.11.2009) | Автор: Админ
Просмотров: 5316 | Комментарии: 1 | Рейтинг: 2.7/3
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск
Друзья сайта
Демотиваторы
Copyright Зямаев Денис © 2024