可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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).
回答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"
回答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.
回答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.
回答4:
LPCTSTR
is a cstring operator. I advocate you to do this in all your calls to setWindowTExt
setWindowText(_T("Record"))
_T()
will call the implicit cast directly if the function is known from the compiler (Which is the case here). You could use L""
aswell, thanks to @Mgetzfor point it out.
回答5:
Try using Mulit-byte character encoding in Project Settings instead of Unicode. In case of VS2013, VS2015 you need to download and install the MBCS library for visual studio from this link https://www.microsoft.com/en-us/download/confirmation.aspx?id=40770
回答6:
Try something like this:
char ch[5] = "test"; int num = MultiByteToWideChar(0,0,ch,-1,NULL,0); wchar_t *wide = new wchar_t[num]; MultiByteToWideChar(0,0,ch,-1,wide,num);