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
}

Dateigröße ermitteln

int iFileHandle;
int iFileLength;

if (OpenDialog1->Execute())
{
    iFileHandle = FileOpen(OpenDialog1->FileName, fmOpenRead);
    iFileLength = FileSeek(iFileHandle, 0, 2);
    FileClose(iFileHandle);
}

Anwendung ausführen

  • Aufruf-Beispiele:
AnsiString FileName = "c:windowscalc.exe";
RunApplication(FileName.c_str(), 0);

RunApplication("mailto:hallihallo@mail.de", 0);

RunApplication("http://www.google.de", 0);

RunApplication("meine.exe", "1 2 3");

RunApplication("net", "use");

RunApplication("format", "a: /s");
  • Code:
// führt per ShellExecute die Anwendung, die mit der Dateiendung von FileName
// assoziert ist aus, FileParam spezifiziert zusätzliche Aufrufparameter
void RunApplication(LPCTSTR FileName, LPCTSTR FileParam)
{
    int ret = (int) ShellExecute(0, "open", FileName, FileParam, 0, SW_SHOWNORMAL);

    if (ret <= 32)
    {
        AnsiString msg;

        switch(ret)
        {
            case ERROR_FILE_NOT_FOUND, SE_ERR_FNF :
            msg = &quot;Die angegebene Datei '&quot; + AnsiString(FileName) + &quot;' wurde nicht gefunden!&quot;;
            break;

            case ERROR_PATH_NOT_FOUND, SE_ERR_PNF :
            msg = &quot;Der Pfad zur Datei '&quot; + AnsiString(FileName) + &quot;' wurde nicht gefunden!&quot;;
            break;

            case ERROR_BAD_FORMAT :
            msg = &quot;Die aufgerufene Anwendung ist ungültig oder beschädigt!&quot;;
            break;

            case SE_ERR_ACCESSDENIED, SE_ERR_SHARE :
            msg = &quot;Der Zugriff auf die Datei '&quot; + AnsiString(FileName) + &quot;' wurde vom Betriebssystem verweigert!&quot;;
            break;

            case SE_ERR_ASSOCINCOMPLETE, SE_ERR_NOASSOC :
            msg = &quot;Der angegebene Dateityp ist auf Ihrem Computer keiner Anwendung zugeordnet!&quot;;
            break;

            case 0, SE_ERR_OOM :
            msg = &quot;Zum Ausführen der Anwendung ist nicht genügend Arbeitsspeicher frei!&quot;;
            break;

            default : msg = &quot;Datei '&quot; + AnsiString(FileName) + &quot;' konnte nicht geöffnet werden!&quot;;
        }

        Application->MessageBox(msg.c_str(), &quot;Fehler&quot;, MB_OK + MB_ICONERROR);
    }
}

ActiveX

  • Datei->Neu->Weitere->ActiveX->ActiveXForm wählen
  • Haken bei “Versionsinformationen hinzufügen”
  • der BCB generiert schon Quellcode und zeigt die ActiveX-Form an
  • Projekt->Optionen für Web-Distribution…
    • Ziel-Verzeichnis: Ausgabepfad
    • Ziel-URL: “./”
    • HTML-Verzeichnis: Ausgabepfad
  • Haken bei “CAB-Dateikompression verwenden”, “Versionsinfo der Datei übernehmen”, “Versionsnummer autom. inkrementieren”, “Benötigte Dateien weitergeben”
  • Form nach Belieben mit Funktionalität füllen und im Ausgabepfad speichern
  • Projekt->”Projektname” erzeugen
  • Projekt->Distribution über das Netz
  • Start->ActiveX-Server austragen
  • im Ausgabepfad stehen nun sämtliche Dateien (*.ocx, *.inf, *.htm, *.lib, *.cab)
  • *.htm doppelklicken

Eine ComboBoxEx mit Elementen füllen

TComboExItem* ExItem; // Zeiger auf ein ExItem

cbxTest->Clear();

ExItem = cbxTest->ItemsEx->Add(); // 1. Item hinzufügen
ExItem->Caption = &quot;Item1&quot;;
ExItem->ImageIndex = 10; // ItemIndex als ID-Merker benutzen
ExItem = cbxTest->ItemsEx->Add(); // 2. Item hinzufügen
ExItem->Caption = &quot;Item2&quot;;
ExItem->ImageIndex = 20; // ItemIndex als ID-Merker benutzen

cbxTest->ItemIndex = 0;

Eine ComboBox in einer StringGrid-Zelle anzeigen

  • auf eine Form 1 StringGrid mit 4 Spalten setzten, FixedCols = 1, FixedRows = 1, Name = sgStringGrid
  • *.h
__published: // Von der IDE verwaltete Komponenten
void __fastcall FormResize(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
void __fastcall ComboEditorChange(TObject *Sender); void __fastcall ComboEditorDropDown(TObject *Sender);
void __fastcall sgStringGridTopLeftChanged(TObject *Sender);
void __fastcall sgStringGridMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y);
void __fastcall sgStringGridMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y);

private: // Anwender-Deklarationen

TComboBox *pComboEditor; // unsere ComboBox AnsiString sOldEditValue; //Zwischenspeicher für alten Zellinhalt
void __fastcall SetColWidth(TStringGrid *Grid);
void __fastcall SetzeComboBox(TStringGrid *Grid);
void __fastcall FillComboEditor(TComboBox *CBox);
  • *.cpp

// Eine ComboBox mit entspr. Eigenschaften erzeugen
void __fastcall TForm1::FormCreate(TObject *Sender)
{
   pComboEditor = new TComboBox(/*Groupbox oder Panel oder sonstwas*/);
   pComboEditor->Parent = /*Groupbox oder Panel oder sonstwas*/;
   pComboEditor->Visible = false;
   pComboEditor->Style = csDropDownList;
   pComboEditor->DropDownCount = 8;
   pComboEditor->BevelInner = bvLowered;
   pComboEditor->BevelOuter = bvSpace;
   pComboEditor->BevelKind = bkSoft;
   pComboEditor->OnChange = ComboEditorChange;
   pComboEditor->OnDropDown = ComboEditorDropDown;
   
   // Items in die ComboBox laden
   FillComboEditor(pComboEditor);
}

// Funktion zum Füllen der ComboBox
void __fastcall TForm1::FillComboEditor(TComboBox *CBox)
{
   CBox->Items->Clear(); CBox->Items->Add("Test1");
   CBox->Items->Add("Test2");
   CBox->Items->Add("Test3");
   CBox->ItemIndex = 0;
}

// bei Programmende die ComboBox wieder löschen
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
   if (pComboEditor)
   {
      delete pComboEditor;
      pComboEditor = NULL;
   }
}

// Falls das Formular / Stringgrid in der Größe geändert wird,
// die ComboBox mit anpassen
void __fastcall TForm1::FormResize(TObject *Sender)
{
   SetColWidth(sgStringGrid);
   SetzeComboBox(sgStringGrid);
}

// Die Größe der letzten StringGrid-Spalte immer auf maximal setzen
void __fastcall TForm1::SetColWidth(TStringGrid *Grid)
{
   // Breite der letzten StringGridspalte an die Formularbreite anpassen:
   int ilColWidthsSum = 0;

   for (int ilCol = 0; ilCol < Grid->ColCount-1; ilCol++)
   {
      ilColWidthsSum += Grid->
      ColWidths[ilCol] + Grid->GridLineWidth;
   }
   
   if (ilColWidthsSum < Grid->ClientWidth) Grid->ColWidths[Grid->ColCount-1] = Grid->ClientWidth - ilColWidthsSum - 1;
}

// Falls im StringGrid gescrollt wird
void __fastcall TForm1::sgStringGridTopLeftChanged(TObject *Sender)
{
   TStringGrid *Grid = (TStringGrid*)Sender;
   SetzeComboBox(Grid);
}

// die eigentliche Funktion zum Setzten der ComboBox
void __fastcall TForm1::SetzeComboBox(TStringGrid *Grid)
{
   int iCol = Grid->Col;
   int iRow = Grid->Row;
   int iCSpalte = 3; // Combobox wir in die 3. Spalte gesetzt

   if ((iCol == iCSpalte) && (Grid->Cells[0][iRow] != ""))
   {
      TRect Rect = Grid->CellRect(iCol, iRow);
      if (Rect.Width() -> 10)
      {  // ComboBox in das TRect der Zelle einpassen
         pComboEditor->Visible = false;
         pComboEditor->Top = Grid->Top; // wichtig!!
         pComboEditor->Left = Grid->Left;
         pComboEditor->ItemIndex = pComboEditor->Items->IndexOf(Grid->Cells[iCol][iRow]);
         pComboEditor->Top = pComboEditor->Top + Rect.Top + Grid->GridLineWidth - 1;
         pComboEditor->Left = pComboEditor->Left + Rect.Left + Grid->GridLineWidth - 1;
         pComboEditor->Height = Rect.Height() + 1;
         pComboEditor->Width = Rect.Width();
         pComboEditor->Visible = true;
         pComboEditor->SetFocus();
      }
      else pComboEditor->Visible = true;
   }
   else pComboEditor->Visible = false;
}

// wenn ein Eintrag ausgewählt wurde, dann in die StringGrid Zelle einsetzen
void __fastcall TForm1::ComboEditorChange(TObject *Sender)
{
   sgStringGrid->Cells[sgStringGrid->Col][sgStringGrid->Row] = pComboEditor->Items->Strings[pComboEditor->ItemIndex];
}

// wenn die ComboBox angeklickt wird, den alten Zellinhalt zwischenspeichern (für spätere Verwendung)
void __fastcall TForm1::ComboEditorDropDown(TObject *Sender)
{
   sOldEditValue = sgStringGrid->Cells[sgStringGrid->Col][sgStringGrid->Row];
}

// wenn im StringGrid geklickt wird, ComboBox setzten // könnte vielleicht auch im OnClick-Ereignis des StringGrids abgehandelt werden
void __fastcall TForm1::sgStringGridMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
   TStringGrid *Grid = (TStringGrid*)Sender;
   if (Grid->Cells[0][1] != "")
   {
      Grid->Options << goEditing;
      SetzeComboBox(Grid);
   }
   else Grid->Options ->-> goEditing;
}

// Wenn im StringGrid die Maus losgelassen wird, nochmal die CBox-setzen
void __fastcall TForm1::sgStringGridMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
   TStringGrid *Grid=(TStringGrid*)Sender;
   SetColWidth(Grid); Grid->Repaint();
   SetzeComboBox(Grid);
}