Cannot convert argument 1 from 'const char [5]' to 'LPCTSTR'

17,193

Solution 1

SetWindowTextW() takes a character pointer to the string's data where your string data consists of regular chars, but your function most likely expects a unicode string, so you cannot input string types directly. You need to use L"thisismystring"

Solution 2

There are two kinds of raw strings that MSVC2013 interacts with. Raw char strings look like "Hello". wchar_t strings look like L"World".

In addition, there is a setting for if your project is using wchar_t or char strings. The macro TCHAR expands to either char or wchar_t, and the macro _T("some text") will expand to either "some text" or L"some text" depending on if your project is compiled to use char or wchar_t.

Almost every windows API taking a string has a macro wrapping it, mapping it to a char version or a wchar_t version.

The goal of all of this was to make it possible to write a single application, and have it wide-character aware or not.

The convention on windows is that narrow character char interfaces use a code-page based system, and wide character wchar_t interfaces use UTF-16 characters (the subset UCS-2 in OS's prior to W2K, and no system font in XP supports characters outside of UCS-2 if I read the wikipedia article right).

The end of all of this? Your project has been somehow set to be using wide character strings. This is a good thing, because narrow character built apps are unable to handle anything other than one codepage of characters.

So your narrow character constants are generating errors, as the APIs are now expecting wide character constants.

The easy fix is to wrap all of your "raw strings"s in _T("raw string") the _T macro. When you use char const* or the like in your code, instead use TCHAR const*.

Include a system to do the same with std::string and std::cout and other char based std and other libraries, or when using those don't interact with the user and when talking to windows use the A terminated interfaces for char or W terminated interface functions for wchar_t based strings.

It is rare nowadays to ever "go back" to char based interfaces on windows, so one approach would be to do away with the macros and just interact with the W based interfaces directly. Your strings all become L"wide character", your std stuff is all std::wstring etc, and your character variables are all wchar_t. This is probably not considered best practices.

Finally, note that both the char and wchar_t narrow and wide based interfaces can have more than one char or wchar_t per "character". This wasn't true for a narrow window when all windows supported was single-wchar_t elements from UTF-16, and multi-wchar_t characters are relatively rare, so a lot of code fails to handle that possibility.

Solution 3

To convert a const char * to an LPCTSTR type, add L before the const char *, as per se:

void CFisterDlg::OnRecord() 
{
    CString string;
    m_RecButton.GetWindowText(string);
    if(string == "Record")
    {
        StartRecordingToFile();
        m_RecButton.SetWindowText(L"Stop");
    }
    else
    {
        StopRecordingToFile();
        m_RecButton.SetWindowText(L"Record");
    }
}

Alternatively you could inexplicably cast it with _T, like so:

void CFisterDlg::OnRecord() 
{
    CString string;
    m_RecButton.GetWindowText(string);
    if(string == "Record")
    {
        StartRecordingToFile();
        m_RecButton.SetWindowText(_T("Stop"));
    }
    else
    {
        StopRecordingToFile();
        m_RecButton.SetWindowText(_T("Record"));
    }
}

The _T macro comes from the 'tchar' library, therefore you'll need to #include <tchar.h> if you haven't already done so.

Share:
17,193
Taurian
Author by

Taurian

Updated on June 06, 2022

Comments

  • Taurian
    Taurian almost 2 years

    I'm using this codeproject: http://www.codeproject.com/Articles/10138/Voice-Recording-Playing-back-using-simple-classes

    void CFisterDlg::OnRecord() 
    {
        CString string;
        m_RecButton.GetWindowText(string);
        if(string == "Record")
        {
            StartRecordingToFile();
            m_RecButton.SetWindowText("Stop");
        }
        else
        {
            StopRecordingToFile();
            m_RecButton.SetWindowText("Record");
        }
    }
    

    But I get this error in numerous places:

    error C2664: 'void CWnd::SetWindowTextW(LPCTSTR)' : cannot convert argument 1 from 'const char [5]' to 'LPCTSTR'
    

    I think it has something to do with me using the latest version of visual studio (2013).

  • Mgetz
    Mgetz about 9 years
    nobody is using windows 9x anymore, there is no need to use _T() any more, just use L""
  • Mekap
    Mekap about 9 years
    @Mgetz In France there's still waaay more windows 9X that'd you think ! That's why i prefer to point out _T() anyway. But yeah, i should have putted both styles.
  • AStopher
    AStopher about 9 years
    Using _T is good for compatibility, although it's surpassed by the newer L.
  • Mekap
    Mekap about 9 years
    In which way its surpassed in terms of compatibility @cybermonkey ?
  • Javia1492
    Javia1492 about 9 years
    Can you elaborate on its degree of wrongness? What specifically is incorrect?
  • Javia1492
    Javia1492 about 9 years
    @Yakk That's interesting because i've received this error multiple times in my work and have solved it using the solution i've provided. Maybe it is platform specific, mine being Wec7 RTOS. Nevertheless, i've provided a solution that i have used myself and have seen in other works. Likewise, you can reference this which goes into detail about the SetWindowText function and you can read about the specifics of the parameter. I am using VS2008 and have received this error. It is not related to VS version.
  • Javia1492
    Javia1492 about 9 years
    Your explanation is very informative, but your solution is no more different than mine. OP's question is very simple and focused, whereas your answer delves into the history and roots of microsoft's thinking. At the end of the day, both _T() and L"" fix OP's solution, which is that he needs. Conversion of regular char to wchar_t. I dont see how this is any different that my "damaging" answer.
  • Javia1492
    Javia1492 about 9 years
    @Yakk What i meant to say is a character pointer to the string's data. I'' revise my grammar.
  • Yakk - Adam Nevraumont
    Yakk - Adam Nevraumont about 9 years
    The second edit repaired the answer. It still confuses `unicode* with wide-character, but that confusion is nearly mandated on windows. -1 removed, +1 added.
  • AStopher
    AStopher about 9 years
    The answer itself isn't wrong, the explanation however was (and still is).
  • Javia1492
    Javia1492 about 9 years
    @cybermonkey can you explain how it is still wrong?
  • AStopher
    AStopher about 9 years
    @Javia1492 As Yakk says, your answer confuses a unicode with a wide character.