Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using _T on a std::string

I'm trying to use this line of code

startingfolder = _T("C:\\VSS\\" +  caseref);

But as I understand, I'm not allowed to use _T on a variable. Basically I'm trying to set the starting folder of the SHBrowseForFolder as a path made up of variables assigned earlier on. I've spent ages trying to get around it, been searching and found stuff about wstrings but nothing seems to work. I hope it's something easy that I've missed because I can't believe it's this difficult to _T a variable.

void folderdialog2()
                 {    
                     PIDLIST_ABSOLUTE xx;
                     PCTSTR startingfolder; 

                     startingfolder = _T("C:\\VSS\\" +  caseref);
                     xx = ILCreateFromPath(startingfolder);

                     BROWSEINFO bi = { 0 };
                     bi.pidlRoot = xx;
                     bi.lpszTitle = _T("Pick a Directory");

                     LPITEMIDLIST pidl = SHBrowseForFolder ( &bi );
                     if ( pidl != 0 )
                     {
                         // get the name of the folder
                         TCHAR path[MAX_PATH];
                         if ( SHGetPathFromIDList ( pidl, path ) )
                         {
                             _tprintf ( _T("Selected Folder: %s\n"), path );                                                                           
                         }
                         // free memory used
                         IMalloc * imalloc = 0;
                         if ( SUCCEEDED( SHGetMalloc ( &imalloc )) )
                         {
                             imalloc->Free ( pidl );
                             imalloc->Release ( );
                         }                               
                     }           

                 }

2 Answers

You may do this:

startingfolder = _T("C:\\VSS\\") +  caseref;

But if caseref is declared as std::string, this won't compile when you're using the Unicode charset. On the other hand, if you declared it as std::wstring, it would not compile when you are using the multibyte charset.

If you need your program to support both character sets, one possible approach is to use a preprocessor directive to define a type alias tstring that resolves into std::wstring if the _UNICODE symbol is defined, and into std::string if not, and declare your string variables as tstring.

#ifdef _UNICODE
typedef std::wstring tstring;
#else
typedef std::string tstring;
#endif

tstring casref = _T("something");
tstring startingfolder = _T("C:\\VSS\\") + caseref;

Notice, however, that non-prehistoric (that is, any NT-based) versions of Windows work with Unicode characters internally, so if you have no particular reasons for supporting both configurations, just drop those ugly macros (including _T) and use the L prefix for string literals (e.g. L"Hello") in combination with std::wstring (and wide versions of streams as well, if you are using them).

like image 74
Andy Prowl Avatar answered Nov 28 '25 09:11

Andy Prowl


Instead of this:

PCTSTR startingfolder;
startingfolder = _T("C:\\VSS\\" +  caseref);

do this:

wstring const startingfolder = wstring() + L"C:\\VSS\\" + caseref;

and change your string types to wide strings, etc., and make sure that UNICODE is defined before including <windows.h>.

The Windows API is built on UTF-16 string representation, using a 16-bit wchar_t. When you use an ANSI function it has to translate to and from the wide character underlying API. So using ANSI strings is

  • Inefficient.
  • Limited (not able to handle general Unicode characters).
  • A lot of extra work, and still most probably bugs left.

You need to support ANSI if you are using pretty old tools that still can target Windows 9x, and you mean to target Windows 9x, and you can't use Layer for Unicode because you're using MFC in DLLs and you don't feel that you're up to rebuilding that. But are you really targeting Windows 9x with MFC in DLL and using sufficiently old tools that you can do that? I doubt it!

So, use wide strings, everywhere.


Summing up, forget about the silly _T macros.

like image 34
Cheers and hth. - Alf Avatar answered Nov 28 '25 11:11

Cheers and hth. - Alf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!