CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - total comander w builderze c++

total comander w builderze c++

dział ogólny

total comander w builderze c++

Nowy postprzez niemamkolan » piątek, 5 listopada 2010, 15:41

witam

mam za zadanie zrobić coś ala total cmd lecz nie wiem jak w FileListBox zrobić otwieranie plików i przechodzenie po folderach byłbym bardzo wdzięczny za jakąkolwiek pomoc

dzięki i pozdrawiam
Avatar użytkownika
niemamkolan
Bladawiec
Bladawiec
 
Posty: 12
Dołączył(a): poniedziałek, 11 października 2010, 16:45
Podziękował : 1
Otrzymał podziękowań: 0
System operacyjny: Win7 Ultimate x64
Kompilator: C++ Builder 6
Gadu Gadu: 2470956
    Windows 7Firefox

Re: total comander w builderze c++

Nowy postprzez Cyfrowy Baron » piątek, 5 listopada 2010, 16:36

Do poruszania się po folderach to masz komponent DirectoryListBox, który łączysz z FileListBox poprzez jego właściwość FileList. By TFileListBox wyświetlał oprócz plików również foldery musisz ustawić mu właściwość FileType -> ftDirectory na true.

Co się tyczy otwierania plików, to należy użyć funkcji ShellExecute - ► patrz serwis: Cyfrowy Baron dział: porady -> API -> Uruchamianie pliku w domyślnym programie.. Zadanie najlepiej jest realizować w zdarzeniu OnDblClick (podwójne kliknięcie) dla FileListBox:

KOD cpp:     UKRYJ  
#include <shellapi.h>
void __fastcall ExecuteFile(const String FileName, const String Params,
        const String DefaultDir, int ShowCmd)
{
  ShellExecute(Application->MainForm->Handle, NULL, FileName.c_str(),
                Params.c_str(), DefaultDir.c_str(), ShowCmd);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FileListBox1DblClick(TObject *Sender)
{
 String fileName = FileListBox1->FileName;
 String dirName = ExtractFilePath(fileName);
 ExecuteFile(fileName, " ", dirName, SW_SHOW);
}
//---------------------------------------------------------------------------


Korzystasz ze środowiska BCB6 więc w katalogu: c:\program files\Borland\CBuilder6\Examples\Doc\Filmanex masz przykładowy program pokazujący jak korzystać z obiektów TDriveComboBox, TDirectoryListBox oraz TFileListBox. Właściwie to gotowy program, dokładnie taki jakiego potrzebujesz.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: total comander w builderze c++

Nowy postprzez niemamkolan » piątek, 5 listopada 2010, 23:00

Wielkie dzięki mate,

a coś żeby też przez filelisbox dało się poruszać po katalogach przez DoubleClick??
Avatar użytkownika
niemamkolan
Bladawiec
Bladawiec
 
Posty: 12
Dołączył(a): poniedziałek, 11 października 2010, 16:45
Podziękował : 1
Otrzymał podziękowań: 0
System operacyjny: Win7 Ultimate x64
Kompilator: C++ Builder 6
Gadu Gadu: 2470956
    Windows XPFirefox

TDirectoryListBox, TFileListBox, ShellExecute

Nowy postprzez Cyfrowy Baron » sobota, 6 listopada 2010, 09:30

a coś żeby też przez filelisbox dało się poruszać po katalogach przez DoubleClick??


Masz to w tym przykładowym programie.

KOD cpp:     UKRYJ  
#include <shellapi.h>

//---------------------------------------------------------------------------
void __fastcall ExecuteFile(const String FileName, const String Params,
        const String DefaultDir, int ShowCmd)
{
  ShellExecute(Application->MainForm->Handle, NULL, FileName.c_str(),
                Params.c_str(), DefaultDir.c_str(), ShowCmd);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FileListBox1DblClick(TObject *Sender)
{
 String fileName = FileListBox1->FileName;
 String dirName = ExtractFilePath(fileName);

 if(FileGetAttr(fileName) & faDirectory)
 {
  fileName = StringReplace(fileName, "[", "", TReplaceFlags() << rfReplaceAll);
  fileName = StringReplace(fileName, "]", "", TReplaceFlags() << rfReplaceAll);

  DirectoryListBox1->Directory = fileName;
 }
 else
  ExecuteFile(fileName, " ", dirName, SW_SHOW);
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: total comander w builderze c++

Nowy postprzez niemamkolan » niedziela, 7 listopada 2010, 14:05

ponownie wielkie dzięki mate, nie będzie szmaty z programowania :)
Avatar użytkownika
niemamkolan
Bladawiec
Bladawiec
 
Posty: 12
Dołączył(a): poniedziałek, 11 października 2010, 16:45
Podziękował : 1
Otrzymał podziękowań: 0
System operacyjny: Win7 Ultimate x64
Kompilator: C++ Builder 6
Gadu Gadu: 2470956
    Windows 7Firefox

Re: total comander w builderze c++

Nowy postprzez niemamkolan » poniedziałek, 8 listopada 2010, 00:46

sorry że jeszcze tyłek zawracam ale jak chce skopiować z filelistbox1 do filelistbox2 plik w taki sposób żeby zrobiło się to z taką samą nazwą,

da rade?
Avatar użytkownika
niemamkolan
Bladawiec
Bladawiec
 
Posty: 12
Dołączył(a): poniedziałek, 11 października 2010, 16:45
Podziękował : 1
Otrzymał podziękowań: 0
System operacyjny: Win7 Ultimate x64
Kompilator: C++ Builder 6
Gadu Gadu: 2470956
    Windows 7Firefox

Re: total comander w builderze c++

Nowy postprzez Cyfrowy Baron » poniedziałek, 8 listopada 2010, 17:45

Tutaj wystarczy zwykła funkcja CopyFile(const char *lpExistingFileName, const char *lpNewFileName, int bFailExists). By można było skopiować plik z tą samą nazwą kopiowanie musi odbywać się między różnymi katalogami, czyli w FileListBox2 musi być wybrany inny katalog niż w FileListBox1. Chyba zdajesz sobie sprawę, że w jednej lokalizacji nie mogą być dwa pliki pod tą samą nazwą z takim samym rozszerzeniem. Do kopiowania katalogów z całą zawartością użyłem "latających folderów". Stworzona przeze mnie funkcja CopyFileListBox(TFileListBox *FromFileListBox, TFileListBox *ToFileListBox)
pozwala kopiować zarówno pojedyncze pliki i katalogi, jak również kilkanaście na raz, czyli obsługuje tzw MultiSelect. Poza tym funkcja działa dwukierunkowo, czyli wystarczy podać z której listy do której się kopiuje. Myślałem nad dodaniem metody Przeciągnij-Upuść, ale już nie chce mi się nad tym siedzieć.


plik nagłówkowy np. Unit1.h:
KOD cpp:     UKRYJ  
private:
        void __fastcall CopyFileListBox(TFileListBox *FromFileListBox,
                                                TFileListBox *ToFileListBox);


plik źródłowy np. Unit1.cpp:
KOD cpp:     UKRYJ  
#include <shellapi.h>

//---------------------------------------------------------------------------
void CopyDirectory(AnsiString oldDir, AnsiString newDir)
{
 SHFILEOPSTRUCTA fos;
 fos.hwnd = Application->Handle;
 fos.wFunc = FO_COPY;

 fos.pFrom = (oldDir + "\0").c_str();
 fos.pTo   = (newDir + "\0").c_str();

 fos.fFlags = 0;
 SHFileOperationA(&fos);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CopyFileListBox(TFileListBox *FromFileListBox,
        TFileListBox *ToFileListBox)
{
 String oldFile = FromFileListBox->FileName;
 int count = -1, selCount = FromFileListBox->SelCount;

 if(FromFileListBox->ItemIndex < 0)
 {
   ShowMessage("Nie wybrano pliku!");
   return;
 }

 if(FromFileListBox->Directory == ToFileListBox->Directory)
 {
   ShowMessage("Nie można kopiować pliku na ten sam plik!");
   return;
 }

 do
 {
  if(selCount > 1)
  {
   ++count;
   oldFile = FromFileListBox->Directory + "\\" +
             FromFileListBox->Items->Strings[count];

   if(!FromFileListBox->Selected[count]) continue;
  }

  if(FileGetAttr(oldFile) & faDirectory)
  {
   oldFile = StringReplace(oldFile, "[", "", TReplaceFlags() << rfReplaceAll);
   oldFile = StringReplace(oldFile, "]", "", TReplaceFlags() << rfReplaceAll);

   String dotDir = ExtractFileName(oldFile);

   if(DirectoryExists(oldFile) && dotDir != "." && dotDir != "..")
    CopyDirectory(oldFile, ToFileListBox->Directory);
  }
  else
  {
   String newFile = ToFileListBox->Directory + "\\" + ExtractFileName(oldFile);

   if(FileExists(newFile))
   {
    int IDx = Application->MessageBox( ("Ten folder zawiera już plik o nazwie: '"
    + ExtractFileName(oldFile) + "'\n\nCzy chcesz zastąpić istniejący plik?").c_str(),
    L"Kopiowanie plików", MB_YESNO | MB_ICONQUESTION);

    if(IDx == ID_YES) CopyFile( oldFile.c_str(), newFile.c_str(), false );
   }
   else
    CopyFile( oldFile.c_str(), newFile.c_str(), true );
  }

 }while(FromFileListBox->Items->Count - 1 > count && selCount > 1);

 ToFileListBox->Update() ; //odświeżam listę
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 CopyFileListBox(FileListBox1, FileListBox2);
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: total comander w builderze c++

Nowy postprzez niemamkolan » poniedziałek, 8 listopada 2010, 21:09

drag and drop też byłby dobry patent, ale to mi wystarczy, wielkie dzięki mate
Avatar użytkownika
niemamkolan
Bladawiec
Bladawiec
 
Posty: 12
Dołączył(a): poniedziałek, 11 października 2010, 16:45
Podziękował : 1
Otrzymał podziękowań: 0
System operacyjny: Win7 Ultimate x64
Kompilator: C++ Builder 6
Gadu Gadu: 2470956
    Windows 7Firefox

Kopiowanie plików metodą Drag and Drop

Nowy postprzez Cyfrowy Baron » wtorek, 9 listopada 2010, 11:46

Dodanie możliwości kopiowania za pomocą metody przeciągnij-upuść nie jest wielce skomplikowane zważywszy na fakt, że większość kodu została już opracowana. Trzeba tylko ustawić obiektom TFileListBox opcję DragMode na dmAutomatic. W przykładzie robię to w kodzie, ale można w Object Inspector. Nie będę objaśniał działania kodu, pomęcz się i przeanalizuj:

Kompletny kod:

plik nagłówkowy Unit1.h
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <FileCtrl.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TButton *Button1;
        TFileListBox *FileListBox1;
        TFileListBox *FileListBox2;
        TDirectoryListBox *DirectoryListBox1;
        TDirectoryListBox *DirectoryListBox2;
        TDriveComboBox *DriveComboBox1;
        TDriveComboBox *DriveComboBox2;
        void __fastcall Button1Click(TObject *Sender);
        void __fastcall FileListBox1DragOver(TObject *Sender, TObject *Source, int X,
          int Y, TDragState State, bool &Accept);
        void __fastcall FileListBox2DragOver(TObject *Sender, TObject *Source, int X,
          int Y, TDragState State, bool &Accept);
        void __fastcall FileListBox1DragDrop(TObject *Sender, TObject *Source, int X,
          int Y);
        void __fastcall FileListBox2DragDrop(TObject *Sender, TObject *Source, int X,
          int Y);

private:
        void __fastcall CopyFileListBox(TFileListBox *FromFileListBox,
                                                TFileListBox *ToFileListBox);
        void __fastcall FDragDrop(TObject *Source, TFileListBox *FListBox);

      /* kod odpowiedzialny za odświeżanie TFileListBox */
        TWndMethod ActiveApp;
        void __fastcall GetActiveApp(TMessage &Msg);

public:         // User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif


plik źródłowy Unit1.cpp
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <shellapi.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"


TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 FileListBox1->MultiSelect = true;
 FileListBox2->MultiSelect = true;

 FileListBox1->DragMode = dmAutomatic;
 FileListBox2->DragMode = dmAutomatic;

 ActiveApp = this->WindowProc;
 this->WindowProc = GetActiveApp;
}
//---------------------------------------------------------------------------
/* Funkcja przechwytująca komunikaty WindowProc - tutaj komunikat o aktywacji okna ma za zadanie odświeżać zawartość TFielListBox, gdy zmiany w zawartości katalogów zaszły poza programe, czyli np. kopiujesz w programie do katalogu [ c:\moje pliki jakiś ] plik, a potem w 'Eksploratorze Windows' usuwasz ten plik. Potem wracasz do swojego programu, a plik mimo iż został usunięty wciąż widnieje na liście TFileListBox. Ta funkcja eliminuje ten błąd odświeżając TFileList, gdy aktywujesz okno programu */

void __fastcall TForm1::GetActiveApp(TMessage &Msg)
{
 /* Msg.WParam == TRUE - odnosi się do aktywacji, FALSE - do dezaktywacji, bez tego warunku obsługiwane były by zarówno aktywacja i dezaktywacja */
 if(Msg.Msg == WM_ACTIVATEAPP && Msg.WParam == TRUE)
 {
  FileListBox1->Update();
  FileListBox2->Update();
 }

 ActiveApp(Msg);
}
//---------------------------------------------------------------------------
void CopyDirectory(AnsiString oldDir, AnsiString newDir)
{
 SHFILEOPSTRUCTA fos;
 fos.hwnd = Application->Handle;
 fos.wFunc = FO_COPY;

 fos.pFrom = (oldDir + "\0").c_str();
 fos.pTo   = (newDir + "\0").c_str();

 fos.fFlags = 0;
 SHFileOperationA(&fos);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CopyFileListBox(TFileListBox *FromFileListBox,
        TFileListBox *ToFileListBox)
{
 String oldFile = FromFileListBox->FileName;
 int count = -1, selCount = FromFileListBox->SelCount;

 if(FromFileListBox->ItemIndex < 0)
 {
   ShowMessage("Nie wybrano pliku!");
   return;
 }

 if(FromFileListBox->Directory == ToFileListBox->Directory)
 {
   ShowMessage("Nie można kopiować pliku na ten sam plik!");
   return;
 }

 do
 {
  if(selCount > 1)
  {
   ++count;
   oldFile = FromFileListBox->Directory + "\\" +
             FromFileListBox->Items->Strings[count];

   if(!FromFileListBox->Selected[count]) continue;
  }

  if(FileGetAttr(oldFile) & faDirectory)
  {
   oldFile = StringReplace(oldFile, "[", "", TReplaceFlags() << rfReplaceAll);
   oldFile = StringReplace(oldFile, "]", "", TReplaceFlags() << rfReplaceAll);

   String dotDir = ExtractFileName(oldFile);

   if(DirectoryExists(oldFile) && dotDir != "." && dotDir != "..")
    CopyDirectory(oldFile, ToFileListBox->Directory);
  }
  else
  {
   String newFile = ToFileListBox->Directory + "\\" + ExtractFileName(oldFile);

   if(FileExists(newFile))
   {
    int IDx = Application->MessageBox( ("Ten folder zawiera już plik o nazwie: '"
    + ExtractFileName(oldFile) + "'\n\nCzy chcesz zastąpić istniejący plik?").c_str(),
    L"Kopiowanie plików", MB_YESNO | MB_ICONQUESTION);

    if(IDx == ID_YES) CopyFile( oldFile.c_str(), newFile.c_str(), false );
   }
   else
    CopyFile( oldFile.c_str(), newFile.c_str(), true );
  }

 }while(FromFileListBox->Items->Count - 1 > count && selCount > 1);

 ToFileListBox->Update() ; //odświeżam listę
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FDragDrop(TObject *Source, TFileListBox *FListBox)
{
 CopyFileListBox(dynamic_cast<TFileListBox *>(Source), FListBox);
}
//  EVENTS ---------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender) /* Button1 Event OnClick */
{
 CopyFileListBox(FileListBox1, FileListBox2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FileListBox1DragOver(TObject *Sender, TObject *Source,
          int X, int Y, TDragState State, bool &Accept) /* FileListBox1 Event OnDragOver */
{
 Accept = Source->ClassNameIs("TFileListBox");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FileListBox2DragOver(TObject *Sender, TObject *Source,
          int X, int Y, TDragState State, bool &Accept)  /* FileListBox2 Event OnDragOver */
{
  Accept = Source->ClassNameIs("TFileListBox");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FileListBox1DragDrop(TObject *Sender, TObject *Source,
          int X, int Y)  /* FileListBox1 Event OnDragDrop */
{
  FDragDrop(Source, FileListBox1);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FileListBox2DragDrop(TObject *Sender, TObject *Source,
          int X, int Y)  /* FileListBox2 Event OnDragDrop */
{
  FDragDrop(Source, FileListBox2);
}
//---------------------------------------------------------------------------
 


Kod można by skrócić i w ten sposób uprościć stosując polymorphism, ale to wymagałoby opisu co i gdzie robię, więc nie będę komplikował. Dodam, że zdarzenia można łączyć ze sobą w Object Inspector na zakładce Events.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 8 gości