функции Shfileoperation и Findfirstfile

dmitry003

New member
12.05.2009
4
0
#1
здравствуйте! есть вопрос - пытаюсь написать код для переименования всех файлов в заданной папке с помощью функций SHFileOperation и FindFirstFile - пишу код - проект компилируется (vs-2005 prof), но при попытке выполнить переименование - выскакивает мессадж параметр задан неверно. вот код:
Код:
void CPereimDlg::OnBnClickedButton3()
{
WIN32_FIND_DATA winFileData;
SHFILEOPSTRUCT fo;
ZeroMemory(&fo, sizeof(fo));
HANDLE hFile;
int nLen = szDisp.GetLength();
LPTSTR lpszBuf = szDisp.GetBuffer(nLen);
szDisp.ReleaseBuffer();
if (GetDlgItemText(IDC_EDIT1, szDisp)) 
{
lstrcat(lpszBuf,"\\*.txt");
hFile = FindFirstFile(lpszBuf,&winFileData);
if (hFile!=INVALID_HANDLE_VALUE)
{
do
{
char chFrom [256], chTo [256];
strcpy (chFrom, winFileData.cFileName);
strcpy (chTo, newName);
chFrom[strlen(chFrom)] = 0; 
chFrom[strlen(chFrom) + 1] = 0;

chTo[strlen(chTo)] = 0; 
chTo[strlen(chTo) + 1] = 0;
fo.wFunc = FO_RENAME;
fo.pFrom = chFrom;
fo.pTo = chTo;
fo.fFlags = FOF_RENAMEONCOLLISION;
}
while (FindNextFile(hFile,&winFileData)!=0);
FindClose(hFile);
}
int nRes = SHFileOperation(&fo);
}
return;
}
это последний вариант - до этого пробовал и без strcpy -результат тот же самый- компилируется но не исполняется.
 

grigsoft

Well-known member
15.11.2005
735
0
#2
1. Ты пытаешься переимновать все файлы за один вызов? так "You cannot use this flag to rename multiple files with a single function call. Use FO_MOVE instead. "
2. Путь к файлам должен быть полный, а в cFileName лежит только имя, без пути.
3. Память выделена в цикле, а используется вне цикла.
4. Если хочешь все сразу переименовать, то 256 байт не хватит. Если хочешь по одному, то вызов SHFileOperation долен быть в цикле.

Ркомендация стандартная - сесть и прогнать программу по шагам в отладке, глядя на состояние переменных. Внимательно изучить что в итоге лежит в fo в момент вызова SHFileOperation.
 

dmitry003

New member
12.05.2009
4
0
#3
да - посидел разобрался почти - но сделал пока без FindFirstFile - с флагом FILESONLY, не тестил поэтому не в курсе хватит ли памяти. На практике нужно будет перемещать и переименовывать максимум 200 jpg файлов.
код выложу завтра(пардон - послезавтра - завтра у жены день рождения :unsure: )
 

dmitry003

New member
12.05.2009
4
0
#4
ещё посидел - сделал с FinFirstFile - но результат не радует - по FO_MOVE перемещает в указанную папку но не переименовывает - так можно и просто одной SHFileOperation обойтись- но там тоже просто перемещает не переименовывая - по идее вот этот код должен работать - но компилится а при исполнении выдает "не удается переместить файл указано неправильное или слишком длинное имя файла. задайте другое имя" имя - короче некуда- test, test(1) и т.д. - в чем трабла- может как то по другому можно переименовать и переместить файлы вместе с папкой? а то скоро мозг взорвется - а отступать - не в принципах..
{
WIN32_FIND_DATA winFileData;
HANDLE hFile;
e_otkuda.GetWindowTextA(szDisplayName);
int nLen = szDisplayName.GetLength();
LPTSTR lpszBuf = szDisplayName.GetBuffer(nLen);
szDisplayName.ReleaseBuffer();
e_kuda.GetWindowTextA(szDisplayName2);
int nLen1 = szDisplayName2.GetLength();
LPTSTR kuda = szDisplayName2.GetBuffer(nLen1);
szDisplayName2.ReleaseBuffer();
if (GetDlgItemText(IDC_EDIT1, szDisplayName))
{
//lstrcat(lpszBuf,"\\*.jpg");
hFile = FindFirstFile(lpszBuf,&winFileData);
if (hFile!=INVALID_HANDLE_VALUE)
{
do
{
SHFILEOPSTRUCT fo;
ZeroMemory(&fo, sizeof(fo));
LPTSTR lpszBuf3 = winFileData.cFileName;
lstrcat(lpszBuf,"\\");
lstrcat(lpszBuf, lpszBuf3);
char chFrom [256], chTo [256];
strcpy (chFrom, lpszBuf);
strcpy (chTo, kuda);
chFrom[strlen(chFrom)] = 0;
chFrom[strlen(chFrom) + 1] = 0;

chTo[strlen(chTo)] = 0;
chTo[strlen(chTo) + 1] = 0;
fo.wFunc = FO_MOVE;
fo.pFrom = chFrom;
fo.pTo = chTo;
fo.fFlags = FOF_FILESONLY || FOF_SIMPLEPROGRESS || FOF_RENAMEONCOLLISION;
SHFileOperation (&fo);
}
while (FindNextFile(hFile,&winFileData)!=0);
FindClose(hFile);
}
}
return;
}