Open File Dialog mit doppeltem backslash



  • Ich bin relativ sicher, das brauchst du nicht. Du möchtest doch am Ende einen String " C:\USER\Dokumente\Test " haben. Auch, wenn du in einem Stringliteral " C:\\USER\\Dokumente\\Test " notierst, kommt am Ende " C:\USER\Dokumente\Test " raus. Das war dir vielleicht noch nicht bewusst. Du kannst dich ja mal schlau machen, was genau Escapesequenzen sind und wie sie funktionieren.



  • Warum Du das auch immer brauchst, ich würde es mit Replace umsetzen...
    Vielleicht erklärst Du es uns ja noch!?

    String^ _newFileName = String::Empty;
    
    OpenFileDialog^ _FileDialog = gcnew OpenFileDialog();
    
    if(_FileDialog->ShowDialog() == System::Windows::Forms::DialogResult::OK)
    {
    		_newFileName = _FileDialog->FileName->Replace("\\","\\\\");
    		MessageBox::Show(_newFileName);//Ausgabe:
    }
    

    Edit: //Ausgabe: hinzugefügt



  • ok ich versuch mal zu erklären, für was ich das brauch:

    ich hab vor ein Programm zu schreiben, dass durch einen Open File Dialog den Pfad eines Ordners bekommt. Dies ist der Einlese-Pfad. Diese Ordner soll dann kopiert werden und wo anderst abgespeichert werden. Wohin abgespeichert wird soll durch einen zweiten Open File Dialog ausgewählt werden können.
    Kopiert wird mit folgender Funktion: http://msdn.microsoft.com/en-us/library/windows/desktop/bb759795(v=vs.85).aspx
    Für diese Funktion brauch ich jedoch den Pfad mit doppelten backslash.
    Wenn der Ordner dann kopiert ist, sollen die einzelnen Dateien in ein Array gespeichert werden.

    ich hoffe ich habe es verständlich erklärt.
    Gruß



  • FlorianB schrieb:

    Für diese Funktion brauch ich jedoch den Pfad mit doppelten backslash.

    Nein, brauchst du nicht. Die doppelten Backslashes brauchst du nur, wenn die Pfade als Stringliteral in deinem Code stehen.



  • FlorianB schrieb:

    ich hoffe ich habe es verständlich erklärt.

    War mein Post denn nicht verständlich erklärt? Ich hatte versucht zu erklären, dass du niemals doppelte Backslashes in einem Pfad brauchst. Du notierst sie nur in Stringliteralen (also die konstanten Strings, die du im Source in Anführungszeichen notierst), damit aus \\ ein einfacher Backslash wird. Denn der Backslash in Stringliteralen ist das initiale Zeichen für Escapesequenzen (z.B. \n für Newline). Damit man auch einen Backslash selbst im String ablegen kann und das darauffolgende Zeichen nicht zu interpretieren versucht wird, muss man in diesem Fall eben \\ notieren. Es sind dann aber nicht 2 Backslashes im String, sondern einer.



  • ok ich hab mir jetzt grad die Escapesequenzen angeschaut.
    Jetzt hab ichs verstanden, is ja im prinzip auch logisch, dass so die blackslashs angezeigt werden.

    nur wie mach ich das jetzt mit der SHFILEOPSTRUCT funktion?
    wenn ich den Pfad verwende, wie ich ihn vom Open File Dialog bekomm, kopiert die Funktion nichts
    Gruß



  • FlorianB schrieb:

    ok ich hab mir jetzt grad die Escapesequenzen angeschaut.
    Jetzt hab ichs verstanden, is ja im prinzip auch logisch, dass so die blackslashs angezeigt werden.

    nur wie mach ich das jetzt mit der SHFILEOPSTRUCT funktion?
    wenn ich den Pfad verwende, wie ich ihn vom Open File Dialog bekomm, kopiert die Funktion nichts
    Gruß

    Debuggen, Variableninhalte prüfen, Rückgaben prüfen (z.B. von SHFileOperation ). Wenn nichts hilft, ein Minimalbeispiel basteln, das den Fehler enthält, und hier posten.

    Btw, die Funktion heißt natürlich SHFileOperation . SHFILEOPSTRUCT ist das dazugehörige struct. 🙂



  • also ich habs mal durchgedebuggt.

    hier erst mal mein code:

    .
    .
    .
    void Programm::OnBnClickedQuellPath()
    {	
    
    	BROWSEINFO rBI= {0};
    	rBI.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI;
    	rBI.lpszTitle= L"Select Folder for Input Files";
    
    	LPITEMIDLIST pidl= SHBrowseForFolder( &rBI ); 
    	if ( pidl != NULL ) {  // else, user canceled	
    		TCHAR quellPath[MAX_PATH];
    		BOOL fRet= SHGetPathFromIDList( pidl, quellPath );
    		m_ctrlEditDecryptFilename.SetWindowTextW( quellPath );
    	}
    
    }	
    
    void Programm::OnBnClickedCopyPath()
    {	
    
    	BROWSEINFO rBI= {0};
    	rBI.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI;
    	rBI.lpszTitle= L"Select Folder for Output Files";
    
    	LPITEMIDLIST pidl= SHBrowseForFolder( &rBI ); 
    	if ( pidl != NULL ) {  // else, user canceled	
    		TCHAR copyPath[MAX_PATH];
    		BOOL fRet= SHGetPathFromIDList( pidl, copyPath );
    		m_ctrlEditEncryptFilename.SetWindowTextW( copyPath );
    	}
    
    }	
    
    void Programm::OnBnClickedStart()
    {	
    
    	SHFILEOPSTRUCT sf;
    	memset(&sf,0,sizeof(sf));
    	sf.hwnd = 0;
    	sf.wFunc = FO_COPY;
    	sf.pFrom = quellPath;
    	sf.pTo = copyPath;
    	sf.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI | FOF_SIMPLEPROGRESS;
    
    	int n = SHFileOperation(&sf);
    	if( n == 0)
    	{
    		LPTSTR geht = _T("Fertig");
    		m_ctrlEditChecksum.SetWindowText(geht);			//quellPath Kopiervorgang erfolgreich
    	}
    	else
    	{
    		LPTSTR nicht = _T("Fehler");
    		m_ctrlEditChecksum.SetWindowText(nicht);			//Kopiervorgang fehlgeschlagen
    	}
    .
    .
    .
    

    nun zu meinen ergebnissen:
    wenn ichs so laufen lass, zeigt er mir beim debuggen an, dass copyPath und quellPath ein Schlechtes Ptr sind und Fehler: CXX0030: Fehler: Ausdruck kann nicht ausgewertet werde.
    habs dann mal noch mit ner Testvariable versucht. Also mit LPTSTR quellPath = _T("C:\KA"); und mit LPTSTR copyPath = _T("C:\KA2");
    Wenn ichs so durchlaufen lass gehts auch nicht. Da fehlt dann bei der Veriable der Backslash. Wenn ich es jedoch mit doppelten Backslash laufen lass mit den Variablen, funktioniert es und er kopiert den Ordner.
    Kann mir da jemand weiter helfen. Ich bin noch anfänger in dem Gebiet und weiß nun nicht mehr weiter.
    Gruß



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum C++/CLI mit .NET in das Forum MFC (Visual C++) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • FlorianB schrieb:

    void Programm::OnBnClickedStart()
    {	
    		
    	SHFILEOPSTRUCT sf;
    	memset(&sf,0,sizeof(sf));
    	sf.hwnd = 0;
    	sf.wFunc = FO_COPY;
    	sf.pFrom = quellPath;    //<==
    	sf.pTo = copyPath;       //<==
    	sf.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI | FOF_SIMPLEPROGRESS;
    

    Wo hast du denn quellPath und copyPath her? In den anderen Funktionen legst du lokale Arrays quellPath und copyPath an. Die Variablen, die du hier verwendest, sind aber was anderes. Vermutlich Member der Klasse Programm . Oder Globale. Oder kopierst du den Inhalt der lokalen Variable quellPath ( OnBnClickedQuellPath ) irgendwann in die (klassen-)globale quellPath ? Ich vermute, das tust du nicht und genau das ist der Fehler.



  • also ich hab ne Headerdatei angelegt, in der hab ich copyPath und quellPath public angelegt. Das müsste doch passen oda?
    Ich steh grad irgendwie auf dem Schlauch 🙄
    wenn ich copyPath und quellPath als TCHAR deklariere in der Header mekert er bei der SHFileOperation. Wenn ich als LPTSTR deklariere mekert er zwar nicht, aber funktioniert auch nicht. Was mach ich jetzt falsch? Warscheinlich ein großer Fehler bei den Variablen.
    Gruß



  • FlorianB schrieb:

    also ich hab ne Headerdatei angelegt, in der hab ich copyPath und quellPath public angelegt. Das müsste doch passen oda?

    Nein! Du deklarierst doch dort lokale Variablen. Wenn du ein lokales quellPath anlegst, schreibst du auch da rein und nicht in deine Globale. Lösche die lokalen Deklarationen und schaue, was passiert. 😉



  • so ich bin schon weiter gekommen.
    hab jetzt in die headerdatei folgendes eingetragen:
    TCHAR quellPath[MAX_PATH];
    TCHAR copyPath[MAX_PATH];

    funktioniert auch wunderbar so. also das Pfad einlesen über den Open File Dialog.
    das Kopieren findet leider nicht statt.
    wenn ich durchdebugge, ist bei vollgender Codezeile ein falscher Wert:
    int n = SHFileOperation(&sf);

    n hat hier den Wert 1148. Aber warum?
    Wenn ich es durchlaufen lass mit Lokalen Variabeln, funktioniert es nur wenn ich doppelte Backslash eintrag. Dann hat n den Wert 0 und kopiert.
    Wenn ich es mit normalem Pfad durchlaufen lass, als mit einfachen Backslash, dann hat n den Wert 1026 und es wir nicht kopiert.

    Was mach ich jetzt noch falsch?
    Durch das debuggen hab ich einiges interessantes rausgefunden 🙂
    gruß



  • Hast Du mal die Doku zu SHFileOperation gelesen? Speziell wie der Pfad auifgebaut sein MUSS? Da reicht *nicht* eine \0 am Ende!



  • hey,
    hab mir alles nocheinmal durchgelesen.
    der Pfad muss doch so aussehen oda?:

    // RIGHT
    LPTSTR pszSource = L"C:\\Windows\\*\0";
    

    Gruß



  • richtig oder falsch?



  • kann mir keiner Helfen?
    MfG



  • Ich würde es so schreiben:

    LPCTSTR pszSource = _T("C:\\Windows\\*\0\0");
    


  • hey,

    ok hmm.
    Bei dem Pfad muss ich jetzt aber doppelte \\ angeben, Dann funktioniert der Kopiervorgang.
    Nur wie mach ich das jetzt mit dme OpenFileDialog-Pfad?
    Mit dem funktioniert es nämlich nicht. Es wird nichts kopiert.
    Gruß



  • hey,
    hab nach langem googeln was zu dem Thema gefunden.
    http://www.c-plusplus.net/forum/39295

    nur handelt es sich hierbei um einen AnsiString.
    Hat der TCHAR die gleichen Eigenschaften?
    Weil dann müsste die Funktion ja funktionieren.
    Gruß


Anmelden zum Antworten