C++ concat LPCTSTR

I am implementing a custom action for a WindowsCE CAB file, and I need to concat a LPCTSTR to get a proper path to an exe.

My custom action receives a LPCTSTR as an argument.

So (pseudocode):

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;
}

This is using the imaginary "+" operator, that I would use in my standard language, C#.

I have relatively little experience in C++. What is the proper way to append a LPCTSTR for my purposes? The LaunchApp method uses this type as an argument.

Also if I want to display the resulting path (for debugging purposes) in a MessageBox, is there a quick way to convert to a LPCWSTR?

For concatenation use StringCchCat

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

C Programming Tutorial for Beginners, Learn C the Hard Way: Practical Exercises on the Computational Subjects You Keep Avoiding (Like C) C is a procedural programming language. It was initially developed by Dennis Ritchie as a system programming language to write operating system. The main features of C language include low-level access to memory, simple set of keywords, and clean style, these features make C language suitable for system programming like operating system or compiler development.

You need to allocate a new buffer to assemble the combined string in and then copy both parts into it. You can either pick a fixed, large buffer size

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

or allocate it dynamically to fit:

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;

If you're in Unicode mode then LPCTSTR == LPCWSTR (in MBCS mode == LPCSTR instead). Either way the MessageBox macro should work for you - it'll choose between MessageBoxA or MessageBoxW as appropriate.


As ctacke points out below, this in on Windows CE and I can't assume you're going to have the _s functions. I think in the second case it's OK to use the non _s variants since we know the buffer is big enough, but in the first _sntprintf does not guarantee a trailing null on the output string (as the _s version does) and so we need to initialise the buffer ourselves first:

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);

(It might also be possible to do this by omitting the memset and using _sntprintf's return value to find the end of the combined generated string and nul the next character.)

AFAICR Windows CE is Unicode only and so LPCTSTR == LPCWSTR always.

"C" Programming Language: Brian Kernighan, This course will give you a full introduction into all of the core concepts in the C programming Duration: 3:46:13 Posted: Aug 15, 2018 Discover historical prices for C stock on Yahoo Finance. View daily, weekly or monthly format back to when Citigroup, Inc. stock was issued.

You can use string to be concatenated and then cast the result to LPCTSTR using ATL helpers like CA2T:

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

Learn C, "C" is one of the most widely used programming languages of all time. Prof Brian Kernighan Duration: 8:26 Posted: Aug 18, 2015 Programming Languages Development - C++ has been used extensively in developing new programming languages like C#, Java, JavaScript, Perl, UNIX’s C Shell, PHP and Python, and Verilog etc. Computation Programming - C++ is the best friends of scientists because of fast speed and computational efficiencies.

C Tutorial, learn-c.org is a free interactive C tutorial for people who want to learn C, fast. Microsoft C++, C, and Assembler documentation. Learn how to use C++, C, and assembly language to develop applications, services, and tools for your platforms and devices.

C Language - Overview, C programming is a general-purpose, procedural, imperative computer programming language developed in 1972 by Dennis M. Ritchie at the Bell Telephone� C - switch statement - A switch statement allows a variable to be tested for equality against a list of values. Each value is called a case, and the variable being switched on is chec

Learn C Programming, C Language - Overview - C is a general-purpose, high-level language that was originally developed by Dennis M. Ritchie to develop the UNIX operating system � Learn C# programming - for beginning developers, developers new to C#, and experienced C# / .NET developers

Comments
  • You probably do not want to add pointers even if the compiler didn't complain. Consider using C++ objects such as std::string or std::wstring where appropriate.
  • That is (pseudocode), I used the + as its meaning would imply in C#. I thought I was clear on that, sorry.
  • For concatenating paths, you could use PathCombine from the shlwapi library. Not sure it's available on Windows CE, though.
  • See also _makepath_s, _wmakepath_s
  • Can you post an example for my situation?
  • This may or may not be available depending on the version of your OS and the components in the image. See @Rup's answer for CE 5.0? (I forget the exact OS version where they added these) and earlier.
  • One comment on this - it assumes that the safe string APIs are in the OS. If they are not (it's a modular OS after all) then you'll have to use the fallbacks of _tcsncpy and _tcsncat
  • Sorry, completely missed it was Windows CE. Yes, I guess the second case should be safe to use the non-secure functions because we know the buffer is big enough; in the first case we'd need to guarantee there was a trailing null. I'll edit that in.