3

I need to convert:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839(v=vs.85).aspx

lpstrFileTitle
Type: LPTSTR
The file name and extension (without path information) of the selected file. This member can be NULL.

Even though in MSVC++ 2012 Express it says its LPSTR.

To

http://msdn.microsoft.com/en-us/library/windows/desktop/bb172802(v=vs.85).aspx

pSrcFile [in]
Type: LPCTSTR
Pointer to a string that specifies the filename. If the compiler settings require Unicode, the data type LPCTSTR resolves to LPCWSTR. Otherwise, the string data type resolves to LPCSTR. See Remarks.

I would very much appreciate this. :)

char szFileName[MAX_PATH] = {0};
char szFileTitleName[MAX_PATH] = {0};
HRESULT hr = S_OK;
RtlZeroMemory(&gc.ofn, sizeof(gc.ofn));

gc.ofn.lStructSize      =   sizeof(gc.ofn);
gc.ofn.hwndOwner        =   hWnd;
gc.ofn.lpstrFilter      =   "All Image Files\0"              "*.bmp;*.dib;*.wdp;*.mdp;*.hdp;*.gif;*.png;*.jpg;*.jpeg;*.tif;*.ico\0"
"Windows Bitmap\0"               "*.bmp;*.dib\0"
"High Definition Photo\0"        "*.wdp;*.mdp;*.hdp\0"
"Graphics Interchange Format\0"  "*.gif\0"
"Portable Network Graphics\0"    "*.png\0"
"JPEG File Interchange Format\0" "*.jpg;*.jpeg\0"
"Tiff File\0"                    "*.tif\0"
"Icon\0"                         "*.ico\0"
"All Files\0"                    "*.*\0"
"\0";
gc.ofn.nMaxFileTitle = MAX_PATH;
gc.ofn.lpstrFileTitle = gc.szFileTitleName; // its a char
gc.ofn.lpstrFile       = szFileName;
gc.ofn.nMaxFile        = MAX_PATH;
gc.ofn.lpstrTitle      = "Open Image";
gc.ofn.Flags           = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;

if(GetOpenFileName(&gc.ofn)) {
gc.render_on = true;
}

.

D3DXCreateTextureFromFileEx (d3dDevice, gc.szFileTitleName , D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, 0, 0,
        D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
        colorkey, &init_map->image_info, NULL, &init_map->texture_buffer)

This will have a blank image. I have tested this with a messagebox right after GetOpenFile, and it returns great.

MessageBoxA ( NULL , gc.ofn.lpstrFileTitle , "" , 0 );

But before the D3DXCreateTextureFromFileEx, its messed up.

Just storing the the char into gc.szFileTitleName. No idea why the other way was going out of scope ...

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
User
  • 659
  • 2
  • 12
  • 29
  • 1
    Remove all those `(LPTSTR)` casts, they should not be needed and could be hiding bugs... – K-ballo Dec 28 '12 at 19:44
  • Why are you calling `MessageBoxA` explicitly? What happens if you call `MessageBox`? – K-ballo Dec 28 '12 at 19:51
  • @K-ballo Still did not work. Seems as if, if I do a messagebox right after GetOpenFileName it will display the correct file name. But if I do it again before the D3DXCreateTextureFromFileEx, its all gibberish. Maybe something is wrong with my other code. – User Dec 28 '12 at 19:51
  • @K-ballo Still Gibberish the second time around. – User Dec 28 '12 at 19:52
  • Oh, well, yeap certainly there is something wrong. It sounds as if `szFileTitleName` is being deleted (going out of scope). And you are trying to access it when it no longer exists. – K-ballo Dec 28 '12 at 19:52
  • Do not use MessageBox(), LPTSTR. See http://utf8everywhere.org on how it is a very bad idea to use constructs sensitive to _UNICODE define. Use MessageBoxW() and char* – Pavel Radzivilovsky Dec 28 '12 at 20:08
  • @PavelRadzivilovsky you mean wchar_t* , MeassageBoxW() is a unicode function, and as such needs a wstring.to_cstr(), or a wchar_t* , also known a s a LPWSTR , or if _UNICODE is defined, LPTSTR, LPTCSTR. – johnathan Dec 28 '12 at 23:35
  • Ohmages, are these (the `GetOpenFileName(`) call and the `D3DXCreateTextureFromFileEx()` call) in the *same* module (DLL, EXE, whatever) ? I ask because clearly your `GetOpenFileName()` is *not* compiling in a Unicode module or all your string constants would be invalid. Check each project's settings if they are in fact, in different build modules and make sure they're both using the same character format (Unicode or otherwise). And see Remy's answer below for a Unicode/Narrow agnostic invoke to `GetOpenFileName()` – WhozCraig Dec 29 '12 at 02:51
  • @johnathon no I didn't, I meant char* for unicode. Apparently, you haven't read the document (http://www.utf8everywhere.org). Will be happy to hear your comments. – Pavel Radzivilovsky Dec 29 '12 at 21:51
  • @PavelRadzivilovsky Sir, MesageBoxW takes two unicode strings, one for the caption, one for the title bar. In c++ we use wchar_t to store unicode strings, while it is possible to use a character array to to do so, you'll have to do conversions to unicode strings before passing them to MessageBoxW, however MessageBoxA will happily accept a char* as a parameter, however it is not as efficient on windows after windows Me, as the operating system coverts all ascii text api calls to unicode under the hood. In such case your better off to use unicode strings and calls to begin with. – johnathan Dec 29 '12 at 23:20
  • @PavelRadzivilovsky and i have read the document, while great in theory it's very flawed, when working with the windows headers all one has to do is define unicode or not, and all windows api's will take unicode or non unicode by using their conventional names, in this case, MessageBox. The OP should not be calling any character encoding specific api in the first place, and instead rely on the fact that his project is using unicode or not using unicode to determine the appropriate type to use. This discussion has gone well away from the OP's needs, and has done more harm than good to the OP – johnathan Dec 29 '12 at 23:25
  • @johnathon Hi, I just disagree that having unicode-unaware application makes any sense.. Also, with that conversions have disadvantage: after all, it is UI code where extra microsecond will not hurt at all. – Pavel Radzivilovsky Dec 30 '12 at 06:36
  • @PavelRadzivilovsky So you admit that your char * does not belong in MessageBoxW? – johnathan Dec 30 '12 at 06:46

2 Answers2

5

LPCTSTR is just a const version of LPTSTR. That type of conversion is a standard conversion, so you shouldn't need to do anything explicitly to get what you want. Your error must be somewhere else.

Unless you are somehow compiling a piece of your code with UNICODE set and some without it...

K-ballo
  • 80,396
  • 20
  • 159
  • 169
1

GetOpenFileName(), D3DXCreateTextureFromFileEx(), and MessageBox() all deal with TCHAR-based strings, but you are not actually utilizing TCHAR in your code. Try this instead:

TCHAR szFileName[MAX_PATH] = {0};
TCHAR szFileTitleName[MAX_PATH] = {0};
HRESULT hr = S_OK;
RtlZeroMemory(&gc.ofn, sizeof(gc.ofn));

gc.ofn.lStructSize      =   sizeof(gc.ofn);
gc.ofn.hwndOwner        =   hWnd;
gc.ofn.lpstrFilter      =   TEXT("All Image Files\0")              TEXT("*.bmp;*.dib;*.wdp;*.mdp;*.hdp;*.gif;*.png;*.jpg;*.jpeg;*.tif;*.ico\0")
                            TEXT("Windows Bitmap\0")               TEXT("*.bmp;*.dib\0")
                            TEXT("High Definition Photo\0")        TEXT("*.wdp;*.mdp;*.hdp\0")
                            TEXT("Graphics Interchange Format\0")  TEXT("*.gif\0")
                            TEXT("Portable Network Graphics\0")    TEXT("*.png\0")
                            TEXT("JPEG File Interchange Format\0") TEXT("*.jpg;*.jpeg\0")
                            TEXT("Tiff File\0")                    TEXT("*.tif\0")
                            TEXT("Icon\0")                         TEXT("*.ico\0")
                            TEXT("All Files\0")                    TEXT("*.*\0")
                            TEXT("\0");
gc.ofn.nMaxFileTitle = MAX_PATH;
gc.ofn.lpstrFileTitle = gc.szFileTitleName;
gc.ofn.lpstrFile       = szFileName;
gc.ofn.nMaxFile        = MAX_PATH;
gc.ofn.lpstrTitle      = TEXT("Open Image");
gc.ofn.Flags           = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;

if(GetOpenFileName(&gc.ofn)) {
    gc.render_on = true;
}

.

D3DXCreateTextureFromFileEx (d3dDevice, gc.szFileTitleName , D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, colorkey, &init_map->image_info, NULL, &init_map->texture_buffer)

.

MessageBox(NULL, gc.ofn.lpstrFileTitle, TEXT(""), 0);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770