【问题标题】:C++ concat LPCTSTRC++ 连接 LPCTSTR
【发布时间】:2011-07-11 06:36:48
【问题描述】:

我正在为 WindowsCE CAB 文件实现自定义操作,我需要连接 LPCTSTR 以获得 exe 的正确路径。

我的自定义操作接收 LPCTSTR 作为参数。

所以(伪代码):

extern "C" codeINSTALL_EXIT MYCUSTOMACTION_API Install_Exit(
    HWND    hwndParent,
    LPCTSTR pszInstallDir,
    WORD    cFailedDirs,
    WORD    cFailedFiles,
    WORD    cFailedRegKeys,
    WORD    cFailedRegVals,
    WORD    cFailedShortcuts
)
{
    if (FALSE == LaunchApp(pszInstallDir + "\\MyApp.exe"))
       ::MessageBox(hwndParent, L"Could not launch app!", L"Setup", MB_ICONINFORMATION );
    return codeINSTALL_EXIT_DONE;
}

这是使用虚构的“+”运算符,我将在我的标准语言 C# 中使用它。

我在 C++ 方面的经验相对较少。为我的目的附加 LPCTSTR 的正确方法是什么? LaunchApp 方法使用此类型作为参数。

另外,如果我想在 MessageBox 中显示结果路径(用于调试目的),有没有一种快速转换为 LPCWSTR 的方法?

【问题讨论】:

  • 即使编译器没有抱怨,您也可能不想添加指针。考虑在适当的情况下使用 C++ 对象,例如 std::stringstd::wstring
  • 那是(伪代码),我使用 + 作为它在 C# 中的含义。我以为我很清楚,抱歉。
  • 对于连接路径,您可以使用 shlwapi 库中的PathCombine。不过,不确定它在 Windows CE 上是否可用。

标签: c++ string windows-ce lpcstr


【解决方案1】:

您可以使用字符串进行连接,然后使用 CA2T 等 ATL 助手将结果转换为 LPCTSTR:

std::string filePath = "\\\\user\\Home\\";
std::string fileName = "file.ex";
std::string fullPath = filePath + fileName;
CA2T t(fullPath.c_str());
LPCTSTR lpctsrFullPath = t;

【讨论】:

    【解决方案2】:

    您需要分配一个新缓冲区来组装组合字符串,然后将两个部分复制到其中。您可以选择一个固定的大缓冲区大小

    TCHAR fullPath[MAX_PATH + 11]; // 11 = length of "\MyApp.exe" + nul in characters
    _sntprintf_s(fullPath, MAX_PATH + 11, _T("%s\\MyApp.exe"), pszInstallDir);
    

    或动态分配以适应:

    size_t installDirLen = tcslen(pszInstallDir);
    size_t bufferLen = installDirLen + 11; // again 11 = len of your string
    LPWSTR fullPath = new TCHAR[bufferLen];
    // if you're paranoid, check allocation succeeded: fullPath != null
    tcsncpy_s(fullPath, bufferLen, pszInstallDir);
    tcsncat_s(fullPath, bufferLen, _T"\\MyApp.exe");
    // use it
    delete fullPath;
    

    如果您处于 Unicode 模式,则 LPCTSTR == LPCWSTR(MBCS 模式 == LPCSTR)。无论哪种方式,MessageBox 宏都应该适合您 - 它会根据需要在 MessageBoxA 或 MessageBoxW 之间进行选择。


    正如 ctacke 在下面指出的那样,这在 Windows CE 上,我不能假设您将拥有 _s 函数。我认为在第二种情况下使用非 _s 变体是可以的,因为我们知道缓冲区足够大,但在第一个 _sntprintf 不保证输出字符串的尾随 null (就像 _s 版本一样),所以我们需要首先我们自己初始化缓冲区:

    size_t bufferLen = MAX_PATH + 11;
    TCHAR fullPath[bufferLen];
    // zero the buffer out first
    memset(fullPath, 0, sizeof(TCHAR) * bufferLen);
    // only write up to bufferLen - 1, i.e. ensure the last character is left zero
    _sntprintf(fullPath, bufferLen - 1, _T("%s\\MyApp.exe"), pszInstallDir);
    

    (也可以通过省略 memset 并使用 _sntprintf 的返回值来查找组合生成的字符串的结尾和 nul 下一个字符来做到这一点。)

    AFAICR Windows CE 仅是 Unicode,因此 LPCTSTR == LPCWSTR 始终。

    【讨论】:

    • 对此有一条评论 - 它假定安全字符串 API 在操作系统中。如果它们不是(毕竟它是模块化操作系统),那么您将不得不使用 _tcsncpy_tcsncat 的后备方法
    • 抱歉,完全错过了 Windows CE。是的,我猜第二种情况应该可以安全地使用非安全函数,因为我们知道缓冲区足够大;在第一种情况下,我们需要保证有一个尾随空值。我将在其中进行编辑。
    【解决方案3】:

    对于串联使用StringCchCat

    TCHAR pszDest[260] = _T("");
    StringCchCat(pszDest, 260, pszInstallDir); 
    StringCchCat(pszDest, 260, _T("\\MyApp.exe"));
    LaunchApp(pszDest);
    

    【讨论】:

    • 你能举个例子来说明我的情况吗?
    • 这可能或可能不可用,具体取决于您的操作系统版本和映像中的组件。查看@Rup 对 CE 5.0 的回答? (我忘记了他们添加这些的确切操作系统版本)和更早的版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 2012-04-04
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    相关资源
    最近更新 更多