GetOpenFileNameW results in FNERR_INVALIDFILENAME or CDERR_INITIALIZATION if I call GetOpenFileNameA

Here's the code using GetOpenFileNameW:

import core.sys.windows.windows;
import std.stdio, std.string, std.utf;

pragma(lib, "comdlg32");

// Fill in some missing holes in core.sys.windows.windows.
extern (Windows) DWORD CommDlgExtendedError();
enum OFN_FILEMUSTEXIST = 0x001000;

void main()
{
    auto buf = new wchar[1024];

    OPENFILENAMEW ofn;
    ofn.lStructSize = ofn.sizeof;
    ofn.lpstrFile = buf.ptr;
    ofn.nMaxFile = buf.length;
    ofn.lpstrInitialDir = null;
    ofn.Flags = OFN_FILEMUSTEXIST;

    BOOL retval = GetOpenFileNameW(&ofn);
    if (retval == 0) {
        // Get 0x3002 for W and 0x0002 for A. ( http://msdn.microsoft.com/en-us/library/windows/desktop/ms646916(v=vs.85).aspx )
        throw new Exception(format("GetOpenFileName failure: 0x%04X.", CommDlgExtendedError()));
    }

    writeln(buf);
}

This leads to FNERR_INVALIDFILENAME, but I do not see any optional lines that I did not fill out. And here is the code (only differences) for GetOpenFileNameA:

auto buf = new char[1024];

OPENFILENAMEA ofn;
// ...
BOOL retval = GetOpenFileNameA(&ofn);

The result is CDERR_INITIALIZATION, and the only MSDN development gives me

The common dialog box function failed during initialization. 
This error often occurs when sufficient memory is not available.

This is for Windows 7 64 bit, DMD v2.059.

+5
source share
1 answer

bufmust be completely reset to zero. The problem here is that wchar.init == wchar.max(for reasons for detecting errors), so your array has essentially 1024 instances wchar.max. Simple buf[] = 0;should fix this.

+5
source

All Articles