Unicode: how to properly read and display directory entries?

Tyro[a.c.edwards] nospam at home.com
Fri Nov 5 14:37:00 PDT 2010


On 11/6/2010 2:10 AM, Dmitry Olshansky wrote:
> On 05.11.2010 18:25, Tyro[a.c.edwards] wrote:
>> On 11/5/2010 10:51 PM, Kagamin wrote:
>>> Tyro[a.c.edwards] Wrote:
>>>
>>>> Hello,
>>>>
>>>> What is the proper way to read a directory such that file names are not
>>>> garbled? Here is the example I borrowed form the std.file
>>>> documentation.
>>>> Screen shots of folder is attached. Thanks.
>>>>
>>>> void main(string[] args)
>>>> {
>>>> bool callback(DirEntry* de)
>>>> {
>>>> if (de.isfile)
>>>> mciPlay(toUTF8(de.name));
>>>> return true;
>>>> }
>>>>
>>>> listdir("snd",&callback);
>>>> }
>>>>
>>>> D:\code>play
>>>> snd\american.ogg
>>>> snd\bigdog.flac
>>>> snd\blackmail.mp3
>>>> snd\ding.wav
>>>> snd\kam.aif.aiff
>>>> snd\豺。縺・ogg
>>>>
>>>
>>> http://d.puremagic.com/issues/show_bug.cgi?id=2742
>>
>> Much appreciate the info. I'm not however interested in outputting to
>> the console. I'm trying to call mciSendString with the name of each
>> file contained in the directory. The process fails however, when it
>> encounters a Japanese file name. Please see code below. Any idea what
>> I'm doing wrong?
>>
>> import std.file;
>> import std.string : cstring = toStringz;
>> import std.c.windows.windows;
>>
>> pragma(lib, "winmm.lib" );
>>
>> extern(Windows) {
>> uint mciSendStringW(
>> LPCWSTR lpszCommand,
>> LPWSTR lpszReturnString,
>> uint cchReturn,
>> HANDLE hwndCallback);
>> }
>>
>> void main(string[] args)
>> {
>> bool callback(DirEntry* de)
>> {
>> if (de.isfile)
>> mciPlay(de.name);
>> return true;
>> }
>>
>> listdir("snd", &callback);
>> }
>>
>> void mciPlay(string audio)
>> {
>> uint mciSendString(string s)
>> {
>> return mciSendStringW( cast(LPCWSTR)s, cast(LPWSTR)null, 0,
>> cast(HANDLE)0 );
>> }
>>
>> auto exists = mciSendString(`open "` ~ audio ~ `" type mpegvideo alias
>> myFile`);
>> auto played = mciSendString("play myFile wait");
>> scope(exit) mciSendString("close myFile");
>> }
> In short : never rely on the casts to do the right thing.
> Bug is here:
> return mciSendStringW( cast(LPCWSTR)s, cast(LPWSTR)null, 0,
> cast(HANDLE)0 );
> changing that to more accurate:
> return mciSendStringW(toUTF16z(s) , cast(LPWSTR)null, 0, cast(HANDLE)0 );
> works for me, even with this name:
> snd\와카미야 온마쓰리.mp3
>
> If you use W version you need to re-encode your UTF8 string to UTF16.
> AFAIK Windows uses slightly outdated version of UTF16, check the web on
> issues.
>

That's it! Thank you much. I tried the toUTFXX() function calls but 
completely missed toUTF16z.


More information about the Digitalmars-d-learn mailing list