Question

I am making a win32 program that is a level editing tool to go with the library I am creating for a 2D tile system.

I want to create dialog box displaying the maps properties when the user selects it from the menu. This means a conversion from int to a wchar_t array. I have created a function that I hoped would do this. However currently it just returns a blank string that the return variable is initialized as. This conversion is necessary to work with the SetDlgItemText() function called by the map properties dialog box.

Here is the function I have currently:

LPWSTR IntToLPWSTR(int value)
{
    std::ostringstream  convert;
    std::string         out;

    convert << value;
    out = convert.str();

    const char*             in;
    in = out.c_str();

    LPWSTR ret = L"";
    MultiByteToWideChar(CP_ACP, MB_COMPOSITE, in, strlen(in), ret, wcslen(ret));

    return ret;
}

It is being called from here:

    case WM_INITDIALOG:
        if (mapToEdit)
        {
            SetDlgItemText(hDlg, IDC_TILE_WIDTH_LBL, IntToLPWSTR(mapToEdit->TileWidth()));
            SetDlgItemText(hDlg, IDC_TILE_HEIGHT_LBL, L"");
            SetDlgItemText(hDlg, IDC_MAP_WIDTH_LBL, L"");
            SetDlgItemText(hDlg, IDC_MAP_HEIGHT_LBL, L"");
        }
        else
        {
            EndDialog(hDlg, LOWORD(wParam));
            MessageBox(hWnd, L"You must create a map first", L"Error", 1);
        }

Map to edit is simply a pointer to my own map class that contains the properies I want to display. The bottom three calls to SetDlgItemText() pass L"" as their string, the intention is that they will also use the function when it works.

Was it helpful?

Solution

std::to_wstring is simpler, but to point out the problem in your code, you never created a buffer. LPWSTR ret = L""; makes ret a pointer to an array held in static memory. This array cannot be modified.

Here is one way to fix the code by using std::wstring as the buffer:

std::wstring IntToWstring(int value)
{
    std::ostringstream  convert;
    std::string         out;

    convert << value;
    out = convert.str();
    std::wstring ret;
    // Find proper length
    int length = MultiByteToWideChar(CP_ACP, 0, out.c_str(), out.length(), nullptr, 0);
    ret.resize(length);
    // Probably should also check for errors (got rid of MB_COMPOSITE flag)
    MultiByteToWideChar(CP_ACP, 0, out.c_str(), out.length(), &ret[0], length);

    return ret;
}

If you don't want to use std::wstring you could dynamically allocate a buffer LPWSTR ret = new LPWSTR[length];.

EDIT

Also, keep in mind that you could simplify the code to the following:

std::wstring IntToWstring(int value)
{
    std::wostringstream  convert;

    convert << value;
    convert.str();
}

OTHER TIPS

You don't need to go to a lot of effort to convert an int into a const wchar_t *. Since C++11, you can take a two-step approach to a std::wstring and a const wchar_t * from there:

SetDlgItemText(hDlg, IDC_TILE_WIDTH_LBL, std::to_wstring(mapToEdit->TileWidth()).c_str());

Sure you could put that into a function to make it one step, but keep in mind that you cannot let the std::wstring be destroyed by the time you use the pointer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top