[BCB] Przenoszenie plików do kosza... dziwny błąd...

0

Witam.

Jako że wszystkie odpowiedzi odnoszą się do Delphi i nie pomagają to może ktoś zajarzy co jest u mnie nie tak.
A więc...

Mam kod który skopiowany i wklejony działa idealnie pod warunkiem że jest bezpośrednio wykonywany a nie przez funkcję.

W chwili kiedy wykonuję go przez funkcję dostaję błąd :
"Access violation at adress 765EF7CC in module 'KERNELBASE.DLL'. Read of address 00000028."

Kod :

void __fastcall TForm1::DeleteFilesX(String FilePath)
{
 bool Recycled;
 if(CoB_Delete->ItemIndex == 0)         Recycled = true;
    else if(CoB_Delete->ItemIndex == 1) Recycled = false;

 if(Recycled)
   {
    //ShowMessage("Przeniesiono do kosza : \n" + ExtractFileName(FilePath));

    SHFILEOPSTRUCT fos;
    fos.hwnd = Handle;
    //operacja kasowania plików
    fos.wFunc = FO_DELETE;
    //pliki do skasowania
    String Plik = FilePath + "\0";
    fos.pFrom = Plik.c_str();
    //przeniesienie plików do kosza po ich skasowaniu
    fos.fFlags = FOF_ALLOWUNDO;
    SHFileOperation(&fos);

   }else{
         ShowMessage("Kasowanie trwałe !!!");

         //DeleteFile(FilePath);
        };
}

funkcja zdeklarowana jest w private jako :

   void __fastcall DeleteFilesX(String FilePath);

Udało mi się sprawdzić że błąd powstaje podczas już koncowego wykonania "SHFileOperation(&fos);"
I to wywala błąd właśnie....

Nie wywala za to jak wykonam go tak :

    SHFILEOPSTRUCT fos;
    fos.hwnd = Handle;
    //operacja kasowania plików
    fos.wFunc = FO_DELETE;
    //pliki do skasowania
    String Plik = CheckListBox1->Items->Strings[CheckListBox1->ItemIndex] + "\0";
    fos.pFrom = Plik.c_str();
    //przeniesienie plików do kosza po ich skasowaniu
    fos.fFlags = FOF_ALLOWUNDO;
    SHFileOperation(&fos);

Mam nadzieję że uda się wam mi coś poradzić bo już nie wiem co źle robię :(

0

Wyzeruj najpierw strukturę SHFILEOPSTRUCT, ew. jawnie ustaw na 0 nieużywane pola - będąc zmienną lokalną zbiera śmieci ze stosu i pola, których nie zapiszesz jawnie przyjmują wartość osobliwą. Znając życie SHFileOperation sprawdza, czy któryś z opcjonalnych pointerów nie jest zerowy i potem zagląda co pod nim siedzi - trafia na nieprawidłowy adres i kończy wyjątkiem.

0

Wyzerować czyli chodzi ci o to aby ustawić

fos.pFrom "\0";

? Bo jeżeli tak to nie działa to :(

1

po SHFILEOPSTRUCT fos; daj ZeroMemory(&fos, sizeof(fos));.

0

Dziękuje :) Działa świetnie :)

PS :

A orientujesz się może jak zrobić aby podczas usuwania (właściwie to przenoszenia) plików do kosza nie było za każdym razem zapytania o zgodę na to ? Bo nie widzę za bardzo możliwości :(

0

Nie widzisz? zajrzyj do dokumentacji:

FOF_NOCONFIRMATION

Respond with Yes to All for any dialog box that is displayed.
...
FOF_SILENT

Do not display a progress dialog box.

0

to wiem ale nie mogę tego połączyć z flagą

fos.wFunc = FO_DELETE;

Próbowałem :

fos.wFunc = FO_DELETE << FOF_NOCONFIRMATION; - ale nic nie działa
fos.wFunc = FO_DELETE && FOF_NOCONFIRMATION; - wyświetla informacje że plik źródłowy i docelowy taki sam :(

Ja... #$%%^&!!!

Przecież podstawiać mam pod
fos.fFlags = FOF_ALLOWUNDO; a nie wFunc... :(

1

Ech, flagi bitowe łączy się operatorem sumy bitowej, nie przesunięcia czy iloczynu logicznego, np. fos.wFunc = FO_DELETE | FOF_NOCONFIRMATION;.

0

Dzięki - nie ma to jak się skupić na całości :)

Całość poprawiona trochę :

void __fastcall TForm1::DeleteFilesX(String FilePath)
{
 if(CoB_Delete->ItemIndex == 0)
   {
    //ShowMessage("Przeniesiono do kosza : \n" + ExtractFileName(FilePath));
    SHFILEOPSTRUCT fos;
    // Zerowanie struktury ze zbędnych śmieci (bez tego wywali błąd "Access...")
    ZeroMemory(&fos, sizeof(fos));
    fos.hwnd = Handle;
    //operacja kasowania plików
    //fos.wFunc = FO_DELETE;
    fos.wFunc = FO_DELETE;
    //pliki do skasowania - poprawić
    String Plik = FilePath + "\0";
    fos.pFrom = Plik.c_str();
    //przeniesienie plików do kosza po ich skasowaniu bez zapytania o zgodę
    fos.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
    SHFileOperation(&fos);
   }else if(CoB_Delete->ItemIndex == 1)
           {
                    // Kasowanie bez odzyskiwania plików
            DeleteFile(FilePath);
           };
}

Może komuś się przyda :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0