Тип LPCTSTR - это длинный указатель на прозрачную строку.
Здесь важен T, Прозрачный (по крайней мере, я думаю, что T означает Прозрачный).
Если ваше приложение скомпилировано как приложение ASCII, все типы T (например, TCHAR) переопределяются как их ASCII-аналог. Так что TCHAR станет просто чаром.
Если ваше приложение скомпилировано как Unicode, все типы T переопределяются как типы Unicode. TCHAR становится wchar_t.
То же самое верно для всех функций Windows (и MFC). Все функции Windows представлены в двух вариантах: версия ASCII (например, MessageBoxA) и версия Unicode (например, MessageBoxW). Сам MessageBox является не чем иным, как определением для MessageBoxA или MessageBoxW (в зависимости от того, как вы компилируете).
В вашем примере буфер определен как тип char-vector, но вы преобразуете его в указатель на прозрачный тип. Я предполагаю, что ваше приложение скомпилировано в Unicode, поэтому LPCTSTR на самом деле является "wchar_t *". Так что это приведение неверно.
Перед строкой «hello» с L указывается, что компилятор должен передать константу «hello» в виде строки Unicode, что делает ее правильным типом для передачи в версию Unxode AfxMessageBox.