在std::string上使用_T

Using _T on a std::string

本文关键字:std string      更新时间:2023-10-16

我想使用这行代码

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

但是据我所知,我不允许在变量上使用_T。基本上,我试图将SHBrowseForFolder的起始文件夹设置为由前面分配的变量组成的路径。我花了很长时间试图绕过它,一直在搜索和发现关于wstrings的东西,但似乎没有任何工作。我希望是我错过的简单的东西,因为我不敢相信_T一个变量这么难。

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: %sn"), path );                                                                           
                         }
                         // free memory used
                         IMalloc * imalloc = 0;
                         if ( SUCCEEDED( SHGetMalloc ( &imalloc )) )
                         {
                             imalloc->Free ( pidl );
                             imalloc->Release ( );
                         }                               
                     }           
                 }

你可以这样做:

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

但是如果caseref被声明为std::string,当你使用Unicode字符集时,这将无法编译。另一方面,如果您将其声明为std::wstring,则当您使用多字节字符集时,它将无法编译。

如果你需要你的程序支持这两个字符集,一个可能的方法是使用一个预处理器指令来定义一个类型别名tstring,如果定义了_UNICODE符号就解析为std::wstring,如果没有就解析为std::string,并声明你的字符串变量为tstring

#ifdef _UNICODE
typedef std::wstring tstring;
#else
typedef std::string tstring;
#endif
tstring casref = _T("something");
tstring startingfolder = _T("C:\VSS\") + caseref;

请注意,非史前(即任何基于nt的)Windows版本在内部使用Unicode字符,因此,如果您没有特别的理由支持这两种配置,只需放弃那些丑陋的宏(包括_T),并将L前缀用于字符串字面值(例如L"Hello")与std::wstring结合使用(以及宽版本的流,如果您正在使用它们)。

而不是:

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

这样做:

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

并将字符串类型更改为宽字符串等,并确保在包含<windows.h>之前定义UNICODE

Windows API建立在UTF-16字符串表示上,使用16位wchar_t。当您使用ANSI函数时,它必须与底层API的宽字符进行转换。所以使用ANSI字符串是

  • 效率低下。
  • 限制(不能处理一般的Unicode字符)。
  • 很多额外的工作,而且很可能还有bug。

你需要支持ANSI,如果你正在使用相当老的工具,仍然可以针对Windows 9x,你的意思是针对Windows 9x,你不能使用Unicode层,因为你在dll中使用MFC,你不觉得你要重建。但是,你真的是针对Windows 9x的MFC在DLL和使用足够老的工具,你可以做到这一点吗?我对此表示怀疑!

所以,使用宽字符串,无处不在


总而言之,忘记愚蠢的_T宏。