MFC: How to pass CString to Windows API functions?
Q: Many Windows API functions require LPCTSTR (pointer to a constant string) or LPTSTR (pointer to a modifiable string buffer) as parameters. How to pass CString type to these functions?
- To get a pointer to const buffer (LPCTSTR) we can use CString::GetString or CString::opertor LPCTSTR.
- To get a pointer to modifiable buffer (LPTSTR) we can use CString::GetBuffer or CString::GetBufferSetLength.
// GlobalAddAtom gets LPCTSTR
CString strAtom = _T("demo atom text");
ATOM atom = ::GlobalAddAtom(strAtom.GetString());
// RegisterWindowMessage gets LPCTSTR
CString strMsg = _T("demo message text");
UINT uMsg = ::RegisterWindowMessage((LPCTSTR)strMsg);
// CreateDirectory gets LPCTSTR
CString strDir = _T("demo directory");
BOOL bRet = ::CreateDirectory(strDir, NULL);
// GetCurrentDirectory gets LPTSTR
- If need LPCTSTR, it's not absolutely necessary an explicit cast (see example #3 vs. #2).
- After a call of GetBuffer, don't forget to call ReleaseBuffer (see example #4).
- Important: an often made mistake is to use double cast (LPTSTR)(LPCTSTR). This is not OK and can lead in troubles:
So, never do that! Call GetBuffer instead, as shown in example #4.
// GetSystemDirectory gets LPTSTR
// Bang!!! The program can crash, sooner or later.
- CString::GetString is not available in MFC6.0 and older. Use opertor LPCTSTR which at last does the same.
- In newer MFC versions, CString is implemented using templates, then you can find the methods and operators docummented at CStringT and CSimpleStringT. Also, you can find operator PCXSTR instead of LPCTSTR.
Anyway, you can still use the "old syntax", as shown in the above examples.
Re: MFC: How to pass CString to Windows API functions?
Instead of CString::GetBuffer or CString::GetBufferSetLength plus CString::ReleaseBuffer, we can use shared MFC/ATL CStrBuf class.
That way, the above example #4 can be re-written a little bit simpler, as follows:
::GetCurrentDirectory(MAX_PATH, CStrBuf(strCurDir, MAX_PATH));