我已将我的字符串移动到资源,幸运的是我有LPCTSTR运算符来方便地实例化字符串:
CString str( (LPCSTR) IDS_MY_STRING);
现在我想用MessageBox()做类似的类型转换,所以它也从资源加载字符串,所以我这样做:
MessageBox( hWnd, (LPCTSTR) IDS_MY_STRING ,"Error", MB_RETRYCANCEL);
但这不起作用,它编译但在运行时崩溃。现在以下工作:
MessageBox( hWnd, (CString) (LPCTSTR) IDS_MY_STRING ,"Error", MB_RETRYCANCEL);
我的问题是MessageBox()无论如何都将LPCTSTR作为第二个参数,为什么我们还要从LPCTSTR到CString进行类型转换以使其工作?
答案 0 :(得分:3)
你的IDS_MY_STRING
实际上并不是指向字符串的指针。这是一个整数。 (如果它是一个字符串指针,你首先不需要LPCTSTR
强制转换。)CString
知道如何从整体资源ID加载资源字符串。
MessageBox
没有;它需要一个真实的字符指针,CString
隐式提供。
答案 1 :(得分:3)
真正的问题(或至少是答案的有趣部分)不是关于第二个失败的方式,而是关于第一个如何工作的更多信息。
第一个可行,因为采用LPCSTR的CString构造函数实际上会查看该值,以确定它是否真的是指向字符串的指针,或者是字符串资源的标识符。在后一种情况下,它会自动加载字符串资源并创建具有相同内容的CString。 IOW,你得到了从字符串标识符到CString的隐式转换。
CString还支持隐式转换为LPCSTR / LPCSTR / LPCWSTR。
然而, C ++只会执行一个用户定义的隐式转换,以从任何类型传递到表达式所需的任何类型。在这种情况下,要从字符串ID获取LPCTSTR
,您需要两个 - 一个从字符串ID到CString
,另一个从CString
到LPCTSTR
。编译器不会自动为您执行此操作。
因此,要从字符串ID到LPCTSTR
,您需要显式地从字符串ID转换为CString
,它使用CString
的构造函数,其中{{1} }}。因此,您将字符串ID转换为LPCTSTR
,然后将其转换为LPCTSTR
,这会创建CString
。然后编译器会自动从CString
转换为(实际)`LPCTSTR。
答案 2 :(得分:1)
MessageBox
没有使用资源ID的重载,但您可以改为使用AfxMessageBox
。
答案 3 :(得分:1)
其他人已经解释了类型转换的细节等。
此外,为了简化您的代码,您可能需要#define
这样一个方便的宏:
#define _S(id) (CString(LPCTSTR(id)))
然后将其与MessageBox
(或其他LPCTSTR
参数一起使用):
MessageBox( hWnd, _S(IDS_MY_STRING), _S(IDS_TITLE), MB_RETRYCANCEL );