Need to get the path to the folder. I use the BROWSEINFO structure and the SHBrowseForFolder () function. But when displaying the resulting path, only the first character is displayed. How to fix it? Already tortured to look.

//get directory of exe file BROWSEINFO bi; LPITEMIDLIST folder = NULL; LPMALLOC shMalloc = NULL; char foldername[MAX_PATH]; char folderpath[MAX_PATH]; string path; memset(&bi, 0, sizeof(bi)); CoInitialize(NULL); SHGetMalloc(&shMalloc); bi.hwndOwner = NULL; bi.pidlRoot = NULL; bi.pszDisplayName = (LPWSTR)foldername; bi.lpszTitle = L"Выберите папку с базой данных:"; bi.ulFlags = BIF_NEWDIALOGSTYLE; folder = SHBrowseForFolder(&bi); if (folder) { SHGetPathFromIDListW(folder, (LPWSTR)folderpath); shMalloc->Free(folder); shMalloc->Release(); printf("Folder selected: %s\n", &folderpath); } 
  • This is not the cause of the error, but still: printf("Folder selected: %s\n", &folderpath); - nonsense. What makes this & in the argument? - AnT 7:42 pm
  • well, you can just cout << folderpath; no difference - io io
  • Instead of the outdated SHBrowseForFolder , use IFileOpenDialog with the FOS_PICKFOLDERS option. - VTT
  • I am writing in visual studio 2017. How to work with this type (or is it a class)? - Io Io

2 answers 2

The problem is that the code uses both "wide functions" (with w at the end) and ordinary (narrow) functions. Wide characters are two bytes. If you store Latin characters in them, then in the debugger it looks like the necessary characters with zero bytes. Of course, if you try to print such a string with a "narrow" (ansi) printf version, only one character will be printed.

What to do? need to go to the same type of function. First, instead of char, use TCHAR, and then print _tprintf

Or explicitly use wchar_t and the like. Here is the minimum remake that works.

 //get directory of exe file BROWSEINFO bi; LPITEMIDLIST folder = NULL; LPMALLOC shMalloc = NULL; wchar_t foldername[MAX_PATH]; wchar_t folderpath[MAX_PATH]; std::wstring path; memset(&bi, 0, sizeof(bi)); CoInitialize(NULL); SHGetMalloc(&shMalloc); bi.hwndOwner = NULL; bi.pidlRoot = NULL; bi.pszDisplayName = (LPWSTR)foldername; bi.lpszTitle = L"Выберите папку с базой данных:"; bi.ulFlags = BIF_NEWDIALOGSTYLE; folder = SHBrowseForFolder(&bi); if (folder) { SHGetPathFromIDListW(folder, (LPWSTR)folderpath); shMalloc->Free(folder); shMalloc->Release(); wprintf(L"Folder selected: %s\n", folderpath); } 
  • Thank you very much!!! It helped a lot - Io Io

The functions you call form the resulting string as a “wide” string ( wchar_t array), and then for some reason you print it as a “narrow” string ( char array). Of course, nonsense will be printed.

Since you form "wide" lines, then you need to print them as such.

 wprintf(L"Folder selected: %s\n", (LPWSTR) folderpath); 

This raises a logical question: since you are going to work with “wide” lines, then why do you have all the buffers for strings declared as consisting of “narrow” char ? Because of this, you have to LPWSTR code with explicit LPWSTR , not to mention the risk of flying out of the array. What for? Why not immediately declare all buffers as consisting of wchar_t ? Then the cast to LPWSTR will become unnecessary.