【发布时间】:2016-06-07 21:00:52
【问题描述】:
使用 MFC 和 Unicode 构建
我想更改 listctrl 的列标题文本,为此我必须将 LPCTSTR 转换为 LPWSTR。我现在要做的是
void CSPCListViewCtrl::SetHeaderText(long lCol, LPCTSTR lColText)
{
CListCtrl& ListCtrl = GetListCtrl();
LV_COLUMN lvc;
::ZeroMemory((void *)&lvc, sizeof(LVCOLUMN));
lvc.mask |= LVCF_TEXT;
ListCtrl.GetColumn(lCol, &lvc);
lvc.pszText = const_cast<LPWSTR>(lColText);
ListCtrl.SetColumn(lCol, &lvc);
}
它似乎有效,但 const_cast 对我来说看起来有些奇怪和错误,所以我尝试了类似的东西
USES_CONVERSION;
lvc.pszText = CT2W(lColText);
这似乎在发布构建中有效,但在调试构建中产生垃圾所以我想知道正确的方法是什么?
【问题讨论】:
-
LV_COLUMN(msdn.microsoft.com/en-us/library/windows/desktop/…) 中没有LPWSTR。我假设 LPTSTR 参数传递的字符串在某种程度上是临时的。您应该考虑传递给 pszText 成员的字符串的所有权和生命周期。 -
好吧,我的错。 LV_COLUMN::pszText 是一个 LPTSTR(在我的 unicode 案例中编译为一个 LPWSTR)。所以你的意思是 const_casting 到 LPTSTR 是正确的方法吗?是的,传递的参数是临时的,但我认为 SetColumn 会复制,不是吗?
-
虽然
const_cast可以在所有现有版本的列表控件中工作,但它肯定不是必须的。想象一下,在下一个版本中,他们将增强列标题,使其具有左右对齐的部分,并选择使用strtok()之类的东西来解析pszText。如果您的字符串实际上是常量,这可能会导致访问冲突。底线是 - 您必须创建该文本的非常量副本;下面的答案中建议了一种方法。 -
@VladFeinstein:这不正确。 pszText 被声明为非常量的事实是一个人工制品。
LV_COLUMN结构用于设置和读取列信息。读取时,指针必须指向一个非常量缓冲区;写入时,它指定一个指向常量的指针。 C 没有规定可以根据它是用作输入参数还是输出参数来修改结构成员的常量。const_cast实际上是安全的,并且可以使用(带有适当的注释)。 Microsoft 不会以会破坏 98% 的软件的方式改变 API 的行为。
标签: visual-c++ unicode mfc