SHFILEOPSTRUCT, SHFILE Operation Dateien kopieren [gelöst]

Alles rund um die Programmierung mit Qt
Antworten
QT-Junkee
Beiträge: 18
Registriert: 14. März 2007 14:59

SHFILEOPSTRUCT, SHFILE Operation Dateien kopieren [gelöst]

Beitrag von QT-Junkee »

Hallo.

Ich benutze SHFILEOPSTRUCT für das Kopieren von Files aus einem bestimmten Ordner in einen Ordner, den der Programmbenutzer auswählt.

Diese Version funktioniert in meinem Programm einwandfrei:

Code: Alles auswählen


...

#define TEMPLATEPATH		"F:\\Myt\\Template\\*\0"
...

void CConverter::SavePathAndCopyFiles()
{

	QString directory = QFileDialog::getExistingDirectory(
			this,
			"Ausgabeordner wählen",
			"/home",
			QFileDialog::ShowDirsOnly |      QFileDialog::DontResolveSymlinks);

		if ("" != directory)
		{
			m_Ausgabeverzeichnis = directory;

			LPCWSTR szTargetName;
			szTargetName = (LPCWSTR)directory.utf16();

			TCHAR szSourceName[] = TEXT(TEMPLATEPATH);


			SHFILEOPSTRUCT s = { 0 };
			//s.hwnd = m_hWnd;
			s.wFunc = FO_COPY;
			s.pTo = szTargetName;
			s.pFrom = szSourceName;
			// Copy the template databases in the chosen folder
			s.fFlags = FOF_SILENT;
			SHFileOperation( &s );

         	}
}


Wenn ich aber versuche, den Pfad für den Ordner mit den Templates variabel zu gestalten, stosse ich auf ein Problem, das mir viel Nerven gekostet hat. Und zwar, kriegt der SHFILEOPSTRUCT kein vernünftiges s.pFrom Input, es findet kein Kopieren statt.

Dies ist die Variante:

Code: Alles auswählen


void CConverter::SavePathAndCopyFiles()
{
        QString TemplatesLocation;
	QString temp = QCoreApplication::applicationDirPath();
	QFileInfo fi(temp+"/Template");

	if (fi.exists())
	{
	TemplatesLocation= temp+"/Template/";
	TemplatesLocation= QDir::convertSeparators(TemplatesLocation);
        TemplatesLocation= TemplatesLocation+ "*\0";

	//////////////////////////////////////////////////////////////////////////
		QString directory = QFileDialog::getExistingDirectory(
			this,
			"Ausgabeordner wählen",
			"/home",
			QFileDialog::ShowDirsOnly |      QFileDialog::DontResolveSymlinks);

		if ("" != directory)
		{
			m_Ausgabeverzeichnis = directory;

			LPCWSTR szTargetName;
			szTargetName = (LPCWSTR)directory.utf16();

	                LPCWSTR szSourceName;
                        szSourceName = (LPCWSTR)TemplatesLocation.utf16();


			SHFILEOPSTRUCT s = { 0 };
			//s.hwnd = m_hWnd;
			s.wFunc = FO_COPY;
			s.pTo = szTargetName;
			s.pFrom = szSourceName;
			// Copy the template databases in the chosen folder
			s.fFlags = FOF_SILENT;
			SHFileOperation( &s );

         	}
	}
	else
	{
		QMessageBox::critical(this, tr("Progy"), "Der Ordner TEMPLATES konnte nicht gefunden werden.",
			QMessageBox::Ok, QMessageBox::NoButton);
		emit close();
	}
}


ich habe sehr viel Zeit investiert, den Fehler zu finden, aber ich schaffe es irgendwie nicht. HILFEEE.

Ich habe unter anderem auch dies hier versucht:

Code: Alles auswählen

..
        //TemplatesLocation.append(QChar('*'));
	//TemplatesLocation.append(QChar('\0'));
	//TemplatesLocation.replace(QChar('\0'), "\\0");
..
PLz help!

MFG
Zuletzt geändert von QT-Junkee am 26. November 2007 09:20, insgesamt 1-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Was hat das ganze jetzt mit Qt zu tun??
Warum soll überhaupt ne WinAPI-funktion hier benutzt werden?
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
QT-Junkee
Beiträge: 18
Registriert: 14. März 2007 14:59

Beitrag von QT-Junkee »

Weil das möglicherweise ein Konvertierungsproblem ist.
Weil diese API schneller , weniger als 1 sek braucht, um die Files rüber zu kopieren (gestestet).
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Schonmal mit QFile::copy() probiert - aber warum einfach wenn es auch kompliziert geht.. :roll:
Die Idee ein \0 anzufügen ist sinnlos -> http://doc.trolltech.com/4.3/qstring.html#utf16
Und der Rest hat nichts mit Qt zu tun, aber die msdn-Doku sagt Dir schon den Fehler:
msdn hat geschrieben: Although this member is declared as a single null-terminated string, it is actually a buffer that can hold multiple null-delimited file names. Each file name is terminated by a single NULL character. The last file name is terminated with a double NULL character ("\0\0") to indicate the end of the buffer.
D.h. Du musst dir selbst einen Buffer zusammenbauen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
QT-Junkee
Beiträge: 18
Registriert: 14. März 2007 14:59

Beitrag von QT-Junkee »

THX Christian, alles einleuchtend.
QT-Junkee
Beiträge: 18
Registriert: 14. März 2007 14:59

Beitrag von QT-Junkee »

Falls jemand noch die Lösung zum Zusammenbau von dem genannten Buffer braucht, hier ist die:

Code: Alles auswählen

	wchar_t *szSourceName = new wchar_t[TemplatesLocation.size() + 2];
	int len = TemplatesLocation.toWCharArray(szSourceName);
	szSourceName[len] = szSourceName[len + 1] = L'\0';
Dabei, wenn es zu einem LINK Error 2019 kommen sollte, muss man unter
Projekt->Projekteigenschaften->C/C++->Sprache->wchar_t als integrierten Typ behandeln auf Yes bzw. auf No setzen.

MFG
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

QT-Junkee hat geschrieben: Dabei, wenn es zu einem LINK Error 2019 kommen sollte, muss man unter
Projekt->Projekteigenschaften->C/C++->Sprache->wchar_t als integrierten Typ behandeln auf Yes bzw. auf No setzen.
Das kann ggf. Probleme machen wenn Qt nicht mit der Option kompiliert wurde.
besser gleich ein WCHAR - Array zu nehmen (oder ein entsprechend dimensioniertes QByteArray)
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten