[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