FileAttribute lesen und setzen

// faReadOnly  0x01  Schreibgeschützte Datei
// faHidden    0x02  Verborgene Datei
// faSysFile   0x04  Systemdatei
// faVolumeID  0x08  Laufwerks-ID
// faDirectory 0x010 Verzeichnis
// faArchive   0x020 Archivdatei
// faAnyFile   0x03F Beliebige Datei

// FileAttribute lesen
int iAttrs = FileGetAttr("test.txt");

if (iAttrs & faReadOnly)
{
    // wenn readonly gesetzt
}

// FileAttribute, z.B. 'readonly' und 'system', setzen
FileSetAttr("test.txt", faReadOnly | faSysFile);

Versionsinformationen einer Datei lesen

  • Verwendung:
VerInfo * pVer = new VerInfo("C:\\WINDOWS\\notepad.exe");

for (int i = 0; i < 10; i++)
{
    Memo1 -> Lines -> Add(pVer -> GetVerInfo(ilCount));
}

if (pVer != NULL) { delete pVer; pVer = NULL; }
  • *.h
#ifndef versionsinfoH
#define versionsinfoH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <vcl.h>
//----------------------------------------------------------------
// Konstanten für die Verwendung als Parameter mit der
// Funktion GetVerInfo(int iId):
//-----------------------------------------------------------------
const int VI_COMPANY_NAME      = 0;      // Firmen-Name
const int VI_FILE_DESCRIPTION  = 1;      // Dateibeschreibung
const int VI_FILE_VERSION      = 2;      // Versionsnummer
const int VI_INTERNAL_NAME     = 3;      // Interner Name
const int VI_LEGAL_COPYRIGHT   = 4;      // Copyright-Info
const int VI_LEGAL_TRADEMARKS  = 5;      // Warenzeichen
const int VI_ORIGINAL_FILENAME = 6;      // Orig.-Dateiname
const int VI_PRODUCT_NAME      = 7;      // Produktname
const int VI_PRODUCT_VERSION   = 8;      // Produkt-Version
const int VI_FILE_COMMENTS     = 9;      // Kommentare

class TVerInfo
{
      private:

        AnsiString sCompany_name;
        AnsiString sFile_description;
        AnsiString sFile_version;
        AnsiString sInternal_name;
        AnsiString sLegal_copyright;
        AnsiString sLegal_trademarks;
        AnsiString sOriginal_filename;
        AnsiString sProduct_name;
        AnsiString sProduct_version;
        AnsiString sFile_comments;

      protected:

        char *GetVersionKey(char *cBuffer, const AnsiString &sPrefix, char *cKey);

      public:

        __fastcall TVerInfo(AnsiString sExeName);
        AnsiString GetVerInfo(int iID);
};
#endif
  • *.cpp
__fastcall TVerInfo::TVerInfo(AnsiString sExeName)
{
           DWORD dwHandle;
           DWORD dwSize;

           sCompany_name       = "";
           sFile_description   = "";
           sFile_version       = "";
           sInternal_name      = "";
           sLegal_copyright    = "";
           sLegal_trademarks   = "";
           sOriginal_filename  = "";
           sProduct_name       = "";
           sProduct_version    = "";
           sFile_comments      = "";

           if (FileExists(sExeName))
           {
              dwSize = GetFileVersionInfoSize(sExeName.c_str(), &dwHandle);

              if (dwSize > 0)
              {
                 char *cBuffer = new char[dwSize];

                 if (GetFileVersionInfo(sExeName.c_str(), 0, dwSize, cBuffer))
                 {
                    UINT uiDataSize;
                    unsigned short *usTranslation;
                    VerQueryValue(cBuffer, "\\VarFileInfo\\Translation",(void **) &usTranslation, &uiDataSize);

                    AnsiString sPrefix = "\\StringFileInfo\\" + AnsiString::IntToHex(usTranslation [0], 4)+ AnsiString::IntToHex(usTranslation [1], 4);

                    sCompany_name       = GetVersionKey(cBuffer, sPrefix, "CompanyName");
                    sFile_description   = GetVersionKey(cBuffer, sPrefix, "FileDescription");
                    sFile_version       = GetVersionKey(cBuffer, sPrefix, "FileVersion");
                    sInternal_name      = GetVersionKey(cBuffer, sPrefix, "InternalName");
                    sLegal_copyright    = GetVersionKey(cBuffer, sPrefix, "LegalCopyright");
                    sLegal_trademarks   = GetVersionKey(cBuffer, sPrefix, "LegalTrademarks");
                    sOriginal_filename  = GetVersionKey(cBuffer, sPrefix, "OriginalFilename");
                    sProduct_name       = GetVersionKey(cBuffer, sPrefix, "ProductName");
                    sProduct_version    = GetVersionKey(cBuffer, sPrefix, "ProductVersion");
                    sFile_comments      = GetVersionKey(cBuffer, sPrefix, "Comments");
                 }

                 delete [] cBuffer;
              }
           }
}

char* TVerInfo::GetVersionKey(char *cBuffer, const AnsiString &sPrefix, char *cKey)
{
      char *cData;
      UINT uiDatasize;
      AnsiString sFullkey = sPrefix + "\\" + cKey;
      bool bStatus = VerQueryValue(cBuffer, sFullkey.c_str(), (void **)&cData, &uiDatasize);
      return (bStatus) ? cData : "";
}

AnsiString TVerInfo::GetVerInfo(int iID)
{
           AnsiString sRetValue;

           switch (iID)
           {
                  case VI_COMPANY_NAME      : { sRetValue = sCompany_name; break; }
                  case VI_FILE_DESCRIPTION  : { sRetValue = sFile_description; break; }
                  case VI_FILE_VERSION      : { sRetValue = sFile_version; break; }
                  case VI_INTERNAL_NAME     : { sRetValue = sInternal_name; break; }
                  case VI_LEGAL_COPYRIGHT   : { sRetValue = sLegal_copyright; break; }
                  case VI_LEGAL_TRADEMARKS  : { sRetValue = sLegal_trademarks; break; }
                  case VI_ORIGINAL_FILENAME : { sRetValue = sOriginal_filename; break; }
                  case VI_PRODUCT_NAME      : { sRetValue = sProduct_name; break; }
                  case VI_PRODUCT_VERSION   : { sRetValue = sProduct_version; break; }
                  case VI_FILE_COMMENTS     : { sRetValue = sFile_comments; break; }
                  default                   : { sRetValue = ""; }
           }

           return sRetValue;
}

LogFile erstellen (zeilenweise in eine Datei schreiben)

void __fastcall TForm1::WriteToFile(AnsiString sLine)
{
    FILE *OutputFile; //Zeiger auf das Logfile
    AnsiString sLogFileName = "test.log";

    // File wird im Modus Append (a) und Text (t) geöffnet
    if ((OutputFile = fopen(sLogFileName.c_str(), "a+t")) == NULL)
    {
        ShowMessage("Fehler beim Öffnen der Datei");
    }
    else
    {
        //Zeilenvorschub zum String hinzufügen
        sLine += "\n";

        //Zeile in die Datei 1x schreiben
        fwrite(sLine.c_str(), sLine.Length(), 1, OutputFile);

        fclose(OutputFile);
    }
}

Ein Verzeichnis (alle Ordner und Dateien) mit findfirst und findnext auslesen

  • Im folgenden Beispiel wird der Inhalt eines Verzeichnisses (c:) in einer ListBox dargestellt.
  • Die Hilfsfunktionen ConvertTimeToStr(), ConvertDateToStr() und ConvertAttribToStr() extrahieren Fileinformationen aus dem Struct dirinfo und generieren daraus fertige AnsiStrings.
  • u.U. sollte man noch den Header dir.h einbinden
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    struct ffblk dirinfo;

    // zum 1. Directoryeintrag in c: springen und alle Filetypen suchen
    int result = findfirst("c:\\*.*", &dirinfo, FA_NORMAL | FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_DIREC | FA_ARCH);

    // solange Einträge da sind, in der Listbox ausgeben
    while (result == 0)
    {
        ListBox1->Items->Add(ConvertTimeToStr(dirinfo.ff_ftime)) +", "+ ConvertDateToStr(dirinfo.ff_fdate)) +", "+ ConvertAttribToStr(dirinfo.ff_attrib)));
        result = findnext(&dirinfo);
    }
}

AnsiString __fastcall TForm1::ConvertTimeToStr(int ffTime)
{
    return IntToStr(ffTime & 0x1F) + ":" + IntToStr(ffTime & 0x3F) + ":" + IntToStr(2 * (ffTime & 0x1F));
}

AnsiString __fastcall TForm1::ConvertDateToStr(int ffDate)
{
    return IntToStr(ffDate & 0x1F) + ":" + IntToStr(ffDate & 0xF) + ":" + IntToStr((ffDate & 0x7F) + 1980);
}

AnsiString __fastcall TForm1::ConvertAttribToStr(int ffAttrib)
{
    AnsiString sResult = "";
    if ((ffAttrib & FA_DIREC) != 0 ) sResult = sResult + "D";
    if ((ffAttrib & FA_RDONLY) != 0 ) sResult = sResult + "R";
    if ((ffAttrib & FA_HIDDEN) != 0 ) sResult = sResult + "H";
    if ((ffAttrib & FA_SYSTEM) != 0 ) sResult = sResult + "S";
    if ((ffAttrib & FA_ARCH) != 0 ) sResult = sResult + "A";
    if ((ffAttrib & FA_NORMAL) != 0 ) sResult = sResult + "N";
    return sResult;
}

FileStreams lesen und schreiben

Die Datensätze (struct) werden in eine Datei geschrieben und daraus ein beliebiger Datensatz zurückgelesen.

  • Im Beispielprogramm werden zwei Buttons verwendet, hinter denen sich das Schreiben bzw. Lesen verbirgt
  • Edit1 beinhaltet die Nummer des zu lesenden Datensatzes
  • Die gelesenen TestDaten werden in einem Memofeld ausgegeben
  • Daten, die in dem Struct ‘Daten’ vom Typ data stehen, werden in eine Datei ‘datafile.dat’ im aktuellen Verzeichnis geschrieben
  • soll die Datei später in einem anderen Zusammenhang geöffnet werden, so muss im TFileStream-Konstruktor statt fmCreate fmOpenRead, fmOpenWrite oder fmOpenReadWrite verwendet werden!!
  • Unit1.h
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
struct data
{
    char Name[15]; // 15 Zeichen langer Name -> kein (!!!) AnsiString verwenden!!!
    bool bWert;
    DWORD dwWert;
    float fWert;
    int iWert;
};

class TForm1 : public TForm
{
__published: // Von der IDE verwaltete Komponenten

    TButton *Button1;
    TMemo *Memo1;
    TButton *Button2;
    TEdit *Edit1;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall Button2Click(TObject *Sender);

private: // Anwender-Deklarationen
public:  // Anwender-Deklarationen

    data *Daten; //Zeiger auf eine Datenstruktur
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
  • Unit1.cpp
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    float Temp; // temporäre Zwischenvariable für float-Wert
    int i;
    AnsiString Name;

    Daten = new data; // Neues Datenstruktur-Objekt
    TFileStream *Datei = new TFileStream(".datafile.dat", fmCreate);

    // 100 Testwerte schreiben
    for (i=1;i<=100;i++)
    {
        Name = "Testname" + IntToStr(i);   // Namen zusammenbauen
        strcpy(Daten->Name, Name.c_str()); // und nach Daten->Name übergeben

        Daten->bWert = i%2 ? true : false; // bool-Wert übergeben
        Daten->dwWert = i;
        Temp = i;
        Daten->fWert = Temp/2;             // float-Wert übergeben
        Daten->iWert = i;                  // int-Wert übergeben

        Datei->Write(Daten, sizeof(data)); // struct "Daten" in die Datei schreiben
    }

    delete Daten;
    delete Datei;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    Daten = new data;
    TFileStream *Datei = new TFileStream(".datafile.dat", fmOpenRead);

    // Datensatzzeiger auf den entsprechenden Datensatz setzen
    // in Edit1 steht die Nummer des zu lesenden Datensatzes
    Datei->Seek(Edit1->Text.ToIntDef(1) * sizeof(data), soFromBeginning);

    // Daten aus der Datei in das struct "Daten" einlesen
    Datei->Read(Daten, sizeof(data));

    // Testdaten ausgeben
    Memo1->Lines->Clear();
    Memo1->Lines->Add(Daten->Name);

    if (Daten->bWert) Memo1->Lines->Add("true");
    else Memo1->Lines->Add("false");

    Memo1->Lines->Add(IntToStr(Daten->dwWert));
    Memo1->Lines->Add(FloatToStr(Daten->fWert));
    Memo1->Lines->Add(IntToStr(Daten->iWert));

    delete Daten;
    delete Datei;
}

INI-Dateien erstellen/bearbeiten

#include "inifiles.hpp" //wichtig!!!

void __fastcall TForm1::IniAction(AnsiString IniData)
{
    AnsiString sIniFileName;
    AnsiString IniData;

    sIniFileName = ExtractFilePath(ParamStr(0)) + "IniDatei.ini";

    TIniFile* IniFile = new TIniFile(sIniFileName);
    if (IniFile != NULL)
    {
        IniFile -> UpdateFile();

        // IniData lesen:
        IniData = IniFile -> ReadString("ReadSection", "Key", "Defaultwert");

        // IniData schreiben:
        IniFile -> WriteString("WriteSection", "Key", IniData);

        delete IniFile;
        IniFile = NULL;
    }
}

Datenbanktabellen (SQLQuery-Abfragen) in eine CSV-Datei schreiben

void __fastcall TForm1::SaveToCSV(TQuery *Abfrage)
{
    TStringList *Spaltenbezeichner, *Ausgabe;
    AnsiString Bezeichner, Inhalt;

    Spaltenbezeichner = new TStringList;
    Ausgabe = new TStringList;

    // ermittle die Spaltenbezeichner
    Abfrage->GetFieldNames(Spaltenbezeichner);

    for (int Spalte=0; Spalte < Spaltenbezeichner->Count; Spalte++)
    {
        Bezeichner += Spaltenbezeichner->Strings[Spalte] + &quot;;&quot;;
    }

    // schreibe die Bezeichner ins AusgabeStringlistenObjekt
    Ausgabe->SetText(Bezeichner.c_str());
    delete Spaltenbezeichner;

    Abfrage->First();

    // ermittle die Einträge aus aktuellem Datensatz
    for (int Zeile=0; Zeile < Abfrage->RecordCount; Zeile++)
    {
        for (int Spalte = 0; Spalte < Abfrage->Fields->Count; Spalte++)
        {
            //gehe zur nächsten Zeile des Abfrageobjekts
            //schreibe Zeile in String durch ; getrennt
            Inhalt += Abfrage->Fields->Fields[Spalte]->AsString + &quot;;&quot;;
        }

        // schreibe Zeile in AusgabeStringlistenobjekt
        Ausgabe->Append(Inhalt);

        // leere String -> für Werte aus neuer Zeile
        Inhalt = &quot;&quot;;

        // gehe zu nächstem Datensatz
        Abfrage->Next();
    }

    // speichere Inhalt als CSV-Datei
    Ausgabe->SaveToFile(&quot;c:\\Ausgabedatei.csv&quot;);

    Application->MessageBox(&quot;Datei wurde erfolgreich gespeichert&quot;, &quot;Hinweis&quot;, MB_OK);
    delete Ausgabe;
}

Prozess mit CreateProcess starten und auf Beendigung warten

void __fastcall StartProcess()
{
    AnsiString sPrgName = "c:winnt
otepad.exe";

    AnsiString sWorkDir = "c:winnt";

    TProcessInformation prozessinfo;
    TStartupInfo startinfo;

    startinfo.cb = sizeof(TStartupInfo);
    setmem(&startinfo,sizeof(TStartupInfo),0);

    if (CreateProcess(NULL, sPrgName.c_str(), NULL, NULL, false, CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, sWorkDir.c_str(), &startinfo, &prozessinfo) == true)
    {
        //Speicher freigeben
        CloseHandle(prozessinfo.hThread);

        //Warteschleife, die PROZESSINFO abfragt
        while(WaitForSingleObject(prozessinfo.hProcess, 100) == WAIT_TIMEOUT)
        Application->ProcessMessages();

        //hier angekommen ist das Programm durch den Benutzer beendet worden
        Application->MessageBox("Programm geschlossen!","",MB_OK);

        //Speicher freigeben
        CloseHandle(prozessinfo.hProcess);
    }
}

Dateien über WINSHELLAPI kopieren oder bewegen

  • Aufruf:
// Quelle: Pfad + Dateiname(n) der Quelldatei(en)
// Ziel: Zielpfad
// Modus: 0 - Dateien kopieren, 1 - Dateien bewegen
if (!CopyMoveFiles("c:\\Temp*.*", "c:\\TempTest", 0))
    ShowMessage("Ausführung erfolgreich !");
else
    ShowMessage("Fehler aufgetreten !");
  • Code:
int TForm1::CopyMoveFiles(AnsiString slSourceDir, AnsiString slTargetDir, int Mode)
{
    SHFILEOPSTRUCT sh;
    ZeroMemory(&sh, sizeof(sh));

    sh.hwnd = NULL;

    sh.fFlags = FOF_NOCONFIRMATION | FOF_FILESONLY | FOF_NOCONFIRMMKDIR | FOF_SILENT;

    if (Mode == 0)

        sh.wFunc = FO_COPY; // Dateien kopieren

    else

        sh.wFunc = FO_MOVE; // Dateien bewegen

    slSourceDir+="\0";
    sh.pFrom = slSourceDir.c_str();
    slTargetDir+="\0";
    sh.pTo = slTargetDir.c_str();
    sh.hNameMappings = NULL;
    sh.lpszProgressTitle = NULL;

    return SHFileOperation (&sh); // Aktion durchführen
}