FileChooser - filter implemented incorrectly on windows when using native dialog


#1


I'm using Windows 7, latest Juce version.
Problem is in file juce_win32_FileChooser.cpp around line 224 where "filter" is copied to "filters". 
Windows OPENFILENAMEW structure uses \0 characters to separate filters. This is ignored in juce implementation.

This is copy/paste from MSDN
lpstrFilter
Type: LPCTSTR
A buffer containing pairs of null-terminated filter strings. The last string in the buffer must be terminated by two NULL characters.
The first string in each pair is a display string that describes the filter (for example, "Text Files"), and the second string specifies the filter pattern (for example, "*.TXT"). To specify multiple filter patterns for a single display string, use a semicolon to separate the patterns (for example, "*.TXT;*.DOC;*.BAK"). A pattern string can be a combination of valid file name characters and the asterisk (*) wildcard character. Do not include spaces in the pattern string.
The system does not change the order of the filters. It displays them in the File Types combo box in the order specified in lpstrFilter.
If lpstrFilter is NULL, the dialog box does not display any filters.
In the case of a shortcut, if no filter is set, GetOpenFileName and GetSaveFileName retrieve the name of the .lnk file, not its target. This behavior is the same as setting the OFN_NODEREFERENCELINKS flag in the Flags member. To retrieve a shortcut's target without filtering, use the string "All Files\0*.*\0\0".
 


#2

I managed to fix it by adding couple of lines to juce_win32_FileChooser.cpp and replacing '|' characters with \0.

 

        filter.copyToUTF16(filters + (bytesWritten / sizeof(WCHAR)),
            ((filterSpaceNumChars - 1) * sizeof(WCHAR) - bytesWritten));

        for (int i = 0; i < filterSpaceNumChars; i++)
            if (filters[i] == '|')  filters[i] = '\0';

        OPENFILENAMEW of = { 0 };

I call FileChooser like this now:

FileChooser fc("Open", File::getCurrentWorkingDirectory(), "All Files|*.*|G-Code Files|*.nc;*.tap;*.cnc;*.iso;*.gcode;*.ncf;*.txt|DXF Files|*.dxf||", useNativeVersion);

 

 

 

 


#3

It alo does not work correctly in Linux with Zenity

I fixed it by replacing this

args.add ("--file-filter");
args.add (filters.replaceCharacter (';', ' '));

args.add ("--file-filter");
args.add ("All files | *");

to this

StringArray tokens;
tokens.addTokens(filters, ";", "\"");
for (int i = 0; i < tokens.size(); i++)
{
    args.add("--file-filter=" + tokens[i]);
}

in file juce_linux_FileChooser.cpp

 


#4

Ah, good catch - thanks! Will sort that out..


#5

G-Code files? You're parsing CAM files using JUCE? I guess you must be controlling some interesting machines in the same application?

Care to share (show-case?) your software? :)


#6

So you're adding multiple "--file-filter=<file>" arguments?
Are you sure that works?
 


#7

Yes, multiple --file-filter arguments must be used.


#8

You can get more information about my software on my web site www.planet-cnc.com


#9

It is still not OK. You also need to remove those two lines:

        filter.copyToUTF16 (filters + (bytesWritten / sizeof (WCHAR)),
                            ((filterSpaceNumChars - 1) * sizeof (WCHAR) - bytesWritten));

file: juce_win32_FileChooser.cpp line: 225