UNICODE and JUCE_STRINGS_ARE_UNICODE


#1

Hello JUCEers,

Should I be defining both of these symbols for full compatibility with foreign-language OSes? Currently I define only JUCE_STRINGS_ARE_UNICODE.

I notice that juce_launchFile() calls ShellExecute instead of ShellExecuteW, regardless of the fact that JUCE_STRINGS_ARE_UNICODE is defined. Is this intentional? We use this to launch external viewers, and I suspect that this could fail on multibyte systems.

We also use File::loadFileAsData(), which seems to use wchar_t all the way through, and that operation is failing for our Japanese tester as well. Any ideas what could be going wrong? Is there any way to test and debug multibyte support, without switching my system to a language I don’t speak?

Thanks,
–scott


#2

I’d just leave the flag turned-on, if I were you. I’ll probably get rid of it entirely at some point, it was really just something I used early on for win98 support.

If you’ve got loadFileAsData failing, I’d just suggest stepping through, as it’ll probably be pretty obvious what’s going on.


#3

It seems I left out the most relevant detail, which is how the application obtains the filename. In this case, the user is drag-and-dropping the file onto the application icon, and the wide characters are garbage by the time I get hold of them in JUCEApplication::initialise(). Apparently you must use GetCommandLineW() to preserve any wide characters in the command line.

I hacked this in (Windows only, not sure what the Mac/Linux equivalent might be) by adding the following static method to the File class and calling it from the WinMain macro in juce.h:

[code]String File::getCommandLine ()
{
int argc = 0;
LPWSTR cmdLine = ::GetCommandLineW();
LPWSTR *argvw = ::CommandLineToArgvW(cmdLine, &argc);

LPWSTR p = argvw[1];
argc--;

String argumentString;
while (argc--)
	argumentString += String(p) + T(" ");


LocalFree(argvw);

return argumentString.trimEnd();

}[/code]


#4

Ok, that’s very interesting… I’ve checked-in some stuff that should hopefully sort it out for you now. Thanks!


#5

Hello again,

I looked over your changes (revision 497) and I don’t see where you are stripping off the executable name. Am I missing it? GetCommandLineW() returns the entire command line, not just the arguments.

Also, are the changes in JUCEApplication::main (int argc, char* argv[], JUCEApplication* const newApp) related? I don’t see where that is ever called.

Thanks for the prompt attention,
–scott


#6

Sorry, you’re right, how about this:

const String JUCE_CALLTYPE PlatformUtilities::getCurrentCommandLineParams() throw()
{
    String s (::GetCommandLineW());

    StringArray tokens;
    tokens.addTokens (s, true); // tokenise so that we can remove the initial filename argument

    return tokens.joinIntoString (T(" "), 1);
}

The version that takes argv and argc is just used on mac/linux.