1

I'm working on a simple project with DirectX9. I'm having a little snag with some conversion of data types, and I've done some research, but haven't found anything particularly useful. Let's start with the code:

LPDIRECT3DSURFACE9 LoadSurface(char *fileName, D3DCOLOR transColor)
{
LPDIRECT3DSURFACE9 image = NULL;
D3DXIMAGE_INFO info;
HRESULT result;

result = D3DXGetImageInfoFromFile(fileName, &info);
if (result != D3D_OK) return NULL;

result = d3ddev->CreateOffscreenPlainSurface(
    info.Width,         //width of the surface 
    info.Height,        //height of the surface
    D3DFMT_X8R8G8B8,    //surface format
    D3DPOOL_DEFAULT,    //memory pool use
    &image,             //reference to image
    NULL);              //reserved - ALWAYS NULL

//make sure file loaded properly
if (result != D3D_OK) return NULL;

return image;

}

At line 6, I'm getting the error for the variable fileName:

IntelliSense: argument of type "char *" is incompatible with parameter of type "LPCWSTR"

I also get the exact same error message at the second and third parameters when trying to use MessageBox's:

if (d3ddev == NULL)
{
MessageBox(hWnd, "Error Creating Direct3D Device", "Error", MB_ICONERROR);
return 0;
}

I've used code exactly like this before and had no problems. No idea what is going on - especially because LPCWSTR and char* are essentially the same thing...

Any help is appreciated!! Thank you

Uchiha Itachi
  • 1,251
  • 1
  • 16
  • 42
  • 1
    LPCSTR and char* i might agree, LPCWSTR though? no. – Borgleader Sep 27 '16 at 19:11
  • 6
    *No idea what is going on - especially because LPCWSTR and char* are essentially the same thing.* -- **No, they are not** – PaulMcKenzie Sep 27 '16 at 19:12
  • 1
    [This Q/A](http://stackoverflow.com/questions/3924926/cannot-convert-parameter-1-from-char-to-lpcwstr?rq=1) might answer your question. (Look at the second answer, change the project config such that the APIs are not expecting unicode). – alain Sep 27 '16 at 19:13
  • Modern C++ applications all use Unicode (aka wide-character or ``wchar_t``). Legacy ANSI (ASCII) interfaces still exist but date back to Windows 3.x. Really the only scenario where you'd still purposely choose an ANSI API is for debug output (since it's never localized) like ``OutputDebugStringA``. Use ``#define _UNICODE`` and ``#define UNICODE`` before you include any headers. – Chuck Walbourn Sep 28 '16 at 04:41
  • Speaking of "modern C++", why are you using legacy Direct3D 9 and the deprecated D3DX library rather than Direct3D 11? See [MSDN](https://msdn.microsoft.com/en-us/library/windows/desktop/ee663275.aspx) and [Living without D3DX](https://blogs.msdn.microsoft.com/chuckw/2013/08/20/living-without-d3dx/). – Chuck Walbourn Sep 28 '16 at 04:43

3 Answers3

5

The most probable reason that you had no problem before is that you turned on unicode in Visual C++ project's settings. See the accepted answer here to turn it off again (if it's possible for you): How do I turn off Unicode in a VC++ project?

Otherwise you need to convert char * to wchar_t * using MultiByteToWideChar function.

Community
  • 1
  • 1
Anton Malyshev
  • 8,686
  • 2
  • 27
  • 45
2

I've used code exactly like this before and had no problems.

No, you haven't.

LPCWSTR and char* are essentially the same thing...

No, they're not.

If you read the documentation, you'll see that a LPCWSTR is a const wchar_t*.

You should take a const wchar_t* into your function instead.

If you really want to convert to a char*, and don't mind that (at least in one of the two directions) this makes no sense, then you can read the answers to the following questions:

… and apply const_cast afterwards. But, seriously, please don't.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
2

Figured it out through looking through the DirectX header files... If anyone is having this same problem, rather than using the:

D3DXGetImageInfoFromFile(varName, &info);

Instead, use:

D3DXGetImageInfoFromFileA(varName, &info);

Same goes for MessageBox's... Use

MessageBoxA(handleVar, messageVar, titleVar, iconType);    

*This comes with the caveat that your project property settings for character sets are set to Unicode. It becomes unnecessary if you switch that to Multi-byte.

As always, Thanks to those that actually contributed and helped me with this; and No Thanks to those who simply post on boards to ridicule or demean those who are less experienced - great use of your time.

Uchiha Itachi
  • 1,251
  • 1
  • 16
  • 42
  • 4
    Yes, that works, but it's a bad idea. Change the project setting, such that the `char` APIs are used. ( `D3DXGetImageInfoFromFile` is a macro that resolves to `D3DXGetImageInfoFromFileW` or `D3DXGetImageInfoFromFileA`, depending on `UNICODE`) – alain Sep 27 '16 at 19:25
  • 1
    I think you should add to this answer why you want to explicitly use the `xyzA` narrow version of the Win32 API over the wide version, or the published and documented name. – Niall Sep 27 '16 at 19:43
  • 1
    As someone pointed out, and I completely overlooked, the project settings were set to Unicode rather than Multibyte. Forgive me - It's been almost a year since I've used DirectX... I'm still remembering all the little tweaks I have to make in the settings. Rookie mistakes. Thanks for your help everyone!! – Uchiha Itachi Sep 27 '16 at 20:34