CFileDialog, maximale Anzahl Dateinamen == 1143 ?

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

  • Hallo

    Folgendes Problem:
    Ich gebe der m_ofn Struktur einen genügend grossen Buffer (100000
    filenames), sowie die Angabe, wieviele characters dort reinpassen,
    jedoch werden auch bei einer Auswahl die grösser als 1143 Dateinamen
    ist, nicht mehr als 1143 davon eingelesen (d.h. m_numFiles == 1143) ?

    Sieht jemand das Problem ?

    vielen Dank
    xlr8


    ....
    #define MAX_FILENAMES 100000
    ....

    CArray<CString,CString> m_filenames;

    char m_fNameBuffer[_MAX_PATH*MAX_FILENAMES];
    long m_numFiles=0;

    // Create an instance
    CFileDialog fileDlg( TRUE, NULL, NULL, OFN_ALLOWMULTISELECT |
    OFN_HIDEREADONLY, "All Files (*.*)|*.*||", this);

    // Initializes m_ofn structure
    fileDlg.m_ofn.lpstrTitle = "Choose which pictures to analyze:";
    fileDlg.m_ofn.lpstrFile= m_fNameBuffer;
    fileDlg.m_ofn.nMaxFile= sizeof(m_fNameBuffer) +10;

    // Call DoModal
    fileDlg.DoModal();

    POSITION pos ( fileDlg.GetStartPosition() );


    // free filename array
    m_filenames.RemoveAll();


    while( pos )
    {
    CString csFileName( fileDlg.GetNextPathName( pos ) );
    m_filenames.Add(csFileName);
    }

    m_numFiles = m_filenames.GetSize();

    ....

  • Hallo,
    Nein sorry rein vom Syntax sieht das FAST Ok aus,bei mir stellt sich nur die Frage was 1143 für eine Zahl sein soll
    (1024,nun ja,das würde ich noch verstehen.....)


    Könnte es sein das du irgendwie die 64kB Grenze überschreitest oder so?
    Im Notfall:
    1142 Elemnte einfügen->Debugger->Jump into....
    1143 Elemten einfügen->Debugger->Jump into....


    Irgendwie müsste sich etwas feststellen lassen.....


    Peter

  • Was für eine 64KB Grenze meinst Du ?


    Jedenfalls versuche ich ca. 6000 Dateinamen einzulesen, könnten auch noch mehr sein.


    Habe aber folgendes entdeckt:


    Note, when selecting multiple files, the total character limit for the file names depends on the operating system and the version of the function.


    * Windows 95/98/Me: (only ANSI is supported) no restriction
    * Microsoft Windows NT4 and earlier: 32k limit
    * Windows 2000/XP: (ANSI) 32k limit, (Unicode) no restriction


    Somit muss ich anscheinend Unicode verwenden (XP). Weiss zwar nicht wo und wie, aber versuche das mal rauszufinden ...


    gruss
    André

  • Hallo,
    na gut dann 32KB... ;)
    also Unicode kannst du so einstellen:
    die afx.h öffnen,da vor allen Include Anweisungen schreibst du
    #define _UNICODE


    zusätzlich folgendes beachten,funktionen wie printf,sprintf usw. davon die Unicode Variante auswählen,statt char entweder tchar oder wchar


    Peter

  • Salü,


    habe das mal gemacht, dann bekomme ich aber eine Reihe von Compilierungsfehlern. _Muss_ ich nach der Definition von Unicode gewisse Unicode-Funktionen brauchen ? Kann ich nicht nur da wo ich das gerade brauche eine Unicode Funktion verwenden, sowie tchar / wchar ?
    Ein Ausschnitt aus den Fehlern :


    ------------------------------------
    vim.cpp(214) : error C2664: 'MessageBoxW' : cannot convert parameter 3 from 'char [6]' to 'const unsigned short *'
    Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast


    vim.cpp(356) : error C2664: 'GetModuleFileNameW' : cannot convert parameter 2 from 'char [260]' to 'unsigned short *'
    ------------------------------------


    Alle Fehler die auftreten sind vom Typ C2664.
    Was mir auffällt ist, dass ich z.B. MessageBox und nicht MessageBoxW brauche, wie dies im Fehler erscheint:

    CString s;
    s.LoadString(ID_ERROR_CIRCULAR_BUFFER);
    ::MessageBox(NULL, s, "Error", MB_OK |
    MB_ICONERROR);


    Wenn ich nun "Error" zu L"Error" ändere, fällt der Fehler weg. Muss ich also doch überall Unicode verwenden, nachdem ich _UNICODE definiere ?


    merci nochmals ...
    André

  • Hallo,
    tja entweder,oder....
    1.Wenn du weist das es sich um eine Windows 2000/XP Programm handelt,bzw. das du sagst "WinME User? Tja,Pech gehabt" solltest du
    ALLE String Funktionen in die entsprechenden Unicodeversion umwandel,bzw. Strings usw. entsprechend deklarieren,also wchar statt char,L"" statt "",usw.
    Bei größeren Programmen wirst du evtl. sogar eine Geschwindigkeitssteigerung mit Unicode bemerken.
    2.Du Programmierst das ganze OHNE Unicode,da müsste man bei einigen Funktionen aber evtl. etwas tricksen...
    3.Du verwendest beides gleichzeitig,bzw. du verwendest Funktionen die dann bei der Kompilierung entsprechend ersetzt werden,also TCHAR funktionen,diese werden dann je nachdem ob UNICODE definiert ist oder nicht.
    Also das Ganze nochmal zusammengefasst:
    Zeichenketten:
    ""->Kein UNICODE
    L""->UNICODE
    _T("")->Beides,wird beim Kompilieren umgesetzt
    Deklaration:
    char a[10]->Kein Unicode
    wchar_t a[10]->UNICODE
    _TCHAR a[10]->beides
    Funktionen:
    printf()->kein Unicode
    wprintf()->UNICODE
    _tprintf->beides


    Peter


    P.S.:Du solltest dir also das mit TCHAR oder gleich alles mit Unicode Programmieren,
    das mit TCHAR ist zwar ganz nett,führt aber auch zu Problemen weil du eben ohne Unicode einige Funktionen ändern muss,siehe z.B das CFileDialog,du müsstes dann eine #IFDEF Funktion einbauen und die Größe dann 32KB begrenzen.
    Mir ganz persönlich ist das etwas zu viel Tipparbeit,ich persönlich verwende daher nur die Unicode Version,wenn du das so machst sollte dein afx.h dann so ausehen:
    #define _UNICODE
    #define WINVER 0x0501
    #define _WIN32_WINNT 0x0501
    So das erzeugt dann zwar nur Win2000/XP Programme,bei Fehlern im Code bekomme ich dann aber wenigsten Hinweise.


    Peter

  • Servus,


    Heisst das für mich also wirklich folgendes:
    Nur damit ich in meinem CFileDialog mehr als 32 KB an Dateinamen einlesen kann, muss ich nun die ganze Software auf UNICODE umstellen, mit allen dazugehörigen Definitionen, d.h. alle Funktionen mit UNICODE Funktionen auswechseln, alle Datentypen entsprechend anpassen und viele, viele Makros einfügen ... ?


    Gibts da nicht nen schönen Hack, damit ich mir das ersparen kann ?


    Grundsätzlich könnte ich ja z.B. in meiner Applikation sagen, anstatt dass ich mit Ctrl-A einfach alles im Ordner anwähle (so mach ich das im Moment, meistens müssen sowieso alle Dateien in einem Ordner angewählt werden), wähle ich den Ordner aus, und es werden alle Dateien in diesem Ordner eingelesen.
    D.h. gibt es eine Funktion, welche mir bei Angabe des Pfades zu einem Ordner, alle darinliegenden Dateinamen zurückgibt, ohne eine Pufferbeschränkung (also wieder z.b. 32KB) ?


    Das ganze soll ausschliesslich auf einem XP Rechner laufen ...


    vielen Dank
    André

  • Hallo,


    Ich konnte mein Problem folgendermassen lösen:
    Den CFileDialog brauche ich nur noch, um an den Pfad zum Ordner zu kommen, in welchem die Dateien (hier .bmp) liegen. Dann lese ich alle Dateinamen nacheinander ein :



    ....
    CArray<CString,CString> m_filenames;
    struct _finddata_t c_file;
    long hFile;
    long cnt = 0;

    /* Find first .bmp file in tmp */
    CString pattern = "c:\\tmp\\*.bmp"; // in meiner App wird das generisch erstellt
    CString path = "c:\\tmp\\"; // den path lese ich mit dem CFileDialog ein

    if( (hFile = _findfirst( pattern, &c_file )) == -1L )
    AfxMessageBox("No .bmp files found !");
    else
    {
    theApp.m_filenames.Add(path += c_file.name);
    /* Find the rest of the .bmp files */
    while( _findnext( hFile, &c_file ) == 0 )
    {
    m_filenames.Add(path += c_file.name);
    }
    _findclose( hFile );
    }

    m_numFiles = m_filenames.GetSize();
    ...
    ...


    nun kann ich alle Dateien einlesen ...


    gruss
    André